vendor/assets/javascripts/webshims/shims/form-shim-extend.js in webshims-rails-1.10.3 vs vendor/assets/javascripts/webshims/shims/form-shim-extend.js in webshims-rails-1.10.6

- old
+ new

@@ -1,11 +1,12 @@ -if(!Modernizr.formvalidation || jQuery.webshims.bugs.bustedValidity){ -jQuery.webshims.register('form-shim-extend', function($, webshims, window, document){ +if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){ +webshims.register('form-shim-extend', function($, webshims, window, document, undefined, options){ "use strict"; webshims.inputTypes = webshims.inputTypes || {}; //some helper-functions var cfg = webshims.cfg.forms; +var bugs = webshims.bugs; var isSubmit; var isNumber = function(string){ return (typeof string == 'number' || (string && string == string * 1)); }, @@ -17,10 +18,55 @@ getType = function(elem){ return (elem.getAttribute('type') || elem.type || '').toLowerCase(); } ; +(function(){ + if('querySelector' in document){ + try { + bugs.findRequired = !($('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /></form>')[0].querySelector('select:required')); + } catch(er){ + bugs.findRequired = false; + } + + if (bugs.bustedValidity || bugs.findRequired) { + (function(){ + var find = $.find; + var matchesSelector = $.find.matchesSelector; + + var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig; + var regFn = function(sel){ + return sel + '-element'; + }; + + $.find = (function(){ + var slice = Array.prototype.slice; + var fn = function(sel){ + var ar = arguments; + ar = slice.call(ar, 1, ar.length); + ar.unshift(sel.replace(regExp, regFn)); + return find.apply(this, ar); + }; + for (var i in find) { + if(find.hasOwnProperty(i)){ + fn[i] = find[i]; + } + } + return fn; + })(); + if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){ + $.find.matchesSelector = function(node, expr){ + expr = expr.replace(regExp, regFn); + return matchesSelector.call(this, node, expr); + }; + } + + })(); + } + } +})(); + //API to add new input types webshims.addInputType = function(type, obj){ typeModels[type] = obj; }; @@ -44,22 +90,44 @@ var option = $('> option:first-child', select); return !!option.prop('selected'); } return false; }; - +var modules = webshims.modules; +var emptyJ = $([]); +var getGroupElements = function(elem){ + elem = $(elem); + var name; + var form; + var ret = emptyJ; + if(elem[0].type == 'radio'){ + form = elem.prop('form'); + name = elem[0].name; + if(!name){ + ret = elem; + } else if(form){ + ret = $(form[name]); + } else { + ret = $(document.getElementsByName(name)).filter(function(){ + return !$.prop(this, 'form'); + }); + } + ret = ret.filter('[type="radio"]'); + } + return ret; +}; var validityRules = { valueMissing: function(input, val, cache){ if(!input.prop('required')){return false;} var ret = false; if(!('type' in cache)){ cache.type = getType(input[0]); } if(cache.nodeName == 'select'){ ret = (!val && (input[0].selectedIndex < 0 || isPlaceholderOptionSelected(input[0]) )); } else if(checkTypes[cache.type]){ - ret = (cache.type == 'checkbox') ? !input.is(':checked') : !webshims.modules["form-core"].getGroupElements(input).filter(':checked')[0]; + ret = (cache.type == 'checkbox') ? !input.is(':checked') : !getGroupElements(input).filter(':checked')[0]; } else { ret = !(val); } return ret; }, @@ -850,10 +918,56 @@ } catch (er) {} }); +if(!Modernizr.input.list){ + webshims.defineNodeNameProperty('datalist', 'options', { + prop: { + writeable: false, + get: function(){ + var elem = this; + var select = $('select', elem); + var options; + if(select[0]){ + options = select[0].options; + } else { + options = $('option', elem).get(); + if(options.length){ + webshims.warn('you should wrap your option-elements for a datalist in a select element to support IE and other old browsers.'); + } + } + return options; + } + } + }); + + webshims.ready('form-datalist', function(){ + webshims.defineNodeNameProperties('input', { + list: { + attr: { + get: function(){ + var val = webshims.contentAttr(this, 'list'); + return (val == null) ? undefined : val; + }, + set: function(value){ + var elem = this; + webshims.contentAttr(elem, 'list', value); + webshims.objectCreate(options.shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')}); + $(elem).triggerHandler('listdatalistchange'); + } + }, + initAttr: true, + reflect: true, + propType: 'element', + propNodeName: 'datalist' + } + }); + }); + +} + if(!Modernizr.formattribute || !Modernizr.fieldsetdisabled){ (function(){ (function(prop, undefined){ $.prop = function(elem, name, value){ var ret; @@ -1101,11 +1215,13 @@ }, removeAttr: { value: function(){ this.removeAttribute(name); if(removeProp){ - delete this.value; + try { + delete this.value; + } catch(er){} } updateProgress.isInChange = name; updateProgress(this); updateProgress.isInChange = false; } @@ -1200,21 +1316,21 @@ $(this).closest('select').each(selectChange); }); webshims.onNodeNamesPropertyModify('input', 'checked', function(value, boolVal){ var type = this.type; if(type == 'radio' && boolVal){ - webshims.modules["form-core"].getGroupElements(this).each(checkChange); + getGroupElements(this).each(checkChange); } else if(checkInputs[type]) { $(this).each(checkChange); } }); $(document).on('change', function(e){ if(checkInputs[e.target.type]){ if(e.target.type == 'radio'){ - webshims.modules["form-core"].getGroupElements(e.target).each(checkChange); + getGroupElements(e.target).each(checkChange); } else { $(e.target)[$.prop(e.target, 'checked') ? 'addClass' : 'removeClass']('prop-checked'); } } else if(e.target.nodeName.toLowerCase() == 'select'){ $(e.target).each(selectChange); @@ -1228,11 +1344,11 @@ var prop; if(checkInputs[this.type]){ prop = 'checked'; } else if(this.nodeName.toLowerCase() == 'option'){ prop = 'selected'; - } + } if(prop){ $(this)[$.prop(this, prop) ? 'addClass' : 'removeClass']('prop-checked'); } }) @@ -1240,17 +1356,45 @@ }); })(); } (function(){ + var bustedPlaceholder; Modernizr.textareaPlaceholder = !!('placeholder' in $('<textarea />')[0]); - if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder){return;} + if(Modernizr.input.placeholder && options.overridePlaceholder){ + bustedPlaceholder = true; + } + if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder && !bustedPlaceholder){ + (function(){ + var ua = navigator.userAgent; + + if(ua.indexOf('Mobile') != -1 && ua.indexOf('Safari') != -1){ + $(window).on('orientationchange', (function(){ + var timer; + var retVal = function(i, value){ + return value; + }; + + var set = function(){ + $('input[placeholder], textarea[placeholder]').attr('placeholder', retVal); + }; + return function(e){ + clearTimeout(timer); + timer = setTimeout(set, 9); + }; + })()); + } + })(); + + //abort + return; + } var isOver = (webshims.cfg.forms.placeholderType == 'over'); var isResponsive = (webshims.cfg.forms.responsivePlaceholder); var polyfillElements = ['textarea']; - if(!Modernizr.input.placeholder){ + if(!Modernizr.input.placeholder || bustedPlaceholder){ polyfillElements.push('input'); } var setSelection = function(elem){ try { @@ -1383,11 +1527,11 @@ tel: 1, number: 1 } ; - if(webshims.modules["form-number-date-ui"].loaded){ + if(modules["form-number-date-ui"].loaded){ delete allowedPlaceholder.number; } return { create: function(elem){ @@ -1401,15 +1545,15 @@ changePlaceholderVisibility(this, false, false, data, e.type ); data.box[e.type == 'focus' ? 'addClass' : 'removeClass']('placeholder-focused'); }); if((form = $.prop(elem, 'form'))){ - $(form).on('reset.placeholder', function(e){ + $(elem).onWSOff('reset.placeholder', function(e){ setTimeout(function(){ changePlaceholderVisibility(elem, false, false, data, e.type ); }, 0); - }); + }, false, form); } if(elem.type == 'password' || isOver){ data.text = createPlaceholder(elem); if(isResponsive || $(elem).is('.responsive-width') || (elem.currentStyle || {width: ''}).width.indexOf('%') != -1){ @@ -1444,43 +1588,41 @@ $.each(['Left', 'Top'], function(i, side){ var size = (parseInt($.css(elem, 'padding'+ side), 10) || 0) + Math.max((parseInt($.css(elem, 'margin'+ side), 10) || 0), 0) + (parseInt($.css(elem, 'border'+ side +'Width'), 10) || 0); data.text.css('padding'+ side, size); }); - $(document) - .onTrigger('updateshadowdom', function(){ + $(elem) + .onWSOff('updateshadowdom', function(){ var height, width; if((width = elem.offsetWidth) || (height = elem.offsetHeight)){ data.text .css({ width: width, height: height }) .css($(elem).position()) ; } - }) + }, true) ; } else { var reset = function(e){ if($(elem).hasClass('placeholder-visible')){ hidePlaceholder(elem, data, ''); - if(e && e.type == 'submit'){ - setTimeout(function(){ - if(e.isDefaultPrevented()){ - changePlaceholderVisibility(elem, false, false, data ); - } - }, 9); - } + setTimeout(function(){ + if(!e || e.type != 'submit' || e.isDefaultPrevented()){ + changePlaceholderVisibility(elem, false, false, data ); + } + }, 9); } }; - $(window).on('beforeunload', reset); + $(elem).onWSOff('beforeunload', reset, false, window); data.box = $(elem); if(form){ - $(form).submit(reset); + $(elem).onWSOff('submit', reset, false, form); } } return data; }, @@ -1509,15 +1651,24 @@ polyfillElements.forEach(function(nodeName){ var desc = webshims.defineNodeNameProperty(nodeName, 'placeholder', { attr: { set: function(val){ var elem = this; - webshims.contentAttr(elem, 'placeholder', val); + if(bustedPlaceholder){ + webshims.data(elem, 'bustedPlaceholder', val); + elem.placeholder = ''; + } else { + webshims.contentAttr(elem, 'placeholder', val); + } pHolder.update(elem, val); }, get: function(){ - return webshims.contentAttr(this, 'placeholder'); + var placeholder; + if(bustedPlaceholder){ + placeholder = webshims.data(this, 'bustedPlaceholder'); + } + return placeholder || webshims.contentAttr(this, 'placeholder'); } }, reflect: true, initAttr: true }); @@ -1530,10 +1681,12 @@ ['attr', 'prop'].forEach(function(propType){ placeholderValueDesc[propType] = { set: function(val){ var elem = this; var placeholder; - + if(bustedPlaceholder){ + placeholder = webshims.data(elem, 'bustedPlaceholder'); + } if(!placeholder){ placeholder = webshims.contentAttr(elem, 'placeholder'); } $.removeData(elem, 'cachedValidity'); var ret = desc[propType]._supset.call(elem, val);