vendor/assets/javascripts/webshims/shims/form-shim-extend.js in webshims-rails-0.4.7 vs vendor/assets/javascripts/webshims/shims/form-shim-extend.js in webshims-rails-1.10.3
- old
+ new
@@ -322,12 +322,12 @@
validityState = $.extend({}, validityPrototype);
if( !$.prop(elem, 'willValidate') || elem.type == 'submit' ){
return validityState;
}
- var val = jElm.val(),
- cache = {nodeName: elem.nodeName.toLowerCase()}
+ var val = jElm.val(),
+ cache = {nodeName: elem.nodeName.toLowerCase()}
;
validityState.customError = !!(webshims.data(elem, 'customvalidationMessage'));
if( validityState.customError ){
validityState.valid = false;
@@ -349,11 +349,11 @@
webshims.defineNodeNamesBooleanProperty(['input', 'textarea', 'select'], 'required', {
set: function(value){
$(this).getShadowFocusElement().attr('aria-required', !!(value)+'');
},
- initAttr: (Modernizr.localstorage)//only if we have aria-support
+ initAttr: Modernizr.localstorage //only if we have aria-support
});
webshims.reflectProperties(['input'], ['pattern']);
@@ -670,11 +670,12 @@
(function(){
var noInputTriggerEvts = {updateInput: 1, input: 1},
fixInputTypes = {
date: 1,
- time: 1
+ time: 1,
+ "datetime-local": 1
},
noFocusEvents = {
focusout: 1,
blur: 1
},
@@ -878,14 +879,12 @@
if(elements){
elements.remove();
$.removeData(form, 'webshimsAddedElements');
}
};
- var rCRLF = /\r?\n/g,
- rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
- rselectTextarea = /^(?:select|textarea)/i;
+
if(!Modernizr.formattribute){
webshims.defineNodeNamesProperty(['input', 'textarea', 'select', 'button', 'fieldset'], 'form', {
prop: {
get: function(){
var form = webshims.contentAttr(this, 'form');
@@ -988,40 +987,188 @@
writeable: false
}
});
}
- $.fn.serializeArray = function() {
- return this.map(function(){
- var elements = $.prop(this, 'elements');
- return elements ? $.makeArray( elements ) : this;
- })
- .filter(function(){
- return this.name && !this.disabled &&
- ( this.checked || rselectTextarea.test( this.nodeName ) ||
- rinput.test( this.type ) );
- })
- .map(function( i, elem ){
- var val = $( this ).val();
+ if(!$.fn.finish && parseFloat($.fn.jquery, 10) < 1.9){
+ var rCRLF = /\r?\n/g,
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+ rselectTextarea = /^(?:select|textarea)/i;
+ $.fn.serializeArray = function() {
+ return this.map(function(){
+ var elements = $.prop(this, 'elements');
+ return elements ? $.makeArray( elements ) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
+ rinput.test( this.type ) );
+ })
+ .map(function( i, elem ){
+ var val = $( this ).val();
+
+ return val == null ?
+ null :
+ $.isArray( val ) ?
+ $.map( val, function( val, i ){
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ };
+ }
- return val == null ?
- null :
- $.isArray( val ) ?
- $.map( val, function( val, i ){
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- }) :
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- }).get();
- };
-
})();
}
+ if($('<input />').prop('labels') == null){
+ webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
+ prop: {
+ get: function(){
+ if(this.type == 'hidden'){return null;}
+ var id = this.id;
+ var labels = $(this)
+ .closest('label')
+ .filter(function(){
+ var hFor = (this.attributes['for'] || {});
+ return (!hFor.specified || hFor.value == id);
+ })
+ ;
+
+ if(id) {
+ labels = labels.add('label[for="'+ id +'"]');
+ }
+ return labels.get();
+ },
+ writeable: false
+ }
+ });
+ }
+
+ if(!('value' in document.createElement('progress'))){
+ (function(){
+
+ var nan = parseInt('NaN', 10);
+
+ var updateProgress = function(progress){
+ var position;
+
+
+ position = $.prop(progress, 'position');
+
+ $.attr(progress, 'data-position', position);
+ $('> span', progress).css({width: (position < 0 ? 100 : position * 100) +'%'});
+ };
+ var desc = {
+ position: {
+ prop: {
+ get: function(){
+ var max;
+ //jQuery 1.8.x try's to normalize "0" to 0
+ var val = this.getAttribute('value');
+ var ret = -1;
+
+ val = val ? (val * 1) : nan;
+ if(!isNaN(val)){
+ max = $.prop(this, 'max');
+ ret = Math.max(Math.min(val / max, 1), 0);
+ if(updateProgress.isInChange){
+ $.attr(this, 'aria-valuenow', ret * 100);
+ if(updateProgress.isInChange == 'max'){
+ $.attr(this, 'aria-valuemax', max);
+ }
+ }
+ } else if(updateProgress.isInChange) {
+ $(this).removeAttr('aria-valuenow');
+ }
+ return ret;
+ },
+ writeable: false
+ }
+ }
+ };
+
+ $.each({value: 0, max: 1}, function(name, defValue){
+ var removeProp = (name == 'value' && !$.fn.finish);
+ desc[name] = {
+ attr: {
+ set: function(value){
+ var ret = desc[name].attr._supset.call(this, value);
+ updateProgress.isInChange = name;
+ updateProgress(this);
+ updateProgress.isInChange = false;
+ return ret;
+ }
+ },
+ removeAttr: {
+ value: function(){
+ this.removeAttribute(name);
+ if(removeProp){
+ delete this.value;
+ }
+ updateProgress.isInChange = name;
+ updateProgress(this);
+ updateProgress.isInChange = false;
+ }
+ },
+ prop: {
+ get: function(){
+ var max;
+ var ret = (desc[name].attr.get.call(this) * 1);
+ if(ret < 0 || isNaN(ret)){
+ ret = defValue;
+ } else if(name == 'value'){
+ ret = Math.min(ret, $.prop(this, 'max'));
+ } else if(ret === 0){
+ ret = defValue;
+ }
+ return ret;
+ },
+ set: function(value){
+ value = value * 1;
+ if(isNaN(value)){
+ webshims.error('Floating-point value is not finite.');
+ }
+ return desc[name].attr.set.call(this, value);
+ }
+ }
+ };
+ });
+
+ webshims.createElement(
+ 'progress',
+ function(){
+ var labels = $(this)
+ .attr({role: 'progressbar', 'aria-valuemin': '0'})
+ .html('<span class="progress-value" />')
+ .jProp('labels')
+ .map(function(){
+ return webshims.getID(this);
+ })
+ .get()
+ ;
+ if(labels.length){
+ $.attr(this, 'aria-labelledby', labels.join(' '));
+ } else {
+ webshims.info("you should use label elements for your prgogress elements");
+ }
+
+ updateProgress.isInChange = 'max';
+ updateProgress(this);
+ updateProgress.isInChange = false;
+ },
+ desc
+ );
+
+ })();
+ }
+
try {
document.querySelector(':checked');
} catch(er){
(function(){
+ $('html').addClass('no-csschecked');
var checkInputs = {
radio: 1,
checkbox: 1
};
var selectChange = function(){
@@ -1123,10 +1270,11 @@
var hidePlaceholder = function(elem, data, value, _onFocus){
if(value === false){
value = $.prop(elem, 'value');
}
+
if(!isOver && elem.type != 'password'){
if(!value && _onFocus && setSelection(elem)){
var selectTimer = setTimeout(function(){
setSelection(elem);
}, 9);
@@ -1152,12 +1300,13 @@
$(elem).unbind('.placeholderremove');
}
})
;
return;
+ } else if(!_onFocus && !value && elem.value){ //especially on submit
+ elem.value = value;
}
- elem.value = value;
} else if(!value && _onFocus){
$(elem)
.off('.placeholderremove')
.on({
'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
@@ -1188,19 +1337,22 @@
if(!data){
data = $.data(elem, 'placeHolder');
if(!data){return;}
}
$(elem).unbind('.placeholderremove');
- if(type == 'focus' || (!type && $(elem).is(':focus'))){
+
+ if(value === false){
+ value = $.prop(elem, 'value');
+ }
+
+ if(!value && (type == 'focus' || (!type && $(elem).is(':focus')))){
if(elem.type == 'password' || isOver || $(elem).hasClass('placeholder-visible')){
hidePlaceholder(elem, data, '', true);
}
return;
}
- if(value === false){
- value = $.prop(elem, 'value');
- }
+
if(value){
hidePlaceholder(elem, data, value);
return;
}
if(placeholderTxt === false){
@@ -1210,25 +1362,17 @@
showPlaceholder(elem, data, placeholderTxt);
} else {
hidePlaceholder(elem, data, value);
}
},
+ hasLabel = function(elem){
+ elem = $(elem);
+ return !!(elem.prop('title') || elem.attr('aria-labelledby') || elem.attr('aria-label') || elem.jProp('labels').length);
+ },
createPlaceholder = function(elem){
elem = $(elem);
- var id = elem.prop('id'),
- hasLabel = !!(elem.prop('title') || elem.attr('aria-labelledby'))
- ;
- if(!hasLabel && id){
- hasLabel = !!( $('label[for="'+ id +'"]', elem[0].form)[0] );
- }
- if(!hasLabel){
- if(!id){
- id = $.webshims.getID(elem);
- }
- hasLabel = !!($('label #'+ id)[0]);
- }
- return $( hasLabel ? '<span class="placeholder-text"></span>' : '<label for="'+ id +'" class="placeholder-text"></label>');
+ return $( hasLabel(elem) ? '<span class="placeholder-text"></span>' : '<label for="'+ elem.prop('id') +'" class="placeholder-text"></label>');
},
pHolder = (function(){
var delReg = /\n|\r|\f|\t/g,
allowedPlaceholder = {
text: 1,
@@ -1239,10 +1383,14 @@
tel: 1,
number: 1
}
;
+ if(webshims.modules["form-number-date-ui"].loaded){
+ delete allowedPlaceholder.number;
+ }
+
return {
create: function(elem){
var data = $.data(elem, 'placeHolder');
var form;
var responsiveElem;
@@ -1337,14 +1485,11 @@
return data;
},
update: function(elem, val){
var type = ($.attr(elem, 'type') || $.prop(elem, 'type') || '').toLowerCase();
if(!allowedPlaceholder[type] && !$.nodeName(elem, 'textarea')){
- webshims.error('placeholder not allowed on input[type="'+type+'"]');
- if(type == 'date'){
- webshims.error('but you can use data-placeholder for input[type="date"]');
- }
+ webshims.warn('placeholder not allowed on input[type="'+type+'"], but it is a good fallback :-)');
return;
}
var data = pHolder.create(elem);
@@ -1384,13 +1529,15 @@
var desc;
['attr', 'prop'].forEach(function(propType){
placeholderValueDesc[propType] = {
set: function(val){
var elem = this;
- var placeholder = webshims.contentAttr(elem, 'placeholder');
-
+ var placeholder;
+ if(!placeholder){
+ placeholder = webshims.contentAttr(elem, 'placeholder');
+ }
$.removeData(elem, 'cachedValidity');
var ret = desc[propType]._supset.call(elem, val);
if(placeholder && 'value' in elem){
changePlaceholderVisibility(elem, val, placeholder);
}
@@ -1437,11 +1584,11 @@
var outputCreate = function(elem){
if(elem.getAttribute('aria-live')){return;}
elem = $(elem);
var value = (elem.text() || '').trim();
- var id = elem.attr('id');
+ var id = elem.prop('id');
var htmlFor = elem.attr('for');
var shim = $('<input class="output-shim" type="text" disabled name="'+ (elem.attr('name') || '')+'" value="'+value+'" style="display: none !important;" />').insertAfter(elem);
var form = shim[0].form || doc;
var setValue = function(val){
shim[0].value = val;
@@ -1454,11 +1601,13 @@
webshims.contentAttr(elem[0], 'value', value);
elem.attr({'aria-live': 'polite'});
if(id){
shim.attr('id', id);
- elem.attr('aria-labelledby', webshims.getID($('label[for="'+id+'"]', form)));
+ elem.attr('aria-labelledby', elem.jProp('labels').map(function(){
+ return webshims.getID(this);
+ }).get().join(' '));
}
if(htmlFor){
id = webshims.getID(elem);
htmlFor.split(' ').forEach(function(control){
control = document.getElementById(control);
@@ -1501,11 +1650,10 @@
lastVal = input.prop('value'),
trigger = function(e){
//input === null
if(!input){return;}
var newVal = input.prop('value');
-
if(newVal !== lastVal){
lastVal = newVal;
if(!e || !noInputTriggerEvts[e.type]){
webshims.triggerInlineForm && webshims.triggerInlineForm(input[0], 'input');
}
@@ -1526,11 +1674,11 @@
}
;
clearInterval(timer);
- timer = setInterval(trigger, 99);
+ timer = setInterval(trigger, 200);
extraTest();
input.on({
'keyup keypress keydown paste cut': extraTest,
focusout: unbind,
'input updateInput change': trigger
@@ -1541,10 +1689,10 @@
$.event.customEvent.updateInput = true;
}
$(doc)
.on('focusin', function(e){
- if( e.target && e.target.type && !e.target.readOnly && !e.target.disabled && (e.target.nodeName || '').toLowerCase() == 'input' && !noInputTypes[e.target.type] ){
+ if( e.target && !e.target.readOnly && !e.target.disabled && (e.target.nodeName || '').toLowerCase() == 'input' && !noInputTypes[e.target.type] && !(webshims.data(e.target, 'implemented') || {}).inputwidgets){
observe($(e.target));
}
})
;
})();