vendor/assets/javascripts/webshims/shims/combos/15.js in webshims-rails-1.10.3 vs vendor/assets/javascripts/webshims/shims/combos/15.js in webshims-rails-1.10.6
- old
+ new
@@ -1,18 +1,69 @@
//DOM-Extension helper
-jQuery.webshims.register('dom-extend', function($, webshims, window, document, undefined){
+webshims.register('dom-extend', function($, webshims, window, document, undefined){
"use strict";
- webshims.assumeARIA = Modernizr.localstorage || Modernizr.video || Modernizr.boxsizing;
+ webshims.assumeARIA = $.support.getSetAttribute || Modernizr.canvas || Modernizr.video || Modernizr.boxsizing;
if($('<input type="email" />').attr('type') == 'text' || $('<form />').attr('novalidate') === "" || ('required' in $('<input />')[0].attributes)){
webshims.error("IE browser modes are busted in IE10. Please test your HTML/CSS/JS with a real IE version or at least IETester or similiar tools");
}
if(!$.parseHTML){
webshims.error("Webshims needs jQuery 1.8+ to work properly. Please update your jQuery version or downgrade webshims.");
}
+ if (!webshims.cfg.no$Switch) {
+ var switch$ = function(){
+ if (window.jQuery && (!window.$ || window.jQuery == window.$) && !window.jQuery.webshims) {
+ webshims.error("jQuery was included more than once. Make sure to include it only once! Webshims and other Plugins might not work properly.");
+ if (window.$) {
+ window.$ = webshims.$;
+ }
+ window.jQuery = webshims.$;
+ }
+ if(webshims.M != Modernizr){
+ webshims.error("Modernizr was included more than once. Make sure to include it only once! Webshims and other scripts might not work properly.");
+ for(var i in Modernizr){
+ if(!(i in webshims.M)){
+ webshims.M[i] = Modernizr[i];
+ }
+ }
+ Modernizr = webshims.M;
+ }
+ };
+ switch$();
+ setTimeout(switch$, 90);
+ $(switch$);
+ }
+// (function(){
+// var hostNames = {
+// 'afarkas.github.io': 1,
+// localhost: 1,
+// '127.0.0.1': 1
+// };
+//
+// if( webshims.debug && (hostNames[location.hostname] || location.protocol == 'file:') ){
+// var list = $('<ul class="webshims-debug-list" />');
+// webshims.errorLog.push = function(message){
+// list.appendTo('body');
+// $('<li style="display: none;">'+ message +'</li>')
+// .appendTo(list)
+// .slideDown()
+// .delay(3000)
+// .slideUp(function(){
+// $(this).remove();
+// if(!$('li', list).length){
+// list.detach();
+// }
+// })
+// ;
+// };
+// $.each(webshims.errorLog, function(i, message){
+// webshims.errorLog.push(message);
+// });
+// }
+// })();
//shortcus
var modules = webshims.modules;
var listReg = /\s*,\s*/;
@@ -26,10 +77,28 @@
var oldVal = $.fn.val;
var singleVal = function(elem, name, val, pass, _argless){
return (_argless) ? oldVal.call($(elem)) : oldVal.call($(elem), val);
};
+ //jquery mobile and jquery ui
+ if(!$.widget){
+ (function(){
+ var _cleanData = $.cleanData;
+ $.cleanData = function( elems ) {
+ if(!$.widget){
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ }
+ _cleanData( elems );
+ };
+ })();
+ }
+
$.fn.val = function(val){
var elem = this[0];
if(arguments.length && val == null){
val = '';
@@ -59,10 +128,22 @@
};
$.fn.onTrigger = function(evt, fn){
return this.on(evt, fn).each(fn);
};
+ $.fn.onWSOff = function(evt, fn, trigger, evtDel){
+ if(!evtDel){
+ evtDel = document;
+ }
+ $(evtDel)[trigger ? 'onTrigger' : 'on'](evt, fn);
+ this.on('remove', function(e){
+ if(!e.originalEvent){
+ $(evtDel).off(evt, fn);
+ }
+ });
+ };
+
var dataID = '_webshimsLib'+ (Math.round(Math.random() * 1000));
var elementData = function(elem, key, val){
elem = elem.jquery ? elem[0] : elem;
if(!elem){return val || {};}
var data = $.data(elem, dataID);
@@ -420,11 +501,11 @@
};
})(),
implement: function(elem, type){
var data = elementData(elem, 'implemented') || elementData(elem, 'implemented', {});
if(data[type]){
- webshims.info(type +' already implemented for element #'+elem.id);
+ webshims.warn(type +' already implemented for element #'+elem.id);
return false;
}
data[type] = true;
return true;
},
@@ -564,10 +645,16 @@
opts.shadowFocusElement = opts.shadowFocusElement[0];
}
shadowFocusElementData = $.data(opts.shadowFocusElement, dataID) || $.data(opts.shadowFocusElement, dataID, shadowFocusElementData);
}
+ $(nativeElem).on('remove', function(e){
+ if (!e.originalEvent) {
+ $(shadowElem).remove();
+ }
+ });
+
nativeData.hasShadow = shadowElem;
shadowFocusElementData.nativeElement = shadowData.nativeElement = nativeElem;
shadowFocusElementData.shadowData = shadowData.shadowData = nativeData.shadowData = {
nativeElement: nativeElem,
shadowElement: shadowElem,
@@ -1039,36 +1126,13 @@
}
});
})(jQuery, document);
-//additional tests for partial implementation of forms features
-(function($){
+webshims.register('form-core', function($, webshims, window, document, undefined, options){
"use strict";
- var isWebkit = 'webkitURL' in window;
- var Modernizr = window.Modernizr;
- var webshims = $.webshims;
- var bugs = webshims.bugs;
- var form = $('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /><input required="" name="a" /></form>');
- var testRequiredFind = function(){
- if(form[0].querySelector){
- try {
- bugs.findRequired = !(form[0].querySelector('select:required'));
- } catch(er){
- bugs.findRequired = false;
- }
- }
- };
- var inputElem = $('input', form).eq(0);
- var onDomextend = function(fn){
- webshims.loader.loadList(['dom-extend']);
- webshims.ready('dom-extend', fn);
- };
-
- bugs.findRequired = false;
- bugs.validationMessage = false;
-
+
webshims.capturingEventPrevented = function(e){
if(!e._isPolyfilled){
var isDefaultPrevented = e.isDefaultPrevented;
var preventDefault = e.preventDefault;
e.preventDefault = function(){
@@ -1083,200 +1147,263 @@
};
e._isPolyfilled = true;
}
};
- if(!Modernizr.formvalidation || bugs.bustedValidity){
- testRequiredFind();
- } else {
+ if(Modernizr.formvalidation && !webshims.bugs.bustedValidity){
//create delegatable events
webshims.capturingEvents(['invalid'], true);
-
- if(window.opera || window.testGoodWithFix){
+ }
+
+ var isValid = function(elem){
+ return ($.prop(elem, 'validity') || {valid: 1}).valid;
+ };
+ var lazyLoad = function(){
+ var toLoad = ['form-validation'];
+ if(options.lazyCustomMessages){
+ options.customMessages = true;
+ toLoad.push('form-message');
+ }
+ if(options.addValidators){
+ toLoad.push('form-validators');
+ }
+ webshims.reTest(toLoad);
+ $(document).off('.lazyloadvalidation');
+ };
+ /*
+ * Selectors for all browsers
+ */
+ var hasInvalid = function(elem){
+ var ret = false;
+ $(elem).jProp('elements').each(function(){
+ ret = $(this).is(':invalid');
+ if(ret){
+ return false;
+ }
+ });
+ return ret;
+ };
+ var rElementsGroup = /^(?:form)$/i;///^(?:form|fieldset)$/i
+ $.extend($.expr[":"], {
+ "valid-element": function(elem){
+ return rElementsGroup.test(elem.nodeName || '') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
+ },
+ "invalid-element": function(elem){
+ return rElementsGroup.test(elem.nodeName || '') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
+ },
+ "required-element": function(elem){
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
+ },
+ "user-error": function(elem){
+ return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
+ },
+ "optional-element": function(elem){
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
+ }
+ });
+
+ ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
+ $.expr[":"][name] = $.expr.filters[name+"-element"];
+ });
+
+
+ $.expr[":"].focus = function( elem ) {
+ try {
+ var doc = elem.ownerDocument;
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
+ } catch(e){}
+ return false;
+ };
+
+ webshims.triggerInlineForm = function(elem, event){
+ $(elem).trigger(event);
+ };
+
+ var lazyLoadProxy = function(obj, fn, args){
+ lazyLoad();
+ webshims.ready('form-validation', function(){
+ obj[fn].apply(obj, args);
+ });
+ };
+
+
+ webshims.wsPopover = {
+ id: 0,
+ _create: function(){
+ this.options = $.extend({}, webshims.cfg.wspopover, this.options);
+ this.id = webshims.wsPopover.id++;
+ this.eventns = '.wsoverlay' + this.id;
+ this.timers = {};
+ this.element = $('<div class="ws-popover" tabindex="-1"><div class="ws-po-outerbox"><div class="ws-po-arrow"><div class="ws-po-arrowbox" /></div><div class="ws-po-box" /></div></div>');
+ this.contentElement = $('.ws-po-box', this.element);
+ this.lastElement = $([]);
+ this.bindElement();
- form.appendTo('head');
+ this.element.data('wspopover', this);
- testRequiredFind();
- bugs.validationMessage = !(inputElem.prop('validationMessage'));
-
- webshims.reTest(['form-native-extend', 'form-message']);
-
- form.remove();
-
- $(function(){
- onDomextend(function(){
-
- //Opera shows native validation bubbles in case of input.checkValidity()
- // Opera 11.6/12 hasn't fixed this issue right, it's buggy
- var preventDefault = function(e){
- e.preventDefault();
- };
-
- ['form', 'input', 'textarea', 'select'].forEach(function(name){
- var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
- prop: {
- value: function(){
- if (!webshims.fromSubmit) {
- $(this).on('invalid.checkvalidity', preventDefault);
- }
-
- webshims.fromCheckValidity = true;
- var ret = desc.prop._supvalue.apply(this, arguments);
- if (!webshims.fromSubmit) {
- $(this).unbind('invalid.checkvalidity', preventDefault);
- }
- webshims.fromCheckValidity = false;
- return ret;
- }
- }
- });
- });
-
- });
+ },
+ options: {},
+ content: function(html){
+ this.contentElement.html(html);
+ },
+ bindElement: function(){
+ var that = this;
+ var stopBlur = function(){
+ that.stopBlur = false;
+ };
+ this.preventBlur = function(e){
+ that.stopBlur = true;
+ clearTimeout(that.timers.stopBlur);
+ that.timers.stopBlur = setTimeout(stopBlur, 9);
+ };
+ this.element.on({
+ 'mousedown': this.preventBlur
});
+ },
+ show: function(){
+ lazyLoadProxy(this, 'show', arguments);
}
-
- if(isWebkit && !webshims.bugs.bustedValidity){
- (function(){
- var elems = /^(?:textarea|input)$/i;
- var form = false;
-
- document.addEventListener('contextmenu', function(e){
- if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
- setTimeout(function(){
- form = false;
- }, 1);
- }
- }, false);
-
- $(window).on('invalid', function(e){
- if(e.originalEvent && form && form == e.target.form){
- e.wrongWebkitInvalid = true;
- e.stopImmediatePropagation();
- }
- });
-
- })();
+ };
+
+ /* some extra validation UI */
+ webshims.validityAlert = {
+ showFor: function(){
+ lazyLoadProxy(this, 'showFor', arguments);
}
- }
-
- $.webshims.register('form-core', function($, webshims, window, document, undefined, options){
+ };
- var checkTypes = {checkbox: 1, radio: 1};
- var emptyJ = $([]);
- var bugs = webshims.bugs;
- 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;
- };
+
+ /* extension, but also used to fix native implementation workaround/bugfixes */
+ (function(){
+ var firstEvent,
+ invalids = [],
+ stopSubmitTimer,
+ form
+ ;
- var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
- var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
- if(key && message[key]){
- message = message[key];
+ $(document).on('invalid', function(e){
+ if(e.wrongWebkitInvalid){return;}
+ var jElm = $(e.target);
+
+
+ if(!firstEvent){
+ //trigger firstinvalid
+ firstEvent = $.Event('firstinvalid');
+ firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
+ var firstSystemInvalid = $.Event('firstinvalidsystem');
+ $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
+ jElm.trigger(firstEvent);
}
- if(typeof message == 'object'){
- validity = validity || $.prop(elem, 'validity') || {valid: 1};
- if(!validity.valid){
- $.each(validity, function(name, prop){
- if(prop && name != 'valid' && message[name]){
- message = message[name];
- return false;
- }
- });
- }
+
+ //if firstinvalid was prevented all invalids will be also prevented
+ if( firstEvent && firstEvent.isDefaultPrevented() ){
+ e.preventDefault();
}
-
- if(typeof message == 'object'){
- message = message.defaultMessage;
+ invalids.push(e.target);
+ e.extraData = 'fix';
+ clearTimeout(stopSubmitTimer);
+ stopSubmitTimer = setTimeout(function(){
+ var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
+ //reset firstinvalid
+ firstEvent = false;
+ invalids = [];
+ $(e.target).trigger(lastEvent, lastEvent);
+ }, 9);
+ jElm = null;
+ });
+ })();
+
+
+ webshims.getContentValidationMessage = function(elem, validity, key){
+ var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
+ if(key && message[key]){
+ message = message[key];
+ }
+ if(typeof message == 'object'){
+ validity = validity || $.prop(elem, 'validity') || {valid: 1};
+ if(!validity.valid){
+ $.each(validity, function(name, prop){
+ if(prop && name != 'valid' && message[name]){
+ message = message[name];
+ return false;
+ }
+ });
}
- return message || '';
- };
+ }
- /*
- * Selectors for all browsers
- */
- var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
- var hasInvalid = function(elem){
- var ret = false;
- $($.prop(elem, 'elements')).each(function(){
- ret = $(this).is(':invalid');
- if(ret){
- return false;
+ if(typeof message == 'object'){
+ message = message.defaultMessage;
+ }
+ return message || '';
+ };
+
+ $.fn.getErrorMessage = function(key){
+ var message = '';
+ var elem = this[0];
+ if(elem){
+ message = webshims.getContentValidationMessage(elem, false, key) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
+ }
+ return message;
+ };
+
+
+ webshims.ready('forms', function(){
+ $(document).on('focusin.lazyloadvalidation', function(e){
+ if('form' in e.target && $(e.target).is(':invalid')){
+ lazyLoad();
+ }
+ });
+ });
+ webshims.ready('WINDOWLOAD', lazyLoad);
+ if(options.overrideMessages){
+ options.customMessages = true;
+ webshims.reTest('form-message');
+ webshims.error('overrideMessages is deprecated. use customMessages instead.');
+ }
+ if(options.replaceValidationUI){
+ webshims.ready('DOM forms', function(){
+ $(document).on('firstinvalid', function(e){
+ if(!e.isInvalidUIPrevented()){
+ e.preventDefault();
+ webshims.validityAlert.showFor( e.target );
}
});
- return ret;
- };
- $.extend($.expr[":"], {
- "valid-element": function(elem){
- return $.nodeName(elem, 'form') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
- },
- "invalid-element": function(elem){
- return $.nodeName(elem, 'form') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
- },
- "required-element": function(elem){
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
- },
- "user-error": function(elem){
- return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
- },
- "optional-element": function(elem){
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
- },
- "in-range": function(elem){
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
- return false;
- }
- var val = $.prop(elem, 'validity');
- return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
- },
- "out-of-range": function(elem){
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
- return false;
- }
- var val = $.prop(elem, 'validity');
- return !!(val && (val.rangeOverflow || val.rangeUnderflow));
- }
-
});
+ }
+});
+
+
+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));
+ },
+ typeModels = webshims.inputTypes,
+ checkTypes = {
+ radio: 1,
+ checkbox: 1
+ },
+ 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;
+ }
- ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
- $.expr[":"][name] = $.expr.filters[name+"-element"];
- });
-
-
- $.expr[":"].focus = function( elem ) {
- try {
- var doc = elem.ownerDocument;
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
- } catch(e){}
- return false;
- };
-
-
- var customEvents = $.event.customEvent || {};
- var isValid = function(elem){
- return ($.prop(elem, 'validity') || {valid: 1}).valid;
- };
-
if (bugs.bustedValidity || bugs.findRequired) {
(function(){
var find = $.find;
var matchesSelector = $.find.matchesSelector;
@@ -1307,484 +1434,12 @@
};
}
})();
}
-
- //ToDo needs testing
- var oldAttr = $.prop;
- var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
- $.prop = function(elem, name, val){
- var ret = oldAttr.apply(this, arguments);
- if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass(invalidClass)){
- if(isValid(elem)){
- $(elem).getShadowElement().removeClass(invalidClass);
- if(name == 'checked' && val) {
- getGroupElements(elem).not(elem).removeClass(invalidClass).removeAttr('aria-invalid');
- }
- }
- }
- return ret;
- };
-
- var returnValidityCause = function(validity, elem){
- var ret;
- $.each(validity, function(name, value){
- if(value){
- ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
- return false;
- }
- });
- return ret;
- };
-
- var isInGroup = function(name){
- var ret;
- try {
- ret = document.activeElement.name === name;
- } catch(e){}
- return ret;
- };
- /* form-ui-invalid/form-ui-valid are deprecated. use user-error/user-success instead */
- var invalidClass = 'user-error';
- var validClass = 'user-success';
- var stopChangeTypes = {
- time: 1,
- date: 1,
- month: 1,
- datetime: 1,
- week: 1,
- 'datetime-local': 1
- };
- var switchValidityClass = function(e){
- var elem, timer;
- if(!e.target){return;}
- elem = $(e.target).getNativeElement()[0];
- if(elem.type == 'submit' || !$.prop(elem, 'willValidate')){return;}
- timer = $.data(elem, 'webshimsswitchvalidityclass');
- var switchClass = function(){
- if(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name)){return;}
- var validity = $.prop(elem, 'validity');
- var shadowElem = $(elem).getShadowElement();
- var addClass, removeClass, trigger, generaltrigger, validityCause;
-
- if(isWebkit && e.type == 'change' && !bugs.bustedValidity && stopChangeTypes[shadowElem.prop('type')] && shadowElem.is(':focus')){return;}
-
- $(elem).trigger('refreshCustomValidityRules');
-
- if(validity.valid){
- if(!shadowElem.hasClass(validClass)){
- addClass = validClass;
- removeClass = invalidClass;
- generaltrigger = 'changedvaliditystate';
- trigger = 'changedvalid';
- if(checkTypes[elem.type] && elem.checked){
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
- }
- $.removeData(elem, 'webshimsinvalidcause');
- }
- } else {
- validityCause = returnValidityCause(validity, elem);
- if($.data(elem, 'webshimsinvalidcause') != validityCause){
- $.data(elem, 'webshimsinvalidcause', validityCause);
- generaltrigger = 'changedvaliditystate';
- }
- if(!shadowElem.hasClass(invalidClass)){
- addClass = invalidClass;
- removeClass = validClass;
- if (checkTypes[elem.type] && !elem.checked) {
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
- }
- trigger = 'changedinvalid';
- }
- }
-
- if(addClass){
- shadowElem.addClass(addClass).removeClass(removeClass);
- //jQuery 1.6.1 IE9 bug (doubble trigger bug)
- setTimeout(function(){
- $(elem).trigger(trigger);
- }, 0);
- }
- if(generaltrigger){
- setTimeout(function(){
- $(elem).trigger(generaltrigger);
- }, 0);
- }
-
- $.removeData(elem, 'webshimsswitchvalidityclass');
- };
-
- if(timer){
- clearTimeout(timer);
- }
- if(e.type == 'refreshvalidityui'){
- switchClass();
- } else {
- $.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
- }
- };
-
- $(document).on(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
- customEvents.changedvaliditystate = true;
- customEvents.refreshCustomValidityRules = true;
- customEvents.changedvalid = true;
- customEvents.changedinvalid = true;
- customEvents.refreshvalidityui = true;
-
-
- webshims.triggerInlineForm = function(elem, event){
- $(elem).trigger(event);
- };
-
- webshims.modules["form-core"].getGroupElements = getGroupElements;
-
-
- var setRoot = function(){
- webshims.scrollRoot = (isWebkit || document.compatMode == 'BackCompat') ?
- $(document.body) :
- $(document.documentElement)
- ;
- };
- var minWidth = (Modernizr.boxSizing || Modernizr['display-table'] || $.support.getSetAttribute) ?
- 'minWidth' :
- 'width'
- ;
- setRoot();
- webshims.ready('DOM', setRoot);
-
- webshims.getRelOffset = function(posElem, relElem){
- posElem = $(posElem);
- var offset = $(relElem).offset();
- var bodyOffset;
- $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
- bodyOffset = posElem.offset();
- });
- offset.top -= bodyOffset.top;
- offset.left -= bodyOffset.left;
- return offset;
- };
-
- webshims.wsPopover = {
- _create: function(){
- this.options = $.extend({}, webshims.cfg.wspopover, this.options);
- this.id = webshims.wsPopover.id++;
- this.eventns = '.wsoverlay'+this.id;
- this.timers = {};
- this.element = $('<div class="ws-popover" tabindex="-1"><div class="ws-po-outerbox"><div class="ws-po-arrow"><div class="ws-po-arrowbox" /></div><div class="ws-po-box" /></div></div>');
- this.contentElement = $('.ws-po-box', this.element);
- this.lastElement = $([]);
- this.bindElement();
-
- this.element.data('wspopover', this);
-
- },
- options: {},
- content: function(html){
- this.contentElement.html(html);
- },
- bindElement: function(){
- var that = this;
- var stopBlur = function(){
- that.stopBlur = false;
- };
- this.preventBlur = function(e){
- that.stopBlur = true;
- clearTimeout(that.timers.stopBlur);
- that.timers.stopBlur = setTimeout(stopBlur, 9);
- };
- this.element.on({
- 'mousedown': this.preventBlur
- });
- },
-
- isInElement: function(container, contained){
- return container == contained || $.contains(container, contained);
- },
- show: function(element){
- var e = $.Event('wspopoverbeforeshow');
- this.element.trigger(e);
- if(e.isDefaultPrevented() || this.isVisible){return;}
- this.isVisible = true;
- element = $(element || this.options.prepareFor).getNativeElement() ;
-
- var that = this;
- var visual = $(element).getShadowElement();
-
- this.clear();
- this.element.removeClass('ws-po-visible').css('display', 'none');
-
- this.prepareFor(element, visual);
-
- this.position(visual);
- that.timers.show = setTimeout(function(){
- that.element.css('display', '');
- that.timers.show = setTimeout(function(){
- that.element.addClass('ws-po-visible').trigger('wspopovershow');
- }, 9);
- }, 9);
- $(document).on('focusin'+this.eventns+' mousedown'+this.eventns, function(e){
- if(that.options.hideOnBlur && !that.stopBlur && !that.isInElement(that.lastElement[0] || document.body, e.target) && !that.isInElement(element[0] || document.body, e.target) && !that.isInElement(that.element[0], e.target)){
- that.hide();
- }
- });
- $(window).on('resize'+this.eventns + ' pospopover'+this.eventns, function(){
- clearTimeout(that.timers.repos);
- that.timers.repos = setTimeout(function(){
- that.position(visual);
- }, 900);
- });
- },
- prepareFor: function(element, visual){
- var onBlur;
- var opts = $.extend({}, this.options, $(element.prop('form') || []).data('wspopover') || {}, element.data('wspopover'));
- var that = this;
- var css = {};
- this.lastElement = $(element).getShadowFocusElement();
- if(opts.appendTo == 'element'){
- this.element.insertAfter(element);
- } else {
- this.element.appendTo(opts.appendTo);
- }
-
- this.element.attr({
- 'data-class': element.prop('className'),
- 'data-id': element.prop('id')
- });
-
- css[minWidth] = opts.constrainWidth ? visual.outerWidth() : '';
-
- this.element.css(css);
-
- if(opts.hideOnBlur){
- onBlur = function(e){
- if(that.stopBlur){
- e.stopImmediatePropagation();
- } else {
- that.hide();
- }
- };
-
- that.timers.bindBlur = setTimeout(function(){
- that.lastElement.off(that.eventns).on('focusout'+that.eventns + ' blur'+that.eventns, onBlur);
- that.lastElement.getNativeElement().off(that.eventns);
- }, 10);
-
-
- }
-
- if(!this.prepared){
-
- if($.fn.bgIframe){
- this.element.bgIframe();
- }
- }
- this.prepared = true;
- },
- clear: function(){
- $(window).off(this.eventns);
- $(document).off(this.eventns);
-
- this.stopBlur = false;
- $.each(this.timers, function(timerName, val){
- clearTimeout(val);
- });
- },
- hide: function(){
- var e = $.Event('wspopoverbeforehide');
- this.element.trigger(e);
- if(e.isDefaultPrevented() || !this.isVisible){return;}
- this.isVisible = false;
- var that = this;
- var forceHide = function(){
- that.element.css('display', 'none').attr({'data-id': '', 'data-class': '', 'hidden': 'hidden'});
- clearTimeout(that.timers.forcehide);
- };
- this.clear();
- this.element.removeClass('ws-po-visible').trigger('wspopoverhide');
- $(window).on('resize'+this.eventns, forceHide);
- that.timers.forcehide = setTimeout(forceHide, 999);
- },
- position: function(element){
- var offset = webshims.getRelOffset(this.element.css({marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0}).removeAttr('hidden'), element);
- offset.top += element.outerHeight();
- this.element.css({marginTop: '', marginLeft: '', marginRight: '', marginBottom: ''}).css(offset);
- }
- };
-
- webshims.wsPopover.id = 0;
-
- /* some extra validation UI */
- webshims.validityAlert = (function(){
-
-
- var focusTimer = false;
-
- var api = webshims.objectCreate(webshims.wsPopover, {}, options.messagePopover);
- var boundHide = api.hide.bind(api);
-
- api.element.addClass('validity-alert').attr({role: 'alert'});
- $.extend(api, {
- hideDelay: 5000,
- showFor: function(elem, message, noFocusElem, noBubble){
-
- elem = $(elem).getNativeElement();
- this.clear();
- this.hide();
- if(!noBubble){
- this.getMessage(elem, message);
-
- this.show(elem);
- if(this.hideDelay){
- this.timers.delayedHide = setTimeout(boundHide, this.hideDelay);
- }
-
- }
-
- if(!noFocusElem){
- this.setFocus(elem);
- }
- },
- setFocus: function(element){
- var focusElem = $(element).getShadowFocusElement();
- var scrollTop = webshims.scrollRoot.scrollTop();
- var elemTop = focusElem.offset().top - 30;
- var smooth;
-
- if(scrollTop > elemTop){
- webshims.scrollRoot.animate(
- {scrollTop: elemTop - 5},
- {
- queue: false,
- duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
- }
- );
- smooth = true;
- }
- try {
- focusElem[0].focus();
- } catch(e){}
- if(smooth){
- webshims.scrollRoot.scrollTop(scrollTop);
- setTimeout(function(){
- webshims.scrollRoot.scrollTop(scrollTop);
- }, 0);
- }
-
- $(window).triggerHandler('pospopover'+this.eventns);
- },
- getMessage: function(elem, message){
- if (!message) {
- message = getContentValidationMessage(elem[0]) || elem.prop('customValidationMessage') || elem.prop('validationMessage');
- }
- if (message) {
- api.contentElement.text(message);
- } else {
- this.hide();
- }
- }
- });
-
-
- return api;
- })();
-
-
- /* extension, but also used to fix native implementation workaround/bugfixes */
- (function(){
- var firstEvent,
- invalids = [],
- stopSubmitTimer,
- form
- ;
-
- $(document).on('invalid', function(e){
- if(e.wrongWebkitInvalid){return;}
- var jElm = $(e.target);
- var shadowElem = jElm.getShadowElement();
- if(!shadowElem.hasClass(invalidClass)){
- shadowElem.addClass(invalidClass).removeClass(validClass);
- setTimeout(function(){
- $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
- }, 0);
- }
-
- if(!firstEvent){
- //trigger firstinvalid
- firstEvent = $.Event('firstinvalid');
- firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
- var firstSystemInvalid = $.Event('firstinvalidsystem');
- $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
- jElm.trigger(firstEvent);
- }
-
- //if firstinvalid was prevented all invalids will be also prevented
- if( firstEvent && firstEvent.isDefaultPrevented() ){
- e.preventDefault();
- }
- invalids.push(e.target);
- e.extraData = 'fix';
- clearTimeout(stopSubmitTimer);
- stopSubmitTimer = setTimeout(function(){
- var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
- //reset firstinvalid
- firstEvent = false;
- invalids = [];
- $(e.target).trigger(lastEvent, lastEvent);
- }, 9);
- jElm = null;
- shadowElem = null;
- });
- })();
-
- $.fn.getErrorMessage = function(){
- var message = '';
- var elem = this[0];
- if(elem){
- message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
- }
- return message;
- };
-
- if(options.replaceValidationUI){
- if(options.overrideMessages && (options.customMessages || options.customMessages == null)){
- options.customMessages = true;
- options.overrideMessages = false;
- webshims.info("set overrideMessages to false. Use customMessages instead");
- }
- webshims.ready('DOM forms', function(){
- $(document).on('firstinvalid', function(e){
- if(!e.isInvalidUIPrevented()){
- e.preventDefault();
- $.webshims.validityAlert.showFor( e.target );
- }
- });
- });
- }
- });
-
-})(jQuery);
-if(!Modernizr.formvalidation || jQuery.webshims.bugs.bustedValidity){
-jQuery.webshims.register('form-shim-extend', function($, webshims, window, document){
-"use strict";
-webshims.inputTypes = webshims.inputTypes || {};
-//some helper-functions
-var cfg = webshims.cfg.forms;
-var isSubmit;
-
-var isNumber = function(string){
- return (typeof string == 'number' || (string && string == string * 1));
- },
- typeModels = webshims.inputTypes,
- checkTypes = {
- radio: 1,
- checkbox: 1
- },
- getType = function(elem){
- return (elem.getAttribute('type') || elem.type || '').toLowerCase();
}
-;
+})();
//API to add new input types
webshims.addInputType = function(type, obj){
typeModels[type] = obj;
};
@@ -1809,22 +1464,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;
},
@@ -2615,10 +2292,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;
@@ -2866,11 +2589,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;
}
@@ -2965,21 +2690,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);
@@ -2993,11 +2718,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');
}
})
@@ -3005,17 +2730,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 {
@@ -3148,11 +2901,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){
@@ -3166,15 +2919,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){
@@ -3209,43 +2962,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;
},
@@ -3274,15 +3025,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
});
@@ -3295,11 +3055,13 @@
['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);
@@ -3465,15 +3227,19 @@
})();
}); //webshims.ready end
}//end formvalidation
-jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
+webshims.register('form-message', function($, webshims, window, document, undefined, options){
"use strict";
+ if(options.overrideMessages){
+ options.customMessages = true;
+ webshims.error('overrideMessages is deprecated. use customMessages instead.');
+ }
var validityMessages = webshims.validityMessages;
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
+ var implementProperties = options.customMessages ? ['customValidationMessage'] : [];
validityMessages.en = $.extend(true, {
typeMismatch: {
defaultMessage: 'Please enter a valid value.',
email: 'Please enter an email address.',
@@ -3500,21 +3266,21 @@
}
}, (validityMessages.en || validityMessages['en-US'] || {}));
if(typeof validityMessages['en'].valueMissing == 'object'){
['select', 'radio'].forEach(function(type){
- validityMessages.en.valueMissing[type] = 'Please select an option.';
+ validityMessages.en.valueMissing[type] = validityMessages.en.valueMissing[type] || 'Please select an option.';
});
}
if(typeof validityMessages.en.rangeUnderflow == 'object'){
['date', 'time', 'datetime-local', 'month'].forEach(function(type){
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
+ validityMessages.en.rangeUnderflow[type] = validityMessages.en.rangeUnderflow[type] || 'Value must be at or after {%min}.';
});
}
if(typeof validityMessages.en.rangeOverflow == 'object'){
['date', 'time', 'datetime-local', 'month'].forEach(function(type){
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
+ validityMessages.en.rangeOverflow[type] = validityMessages.en.rangeOverflow[type] || 'Value must be at or before {%max}.';
});
}
validityMessages['en-US'] = validityMessages['en-US'] || validityMessages.en;
validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
@@ -3546,21 +3312,21 @@
}
}, (validityMessages.de || {}));
if(typeof validityMessages.de.valueMissing == 'object'){
['select', 'radio'].forEach(function(type){
- validityMessages.de.valueMissing[type] = 'Bitte wählen Sie eine Option aus.';
+ validityMessages.de.valueMissing[type] = validityMessages.de.valueMissing[type] || 'Bitte wählen Sie eine Option aus.';
});
}
if(typeof validityMessages.de.rangeUnderflow == 'object'){
['date', 'time', 'datetime-local', 'month'].forEach(function(type){
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
+ validityMessages.de.rangeUnderflow[type] = validityMessages.de.rangeUnderflow[type] || '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
});
}
if(typeof validityMessages.de.rangeOverflow == 'object'){
['date', 'time', 'datetime-local', 'month'].forEach(function(type){
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
+ validityMessages.de.rangeOverflow[type] = validityMessages.de.rangeOverflow[type] || '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
});
}
var currentValidationMessage = validityMessages[''];
var getMessageFromObj = function(message, elem){
@@ -3574,30 +3340,30 @@
min: 1,
max: 1
};
webshims.createValidationMessage = function(elem, name){
- var spinner;
+ var widget;
var message = getMessageFromObj(currentValidationMessage[name], elem);
-
+ var type = $.prop(elem, 'type');
if(!message){
- message = getMessageFromObj(validityMessages[''][name], elem) || 'invalid value';
- webshims.info('could not find errormessage for: '+ name +' / '+ $.prop(elem, 'type') +'. in language: '+$.webshims.activeLang());
+ message = getMessageFromObj(validityMessages[''][name], elem) || $.prop(elem, 'validationMessage');
+ webshims.info('could not find errormessage for: '+ name +' / '+ type +'. in language: '+$.webshims.activeLang());
}
if(message){
['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
if(message.indexOf('{%'+attr) === -1){return;}
var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.prop(elem, attr)) || '';
if(name == 'patternMismatch' && attr == 'title' && !val){
webshims.error('no title for patternMismatch provided. Always add a title attribute.');
}
if(valueVals[attr]){
- if(!spinner){
- spinner = $(elem).getShadowElement().data('wsspinner');
+ if(!widget){
+ widget = $(elem).getShadowElement().data('wsWidget'+type);
}
- if(spinner && spinner.formatValue){
- val = spinner.formatValue(val, false);
+ if(widget && widget.formatValue){
+ val = widget.formatValue(val, false);
}
}
message = message.replace('{%'+ attr +'}', val);
if('value' == attr){
message = message.replace('{%valueLen}', val.length);
@@ -3608,11 +3374,11 @@
return message || '';
};
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
+ if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){
implementProperties.push('validationMessage');
}
webshims.activeLang({
langObj: validityMessages,
@@ -3666,13 +3432,41 @@
});
});
});
});
-jQuery.webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
+webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
"use strict";
- var doc = document;
+ var doc = document;
+ var lazyLoad = function(name){
+ if(!name || typeof name != 'string'){
+ name = 'DOM';
+ }
+ if(!lazyLoad[name+'Loaded']){
+ lazyLoad[name+'Loaded'] = true;
+ webshims.ready(name, function(){
+ webshims.loader.loadList(['form-datalist-lazy']);
+ });
+ }
+ };
+ var noDatalistSupport = {
+ submit: 1,
+ button: 1,
+ reset: 1,
+ hidden: 1,
+
+ range: 1,
+ date: 1,
+ month: 1
+ };
+ if(webshims.modules["form-number-date-ui"].loaded){
+ $.extend(noDatalistSupport, {
+ number: 1,
+ time: 1
+ });
+ }
+
/*
* implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed)
*/
webshims.propTypes.element = function(descs){
@@ -3704,32 +3498,10 @@
if(listSupport && !formsCFG.customDatalist){return;}
var initializeDatalist = function(){
- if(!listSupport){
- 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;
- }
- }
- });
- }
-
var inputListProto = {
//override autocomplete
autocomplete: {
attr: {
get: function(){
@@ -3785,31 +3557,12 @@
}
}
};
}
- if(!listSupport){
-
- inputListProto['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(shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
- $(elem).triggerHandler('listdatalistchange');
- }
- },
- initAttr: true,
- reflect: true,
- propType: 'element',
- propNodeName: 'datalist'
- };
- } else {
+
+ if(listSupport){
//options only return options, if option-elements are rooted: but this makes this part of HTML5 less backwards compatible
if(!($('<datalist><select><option></option></select></datalist>').prop('options') || []).length ){
webshims.defineNodeNameProperty('datalist', 'options', {
prop: {
writeable: false,
@@ -3825,27 +3578,37 @@
return options;
}
}
});
}
- inputListProto['list'] = {
+ inputListProto.list = {
attr: {
get: function(){
var val = webshims.contentAttr(this, 'list');
if(val != null){
$.data(this, 'datalistListAttr', val);
- this.removeAttribute('list');
+ if(!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]){
+ this.removeAttribute('list');
+ }
} else {
val = $.data(this, 'datalistListAttr');
}
return (val == null) ? undefined : val;
},
set: function(value){
var elem = this;
$.data(elem, 'datalistListAttr', value);
- webshims.objectCreate(shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
+ if (!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]) {
+ webshims.objectCreate(shadowListProto, undefined, {
+ input: elem,
+ id: value,
+ datalist: $.prop(elem, 'list')
+ });
+ } else {
+ elem.setAttribute('list', value);
+ }
$(elem).triggerHandler('listdatalistchange');
}
},
initAttr: true,
reflect: true,
@@ -3861,73 +3624,26 @@
.filter('datalist > select, datalist, datalist > option, datalist > select > option')
.closest('datalist')
.each(function(){
$(this).triggerHandler('updateDatalist');
})
-
;
-
});
-
-
};
/*
* ShadowList
*/
- var listidIndex = 0;
- var noDatalistSupport = {
- submit: 1,
- button: 1,
- reset: 1,
- hidden: 1,
-
- range: 1,
- date: 1,
- month: 1
- };
- if(webshims.modules["form-number-date-ui"].loaded){
- $.extend(noDatalistSupport, {
- number: 1,
- time: 1
- });
- }
-
- var globStoredOptions = {};
- var getStoredOptions = function(name){
- if(!name){return [];}
- if(globStoredOptions[name]){
- return globStoredOptions[name];
- }
- var data;
- try {
- data = JSON.parse(localStorage.getItem('storedDatalistOptions'+name));
- } catch(e){}
- globStoredOptions[name] = data || [];
- return data || [];
- };
- var storeOptions = function(name, val){
- if(!name){return;}
- val = val || [];
- try {
- localStorage.setItem( 'storedDatalistOptions'+name, JSON.stringify(val) );
- } catch(e){}
- };
- var getText = function(elem){
- return (elem.textContent || elem.innerText || $.text([ elem ]) || '');
- };
- var lReg = /</g;
- var gReg = />/g;
-
var shadowListProto = {
_create: function(opts){
if(noDatalistSupport[$.prop(opts.input, 'type')] || noDatalistSupport[$.attr(opts.input, 'type')]){return;}
var datalist = opts.datalist;
var data = $.data(opts.input, 'datalistWidget');
+ var that = this;
if(datalist && data && data.datalist !== datalist){
data.datalist = datalist;
data.id = opts.id;
@@ -3944,135 +3660,34 @@
}
return;
} else if(data && data.datalist === datalist){
return;
}
- listidIndex++;
- var that = this;
- this.hideList = $.proxy(that, 'hideList');
+
+
this.datalist = datalist;
this.id = opts.id;
this.hasViewableData = true;
this._autocomplete = $.attr(opts.input, 'autocomplete');
$.data(opts.input, 'datalistWidget', this);
- this.popover = webshims.objectCreate(webshims.wsPopover, {}, options.datalistPopover);
- this.shadowList = this.popover.element.addClass('datalist-polyfill');
+ lazyLoad('WINDOWLOAD');
-
- this.index = -1;
- this.input = opts.input;
- this.arrayOptions = [];
-
- this.shadowList
- .delegate('li', 'mouseenter.datalistWidget mousedown.datalistWidget click.datalistWidget', function(e){
- var items = $('li:not(.hidden-item)', that.shadowList);
- var select = (e.type == 'mousedown' || e.type == 'click');
- that.markItem(items.index(e.currentTarget), select, items);
- if(e.type == 'click'){
- that.hideList();
- if(formsCFG.customDatalist){
- $(opts.input).getNativeElement().trigger('datalistselect');
- }
+ if(webshims.isReady('form-datalist-lazy')){
+ this._lazyCreate(opts);
+ } else {
+ $(opts.input).one('focus', lazyLoad);
+ webshims.ready('form-datalist-lazy', function(){
+ if(!that._destroyed){
+ that._lazyCreate(opts);
}
- return (e.type != 'mousedown');
- })
- ;
-
- opts.input.setAttribute('autocomplete', 'off');
-
- $(opts.input)
- .attr({
- //role: 'combobox',
- 'aria-haspopup': 'true'
- })
- .on({
- 'input.datalistWidget': function(){
- if(!that.triggeredByDatalist){
- that.changedValue = false;
- that.showHideOptions();
- }
- },
- 'keydown.datalistWidget': function(e){
- var keyCode = e.keyCode;
- var activeItem;
- var items;
- if(keyCode == 40 && !that.showList()){
- that.markItem(that.index + 1, true);
- return false;
- }
-
- if(!that.popover.isVisible){return;}
-
-
- if(keyCode == 38){
- that.markItem(that.index - 1, true);
- return false;
- }
- if(!e.shiftKey && (keyCode == 33 || keyCode == 36)){
- that.markItem(0, true);
- return false;
- }
- if(!e.shiftKey && (keyCode == 34 || keyCode == 35)){
- items = $('li:not(.hidden-item)', that.shadowList);
- that.markItem(items.length - 1, true, items);
- return false;
- }
- if(keyCode == 13 || keyCode == 27){
- if (keyCode == 13){
- activeItem = $('li.active-item:not(.hidden-item)', that.shadowList);
- that.changeValue( $('li.active-item:not(.hidden-item)', that.shadowList) );
- }
- that.hideList();
- if(formsCFG.customDatalist && activeItem && activeItem[0]){
- $(opts.input).getNativeElement().trigger('datalistselect');
- }
- return false;
- }
- },
- 'focus.datalistWidget': function(){
- if($(this).hasClass('list-focus')){
- that.showList();
- }
- },
- 'mousedown.datalistWidget': function(){
- if($(this).is(':focus')){
- that.showList();
- }
- }
- })
- ;
-
-
- $(this.datalist)
- .off('updateDatalist.datalistWidget')
- .on('updateDatalist.datalistWidget', $.proxy(this, '_resetListCached'))
- ;
-
- this._resetListCached();
-
- if(opts.input.form && (opts.input.name || opts.input.id)){
- $(opts.input.form).on('submit.datalistWidget'+opts.input.id, function(){
- if(!$(opts.input).hasClass('no-datalist-cache') && that._autocomplete != 'off'){
- var val = $.prop(opts.input, 'value');
- var name = (opts.input.name || opts.input.id) + $.prop(opts.input, 'type');
- if(!that.storedOptions){
- that.storedOptions = getStoredOptions( name );
- }
- if(val && that.storedOptions.indexOf(val) == -1){
- that.storedOptions.push(val);
- storeOptions(name, that.storedOptions );
- }
- }
});
}
- $(window).on('unload.datalist'+this.id+' beforeunload.datalist'+this.id, function(){
- that.destroy();
- });
},
- destroy: function(){
+ destroy: function(e){
+ var input;
var autocomplete = $.attr(this.input, 'autocomplete');
$(this.input)
.off('.datalistWidget')
.removeData('datalistWidget')
;
@@ -4086,270 +3701,23 @@
if(autocomplete === undefined){
this.input.removeAttribute('autocomplete');
} else {
$(this.input).attr('autocomplete', autocomplete);
}
- },
- _resetListCached: function(e){
- var that = this;
- var forceShow;
- this.needsUpdate = true;
- this.lastUpdatedValue = false;
- this.lastUnfoundValue = '';
-
- if(!this.updateTimer){
- if(window.QUnit || (forceShow = ($(that.input).is(':focus') && ($(that.input).hasClass('list-focus') || $.prop(that.input, 'value'))) )){
- that.updateListOptions(forceShow);
- } else {
- webshims.ready('WINDOWLOAD', function(){
- that.updateTimer = setTimeout(function(){
- that.updateListOptions();
- that = null;
- listidIndex = 1;
- }, 200 + (100 * listidIndex));
- });
- }
+ if(e && e.type == 'beforeunload'){
+ input = this.input;
+ setTimeout(function(){
+ $.attr(input, 'list', $.attr(input, 'list'));
+ }, 9);
}
- },
- updateListOptions: function(_forceShow){
- this.needsUpdate = false;
- clearTimeout(this.updateTimer);
- this.updateTimer = false;
-
- this.searchStart = formsCFG.customDatalist && $(this.input).hasClass('search-start');
- this.addMarkElement = options.addMark || $(this.input).hasClass('mark-option-text');
-
- var list = [];
-
- var values = [];
- var allOptions = [];
- var rElem, rItem, rOptions, rI, rLen, item, value;
- for(rOptions = $.prop(this.datalist, 'options'), rI = 0, rLen = rOptions.length; rI < rLen; rI++){
- rElem = rOptions[rI];
- if(!rElem.disabled && (value = $(rElem).val())){
- rItem = {
- value: value.replace(lReg, '<').replace(gReg, '>'),
- label: $.trim($.attr(rElem, 'label') || getText(rElem)).replace(lReg, '<').replace(gReg, '>'),
- className: rElem.className || ''
- };
-
- if(rItem.label){
- rItem.className += ' has-option-label';
- }
- values.push(rItem.value);
- allOptions.push(rItem);
- }
- }
-
- if(!this.storedOptions){
- this.storedOptions = ($(this.input).hasClass('no-datalist-cache') || this._autocomplete == 'off') ? [] : getStoredOptions((this.input.name || this.input.id) + $.prop(this.input, 'type'));
- }
-
- this.storedOptions.forEach(function(val, i){
- if(values.indexOf(val) == -1){
- allOptions.push({value: val, label: '', className: 'stored-suggest', style: ''});
- }
- });
-
- for(rI = 0, rLen = allOptions.length; rI < rLen; rI++){
- item = allOptions[rI];
- list[rI] = '<li class="'+ item.className +'" tabindex="-1" role="listitem">'+ this.getOptionContent(item) +'</li>';
- }
-
- this.arrayOptions = allOptions;
- this.popover.contentElement.html('<div class="datalist-box"><ul role="list">'+ list.join("\n") +'</ul></div>');
-
-
- if(_forceShow || this.popover.isVisible){
- this.showHideOptions();
- }
- },
- getOptionContent: function(item){
- var content = '';
- if(options.getOptionContent){
- content = options.apply(this, arguments) || '';
- } else {
- content = '<span class="option-value">'+ item.value +'</span>';
- if(item.label){
- content += ' <span class="option-label">'+ item.label +'</span>';
- }
- }
- return content;
- },
- showHideOptions: function(_fromShowList){
- var value = $.prop(this.input, 'value').toLowerCase();
-
- //first check prevent infinite loop, second creates simple lazy optimization
- if(value === this.lastUpdatedValue){
- return;
- }
- if(this.lastUnfoundValue && value.indexOf(this.lastUnfoundValue) === 0){
- this.hideList();
- return;
- }
-
-
- this.lastUpdatedValue = value;
- var found = false;
- var startSearch = this.searchStart;
- var lis = $('li', this.shadowList);
- var that = this;
- if(value){
-
- this.arrayOptions.forEach(function(item, i){
- var search, searchIndex, foundName;
- if(!('lowerValue' in item)){
- item.lowerValue = item.value.toLowerCase();
- if(item.label && item.label != item.value ){
- item.lowerLabel = item.label.toLowerCase();
- }
- }
-
- if(value != item.lowerValue && item.lowerLabel != value){
- searchIndex = item.lowerValue.indexOf(value);
- search = startSearch ? !searchIndex : searchIndex !== -1;
- if(search){
- foundName = 'value';
- } else if(item.lowerLabel){
- searchIndex = item.lowerLabel.indexOf(value);
- search = startSearch ? !searchIndex : searchIndex !== -1;
- foundName = 'label';
- }
- }
-
- if(search){
- that.addMark($(lis[i]).removeClass('hidden-item'), item, foundName, searchIndex, value.length);
- found = true;
- } else {
- $(lis[i]).addClass('hidden-item');
- }
- });
- } else if(lis.length) {
- this.removeMark(lis.removeClass('hidden-item'));
- found = true;
- }
-
- this.hasViewableData = found;
- if(!_fromShowList && found){
- this.showList();
- }
-
- if(!found){
- this.lastUnfoundValue = value;
- this.hideList();
- } else {
- this.lastUnfoundValue = false;
- }
- },
- otherType: {
- value: 'label',
- label: 'value'
- },
- addMark: function(elem, item, prop, start, length){
- if(this.addMarkElement){
- var text = item[prop].substr(start, length);
- text = item[prop].replace(text ,'<mark>'+ text +'</mark>');
- $('.option-'+ this.otherType[prop] +' > mark', elem).each(this._replaceMark);
- $('.option-'+prop, elem).html(text);
-
- }
- },
- _replaceMark: function(){
- var content = $(this).html();
- $(this).replaceWith(content);
- },
- removeMark: function(lis){
- if(this.addMarkElement){
- $('mark', lis).each(this._replaceMark);
- }
- },
- showList: function(){
- if(this.popover.isVisible){return false;}
- if(this.needsUpdate){
- this.updateListOptions();
- }
- this.showHideOptions(true);
- if(!this.hasViewableData){return false;}
- var that = this;
-
- that.shadowList.find('li.active-item').removeClass('active-item');
- that.popover.show(this.input);
-
-
- return true;
- },
- hideList: function(){
- if(!this.popover.isVisible){return false;}
- var that = this;
-
-
- this.popover.hide();
- that.shadowList.removeClass('datalist-visible list-item-active');
- that.index = -1;
- if(that.changedValue){
- that.triggeredByDatalist = true;
- $(that.input).trigger('input').trigger('change');
- that.changedValue = false;
- that.triggeredByDatalist = false;
- }
-
- return true;
- },
- scrollIntoView: function(elem){
- var ul = $('ul', this.shadowList);
- var div = $('div.datalist-box', this.shadowList);
- var elemPos = elem.position();
- var containerHeight;
- elemPos.top -= (parseInt(ul.css('paddingTop'), 10) || 0) + (parseInt(ul.css('marginTop'), 10) || 0) + (parseInt(ul.css('borderTopWidth'), 10) || 0);
- if(elemPos.top < 0){
- div.scrollTop( div.scrollTop() + elemPos.top - 2);
- return;
- }
- elemPos.top += elem.outerHeight();
- containerHeight = div.height();
- if(elemPos.top > containerHeight){
- div.scrollTop( div.scrollTop() + (elemPos.top - containerHeight) + 2);
- }
- },
- changeValue: function(activeItem){
- if(!activeItem[0]){return;}
- var spinner;
- var newValue = $('span.option-value', activeItem).text();
- var oldValue = $.prop(this.input, 'value');
- if(newValue != oldValue){
-
- $(this.input)
- .prop('value', newValue)
- .triggerHandler('updateInput')
- ;
- this.changedValue = true;
- if((spinner = $.data(this.input, 'wsspinner')) && spinner.setInput){
- spinner.setInput(newValue);
- }
- }
- },
- markItem: function(index, doValue, items){
- var activeItem;
- var goesUp;
-
- items = items || $('li:not(.hidden-item)', this.shadowList);
- if(!items.length){return;}
- if(index < 0){
- index = items.length - 1;
- } else if(index >= items.length){
- index = 0;
- }
- items.removeClass('active-item');
- this.shadowList.addClass('list-item-active');
- activeItem = items.filter(':eq('+ index +')').addClass('active-item');
-
- if(doValue){
- this.changeValue(activeItem);
- this.scrollIntoView(activeItem);
- }
- this.index = index;
+ this._destroyed = true;
}
};
+
+ webshims.loader.addModule('form-datalist-lazy', {
+ noAutoCallback: true,
+ options: $.extend(options, {shadowListProto: shadowListProto})
+ });
//init datalist update
initializeDatalist();
})();
\ No newline at end of file