vendor/assets/javascripts/webshims/shims/combos/24.js in webshims-rails-0.4.3 vs vendor/assets/javascripts/webshims/shims/combos/24.js in webshims-rails-0.4.4

- old
+ new

@@ -1,2781 +1,2776 @@ -//DOM-Extension helper -jQuery.webshims.register('dom-extend', function($, webshims, window, document, undefined){ - "use strict"; - //shortcus - var modules = webshims.modules; - var listReg = /\s*,\s*/; - - //proxying attribute - var olds = {}; - var havePolyfill = {}; - var extendedProps = {}; - var extendQ = {}; - var modifyProps = {}; - - var oldVal = $.fn.val; - var singleVal = function(elem, name, val, pass, _argless){ - return (_argless) ? oldVal.call($(elem)) : oldVal.call($(elem), val); - }; - $.fn.val = function(val){ - var elem = this[0]; - if(arguments.length && val == null){ - val = ''; - } - if(!arguments.length){ - if(!elem || elem.nodeType !== 1){return oldVal.call(this);} - return $.prop(elem, 'value', val, 'val', true); - } - if($.isArray(val)){ - return oldVal.apply(this, arguments); - } - var isFunction = $.isFunction(val); - return this.each(function(i){ - elem = this; - if(elem.nodeType === 1){ - if(isFunction){ - var genVal = val.call( elem, i, $.prop(elem, 'value', undefined, 'val', true)); - if(genVal == null){ - genVal = ''; - } - $.prop(elem, 'value', genVal, 'val') ; - } else { - $.prop(elem, 'value', val, 'val'); - } - } - }); - }; - - 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); - if(val !== undefined){ - if(!data){ - data = $.data(elem, dataID, {}); - } - if(key){ - data[key] = val; - } - } - - return key ? data && data[key] : data; - }; - - - [{name: 'getNativeElement', prop: 'nativeElement'}, {name: 'getShadowElement', prop: 'shadowElement'}, {name: 'getShadowFocusElement', prop: 'shadowFocusElement'}].forEach(function(data){ - $.fn[data.name] = function(){ - return this.map(function(){ - var shadowData = elementData(this, 'shadowData'); - return shadowData && shadowData[data.prop] || this; - }); - }; - }); - - - ['removeAttr', 'prop', 'attr'].forEach(function(type){ - olds[type] = $[type]; - $[type] = function(elem, name, value, pass, _argless){ - var isVal = (pass == 'val'); - var oldMethod = !isVal ? olds[type] : singleVal; - if( !elem || !havePolyfill[name] || elem.nodeType !== 1 || (!isVal && pass && type == 'attr' && $.attrFn[name]) ){ - return oldMethod(elem, name, value, pass, _argless); - } - - var nodeName = (elem.nodeName || '').toLowerCase(); - var desc = extendedProps[nodeName]; - var curType = (type == 'attr' && (value === false || value === null)) ? 'removeAttr' : type; - var propMethod; - var oldValMethod; - var ret; - - - if(!desc){ - desc = extendedProps['*']; - } - if(desc){ - desc = desc[name]; - } - - if(desc){ - propMethod = desc[curType]; - } - - if(propMethod){ - if(name == 'value'){ - oldValMethod = propMethod.isVal; - propMethod.isVal = isVal; - } - if(curType === 'removeAttr'){ - return propMethod.value.call(elem); - } else if(value === undefined){ - return (propMethod.get) ? - propMethod.get.call(elem) : - propMethod.value - ; - } else if(propMethod.set) { - if(type == 'attr' && value === true){ - value = name; - } - - ret = propMethod.set.call(elem, value); - } - if(name == 'value'){ - propMethod.isVal = oldValMethod; - } - } else { - ret = oldMethod(elem, name, value, pass, _argless); - } - if((value !== undefined || curType === 'removeAttr') && modifyProps[nodeName] && modifyProps[nodeName][name]){ - - var boolValue; - if(curType == 'removeAttr'){ - boolValue = false; - } else if(curType == 'prop'){ - boolValue = !!(value); - } else { - boolValue = true; - } - - modifyProps[nodeName][name].forEach(function(fn){ - if(!fn.only || (fn.only = 'prop' && type == 'prop') || (fn.only == 'attr' && type != 'prop')){ - fn.call(elem, value, boolValue, (isVal) ? 'val' : curType, type); - } - }); - } - return ret; - }; - - extendQ[type] = function(nodeName, prop, desc){ - - if(!extendedProps[nodeName]){ - extendedProps[nodeName] = {}; - } - if(!extendedProps[nodeName][prop]){ - extendedProps[nodeName][prop] = {}; - } - var oldDesc = extendedProps[nodeName][prop][type]; - var getSup = function(propType, descriptor, oDesc){ - if(descriptor && descriptor[propType]){ - return descriptor[propType]; - } - if(oDesc && oDesc[propType]){ - return oDesc[propType]; - } - if(type == 'prop' && prop == 'value'){ - return function(value){ - var elem = this; - return (desc.isVal) ? - singleVal(elem, prop, value, false, (arguments.length === 0)) : - olds[type](elem, prop, value) - ; - }; - } - if(type == 'prop' && propType == 'value' && desc.value.apply){ - return function(value){ - var sup = olds[type](this, prop); - if(sup && sup.apply){ - sup = sup.apply(this, arguments); - } - return sup; - }; - } - return function(value){ - return olds[type](this, prop, value); - }; - }; - extendedProps[nodeName][prop][type] = desc; - if(desc.value === undefined){ - if(!desc.set){ - desc.set = desc.writeable ? - getSup('set', desc, oldDesc) : - (webshims.cfg.useStrict && prop == 'prop') ? - function(){throw(prop +' is readonly on '+ nodeName);} : - $.noop - ; - } - if(!desc.get){ - desc.get = getSup('get', desc, oldDesc); - } - - } - - ['value', 'get', 'set'].forEach(function(descProp){ - if(desc[descProp]){ - desc['_sup'+descProp] = getSup(descProp, oldDesc); - } - }); - }; - - }); - - //see also: https://github.com/lojjic/PIE/issues/40 | https://prototype.lighthouseapp.com/projects/8886/tickets/1107-ie8-fatal-crash-when-prototypejs-is-loaded-with-rounded-cornershtc - var isExtendNativeSave = (!$.browser.msie || parseInt($.browser.version, 10) > 8); - var extendNativeValue = (function(){ - var UNKNOWN = webshims.getPrototypeOf(document.createElement('foobar')); - var has = Object.prototype.hasOwnProperty; - return function(nodeName, prop, desc){ - var elem = document.createElement(nodeName); - var elemProto = webshims.getPrototypeOf(elem); - if( isExtendNativeSave && elemProto && UNKNOWN !== elemProto && ( !elem[prop] || !has.call(elem, prop) ) ){ - var sup = elem[prop]; - desc._supvalue = function(){ - if(sup && sup.apply){ - return sup.apply(this, arguments); - } - return sup; - }; - elemProto[prop] = desc.value; - } else { - desc._supvalue = function(){ - var data = elementData(this, 'propValue'); - if(data && data[prop] && data[prop].apply){ - return data[prop].apply(this, arguments); - } - return data && data[prop]; - }; - initProp.extendValue(nodeName, prop, desc.value); - } - desc.value._supvalue = desc._supvalue; - }; - })(); - - var initProp = (function(){ - - var initProps = {}; - - webshims.addReady(function(context, contextElem){ - var nodeNameCache = {}; - var getElementsByName = function(name){ - if(!nodeNameCache[name]){ - nodeNameCache[name] = $(context.getElementsByTagName(name)); - if(contextElem[0] && $.nodeName(contextElem[0], name)){ - nodeNameCache[name] = nodeNameCache[name].add(contextElem); - } - } - }; - - - $.each(initProps, function(name, fns){ - getElementsByName(name); - if(!fns || !fns.forEach){ - webshims.warn('Error: with '+ name +'-property. methods: '+ fns); - return; - } - fns.forEach(function(fn){ - nodeNameCache[name].each(fn); - }); - }); - nodeNameCache = null; - }); - - var tempCache; - var emptyQ = $([]); - var createNodeNameInit = function(nodeName, fn){ - if(!initProps[nodeName]){ - initProps[nodeName] = [fn]; - } else { - initProps[nodeName].push(fn); - } - if($.isDOMReady){ - (tempCache || $( document.getElementsByTagName(nodeName) )).each(fn); - } - }; - - var elementExtends = {}; - return { - createTmpCache: function(nodeName){ - if($.isDOMReady){ - tempCache = tempCache || $( document.getElementsByTagName(nodeName) ); - } - return tempCache || emptyQ; - }, - flushTmpCache: function(){ - tempCache = null; - }, - content: function(nodeName, prop){ - createNodeNameInit(nodeName, function(){ - var val = $.attr(this, prop); - if(val != null){ - $.attr(this, prop, val); - } - }); - }, - createElement: function(nodeName, fn){ - createNodeNameInit(nodeName, fn); - }, - extendValue: function(nodeName, prop, value){ - createNodeNameInit(nodeName, function(){ - $(this).each(function(){ - var data = elementData(this, 'propValue', {}); - data[prop] = this[prop]; - this[prop] = value; - }); - }); - } - }; - })(); - - var createPropDefault = function(descs, removeType){ - if(descs.defaultValue === undefined){ - descs.defaultValue = ''; - } - if(!descs.removeAttr){ - descs.removeAttr = { - value: function(){ - descs[removeType || 'prop'].set.call(this, descs.defaultValue); - descs.removeAttr._supvalue.call(this); - } - }; - } - if(!descs.attr){ - descs.attr = {}; - } - }; - - $.extend(webshims, { - - getID: (function(){ - var ID = new Date().getTime(); - return function(elem){ - elem = $(elem); - var id = elem.attr('id'); - if(!id){ - ID++; - id = 'ID-'+ ID; - elem.attr('id', id); - } - return id; - }; - })(), - extendUNDEFProp: function(obj, props){ - $.each(props, function(name, prop){ - if( !(name in obj) ){ - obj[name] = prop; - } - }); - }, - //http://www.w3.org/TR/html5/common-dom-interfaces.html#reflect - createPropDefault: createPropDefault, - data: elementData, - moveToFirstEvent: (function(){ - var getData = $._data ? '_data' : 'data'; - return function(elem, eventType, bindType){ - var events = ($[getData](elem, 'events') || {})[eventType]; - var fn; - - if(events && events.length > 1){ - fn = events.pop(); - if(!bindType){ - bindType = 'bind'; - } - if(bindType == 'bind' && events.delegateCount){ - events.splice( events.delegateCount, 0, fn); - } else { - events.unshift( fn ); - } - - - } - elem = null; - }; - })(), - addShadowDom: (function(){ - var resizeTimer; - var lastHeight; - var lastWidth; - var handler; - var docObserve = { - init: false, - start: function(){ - if(!this.init && document.body){ - this.init = true; - this.height = $(document).height(); - this.width = $(document).width(); - setInterval(function(){ - var height = $(document).height(); - var width = $(document).width(); - if(height != docObserve.height || width != docObserve.width){ - docObserve.height = height; - docObserve.width = width; - handler({type: 'docresize'}); - } - }, 600); - } - } - }; - - handler = function(e){ - clearTimeout(resizeTimer); - resizeTimer = setTimeout(function(){ - if(e.type == 'resize'){ - var width = $(window).width(); - var height = $(window).width(); - if(height == lastHeight && width == lastWidth){ - return; - } - lastHeight = height; - lastWidth = width; - if(document.body){ - docObserve.height = $(document).height(); - docObserve.width = $(document).width(); - } - } - $.event.trigger('updateshadowdom'); - }, 40); - }; - $(window).bind('resize', handler); - - $.event.customEvent.updateshadowdom = true; - - return function(nativeElem, shadowElem, opts){ - opts = opts || {}; - if(nativeElem.jquery){ - nativeElem = nativeElem[0]; - } - if(shadowElem.jquery){ - shadowElem = shadowElem[0]; - } - var nativeData = $.data(nativeElem, dataID) || $.data(nativeElem, dataID, {}); - var shadowData = $.data(shadowElem, dataID) || $.data(shadowElem, dataID, {}); - var shadowFocusElementData = {}; - if(!opts.shadowFocusElement){ - opts.shadowFocusElement = shadowElem; - } else if(opts.shadowFocusElement){ - if(opts.shadowFocusElement.jquery){ - opts.shadowFocusElement = opts.shadowFocusElement[0]; - } - shadowFocusElementData = $.data(opts.shadowFocusElement, dataID) || $.data(opts.shadowFocusElement, dataID, shadowFocusElementData); - } - - nativeData.hasShadow = shadowElem; - shadowFocusElementData.nativeElement = shadowData.nativeElement = nativeElem; - shadowFocusElementData.shadowData = shadowData.shadowData = nativeData.shadowData = { - nativeElement: nativeElem, - shadowElement: shadowElem, - shadowFocusElement: opts.shadowFocusElement - }; - if(opts.shadowChilds){ - opts.shadowChilds.each(function(){ - elementData(this, 'shadowData', shadowData.shadowData); - }); - } - - if(opts.data){ - shadowFocusElementData.shadowData.data = shadowData.shadowData.data = nativeData.shadowData.data = opts.data; - } - opts = null; - webshims.ready('DOM', function(){ - docObserve.start(); - }); - } - })(), - propTypes: { - standard: function(descs, name){ - createPropDefault(descs); - if(descs.prop){return;} - descs.prop = { - set: function(val){ - descs.attr.set.call(this, ''+val); - }, - get: function(){ - return descs.attr.get.call(this) || descs.defaultValue; - } - }; - - }, - "boolean": function(descs, name){ - - createPropDefault(descs); - if(descs.prop){return;} - descs.prop = { - set: function(val){ - if(val){ - descs.attr.set.call(this, ""); - } else { - descs.removeAttr.value.call(this); - } - }, - get: function(){ - return descs.attr.get.call(this) != null; - } - }; - }, - "src": (function(){ - var anchor = document.createElement('a'); - anchor.style.display = "none"; - return function(descs, name){ - - createPropDefault(descs); - if(descs.prop){return;} - descs.prop = { - set: function(val){ - descs.attr.set.call(this, val); - }, - get: function(){ - var href = this.getAttribute(name); - var ret; - if(href == null){return '';} - - anchor.setAttribute('href', href+'' ); - - if(!$.support.hrefNormalized){ - try { - $(anchor).insertAfter(this); - ret = anchor.getAttribute('href', 4); - } catch(er){ - ret = anchor.getAttribute('href', 4); - } - $(anchor).detach(); - } - return ret || anchor.href; - } - }; - }; - })(), - enumarated: function(descs, name){ - - createPropDefault(descs); - if(descs.prop){return;} - descs.prop = { - set: function(val){ - descs.attr.set.call(this, val); - }, - get: function(){ - var val = (descs.attr.get.call(this) || '').toLowerCase(); - if(!val || descs.limitedTo.indexOf(val) == -1){ - val = descs.defaultValue; - } - return val; - } - }; - } - -// ,unsignedLong: $.noop -// ,"doubble": $.noop -// ,"long": $.noop -// ,tokenlist: $.noop -// ,settableTokenlist: $.noop - }, - reflectProperties: function(nodeNames, props){ - if(typeof props == 'string'){ - props = props.split(listReg); - } - props.forEach(function(prop){ - webshims.defineNodeNamesProperty(nodeNames, prop, { - prop: { - set: function(val){ - $.attr(this, prop, val); - }, - get: function(){ - return $.attr(this, prop) || ''; - } - } - }); - }); - }, - defineNodeNameProperty: function(nodeName, prop, descs){ - havePolyfill[prop] = true; - - if(descs.reflect){ - webshims.propTypes[descs.propType || 'standard'](descs, prop); - } - - ['prop', 'attr', 'removeAttr'].forEach(function(type){ - var desc = descs[type]; - if(desc){ - if(type === 'prop'){ - desc = $.extend({writeable: true}, desc); - } else { - desc = $.extend({}, desc, {writeable: true}); - } - - extendQ[type](nodeName, prop, desc); - if(nodeName != '*' && webshims.cfg.extendNative && type == 'prop' && desc.value && $.isFunction(desc.value)){ - extendNativeValue(nodeName, prop, desc); - } - descs[type] = desc; - } - }); - if(descs.initAttr){ - initProp.content(nodeName, prop); - } - return descs; - }, - - defineNodeNameProperties: function(name, descs, propType, _noTmpCache){ - var olddesc; - for(var prop in descs){ - if(!_noTmpCache && descs[prop].initAttr){ - initProp.createTmpCache(name); - } - if(propType){ - if(descs[prop][propType]){ - //webshims.log('override: '+ name +'['+prop +'] for '+ propType); - } else { - descs[prop][propType] = {}; - ['value', 'set', 'get'].forEach(function(copyProp){ - if(copyProp in descs[prop]){ - descs[prop][propType][copyProp] = descs[prop][copyProp]; - delete descs[prop][copyProp]; - } - }); - } - } - descs[prop] = webshims.defineNodeNameProperty(name, prop, descs[prop]); - } - if(!_noTmpCache){ - initProp.flushTmpCache(); - } - return descs; - }, - - createElement: function(nodeName, create, descs){ - var ret; - if($.isFunction(create)){ - create = { - after: create - }; - } - initProp.createTmpCache(nodeName); - if(create.before){ - initProp.createElement(nodeName, create.before); - } - if(descs){ - ret = webshims.defineNodeNameProperties(nodeName, descs, false, true); - } - if(create.after){ - initProp.createElement(nodeName, create.after); - } - initProp.flushTmpCache(); - return ret; - }, - onNodeNamesPropertyModify: function(nodeNames, props, desc, only){ - if(typeof nodeNames == 'string'){ - nodeNames = nodeNames.split(listReg); - } - if($.isFunction(desc)){ - desc = {set: desc}; - } - - nodeNames.forEach(function(name){ - if(!modifyProps[name]){ - modifyProps[name] = {}; - } - if(typeof props == 'string'){ - props = props.split(listReg); - } - if(desc.initAttr){ - initProp.createTmpCache(name); - } - props.forEach(function(prop){ - if(!modifyProps[name][prop]){ - modifyProps[name][prop] = []; - havePolyfill[prop] = true; - } - if(desc.set){ - if(only){ - desc.set.only = only; - } - modifyProps[name][prop].push(desc.set); - } - - if(desc.initAttr){ - initProp.content(name, prop); - } - }); - initProp.flushTmpCache(); - - }); - }, - defineNodeNamesBooleanProperty: function(elementNames, prop, descs){ - if(!descs){ - descs = {}; - } - if($.isFunction(descs)){ - descs.set = descs; - } - webshims.defineNodeNamesProperty(elementNames, prop, { - attr: { - set: function(val){ - this.setAttribute(prop, val); - if(descs.set){ - descs.set.call(this, true); - } - }, - get: function(){ - var ret = this.getAttribute(prop); - return (ret == null) ? undefined : prop; - } - }, - removeAttr: { - value: function(){ - this.removeAttribute(prop); - if(descs.set){ - descs.set.call(this, false); - } - } - }, - reflect: true, - propType: 'boolean', - initAttr: descs.initAttr || false - }); - }, - contentAttr: function(elem, name, val){ - if(!elem.nodeName){return;} - var attr; - if(val === undefined){ - attr = (elem.attributes[name] || {}); - val = attr.specified ? attr.value : null; - return (val == null) ? undefined : val; - } - - if(typeof val == 'boolean'){ - if(!val){ - elem.removeAttribute(name); - } else { - elem.setAttribute(name, name); - } - } else { - elem.setAttribute(name, val); - } - }, - -// set current Lang: -// - webshims.activeLang(lang:string); -// get current lang -// - webshims.activeLang(); -// get current lang -// webshims.activeLang({ -// register: moduleName:string, -// callback: callback:function -// }); -// get/set including removeLang -// - webshims.activeLang({ -// module: moduleName:string, -// callback: callback:function, -// langObj: languageObj:array/object -// }); - activeLang: (function(){ - var callbacks = []; - var registeredCallbacks = {}; - var currentLang; - var shortLang; - var notLocal = /:\/\/|^\.*\//; - var loadRemoteLang = function(data, lang, options){ - var langSrc; - if(lang && options && $.inArray(lang, options.availabeLangs || []) !== -1){ - data.loading = true; - langSrc = options.langSrc; - if(!notLocal.test(langSrc)){ - langSrc = webshims.cfg.basePath+langSrc; - } - webshims.loader.loadScript(langSrc+lang+'.js', function(){ - if(data.langObj[lang]){ - data.loading = false; - callLang(data, true); - } else { - $(function(){ - if(data.langObj[lang]){ - callLang(data, true); - } - data.loading = false; - }); - } - }); - return true; - } - return false; - }; - var callRegister = function(module){ - if(registeredCallbacks[module]){ - registeredCallbacks[module].forEach(function(data){ - data.callback(); - }); - } - }; - var callLang = function(data, _noLoop){ - if(data.activeLang != currentLang && data.activeLang !== shortLang){ - var options = modules[data.module].options; - if( data.langObj[currentLang] || (shortLang && data.langObj[shortLang]) ){ - data.activeLang = currentLang; - data.callback(data.langObj[currentLang] || data.langObj[shortLang], currentLang); - callRegister(data.module); - } else if( !_noLoop && - !loadRemoteLang(data, currentLang, options) && - !loadRemoteLang(data, shortLang, options) && - data.langObj[''] && data.activeLang !== '' ) { - data.activeLang = ''; - data.callback(data.langObj[''], currentLang); - callRegister(data.module); - } - } - }; - - - var activeLang = function(lang){ - - if(typeof lang == 'string' && lang !== currentLang){ - currentLang = lang; - shortLang = currentLang.split('-')[0]; - if(currentLang == shortLang){ - shortLang = false; - } - $.each(callbacks, function(i, data){ - callLang(data); - }); - } else if(typeof lang == 'object'){ - - if(lang.register){ - if(!registeredCallbacks[lang.register]){ - registeredCallbacks[lang.register] = []; - } - registeredCallbacks[lang.register].push(lang); - lang.callback(); - } else { - if(!lang.activeLang){ - lang.activeLang = ''; - } - callbacks.push(lang); - callLang(lang); - } - } - return currentLang; - }; - - return activeLang; - })() - }); - - $.each({ - defineNodeNamesProperty: 'defineNodeNameProperty', - defineNodeNamesProperties: 'defineNodeNameProperties', - createElements: 'createElement' - }, function(name, baseMethod){ - webshims[name] = function(names, a, b, c){ - if(typeof names == 'string'){ - names = names.split(listReg); - } - var retDesc = {}; - names.forEach(function(nodeName){ - retDesc[nodeName] = webshims[baseMethod](nodeName, a, b, c); - }); - return retDesc; - }; - }); - - webshims.isReady('webshimLocalization', true); -}); -//html5a11y -(function($, document){ - var browserVersion = $.webshims.browserVersion; - if($.browser.mozilla && browserVersion > 5){return;} - if (!$.browser.msie || (browserVersion < 12 && browserVersion > 7)) { - var elemMappings = { - article: "article", - aside: "complementary", - section: "region", - nav: "navigation", - address: "contentinfo" - }; - var addRole = function(elem, role){ - var hasRole = elem.getAttribute('role'); - if (!hasRole) { - elem.setAttribute('role', role); - } - }; - - $.webshims.addReady(function(context, contextElem){ - $.each(elemMappings, function(name, role){ - var elems = $(name, context).add(contextElem.filter(name)); - for (var i = 0, len = elems.length; i < len; i++) { - addRole(elems[i], role); - } - }); - if (context === document) { - var header = document.getElementsByTagName('header')[0]; - var footers = document.getElementsByTagName('footer'); - var footerLen = footers.length; - if (header && !$(header).closest('section, article')[0]) { - addRole(header, 'banner'); - } - if (!footerLen) { - return; - } - var footer = footers[footerLen - 1]; - if (!$(footer).closest('section, article')[0]) { - addRole(footer, 'contentinfo'); - } - } - }); - } -})(jQuery, document); -jQuery.webshims.register('form-datalist', function($, webshims, window, document, undefined){ - var doc = document; - - /* - * implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed) - */ - webshims.propTypes.element = function(descs){ - webshims.createPropDefault(descs, 'attr'); - if(descs.prop){return;} - descs.prop = { - get: function(){ - var elem = descs.attr.get.call(this); - if(elem){ - elem = document.getElementById(elem); - if(elem && descs.propNodeName && !$.nodeName(elem, descs.propNodeName)){ - elem = null; - } - } - return elem || null; - }, - writeable: false - }; - }; - - - /* - * Implements datalist element and list attribute - */ - - (function(){ - var formsCFG = $.webshims.cfg.forms; - var listSupport = Modernizr.input.list; - 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(){ - var elem = this; - var data = $.data(elem, 'datalistWidget'); - if(data){ - return data._autocomplete; - } - return ('autocomplete' in elem) ? elem.autocomplete : elem.getAttribute('autocomplete'); - }, - set: function(value){ - var elem = this; - var data = $.data(elem, 'datalistWidget'); - if(data){ - data._autocomplete = value; - if(value == 'off'){ - data.hideList(); - } - } else { - if('autocomplete' in elem){ - elem.autocomplete = value; - } else { - elem.setAttribute('autocomplete', value); - } - } - } - } - } - }; - -// if(formsCFG.customDatalist && (!listSupport || !('selectedOption') in $('<input />')[0])){ -// //currently not supported x-browser (FF4 has not implemented and is not polyfilled ) -// inputListProto.selectedOption = { -// prop: { -// writeable: false, -// get: function(){ -// var elem = this; -// var list = $.prop(elem, 'list'); -// var ret = null; -// var value, options; -// if(!list){return ret;} -// value = $.prop(elem, 'value'); -// if(!value){return ret;} -// options = $.prop(list, 'options'); -// if(!options.length){return ret;} -// $.each(options, function(i, option){ -// if(value == $.prop(option, 'value')){ -// ret = option; -// return false; -// } -// }); -// return ret; -// } -// } -// }; -// } - - 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')}); - } - }, - initAttr: true, - reflect: true, - propType: 'element', - propNodeName: 'datalist' - }; - } else { - //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, - get: function(){ - var options = this.options || []; - if(!options.length){ - var elem = this; - var select = $('select', elem); - if(select[0] && select[0].options && select[0].options.length){ - options = select[0].options; - } - } - return options; - } - } - }); - } - inputListProto['list'] = { - attr: { - get: function(){ - var val = webshims.contentAttr(this, 'list'); - if(val != null){ - 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')}); - } - }, - initAttr: true, - reflect: true, - propType: 'element', - propNodeName: 'datalist' - }; - } - - - webshims.defineNodeNameProperties('input', inputListProto); - - if($.event.customEvent){ - $.event.customEvent.updateDatalist = true; - $.event.customEvent.updateInput = true; - $.event.customEvent.datalistselect = true; - } - webshims.addReady(function(context, contextElem){ - contextElem - .filter('datalist > select, datalist, datalist > option, datalist > select > option') - .closest('datalist') - .triggerHandler('updateDatalist') - ; - - }); - - - }; - - - /* - * ShadowList - */ - var listidIndex = 0; - - var noDatalistSupport = { - submit: 1, - button: 1, - reset: 1, - hidden: 1, - - //ToDo - range: 1, - date: 1 - }; - var lteie6 = ($.browser.msie && parseInt($.browser.version, 10) < 7); - 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 shadowListProto = { - _create: function(opts){ - - if(noDatalistSupport[$.prop(opts.input, 'type')]){return;} - var datalist = opts.datalist; - var data = $.data(opts.input, 'datalistWidget'); - if(datalist && data && data.datalist !== datalist){ - data.datalist = datalist; - data.id = opts.id; - - data.shadowList.prop('className', 'datalist-polyfill '+ (data.datalist.className || '') + ' '+ data.datalist.id +'-shadowdom'); - if(formsCFG.positionDatalist){ - data.shadowList.insertAfter(opts.input); - } else { - data.shadowList.appendTo('body'); - } - $(data.datalist) - .unbind('updateDatalist.datalistWidget') - .bind('updateDatalist.datalistWidget', $.proxy(data, '_resetListCached')) - ; - data._resetListCached(); - return; - } else if(!datalist){ - if(data){ - data.destroy(); - } - return; - } else if(data && data.datalist === datalist){ - return; - } - listidIndex++; - var that = this; - this.hideList = $.proxy(that, 'hideList'); - this.timedHide = function(){ - clearTimeout(that.hideTimer); - that.hideTimer = setTimeout(that.hideList, 9); - }; - this.datalist = datalist; - this.id = opts.id; - this.hasViewableData = true; - this._autocomplete = $.attr(opts.input, 'autocomplete'); - $.data(opts.input, 'datalistWidget', this); - this.shadowList = $('<div class="datalist-polyfill '+ (this.datalist.className || '') + ' '+ this.datalist.id +'-shadowdom' +'" />'); - - if(formsCFG.positionDatalist || $(opts.input).hasClass('position-datalist')){ - this.shadowList.insertAfter(opts.input); - } else { - this.shadowList.appendTo('body'); - } - - 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).trigger('datalistselect'); - } - } - return (e.type != 'mousedown'); - }) - .bind('focusout', this.timedHide) - ; - - opts.input.setAttribute('autocomplete', 'off'); - - $(opts.input) - .attr({ - //role: 'combobox', - 'aria-haspopup': 'true' - }) - .bind('input.datalistWidget', function(){ - if(!that.triggeredByDatalist){ - that.changedValue = false; - that.showHideOptions(); - } - }) - - .bind('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.isListVisible){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).trigger('datalistselect'); - } - return false; - } - }) - .bind('focus.datalistWidget', function(){ - if($(this).hasClass('list-focus')){ - that.showList(); - } - }) - .bind('mousedown.datalistWidget', function(){ - if($(this).is(':focus')){ - that.showList(); - } - }) - .bind('blur.datalistWidget', this.timedHide) - ; - - - $(this.datalist) - .unbind('updateDatalist.datalistWidget') - .bind('updateDatalist.datalistWidget', $.proxy(this, '_resetListCached')) - ; - - this._resetListCached(); - - if(opts.input.form && (opts.input.name || opts.input.id)){ - $(opts.input.form).bind('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).bind('unload.datalist'+this.id+' beforeunload.datalist'+this.id, function(){ - that.destroy(); - }); - }, - destroy: function(){ - var autocomplete = $.attr(this.input, 'autocomplete'); - $(this.input) - .unbind('.datalistWidget') - .removeData('datalistWidget') - ; - this.shadowList.remove(); - $(document).unbind('.datalist'+this.id); - $(window).unbind('.datalist'+this.id); - if(this.input.form && this.input.id){ - $(this.input.form).unbind('submit.datalistWidget'+this.input.id); - } - this.input.removeAttribute('aria-haspopup'); - 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 = (e && document.activeElement == that.input))){ - that.updateListOptions(forceShow); - } else { - webshims.ready('WINDOWLOAD', function(){ - that.updateTimer = setTimeout(function(){ - that.updateListOptions(); - that = null; - listidIndex = 1; - }, 200 + (100 * listidIndex)); - }); - } - } - }, - updateListOptions: function(_forceShow){ - this.needsUpdate = false; - clearTimeout(this.updateTimer); - this.updateTimer = false; - this.shadowList - .css({ - fontSize: $.css(this.input, 'fontSize'), - fontFamily: $.css(this.input, 'fontFamily') - }) - ; - this.searchStart = formsCFG.customDatalist && $(this.input).hasClass('search-start'); - - var list = []; - - var values = []; - var allOptions = []; - var rElem, rItem, rOptions, rI, rLen, item; - for(rOptions = $.prop(this.datalist, 'options'), rI = 0, rLen = rOptions.length; rI < rLen; rI++){ - rElem = rOptions[rI]; - if(rElem.disabled){return;} - rItem = { - value: $(rElem).val() || '', - text: $.trim($.attr(rElem, 'label') || getText(rElem)), - className: rElem.className || '', - style: $.attr(rElem, 'style') || '' - }; - if(!rItem.text){ - rItem.text = rItem.value; - } else if(rItem.text != rItem.value){ - rItem.className += ' different-label-value'; - } - values[rI] = rItem.value; - allOptions[rI] = 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, text: val, className: 'stored-suggest', style: ''}); - } - }); - - for(rI = 0, rLen = allOptions.length; rI < rLen; rI++){ - item = allOptions[rI]; - list[rI] = '<li class="'+ item.className +'" style="'+ item.style +'" tabindex="-1" role="listitem"><span class="option-label">'+ item.text +'</span> <span class="option-value">'+item.value+'</span></li>'; - } - - this.arrayOptions = allOptions; - this.shadowList.html('<div class="datalist-outer-box"><div class="datalist-box"><ul role="list">'+ list.join("\n") +'</ul></div></div>'); - - if($.fn.bgIframe && lteie6){ - this.shadowList.bgIframe(); - } - - if(_forceShow || this.isListVisible){ - this.showHideOptions(); - } - }, - showHideOptions: function(_fromShowList){ - var value = $.prop(this.input, 'value').toLowerCase(); - //first check prevent infinite loop, second creates simple lazy optimization - if(value === this.lastUpdatedValue || (this.lastUnfoundValue && value.indexOf(this.lastUnfoundValue) === 0)){ - return; - } - - this.lastUpdatedValue = value; - var found = false; - var startSearch = this.searchStart; - var lis = $('li', this.shadowList); - if(value){ - this.arrayOptions.forEach(function(item, i){ - var search; - if(!('lowerText' in item)){ - if(item.text != item.value){ - item.lowerText = item.value.toLowerCase() + item.text.toLowerCase(); - } else { - item.lowerText = item.text.toLowerCase(); - } - } - search = item.lowerText.indexOf(value); - search = startSearch ? !search : search !== -1; - if(search){ - $(lis[i]).removeClass('hidden-item'); - found = true; - } else { - $(lis[i]).addClass('hidden-item'); - } - }); - } else if(lis.length) { - lis.removeClass('hidden-item'); - found = true; - } - - this.hasViewableData = found; - if(!_fromShowList && found){ - this.showList(); - } - if(!found){ - this.lastUnfoundValue = value; - this.hideList(); - } - }, - setPos: function(){ - this.shadowList.css({marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0}); - var css = (formsCFG.positionDatalist) ? $(this.input).position() : webshims.getRelOffset(this.shadowList, this.input); - css.top += $(this.input).outerHeight(); - css.width = $(this.input).outerWidth() - (parseInt(this.shadowList.css('borderLeftWidth'), 10) || 0) - (parseInt(this.shadowList.css('borderRightWidth'), 10) || 0); - this.shadowList.css({marginTop: '', marginLeft: '', marginRight: '', marginBottom: ''}).css(css); - return css; - }, - showList: function(){ - if(this.isListVisible){return false;} - if(this.needsUpdate){ - this.updateListOptions(); - } - this.showHideOptions(true); - if(!this.hasViewableData){return false;} - this.isListVisible = true; - var that = this; - - that.setPos(); - that.shadowList.addClass('datalist-visible').find('li.active-item').removeClass('active-item'); - - $(window).unbind('.datalist'+that.id); - $(document) - .unbind('.datalist'+that.id) - .bind('mousedown.datalist'+that.id +' focusin.datalist'+that.id, function(e){ - if(e.target === that.input || that.shadowList[0] === e.target || $.contains( that.shadowList[0], e.target )){ - clearTimeout(that.hideTimer); - setTimeout(function(){ - clearTimeout(that.hideTimer); - }, 9); - } else { - that.timedHide(); - } - }) - .bind('updateshadowdom.datalist'+that.id, function(){ - that.setPos(); - }) - ; - return true; - }, - hideList: function(){ - if(!this.isListVisible){return false;} - var that = this; - var triggerChange = function(e){ - if(that.changedValue){ - $(that.input).trigger('change'); - } - that.changedValue = false; - }; - - that.shadowList.removeClass('datalist-visible list-item-active'); - that.index = -1; - that.isListVisible = false; - if(that.changedValue){ - that.triggeredByDatalist = true; - webshims.triggerInlineForm && webshims.triggerInlineForm(that.input, 'input'); - if($(that.input).is(':focus')){ - $(that.input).one('blur', triggerChange); - } else { - triggerChange(); - } - that.triggeredByDatalist = false; - } - $(document).unbind('.datalist'+that.id); - $(window) - .unbind('.datalist'+that.id) - .one('resize.datalist'+that.id, function(){ - that.shadowList.css({top: 0, left: 0}); - }) - ; - 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 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; - } - }, - 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; - } - }; - - //init datalist update - initializeDatalist(); - })(); - -});//additional tests for partial implementation of forms features -(function($){ - 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 type="date" required="" name="a" /><input type="submit" /></form>'); - var testRequiredFind = function(){ - if(form[0].querySelector){ - try { - bugs.findRequired = !(form[0].querySelector('select:required')); - } catch(er){ - bugs.findRequired = false; - } - } - }; - bugs.findRequired = false; - bugs.validationMessage = false; - bugs.valueAsNumberSet = false; - - webshims.capturingEventPrevented = function(e){ - if(!e._isPolyfilled){ - var isDefaultPrevented = e.isDefaultPrevented; - var preventDefault = e.preventDefault; - e.preventDefault = function(){ - clearTimeout($.data(e.target, e.type + 'DefaultPrevented')); - $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){ - $.removeData(e.target, e.type + 'DefaultPrevented'); - }, 30)); - return preventDefault.apply(this, arguments); - }; - e.isDefaultPrevented = function(){ - return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false); - }; - e._isPolyfilled = true; - } - }; - - if(!Modernizr.formvalidation || bugs.bustedValidity){ - testRequiredFind(); - return; - } - - //create delegatable events - webshims.capturingEvents(['input']); - webshims.capturingEvents(['invalid'], true); - - Modernizr.bugfreeformvalidation = true; - if(window.opera || $.browser.webkit || window.testGoodWithFix){ - var dateElem = $('input', form).eq(0); - var timer; - var onDomextend = function(fn){ - webshims.loader.loadList(['dom-extend']); - webshims.ready('dom-extend', fn); - }; - var loadFormFixes = function(e){ - var reTest = ['form-extend', 'form-message', 'form-native-fix']; - if(e){ - e.preventDefault(); - e.stopImmediatePropagation(); - } - clearTimeout(timer); - setTimeout(function(){ - if(!form){return;} - form.remove(); - form = dateElem = null; - }, 9); - if(!Modernizr.bugfreeformvalidation){ - webshims.addPolyfill('form-native-fix', { - f: 'forms', - d: ['form-extend'] - }); - //remove form-extend readyness - webshims.modules['form-extend'].test = $.noop; - } - - if(webshims.isReady('form-number-date-api')){ - reTest.push('form-number-date-api'); - } - - webshims.reTest(reTest); - - if(dateElem){ - try { - if(dateElem.prop({disabled: true, value: ''}).prop('disabled', false).is(':valid')){ - onDomextend(function(){ - webshims.onNodeNamesPropertyModify(['input', 'textarea'], ['disabled', 'readonly'], { - set: function(val){ - var elem = this; - if(!val && elem){ - $.prop(elem, 'value', $.prop(elem, 'value')); - } - } - }); - webshims.onNodeNamesPropertyModify(['select'], ['disabled', 'readonly'], { - set: function(val){ - var elem = this; - if(!val && elem){ - val = $(elem).val(); - ($('option:last-child', elem)[0] || {}).selected = true; - $(elem).val( val ); - } - } - }); - }); - } - } catch(er){} - } - - if ($.browser.opera || window.testGoodWithFix) { - 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).bind('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; - } - } - }); - }); - - }); - } - }; - - form.appendTo('head'); - if(window.opera || window.testGoodWithFix) { - testRequiredFind(); - bugs.validationMessage = !(dateElem.prop('validationMessage')); - if((Modernizr.inputtypes || {}).date){ - try { - dateElem.prop('valueAsNumber', 0); - } catch(er){} - bugs.valueAsNumberSet = (dateElem.prop('value') != '1970-01-01'); - } - dateElem.prop('value', ''); - } - - form.bind('submit', function(e){ - Modernizr.bugfreeformvalidation = false; - loadFormFixes(e); - }); - - timer = setTimeout(function(){ - if (form) { - form.triggerHandler('submit'); - } - }, 9); - - $('input, select', form).bind('invalid', loadFormFixes) - .filter('[type="submit"]') - .bind('click', function(e){ - e.stopImmediatePropagation(); - }) - .trigger('click') - ; - - if($.browser.webkit && Modernizr.bugfreeformvalidation && !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).bind('invalid', function(e){ - if(e.originalEvent && form && form == e.target.form){ - e.wrongWebkitInvalid = true; - e.stopImmediatePropagation(); - } - }); - })(); - } - } - -})(jQuery); - -jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){ - "use strict"; - - var groupTypes = {radio: 1}; - 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(groupTypes[elem[0].type]){ - 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 getContentValidationMessage = 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; - } - }); - } - } - - if(typeof message == 'object'){ - message = message.defaultMessage; - } - 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*/}; - $.extend($.expr[":"], { - "valid-element": function(elem){ - return !!($.prop(elem, 'willValidate') && ($.prop(elem, 'validity') || {valid: 1}).valid); - }, - "invalid-element": function(elem){ - return !!($.prop(elem, 'willValidate') && !isValid(elem)); - }, - "required-element": function(elem){ - return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required')); - }, - "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)); - } - - }); - - ['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 || !Modernizr.bugfreeformvalidation) { - (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); - }; - } - - })(); - } - - //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('form-ui-invalid')){ - if(isValid(elem)){ - $(elem).getShadowElement().removeClass('form-ui-invalid'); - if(name == 'checked' && val) { - getGroupElements(elem).not(elem).removeClass('form-ui-invalid').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 switchValidityClass = function(e){ - var elem, timer; - if(!e.target){return;} - elem = $(e.target).getNativeElement()[0]; - if(elem.type == 'submit' || !$.prop(elem, 'willValidate') || (e.type == 'focusout' && e.type == 'radio')){return;} - timer = $.data(elem, 'webshimsswitchvalidityclass'); - var switchClass = function(){ - var validity = $.prop(elem, 'validity'); - var shadowElem = $(elem).getShadowElement(); - var addClass, removeClass, trigger, generaltrigger, validityCause; - - $(elem).trigger('refreshCustomValidityRules'); - if(validity.valid){ - if(!shadowElem.hasClass('form-ui-valid')){ - addClass = 'form-ui-valid'; - removeClass = 'form-ui-invalid'; - 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('form-ui-invalid')){ - addClass = 'form-ui-invalid'; - removeClass = 'form-ui-valid'; - 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(e.target, 'webshimsswitchvalidityclass'); - - }; - if(timer){ - clearTimeout(timer); - } - if(e.type == 'refreshvalidityui'){ - switchClass(); - } else { - $.data(e.target, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9)); - } - }; - - $(document).bind(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 = ($.browser.webkit || document.compatMode == 'BackCompat') ? - $(document.body) : - $(document.documentElement) - ; - }; - 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; - }; - - /* some extra validation UI */ - webshims.validityAlert = (function(){ - var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label'; - var errorBubble; - var hideTimer = false; - var focusTimer = false; - var resizeTimer = false; - var boundHide; - - var api = { - hideDelay: 5000, - - showFor: function(elem, message, noFocusElem, noBubble){ - api._create(); - elem = $(elem); - var visual = $(elem).getShadowElement(); - var offset = api.getOffsetFromBody(visual); - api.clear(); - if(noBubble){ - this.hide(); - } else { - this.getMessage(elem, message); - this.position(visual, offset); - - this.show(); - if(this.hideDelay){ - hideTimer = setTimeout(boundHide, this.hideDelay); - } - $(window) - .bind('resize.validityalert', function(){ - clearTimeout(resizeTimer); - resizeTimer = setTimeout(function(){ - api.position(visual); - }, 9); - }) - ; - } - - if(!noFocusElem){ - this.setFocus(visual, offset); - } - }, - getOffsetFromBody: function(elem){ - return webshims.getRelOffset(errorBubble, elem); - }, - setFocus: function(visual, offset){ - var focusElem = $(visual).getShadowFocusElement(); - var scrollTop = webshims.scrollRoot.scrollTop(); - var elemTop = ((offset || focusElem.offset()).top) - 30; - var smooth; - - if(webshims.getID && alertElem == 'label'){ - errorBubble.attr('for', webshims.getID(focusElem)); - } - - 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); - } - setTimeout(function(){ - $(document).bind('focusout.validityalert', boundHide); - }, 10); - }, - getMessage: function(elem, message){ - if (!message) { - message = getContentValidationMessage(elem[0]) || elem.prop('validationMessage'); - } - if (message) { - $('span.va-box', errorBubble).text(message); - } - else { - this.hide(); - } - }, - position: function(elem, offset){ - offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem); - offset.top += elem.outerHeight(); - errorBubble.css(offset); - }, - show: function(){ - if(errorBubble.css('display') === 'none'){ - errorBubble.css({opacity: 0}).show(); - } - errorBubble.addClass('va-visible').fadeTo(400, 1); - }, - hide: function(){ - errorBubble.removeClass('va-visible').fadeOut(); - }, - clear: function(){ - clearTimeout(focusTimer); - clearTimeout(hideTimer); - $(document).unbind('.validityalert'); - $(window).unbind('.validityalert'); - errorBubble.stop().removeAttr('for'); - }, - _create: function(){ - if(errorBubble){return;} - errorBubble = api.errorBubble = $('<'+alertElem+' class="validity-alert-wrapper" role="alert"><span class="validity-alert"><span class="va-arrow"><span class="va-arrow-box"></span></span><span class="va-box"></span></span></'+alertElem+'>').css({position: 'absolute', display: 'none'}); - webshims.ready('DOM', function(){ - errorBubble.appendTo('body'); - if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){ - errorBubble.bgIframe(); - } - }); - } - }; - - - boundHide = $.proxy(api, 'hide'); - - return api; - })(); - - - /* extension, but also used to fix native implementation workaround/bugfixes */ - (function(){ - var firstEvent, - invalids = [], - stopSubmitTimer, - form - ; - - $(document).bind('invalid', function(e){ - if(e.wrongWebkitInvalid){return;} - var jElm = $(e.target); - var shadowElem = jElm.getShadowElement(); - if(!shadowElem.hasClass('form-ui-invalid')){ - shadowElem.addClass('form-ui-invalid').removeClass('form-ui-valid'); - 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){ - webshims.ready('DOM forms', function(){ - $(document).bind('firstinvalid', function(e){ - if(!e.isInvalidUIPrevented()){ - e.preventDefault(); - $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') ); - } - }); - }); - } - -});(function($, Modernizr, webshims){ - "use strict"; - var hasNative = Modernizr.audio && Modernizr.video; - var supportsLoop = false; - var options = webshims.cfg.mediaelement; - var bugs = webshims.bugs; - var loadSwf = function(){ - webshims.ready('mediaelement-swf', function(){ - if(!webshims.mediaelement.createSWF){ - webshims.modules["mediaelement-swf"].test = $.noop; - webshims.reTest(["mediaelement-swf"], hasNative); - } - }); - }; - var hasSwf; - if(hasNative){ - var videoElem = document.createElement('video'); - Modernizr.videoBuffered = ('buffered' in videoElem); - supportsLoop = ('loop' in videoElem); - - webshims.capturingEvents(['play', 'playing', 'waiting', 'paused', 'ended', 'durationchange', 'loadedmetadata', 'canplay', 'volumechange']); - - if(!Modernizr.videoBuffered){ - webshims.addPolyfill('mediaelement-native-fix', { - f: 'mediaelement', - test: Modernizr.videoBuffered, - d: ['dom-support'] - }); - - webshims.reTest('mediaelement-native-fix'); - } - } - - if(hasNative && !options.preferFlash){ - var switchOptions = function(e){ - var parent = e.target.parentNode; - if(!options.preferFlash && ($(e.target).is('audio, video') || (parent && $('source:last', parent)[0] == e.target)) ){ - webshims.ready('DOM mediaelement', function(){ - if(hasSwf){ - loadSwf(); - } - webshims.ready('WINDOWLOAD mediaelement-swf', function(){ - setTimeout(function(){ - if(hasSwf && !options.preferFlash && webshims.mediaelement.createSWF && !$(e.target).closest('audio, video').is('.nonnative-api-active')){ - options.preferFlash = true; - document.removeEventListener('error', switchOptions, true); - $('audio, video').mediaLoad(); - webshims.info("switching mediaelements option to 'preferFlash', due to an error with native player: "+e.target.src); - } else if(!hasSwf){ - document.removeEventListener('error', switchOptions, true); - } - }, 20); - }); - }); - } - }; - document.addEventListener('error', switchOptions, true); - $('audio, video').each(function(){ - if(this.error){ - switchOptions({target: this}); - } - }); - } - - bugs.track = false; - - if(Modernizr.track){ - (function(){ - - if(!bugs.track){ - bugs.track = typeof $('<track />')[0].readyState != 'number'; - } - - if(!bugs.track){ - try { - new TextTrackCue(2, 3, ''); - } catch(e){ - bugs.track = true; - } - } - - var trackOptions = webshims.cfg.track; - var trackListener = function(e){ - $(e.target).filter('track').each(changeApi); - }; - var changeApi = function(){ - if(bugs.track || (!trackOptions.override && $.prop(this, 'readyState') == 3)){ - trackOptions.override = true; - webshims.reTest('track'); - document.removeEventListener('error', trackListener, true); - if(this && $.nodeName(this, 'track')){ - webshims.error("track support was overwritten. Please check your vtt including your vtt mime-type"); - } else { - webshims.info("track support was overwritten. due to bad browser support"); - } - } - }; - var detectTrackError = function(){ - document.addEventListener('error', trackListener, true); - - if(bugs.track){ - changeApi(); - } else { - $('track').each(changeApi); - } - }; - if(!trackOptions.override){ - if(webshims.isReady('track')){ - detectTrackError(); - } else { - $(detectTrackError); - } - } - })(); - - } - -webshims.register('mediaelement-core', function($, webshims, window, document, undefined){ - hasSwf = swfobject.hasFlashPlayerVersion('9.0.115'); - - var mediaelement = webshims.mediaelement; - - var getSrcObj = function(elem, nodeName){ - elem = $(elem); - var src = {src: elem.attr('src') || '', elem: elem, srcProp: elem.prop('src')}; - if(!src.src){return src;} - var tmp = elem.attr('type'); - if(tmp){ - src.type = tmp; - src.container = $.trim(tmp.split(';')[0]); - } else { - if(!nodeName){ - nodeName = elem[0].nodeName.toLowerCase(); - if(nodeName == 'source'){ - nodeName = (elem.closest('video, audio')[0] || {nodeName: 'video'}).nodeName.toLowerCase(); - } - } - tmp = mediaelement.getTypeForSrc(src.src, nodeName ); - - if(tmp){ - src.type = tmp; - src.container = tmp; - } - } - tmp = elem.attr('media'); - if(tmp){ - src.media = tmp; - } - return src; - }; - - - - var hasYt = !hasSwf && ('postMessage' in window) && hasNative; - - var loadYt = (function(){ - var loaded; - return function(){ - if(loaded || !hasYt){return;} - loaded = true; - webshims.loader.loadScript("https://www.youtube.com/player_api"); - $(function(){ - webshims.polyfill("mediaelement-yt"); - }); - }; - })(); - var loadThird = function(){ - if(hasSwf){ - loadSwf(); - } else { - loadYt(); - } - }; - - webshims.addPolyfill('mediaelement-yt', { - test: !hasYt, - d: ['dom-support'] - }); - - mediaelement.mimeTypes = { - audio: { - //ogm shouldn´t be used! - 'audio/ogg': ['ogg','oga', 'ogm'], - 'audio/ogg;codecs="opus"': 'opus', - 'audio/mpeg': ['mp2','mp3','mpga','mpega'], - 'audio/mp4': ['mp4','mpg4', 'm4r', 'm4a', 'm4p', 'm4b', 'aac'], - 'audio/wav': ['wav'], - 'audio/3gpp': ['3gp','3gpp'], - 'audio/webm': ['webm'], - 'audio/fla': ['flv', 'f4a', 'fla'], - 'application/x-mpegURL': ['m3u8', 'm3u'] - }, - video: { - //ogm shouldn´t be used! - 'video/ogg': ['ogg','ogv', 'ogm'], - 'video/mpeg': ['mpg','mpeg','mpe'], - 'video/mp4': ['mp4','mpg4', 'm4v'], - 'video/quicktime': ['mov','qt'], - 'video/x-msvideo': ['avi'], - 'video/x-ms-asf': ['asf', 'asx'], - 'video/flv': ['flv', 'f4v'], - 'video/3gpp': ['3gp','3gpp'], - 'video/webm': ['webm'], - 'application/x-mpegURL': ['m3u8', 'm3u'], - 'video/MP2T': ['ts'] - } - } - ; - - mediaelement.mimeTypes.source = $.extend({}, mediaelement.mimeTypes.audio, mediaelement.mimeTypes.video); - - mediaelement.getTypeForSrc = function(src, nodeName){ - if(src.indexOf('youtube.com/watch?') != -1 || src.indexOf('youtube.com/v/') != -1){ - return 'video/youtube'; - } - src = src.split('?')[0].split('.'); - src = src[src.length - 1]; - var mt; - - $.each(mediaelement.mimeTypes[nodeName], function(mimeType, exts){ - if(exts.indexOf(src) !== -1){ - mt = mimeType; - return false; - } - }); - return mt; - }; - - - mediaelement.srces = function(mediaElem, srces){ - mediaElem = $(mediaElem); - if(!srces){ - srces = []; - var nodeName = mediaElem[0].nodeName.toLowerCase(); - var src = getSrcObj(mediaElem, nodeName); - - if(!src.src){ - - $('source', mediaElem).each(function(){ - src = getSrcObj(this, nodeName); - if(src.src){srces.push(src);} - }); - } else { - srces.push(src); - } - return srces; - } else { - mediaElem.removeAttr('src').removeAttr('type').find('source').remove(); - if(!$.isArray(srces)){ - srces = [srces]; - } - srces.forEach(function(src){ - var source = document.createElement('source'); - if(typeof src == 'string'){ - src = {src: src}; - } - source.setAttribute('src', src.src); - if(src.type){ - source.setAttribute('type', src.type); - } - if(src.media){ - source.setAttribute('media', src.media); - } - mediaElem.append(source); - }); - - } - }; - - - $.fn.loadMediaSrc = function(srces, poster){ - return this.each(function(){ - if(poster !== undefined){ - $(this).removeAttr('poster'); - if(poster){ - $.attr(this, 'poster', poster); - } - } - mediaelement.srces(this, srces); - $(this).mediaLoad(); - }); - }; - - mediaelement.swfMimeTypes = ['video/3gpp', 'video/x-msvideo', 'video/quicktime', 'video/x-m4v', 'video/mp4', 'video/m4p', 'video/x-flv', 'video/flv', 'audio/mpeg', 'audio/aac', 'audio/mp4', 'audio/x-m4a', 'audio/m4a', 'audio/mp3', 'audio/x-fla', 'audio/fla', 'youtube/flv', 'jwplayer/jwplayer', 'video/youtube']; - - mediaelement.canThirdPlaySrces = function(mediaElem, srces){ - var ret = ''; - if(hasSwf || hasYt){ - mediaElem = $(mediaElem); - srces = srces || mediaelement.srces(mediaElem); - $.each(srces, function(i, src){ - if(src.container && src.src && ((hasSwf && mediaelement.swfMimeTypes.indexOf(src.container) != -1) || (hasYt && src.container == 'video/youtube'))){ - ret = src; - return false; - } - }); - - } - - return ret; - }; - - var nativeCanPlayType = {}; - mediaelement.canNativePlaySrces = function(mediaElem, srces){ - var ret = ''; - if(hasNative){ - mediaElem = $(mediaElem); - var nodeName = (mediaElem[0].nodeName || '').toLowerCase(); - if(!nativeCanPlayType[nodeName]){return ret;} - srces = srces || mediaelement.srces(mediaElem); - - $.each(srces, function(i, src){ - if(src.type && nativeCanPlayType[nodeName].prop._supvalue.call(mediaElem[0], src.type) ){ - ret = src; - return false; - } - }); - } - return ret; - }; - - mediaelement.setError = function(elem, message){ - if(!message){ - message = "can't play sources"; - } - - $(elem).pause().data('mediaerror', message); - webshims.warn('mediaelementError: '+ message); - setTimeout(function(){ - if($(elem).data('mediaerror')){ - $(elem).trigger('mediaerror'); - } - }, 1); - }; - - var handleThird = (function(){ - var requested; - return function( mediaElem, ret, data ){ - webshims.ready(hasSwf ? 'mediaelement-swf' : 'mediaelement-yt', function(){ - if(mediaelement.createSWF){ - mediaelement.createSWF( mediaElem, ret, data ); - } else if(!requested) { - requested = true; - loadThird(); - //readd to ready - handleThird( mediaElem, ret, data ); - } - }); - if(!requested && hasYt && !mediaelement.createSWF){ - loadYt(); - } - }; - })(); - - var stepSources = function(elem, data, useSwf, _srces, _noLoop){ - var ret; - if(useSwf || (useSwf !== false && data && data.isActive == 'third')){ - ret = mediaelement.canThirdPlaySrces(elem, _srces); - if(!ret){ - if(_noLoop){ - mediaelement.setError(elem, false); - } else { - stepSources(elem, data, false, _srces, true); - } - } else { - handleThird(elem, ret, data); - } - } else { - ret = mediaelement.canNativePlaySrces(elem, _srces); - if(!ret){ - if(_noLoop){ - mediaelement.setError(elem, false); - if(data && data.isActive == 'third') { - mediaelement.setActive(elem, 'html5', data); - } - } else { - stepSources(elem, data, true, _srces, true); - } - } else if(data && data.isActive == 'third') { - mediaelement.setActive(elem, 'html5', data); - } - } - }; - var stopParent = /^(?:embed|object|datalist)$/i; - var selectSource = function(elem, data){ - var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {}); - var _srces = mediaelement.srces(elem); - var parent = elem.parentNode; - - clearTimeout(baseData.loadTimer); - $.data(elem, 'mediaerror', false); - - if(!_srces.length || !parent || parent.nodeType != 1 || stopParent.test(parent.nodeName || '')){return;} - data = data || webshims.data(elem, 'mediaelement'); - stepSources(elem, data, options.preferFlash || undefined, _srces); - }; - - - $(document).bind('ended', function(e){ - var data = webshims.data(e.target, 'mediaelement'); - if( supportsLoop && (!data || data.isActive == 'html5') && !$.prop(e.target, 'loop')){return;} - setTimeout(function(){ - if( $.prop(e.target, 'paused') || !$.prop(e.target, 'loop') ){return;} - $(e.target).prop('currentTime', 0).play(); - }, 1); - - }); - if(!supportsLoop){ - webshims.defineNodeNamesBooleanProperty(['audio', 'video'], 'loop'); - } - - ['audio', 'video'].forEach(function(nodeName){ - var supLoad = webshims.defineNodeNameProperty(nodeName, 'load', { - prop: { - value: function(){ - var data = webshims.data(this, 'mediaelement'); - selectSource(this, data); - if(hasNative && (!data || data.isActive == 'html5') && supLoad.prop._supvalue){ - supLoad.prop._supvalue.apply(this, arguments); - } - } - } - }); - nativeCanPlayType[nodeName] = webshims.defineNodeNameProperty(nodeName, 'canPlayType', { - prop: { - value: function(type){ - var ret = ''; - if(hasNative && nativeCanPlayType[nodeName].prop._supvalue){ - ret = nativeCanPlayType[nodeName].prop._supvalue.call(this, type); - if(ret == 'no'){ - ret = ''; - } - } - if(!ret && hasSwf){ - type = $.trim((type || '').split(';')[0]); - if(mediaelement.swfMimeTypes.indexOf(type) != -1){ - ret = 'maybe'; - } - } - return ret; - } - } - }); - }); - webshims.onNodeNamesPropertyModify(['audio', 'video'], ['src', 'poster'], { - set: function(){ - var elem = this; - var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {}); - clearTimeout(baseData.loadTimer); - baseData.loadTimer = setTimeout(function(){ - selectSource(elem); - elem = null; - }, 9); - } - }); - - var initMediaElements = function(){ - - webshims.addReady(function(context, insertedElement){ - $('video, audio', context) - .add(insertedElement.filter('video, audio')) - .each(function(){ - if($.browser.msie && webshims.browserVersion > 8 && $.prop(this, 'paused') && !$.prop(this, 'readyState') && $(this).is('audio[preload="none"][controls]:not([autoplay])')){ - $(this).prop('preload', 'metadata').mediaLoad(); - } else { - selectSource(this); - } - - - - if(hasNative){ - var bufferTimer; - var lastBuffered; - var elem = this; - var getBufferedString = function(){ - var buffered = $.prop(elem, 'buffered'); - if(!buffered){return;} - var bufferString = ""; - for(var i = 0, len = buffered.length; i < len;i++){ - bufferString += buffered.end(i); - } - return bufferString; - }; - var testBuffer = function(){ - var buffered = getBufferedString(); - if(buffered != lastBuffered){ - lastBuffered = buffered; - $(elem).triggerHandler('progress'); - } - }; - - $(this) - .bind('play loadstart progress', function(e){ - if(e.type == 'progress'){ - lastBuffered = getBufferedString(); - } - clearTimeout(bufferTimer); - bufferTimer = setTimeout(testBuffer, 999); - }) - .bind('emptied stalled mediaerror abort suspend', function(e){ - if(e.type == 'emptied'){ - lastBuffered = false; - } - clearTimeout(bufferTimer); - }) - ; - } - - }) - ; - }); - }; - - if(Modernizr.track && !bugs.track){ - webshims.defineProperty(TextTrack.prototype, 'shimActiveCues', { - get: function(){ - return this._shimActiveCues || this.activeCues; - } - }); - } - //set native implementation ready, before swf api is retested - if(hasNative){ - webshims.isReady('mediaelement-core', true); - initMediaElements(); - webshims.ready('WINDOWLOAD mediaelement', loadThird); - } else { - webshims.ready('mediaelement-swf', initMediaElements); - } - $(function(){ - webshims.loader.loadList(['track-ui']); - }); - -}); +//DOM-Extension helper +jQuery.webshims.register('dom-extend', function($, webshims, window, document, undefined){ + "use strict"; + //shortcus + var modules = webshims.modules; + var listReg = /\s*,\s*/; + + //proxying attribute + var olds = {}; + var havePolyfill = {}; + var extendedProps = {}; + var extendQ = {}; + var modifyProps = {}; + + var oldVal = $.fn.val; + var singleVal = function(elem, name, val, pass, _argless){ + return (_argless) ? oldVal.call($(elem)) : oldVal.call($(elem), val); + }; + $.fn.val = function(val){ + var elem = this[0]; + if(arguments.length && val == null){ + val = ''; + } + if(!arguments.length){ + if(!elem || elem.nodeType !== 1){return oldVal.call(this);} + return $.prop(elem, 'value', val, 'val', true); + } + if($.isArray(val)){ + return oldVal.apply(this, arguments); + } + var isFunction = $.isFunction(val); + return this.each(function(i){ + elem = this; + if(elem.nodeType === 1){ + if(isFunction){ + var genVal = val.call( elem, i, $.prop(elem, 'value', undefined, 'val', true)); + if(genVal == null){ + genVal = ''; + } + $.prop(elem, 'value', genVal, 'val') ; + } else { + $.prop(elem, 'value', val, 'val'); + } + } + }); + }; + + 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); + if(val !== undefined){ + if(!data){ + data = $.data(elem, dataID, {}); + } + if(key){ + data[key] = val; + } + } + + return key ? data && data[key] : data; + }; + + + [{name: 'getNativeElement', prop: 'nativeElement'}, {name: 'getShadowElement', prop: 'shadowElement'}, {name: 'getShadowFocusElement', prop: 'shadowFocusElement'}].forEach(function(data){ + $.fn[data.name] = function(){ + return this.map(function(){ + var shadowData = elementData(this, 'shadowData'); + return shadowData && shadowData[data.prop] || this; + }); + }; + }); + + + ['removeAttr', 'prop', 'attr'].forEach(function(type){ + olds[type] = $[type]; + $[type] = function(elem, name, value, pass, _argless){ + var isVal = (pass == 'val'); + var oldMethod = !isVal ? olds[type] : singleVal; + if( !elem || !havePolyfill[name] || elem.nodeType !== 1 || (!isVal && pass && type == 'attr' && $.attrFn[name]) ){ + return oldMethod(elem, name, value, pass, _argless); + } + + var nodeName = (elem.nodeName || '').toLowerCase(); + var desc = extendedProps[nodeName]; + var curType = (type == 'attr' && (value === false || value === null)) ? 'removeAttr' : type; + var propMethod; + var oldValMethod; + var ret; + + + if(!desc){ + desc = extendedProps['*']; + } + if(desc){ + desc = desc[name]; + } + + if(desc){ + propMethod = desc[curType]; + } + + if(propMethod){ + if(name == 'value'){ + oldValMethod = propMethod.isVal; + propMethod.isVal = isVal; + } + if(curType === 'removeAttr'){ + return propMethod.value.call(elem); + } else if(value === undefined){ + return (propMethod.get) ? + propMethod.get.call(elem) : + propMethod.value + ; + } else if(propMethod.set) { + if(type == 'attr' && value === true){ + value = name; + } + + ret = propMethod.set.call(elem, value); + } + if(name == 'value'){ + propMethod.isVal = oldValMethod; + } + } else { + ret = oldMethod(elem, name, value, pass, _argless); + } + if((value !== undefined || curType === 'removeAttr') && modifyProps[nodeName] && modifyProps[nodeName][name]){ + + var boolValue; + if(curType == 'removeAttr'){ + boolValue = false; + } else if(curType == 'prop'){ + boolValue = !!(value); + } else { + boolValue = true; + } + + modifyProps[nodeName][name].forEach(function(fn){ + if(!fn.only || (fn.only = 'prop' && type == 'prop') || (fn.only == 'attr' && type != 'prop')){ + fn.call(elem, value, boolValue, (isVal) ? 'val' : curType, type); + } + }); + } + return ret; + }; + + extendQ[type] = function(nodeName, prop, desc){ + + if(!extendedProps[nodeName]){ + extendedProps[nodeName] = {}; + } + if(!extendedProps[nodeName][prop]){ + extendedProps[nodeName][prop] = {}; + } + var oldDesc = extendedProps[nodeName][prop][type]; + var getSup = function(propType, descriptor, oDesc){ + if(descriptor && descriptor[propType]){ + return descriptor[propType]; + } + if(oDesc && oDesc[propType]){ + return oDesc[propType]; + } + if(type == 'prop' && prop == 'value'){ + return function(value){ + var elem = this; + return (desc.isVal) ? + singleVal(elem, prop, value, false, (arguments.length === 0)) : + olds[type](elem, prop, value) + ; + }; + } + if(type == 'prop' && propType == 'value' && desc.value.apply){ + return function(value){ + var sup = olds[type](this, prop); + if(sup && sup.apply){ + sup = sup.apply(this, arguments); + } + return sup; + }; + } + return function(value){ + return olds[type](this, prop, value); + }; + }; + extendedProps[nodeName][prop][type] = desc; + if(desc.value === undefined){ + if(!desc.set){ + desc.set = desc.writeable ? + getSup('set', desc, oldDesc) : + (webshims.cfg.useStrict && prop == 'prop') ? + function(){throw(prop +' is readonly on '+ nodeName);} : + $.noop + ; + } + if(!desc.get){ + desc.get = getSup('get', desc, oldDesc); + } + + } + + ['value', 'get', 'set'].forEach(function(descProp){ + if(desc[descProp]){ + desc['_sup'+descProp] = getSup(descProp, oldDesc); + } + }); + }; + + }); + + //see also: https://github.com/lojjic/PIE/issues/40 | https://prototype.lighthouseapp.com/projects/8886/tickets/1107-ie8-fatal-crash-when-prototypejs-is-loaded-with-rounded-cornershtc + var isExtendNativeSave = (!$.browser.msie || parseInt($.browser.version, 10) > 8); + var extendNativeValue = (function(){ + var UNKNOWN = webshims.getPrototypeOf(document.createElement('foobar')); + var has = Object.prototype.hasOwnProperty; + return function(nodeName, prop, desc){ + var elem = document.createElement(nodeName); + var elemProto = webshims.getPrototypeOf(elem); + if( isExtendNativeSave && elemProto && UNKNOWN !== elemProto && ( !elem[prop] || !has.call(elem, prop) ) ){ + var sup = elem[prop]; + desc._supvalue = function(){ + if(sup && sup.apply){ + return sup.apply(this, arguments); + } + return sup; + }; + elemProto[prop] = desc.value; + } else { + desc._supvalue = function(){ + var data = elementData(this, 'propValue'); + if(data && data[prop] && data[prop].apply){ + return data[prop].apply(this, arguments); + } + return data && data[prop]; + }; + initProp.extendValue(nodeName, prop, desc.value); + } + desc.value._supvalue = desc._supvalue; + }; + })(); + + var initProp = (function(){ + + var initProps = {}; + + webshims.addReady(function(context, contextElem){ + var nodeNameCache = {}; + var getElementsByName = function(name){ + if(!nodeNameCache[name]){ + nodeNameCache[name] = $(context.getElementsByTagName(name)); + if(contextElem[0] && $.nodeName(contextElem[0], name)){ + nodeNameCache[name] = nodeNameCache[name].add(contextElem); + } + } + }; + + + $.each(initProps, function(name, fns){ + getElementsByName(name); + if(!fns || !fns.forEach){ + webshims.warn('Error: with '+ name +'-property. methods: '+ fns); + return; + } + fns.forEach(function(fn){ + nodeNameCache[name].each(fn); + }); + }); + nodeNameCache = null; + }); + + var tempCache; + var emptyQ = $([]); + var createNodeNameInit = function(nodeName, fn){ + if(!initProps[nodeName]){ + initProps[nodeName] = [fn]; + } else { + initProps[nodeName].push(fn); + } + if($.isDOMReady){ + (tempCache || $( document.getElementsByTagName(nodeName) )).each(fn); + } + }; + + var elementExtends = {}; + return { + createTmpCache: function(nodeName){ + if($.isDOMReady){ + tempCache = tempCache || $( document.getElementsByTagName(nodeName) ); + } + return tempCache || emptyQ; + }, + flushTmpCache: function(){ + tempCache = null; + }, + content: function(nodeName, prop){ + createNodeNameInit(nodeName, function(){ + var val = $.attr(this, prop); + if(val != null){ + $.attr(this, prop, val); + } + }); + }, + createElement: function(nodeName, fn){ + createNodeNameInit(nodeName, fn); + }, + extendValue: function(nodeName, prop, value){ + createNodeNameInit(nodeName, function(){ + $(this).each(function(){ + var data = elementData(this, 'propValue', {}); + data[prop] = this[prop]; + this[prop] = value; + }); + }); + } + }; + })(); + + var createPropDefault = function(descs, removeType){ + if(descs.defaultValue === undefined){ + descs.defaultValue = ''; + } + if(!descs.removeAttr){ + descs.removeAttr = { + value: function(){ + descs[removeType || 'prop'].set.call(this, descs.defaultValue); + descs.removeAttr._supvalue.call(this); + } + }; + } + if(!descs.attr){ + descs.attr = {}; + } + }; + + $.extend(webshims, { + + getID: (function(){ + var ID = new Date().getTime(); + return function(elem){ + elem = $(elem); + var id = elem.attr('id'); + if(!id){ + ID++; + id = 'ID-'+ ID; + elem.attr('id', id); + } + return id; + }; + })(), + extendUNDEFProp: function(obj, props){ + $.each(props, function(name, prop){ + if( !(name in obj) ){ + obj[name] = prop; + } + }); + }, + //http://www.w3.org/TR/html5/common-dom-interfaces.html#reflect + createPropDefault: createPropDefault, + data: elementData, + moveToFirstEvent: (function(){ + var getData = $._data ? '_data' : 'data'; + return function(elem, eventType, bindType){ + var events = ($[getData](elem, 'events') || {})[eventType]; + var fn; + + if(events && events.length > 1){ + fn = events.pop(); + if(!bindType){ + bindType = 'bind'; + } + if(bindType == 'bind' && events.delegateCount){ + events.splice( events.delegateCount, 0, fn); + } else { + events.unshift( fn ); + } + + + } + elem = null; + }; + })(), + addShadowDom: (function(){ + var resizeTimer; + var lastHeight; + var lastWidth; + + var docObserve = { + init: false, + runs: 0, + test: function(){ + var height = docObserve.getHeight(); + var width = docObserve.getWidth(); + if(height != docObserve.height || width != docObserve.width){ + docObserve.height = height; + docObserve.width = width; + docObserve.handler({type: 'docresize'}); + docObserve.runs++; + if(docObserve.runs < 30){ + setTimeout(docObserve.test, 30); + } + } else { + docObserve.runs = 0; + } + }, + handler: function(e){ + clearTimeout(resizeTimer); + resizeTimer = setTimeout(function(){ + if(e.type == 'resize'){ + var width = $(window).width(); + var height = $(window).width(); + if(height == lastHeight && width == lastWidth){ + return; + } + lastHeight = height; + lastWidth = width; + + docObserve.height = docObserve.getHeight(); + docObserve.width = docObserve.getWidth(); + + } + $.event.trigger('updateshadowdom'); + }, (e.type == 'resize') ? 50 : 9); + }, + _create: function(){ + $.each({ Height: "getHeight", Width: "getWidth" }, function(name, type){ + var body = document.body; + var doc = document.documentElement; + docObserve[type] = function(){ + return Math.max( + body[ "scroll" + name ], doc[ "scroll" + name ], + body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + }; + }); + }, + start: function(){ + if(!this.init && document.body){ + this.init = true; + this._create(); + this.height = docObserve.getHeight(); + this.width = docObserve.getWidth(); + setInterval(this.test, 400); + $(this.test); + $(window).bind('load', this.test); + $(window).bind('resize', this.handler); + (function(){ + var oldAnimate = $.fn.animate; + var animationTimer; + + $.fn.animate = function(){ + clearTimeout(animationTimer); + animationTimer = setTimeout(function(){ + docObserve.test(); + docObserve.handler({type: 'animationstart'}); + }, 19); + + return oldAnimate.apply(this, arguments); + }; + })(); + } + } + }; + + + $.event.customEvent.updateshadowdom = true; + webshims.docObserve = function(){ + webshims.ready('DOM', function(){ + docObserve.start(); + }); + }; + return function(nativeElem, shadowElem, opts){ + opts = opts || {}; + if(nativeElem.jquery){ + nativeElem = nativeElem[0]; + } + if(shadowElem.jquery){ + shadowElem = shadowElem[0]; + } + var nativeData = $.data(nativeElem, dataID) || $.data(nativeElem, dataID, {}); + var shadowData = $.data(shadowElem, dataID) || $.data(shadowElem, dataID, {}); + var shadowFocusElementData = {}; + if(!opts.shadowFocusElement){ + opts.shadowFocusElement = shadowElem; + } else if(opts.shadowFocusElement){ + if(opts.shadowFocusElement.jquery){ + opts.shadowFocusElement = opts.shadowFocusElement[0]; + } + shadowFocusElementData = $.data(opts.shadowFocusElement, dataID) || $.data(opts.shadowFocusElement, dataID, shadowFocusElementData); + } + + nativeData.hasShadow = shadowElem; + shadowFocusElementData.nativeElement = shadowData.nativeElement = nativeElem; + shadowFocusElementData.shadowData = shadowData.shadowData = nativeData.shadowData = { + nativeElement: nativeElem, + shadowElement: shadowElem, + shadowFocusElement: opts.shadowFocusElement + }; + if(opts.shadowChilds){ + opts.shadowChilds.each(function(){ + elementData(this, 'shadowData', shadowData.shadowData); + }); + } + + if(opts.data){ + shadowFocusElementData.shadowData.data = shadowData.shadowData.data = nativeData.shadowData.data = opts.data; + } + opts = null; + webshims.docObserve(); + }; + })(), + propTypes: { + standard: function(descs, name){ + createPropDefault(descs); + if(descs.prop){return;} + descs.prop = { + set: function(val){ + descs.attr.set.call(this, ''+val); + }, + get: function(){ + return descs.attr.get.call(this) || descs.defaultValue; + } + }; + + }, + "boolean": function(descs, name){ + + createPropDefault(descs); + if(descs.prop){return;} + descs.prop = { + set: function(val){ + if(val){ + descs.attr.set.call(this, ""); + } else { + descs.removeAttr.value.call(this); + } + }, + get: function(){ + return descs.attr.get.call(this) != null; + } + }; + }, + "src": (function(){ + var anchor = document.createElement('a'); + anchor.style.display = "none"; + return function(descs, name){ + + createPropDefault(descs); + if(descs.prop){return;} + descs.prop = { + set: function(val){ + descs.attr.set.call(this, val); + }, + get: function(){ + var href = this.getAttribute(name); + var ret; + if(href == null){return '';} + + anchor.setAttribute('href', href+'' ); + + if(!$.support.hrefNormalized){ + try { + $(anchor).insertAfter(this); + ret = anchor.getAttribute('href', 4); + } catch(er){ + ret = anchor.getAttribute('href', 4); + } + $(anchor).detach(); + } + return ret || anchor.href; + } + }; + }; + })(), + enumarated: function(descs, name){ + + createPropDefault(descs); + if(descs.prop){return;} + descs.prop = { + set: function(val){ + descs.attr.set.call(this, val); + }, + get: function(){ + var val = (descs.attr.get.call(this) || '').toLowerCase(); + if(!val || descs.limitedTo.indexOf(val) == -1){ + val = descs.defaultValue; + } + return val; + } + }; + } + +// ,unsignedLong: $.noop +// ,"doubble": $.noop +// ,"long": $.noop +// ,tokenlist: $.noop +// ,settableTokenlist: $.noop + }, + reflectProperties: function(nodeNames, props){ + if(typeof props == 'string'){ + props = props.split(listReg); + } + props.forEach(function(prop){ + webshims.defineNodeNamesProperty(nodeNames, prop, { + prop: { + set: function(val){ + $.attr(this, prop, val); + }, + get: function(){ + return $.attr(this, prop) || ''; + } + } + }); + }); + }, + defineNodeNameProperty: function(nodeName, prop, descs){ + havePolyfill[prop] = true; + + if(descs.reflect){ + webshims.propTypes[descs.propType || 'standard'](descs, prop); + } + + ['prop', 'attr', 'removeAttr'].forEach(function(type){ + var desc = descs[type]; + if(desc){ + if(type === 'prop'){ + desc = $.extend({writeable: true}, desc); + } else { + desc = $.extend({}, desc, {writeable: true}); + } + + extendQ[type](nodeName, prop, desc); + if(nodeName != '*' && webshims.cfg.extendNative && type == 'prop' && desc.value && $.isFunction(desc.value)){ + extendNativeValue(nodeName, prop, desc); + } + descs[type] = desc; + } + }); + if(descs.initAttr){ + initProp.content(nodeName, prop); + } + return descs; + }, + + defineNodeNameProperties: function(name, descs, propType, _noTmpCache){ + var olddesc; + for(var prop in descs){ + if(!_noTmpCache && descs[prop].initAttr){ + initProp.createTmpCache(name); + } + if(propType){ + if(descs[prop][propType]){ + //webshims.log('override: '+ name +'['+prop +'] for '+ propType); + } else { + descs[prop][propType] = {}; + ['value', 'set', 'get'].forEach(function(copyProp){ + if(copyProp in descs[prop]){ + descs[prop][propType][copyProp] = descs[prop][copyProp]; + delete descs[prop][copyProp]; + } + }); + } + } + descs[prop] = webshims.defineNodeNameProperty(name, prop, descs[prop]); + } + if(!_noTmpCache){ + initProp.flushTmpCache(); + } + return descs; + }, + + createElement: function(nodeName, create, descs){ + var ret; + if($.isFunction(create)){ + create = { + after: create + }; + } + initProp.createTmpCache(nodeName); + if(create.before){ + initProp.createElement(nodeName, create.before); + } + if(descs){ + ret = webshims.defineNodeNameProperties(nodeName, descs, false, true); + } + if(create.after){ + initProp.createElement(nodeName, create.after); + } + initProp.flushTmpCache(); + return ret; + }, + onNodeNamesPropertyModify: function(nodeNames, props, desc, only){ + if(typeof nodeNames == 'string'){ + nodeNames = nodeNames.split(listReg); + } + if($.isFunction(desc)){ + desc = {set: desc}; + } + + nodeNames.forEach(function(name){ + if(!modifyProps[name]){ + modifyProps[name] = {}; + } + if(typeof props == 'string'){ + props = props.split(listReg); + } + if(desc.initAttr){ + initProp.createTmpCache(name); + } + props.forEach(function(prop){ + if(!modifyProps[name][prop]){ + modifyProps[name][prop] = []; + havePolyfill[prop] = true; + } + if(desc.set){ + if(only){ + desc.set.only = only; + } + modifyProps[name][prop].push(desc.set); + } + + if(desc.initAttr){ + initProp.content(name, prop); + } + }); + initProp.flushTmpCache(); + + }); + }, + defineNodeNamesBooleanProperty: function(elementNames, prop, descs){ + if(!descs){ + descs = {}; + } + if($.isFunction(descs)){ + descs.set = descs; + } + webshims.defineNodeNamesProperty(elementNames, prop, { + attr: { + set: function(val){ + this.setAttribute(prop, val); + if(descs.set){ + descs.set.call(this, true); + } + }, + get: function(){ + var ret = this.getAttribute(prop); + return (ret == null) ? undefined : prop; + } + }, + removeAttr: { + value: function(){ + this.removeAttribute(prop); + if(descs.set){ + descs.set.call(this, false); + } + } + }, + reflect: true, + propType: 'boolean', + initAttr: descs.initAttr || false + }); + }, + contentAttr: function(elem, name, val){ + if(!elem.nodeName){return;} + var attr; + if(val === undefined){ + attr = (elem.attributes[name] || {}); + val = attr.specified ? attr.value : null; + return (val == null) ? undefined : val; + } + + if(typeof val == 'boolean'){ + if(!val){ + elem.removeAttribute(name); + } else { + elem.setAttribute(name, name); + } + } else { + elem.setAttribute(name, val); + } + }, + +// set current Lang: +// - webshims.activeLang(lang:string); +// get current lang +// - webshims.activeLang(); +// get current lang +// webshims.activeLang({ +// register: moduleName:string, +// callback: callback:function +// }); +// get/set including removeLang +// - webshims.activeLang({ +// module: moduleName:string, +// callback: callback:function, +// langObj: languageObj:array/object +// }); + activeLang: (function(){ + var callbacks = []; + var registeredCallbacks = {}; + var currentLang; + var shortLang; + var notLocal = /:\/\/|^\.*\//; + var loadRemoteLang = function(data, lang, options){ + var langSrc; + if(lang && options && $.inArray(lang, options.availabeLangs || []) !== -1){ + data.loading = true; + langSrc = options.langSrc; + if(!notLocal.test(langSrc)){ + langSrc = webshims.cfg.basePath+langSrc; + } + webshims.loader.loadScript(langSrc+lang+'.js', function(){ + if(data.langObj[lang]){ + data.loading = false; + callLang(data, true); + } else { + $(function(){ + if(data.langObj[lang]){ + callLang(data, true); + } + data.loading = false; + }); + } + }); + return true; + } + return false; + }; + var callRegister = function(module){ + if(registeredCallbacks[module]){ + registeredCallbacks[module].forEach(function(data){ + data.callback(); + }); + } + }; + var callLang = function(data, _noLoop){ + if(data.activeLang != currentLang && data.activeLang !== shortLang){ + var options = modules[data.module].options; + if( data.langObj[currentLang] || (shortLang && data.langObj[shortLang]) ){ + data.activeLang = currentLang; + data.callback(data.langObj[currentLang] || data.langObj[shortLang], currentLang); + callRegister(data.module); + } else if( !_noLoop && + !loadRemoteLang(data, currentLang, options) && + !loadRemoteLang(data, shortLang, options) && + data.langObj[''] && data.activeLang !== '' ) { + data.activeLang = ''; + data.callback(data.langObj[''], currentLang); + callRegister(data.module); + } + } + }; + + + var activeLang = function(lang){ + + if(typeof lang == 'string' && lang !== currentLang){ + currentLang = lang; + shortLang = currentLang.split('-')[0]; + if(currentLang == shortLang){ + shortLang = false; + } + $.each(callbacks, function(i, data){ + callLang(data); + }); + } else if(typeof lang == 'object'){ + + if(lang.register){ + if(!registeredCallbacks[lang.register]){ + registeredCallbacks[lang.register] = []; + } + registeredCallbacks[lang.register].push(lang); + lang.callback(); + } else { + if(!lang.activeLang){ + lang.activeLang = ''; + } + callbacks.push(lang); + callLang(lang); + } + } + return currentLang; + }; + + return activeLang; + })() + }); + + $.each({ + defineNodeNamesProperty: 'defineNodeNameProperty', + defineNodeNamesProperties: 'defineNodeNameProperties', + createElements: 'createElement' + }, function(name, baseMethod){ + webshims[name] = function(names, a, b, c){ + if(typeof names == 'string'){ + names = names.split(listReg); + } + var retDesc = {}; + names.forEach(function(nodeName){ + retDesc[nodeName] = webshims[baseMethod](nodeName, a, b, c); + }); + return retDesc; + }; + }); + + webshims.isReady('webshimLocalization', true); +}); +//html5a11y +(function($, document){ + var browserVersion = $.webshims.browserVersion; + if($.browser.mozilla && browserVersion > 5){return;} + if (!$.browser.msie || (browserVersion < 12 && browserVersion > 7)) { + var elemMappings = { + article: "article", + aside: "complementary", + section: "region", + nav: "navigation", + address: "contentinfo" + }; + var addRole = function(elem, role){ + var hasRole = elem.getAttribute('role'); + if (!hasRole) { + elem.setAttribute('role', role); + } + }; + + $.webshims.addReady(function(context, contextElem){ + $.each(elemMappings, function(name, role){ + var elems = $(name, context).add(contextElem.filter(name)); + for (var i = 0, len = elems.length; i < len; i++) { + addRole(elems[i], role); + } + }); + if (context === document) { + var header = document.getElementsByTagName('header')[0]; + var footers = document.getElementsByTagName('footer'); + var footerLen = footers.length; + if (header && !$(header).closest('section, article')[0]) { + addRole(header, 'banner'); + } + if (!footerLen) { + return; + } + var footer = footers[footerLen - 1]; + if (!$(footer).closest('section, article')[0]) { + addRole(footer, 'contentinfo'); + } + } + }); + } +})(jQuery, document); +jQuery.webshims.register('form-datalist', function($, webshims, window, document, undefined){ + "use strict"; + var doc = document; + + /* + * implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed) + */ + webshims.propTypes.element = function(descs){ + webshims.createPropDefault(descs, 'attr'); + if(descs.prop){return;} + descs.prop = { + get: function(){ + var elem = descs.attr.get.call(this); + if(elem){ + elem = document.getElementById(elem); + if(elem && descs.propNodeName && !$.nodeName(elem, descs.propNodeName)){ + elem = null; + } + } + return elem || null; + }, + writeable: false + }; + }; + + + /* + * Implements datalist element and list attribute + */ + + (function(){ + var formsCFG = $.webshims.cfg.forms; + var listSupport = Modernizr.input.list; + 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(){ + var elem = this; + var data = $.data(elem, 'datalistWidget'); + if(data){ + return data._autocomplete; + } + return ('autocomplete' in elem) ? elem.autocomplete : elem.getAttribute('autocomplete'); + }, + set: function(value){ + var elem = this; + var data = $.data(elem, 'datalistWidget'); + if(data){ + data._autocomplete = value; + if(value == 'off'){ + data.hideList(); + } + } else { + if('autocomplete' in elem){ + elem.autocomplete = value; + } else { + elem.setAttribute('autocomplete', value); + } + } + } + } + } + }; + +// if(formsCFG.customDatalist && (!listSupport || !('selectedOption') in $('<input />')[0])){ +// //currently not supported x-browser (FF4 has not implemented and is not polyfilled ) +// inputListProto.selectedOption = { +// prop: { +// writeable: false, +// get: function(){ +// var elem = this; +// var list = $.prop(elem, 'list'); +// var ret = null; +// var value, options; +// if(!list){return ret;} +// value = $.prop(elem, 'value'); +// if(!value){return ret;} +// options = $.prop(list, 'options'); +// if(!options.length){return ret;} +// $.each(options, function(i, option){ +// if(value == $.prop(option, 'value')){ +// ret = option; +// return false; +// } +// }); +// return ret; +// } +// } +// }; +// } + + 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')}); + } + }, + initAttr: true, + reflect: true, + propType: 'element', + propNodeName: 'datalist' + }; + } else { + //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, + get: function(){ + var options = this.options || []; + if(!options.length){ + var elem = this; + var select = $('select', elem); + if(select[0] && select[0].options && select[0].options.length){ + options = select[0].options; + } + } + return options; + } + } + }); + } + inputListProto['list'] = { + attr: { + get: function(){ + var val = webshims.contentAttr(this, 'list'); + if(val != null){ + 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')}); + } + }, + initAttr: true, + reflect: true, + propType: 'element', + propNodeName: 'datalist' + }; + } + + + webshims.defineNodeNameProperties('input', inputListProto); + + if($.event.customEvent){ + $.event.customEvent.updateDatalist = true; + $.event.customEvent.updateInput = true; + $.event.customEvent.datalistselect = true; + } + webshims.addReady(function(context, contextElem){ + contextElem + .filter('datalist > select, datalist, datalist > option, datalist > select > option') + .closest('datalist') + .triggerHandler('updateDatalist') + ; + + }); + + + }; + + + /* + * ShadowList + */ + var listidIndex = 0; + + var noDatalistSupport = { + submit: 1, + button: 1, + reset: 1, + hidden: 1, + + //ToDo + range: 1, + date: 1 + }; + var lteie6 = ($.browser.msie && parseInt($.browser.version, 10) < 7); + 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 shadowListProto = { + _create: function(opts){ + + if(noDatalistSupport[$.prop(opts.input, 'type')]){return;} + var datalist = opts.datalist; + var data = $.data(opts.input, 'datalistWidget'); + if(datalist && data && data.datalist !== datalist){ + data.datalist = datalist; + data.id = opts.id; + + data.shadowList.prop('className', 'datalist-polyfill '+ (data.datalist.className || '') + ' '+ data.datalist.id +'-shadowdom'); + if(formsCFG.positionDatalist){ + data.shadowList.insertAfter(opts.input); + } else { + data.shadowList.appendTo('body'); + } + $(data.datalist) + .off('updateDatalist.datalistWidget') + .on('updateDatalist.datalistWidget', $.proxy(data, '_resetListCached')) + ; + data._resetListCached(); + return; + } else if(!datalist){ + if(data){ + data.destroy(); + } + return; + } else if(data && data.datalist === datalist){ + return; + } + listidIndex++; + var that = this; + this.hideList = $.proxy(that, 'hideList'); + this.timedHide = function(){ + clearTimeout(that.hideTimer); + that.hideTimer = setTimeout(that.hideList, 9); + }; + this.datalist = datalist; + this.id = opts.id; + this.hasViewableData = true; + this._autocomplete = $.attr(opts.input, 'autocomplete'); + $.data(opts.input, 'datalistWidget', this); + this.shadowList = $('<div class="datalist-polyfill '+ (this.datalist.className || '') + ' '+ this.datalist.id +'-shadowdom' +'" />'); + + if(formsCFG.positionDatalist || $(opts.input).hasClass('position-datalist')){ + this.shadowList.insertAfter(opts.input); + } else { + this.shadowList.appendTo('body'); + } + + 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).trigger('datalistselect'); + } + } + return (e.type != 'mousedown'); + }) + .on('focusout', this.timedHide) + ; + + 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.isListVisible){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).trigger('datalistselect'); + } + return false; + } + }, + 'focus.datalistWidget': function(){ + if($(this).hasClass('list-focus')){ + that.showList(); + } + }, + 'mousedown.datalistWidget': function(){ + if($(this).is(':focus')){ + that.showList(); + } + }, + 'blur.datalistWidget': this.timedHide + }) + ; + + + $(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(){ + var autocomplete = $.attr(this.input, 'autocomplete'); + $(this.input) + .off('.datalistWidget') + .removeData('datalistWidget') + ; + this.shadowList.remove(); + $(document).off('.datalist'+this.id); + $(window).off('.datalist'+this.id); + if(this.input.form && this.input.id){ + $(this.input.form).off('submit.datalistWidget'+this.input.id); + } + this.input.removeAttribute('aria-haspopup'); + 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 = (e && document.activeElement == that.input))){ + that.updateListOptions(forceShow); + } else { + webshims.ready('WINDOWLOAD', function(){ + that.updateTimer = setTimeout(function(){ + that.updateListOptions(); + that = null; + listidIndex = 1; + }, 200 + (100 * listidIndex)); + }); + } + } + }, + maskHTML: function(str){ + return str.replace(/</g, '&lt;').replace(/>/g, '&gt;'); + }, + updateListOptions: function(_forceShow){ + this.needsUpdate = false; + clearTimeout(this.updateTimer); + this.updateTimer = false; + this.shadowList + .css({ + fontSize: $.css(this.input, 'fontSize'), + fontFamily: $.css(this.input, 'fontFamily') + }) + ; + this.searchStart = formsCFG.customDatalist && $(this.input).hasClass('search-start'); + + var list = []; + + var values = []; + var allOptions = []; + var rElem, rItem, rOptions, rI, rLen, item; + for(rOptions = $.prop(this.datalist, 'options'), rI = 0, rLen = rOptions.length; rI < rLen; rI++){ + rElem = rOptions[rI]; + if(rElem.disabled){return;} + rItem = { + value: $(rElem).val() || '', + text: $.trim($.attr(rElem, 'label') || getText(rElem)), + className: rElem.className || '', + style: $.attr(rElem, 'style') || '' + }; + if(!rItem.text){ + rItem.text = rItem.value; + } else if(rItem.text != rItem.value){ + rItem.className += ' different-label-value'; + } + values[rI] = rItem.value; + allOptions[rI] = 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, text: val, className: 'stored-suggest', style: ''}); + } + }); + + for(rI = 0, rLen = allOptions.length; rI < rLen; rI++){ + item = allOptions[rI]; + list[rI] = '<li class="'+ item.className +'" style="'+ item.style +'" tabindex="-1" role="listitem"><span class="option-label">'+ this.maskHTML(item.text) +'</span> <span class="option-value">'+ this.maskHTML(item.value) +'</span></li>'; + } + + this.arrayOptions = allOptions; + this.shadowList.html('<div class="datalist-outer-box"><div class="datalist-box"><ul role="list">'+ list.join("\n") +'</ul></div></div>'); + + if($.fn.bgIframe && lteie6){ + this.shadowList.bgIframe(); + } + + if(_forceShow || this.isListVisible){ + this.showHideOptions(); + } + }, + showHideOptions: function(_fromShowList){ + var value = $.prop(this.input, 'value').toLowerCase(); + //first check prevent infinite loop, second creates simple lazy optimization + if(value === this.lastUpdatedValue || (this.lastUnfoundValue && value.indexOf(this.lastUnfoundValue) === 0)){ + return; + } + + this.lastUpdatedValue = value; + var found = false; + var startSearch = this.searchStart; + var lis = $('li', this.shadowList); + if(value){ + this.arrayOptions.forEach(function(item, i){ + var search; + if(!('lowerText' in item)){ + if(item.text != item.value){ + item.lowerText = item.value.toLowerCase() + item.text.toLowerCase(); + } else { + item.lowerText = item.text.toLowerCase(); + } + } + search = item.lowerText.indexOf(value); + search = startSearch ? !search : search !== -1; + if(search){ + $(lis[i]).removeClass('hidden-item'); + found = true; + } else { + $(lis[i]).addClass('hidden-item'); + } + }); + } else if(lis.length) { + lis.removeClass('hidden-item'); + found = true; + } + + this.hasViewableData = found; + if(!_fromShowList && found){ + this.showList(); + } + if(!found){ + this.lastUnfoundValue = value; + this.hideList(); + } + }, + setPos: function(){ + this.shadowList.css({marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0}); + var css = (formsCFG.positionDatalist) ? $(this.input).position() : webshims.getRelOffset(this.shadowList, this.input); + css.top += $(this.input).outerHeight(); + css.width = $(this.input).outerWidth() - (parseInt(this.shadowList.css('borderLeftWidth'), 10) || 0) - (parseInt(this.shadowList.css('borderRightWidth'), 10) || 0); + this.shadowList.css({marginTop: '', marginLeft: '', marginRight: '', marginBottom: ''}).css(css); + return css; + }, + showList: function(){ + if(this.isListVisible){return false;} + if(this.needsUpdate){ + this.updateListOptions(); + } + this.showHideOptions(true); + if(!this.hasViewableData){return false;} + this.isListVisible = true; + var that = this; + + that.setPos(); + that.shadowList.addClass('datalist-visible').find('li.active-item').removeClass('active-item'); + + $(window).unbind('.datalist'+that.id); + $(document) + .off('.datalist'+that.id) + .on('mousedown.datalist'+that.id +' focusin.datalist'+that.id, function(e){ + if(e.target === that.input || that.shadowList[0] === e.target || $.contains( that.shadowList[0], e.target )){ + clearTimeout(that.hideTimer); + setTimeout(function(){ + clearTimeout(that.hideTimer); + }, 9); + } else { + that.timedHide(); + } + }) + .on('updateshadowdom.datalist'+that.id, function(){ + that.setPos(); + }) + ; + return true; + }, + hideList: function(){ + if(!this.isListVisible){return false;} + var that = this; + var triggerChange = function(e){ + if(that.changedValue){ + $(that.input).trigger('change'); + } + that.changedValue = false; + }; + + that.shadowList.removeClass('datalist-visible list-item-active'); + that.index = -1; + that.isListVisible = false; + if(that.changedValue){ + that.triggeredByDatalist = true; + webshims.triggerInlineForm && webshims.triggerInlineForm(that.input, 'input'); + if($(that.input).is(':focus')){ + $(that.input).one('blur', triggerChange); + } else { + triggerChange(); + } + that.triggeredByDatalist = false; + } + $(document).unbind('.datalist'+that.id); + $(window) + .off('.datalist'+that.id) + .one('resize.datalist'+that.id, function(){ + that.shadowList.css({top: 0, left: 0}); + }) + ; + 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 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; + } + }, + 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; + } + }; + + //init datalist update + initializeDatalist(); + })(); + +});//additional tests for partial implementation of forms features +(function($){ + "use strict"; + 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(){ + clearTimeout($.data(e.target, e.type + 'DefaultPrevented')); + $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){ + $.removeData(e.target, e.type + 'DefaultPrevented'); + }, 30)); + return preventDefault.apply(this, arguments); + }; + e.isDefaultPrevented = function(){ + return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false); + }; + e._isPolyfilled = true; + } + }; + + if(!Modernizr.formvalidation || bugs.bustedValidity){ + testRequiredFind(); + return; + } + + //create delegatable events + webshims.capturingEvents(['input']); + webshims.capturingEvents(['invalid'], true); + + if(window.opera || window.testGoodWithFix){ + + form.appendTo('head'); + + testRequiredFind(); + bugs.validationMessage = !(inputElem.prop('validationMessage')); + + webshims.reTest(['form-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; + } + } + }); + }); + + }); + }); + } + + if($.browser.webkit && !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(); + } + }); + })(); + } +})(jQuery); + +jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){ + "use strict"; + + var groupTypes = {radio: 1}; + 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(groupTypes[elem[0].type]){ + 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 getContentValidationMessage = 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; + } + }); + } + } + + if(typeof message == 'object'){ + message = message.defaultMessage; + } + 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; + } + }); + 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)); + } + + }); + + ['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; + + 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); + }; + } + + })(); + } + + //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(invalidClasses); + if(name == 'checked' && val) { + getGroupElements(elem).not(elem).removeClass(invalidClasses).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-succes instead */ + var invalidClass = 'user-error'; + var invalidClasses = 'user-error form-ui-invalid'; + var validClass = 'user-success'; + var validClasses = 'user-success form-ui-valid'; + 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; + + $(elem).trigger('refreshCustomValidityRules'); + if(validity.valid){ + if(!shadowElem.hasClass(validClass)){ + addClass = validClasses; + removeClass = invalidClasses; + 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 = invalidClasses; + removeClass = validClasses; + 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(e.target, '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 = ($.browser.webkit || document.compatMode == 'BackCompat') ? + $(document.body) : + $(document.documentElement) + ; + }; + 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; + }; + + /* some extra validation UI */ + webshims.validityAlert = (function(){ + var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label'; + var errorBubble; + var hideTimer = false; + var focusTimer = false; + var resizeTimer = false; + var boundHide; + + var api = { + hideDelay: 5000, + + showFor: function(elem, message, noFocusElem, noBubble){ + api._create(); + elem = $(elem); + var visual = $(elem).getShadowElement(); + var offset = api.getOffsetFromBody(visual); + api.clear(); + if(noBubble){ + this.hide(); + } else { + this.getMessage(elem, message); + this.position(visual, offset); + + this.show(); + if(this.hideDelay){ + hideTimer = setTimeout(boundHide, this.hideDelay); + } + $(window) + .on('resize.validityalert', function(){ + clearTimeout(resizeTimer); + resizeTimer = setTimeout(function(){ + api.position(visual); + }, 9); + }) + ; + } + + if(!noFocusElem){ + this.setFocus(visual, offset); + } + }, + getOffsetFromBody: function(elem){ + return webshims.getRelOffset(errorBubble, elem); + }, + setFocus: function(visual, offset){ + var focusElem = $(visual).getShadowFocusElement(); + var scrollTop = webshims.scrollRoot.scrollTop(); + var elemTop = ((offset || focusElem.offset()).top) - 30; + var smooth; + + if(webshims.getID && alertElem == 'label'){ + errorBubble.attr('for', webshims.getID(focusElem)); + } + + 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); + } + setTimeout(function(){ + $(document).on('focusout.validityalert', boundHide); + }, 10); + }, + getMessage: function(elem, message){ + if (!message) { + message = getContentValidationMessage(elem[0]) || elem.prop('validationMessage'); + } + if (message) { + $('span.va-box', errorBubble).text(message); + } + else { + this.hide(); + } + }, + position: function(elem, offset){ + offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem); + offset.top += elem.outerHeight(); + errorBubble.css(offset); + }, + show: function(){ + if(errorBubble.css('display') === 'none'){ + errorBubble.css({opacity: 0}).show(); + } + errorBubble.addClass('va-visible').fadeTo(400, 1); + }, + hide: function(){ + errorBubble.removeClass('va-visible').fadeOut(); + }, + clear: function(){ + clearTimeout(focusTimer); + clearTimeout(hideTimer); + $(document).unbind('.validityalert'); + $(window).unbind('.validityalert'); + errorBubble.stop().removeAttr('for'); + }, + _create: function(){ + if(errorBubble){return;} + errorBubble = api.errorBubble = $('<'+alertElem+' class="validity-alert-wrapper" role="alert"><span class="validity-alert"><span class="va-arrow"><span class="va-arrow-box"></span></span><span class="va-box"></span></span></'+alertElem+'>').css({position: 'absolute', display: 'none'}); + webshims.ready('DOM', function(){ + errorBubble.appendTo('body'); + if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){ + errorBubble.bgIframe(); + } + }); + } + }; + + + boundHide = $.proxy(api, '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(invalidClasses).removeClass(validClasses); + 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){ + webshims.ready('DOM forms', function(){ + $(document).on('firstinvalid', function(e){ + if(!e.isInvalidUIPrevented()){ + e.preventDefault(); + $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') ); + } + }); + }); + } + +});(function($, Modernizr, webshims){ + "use strict"; + var hasNative = Modernizr.audio && Modernizr.video; + var supportsLoop = false; + var options = webshims.cfg.mediaelement; + var bugs = webshims.bugs; + var swfType = options.player == 'jwplayer' ? 'mediaelement-swf' : 'mediaelement-jaris' + var loadSwf = function(){ + webshims.ready(swfType, function(){ + if(!webshims.mediaelement.createSWF){ + webshims.mediaelement.loadSwf = true; + webshims.reTest([swfType], hasNative); + } + }); + }; + var hasSwf; + if(hasNative){ + var videoElem = document.createElement('video'); + Modernizr.videoBuffered = ('buffered' in videoElem); + supportsLoop = ('loop' in videoElem); + + webshims.capturingEvents(['play', 'playing', 'waiting', 'paused', 'ended', 'durationchange', 'loadedmetadata', 'canplay', 'volumechange']); + + if(!Modernizr.videoBuffered){ + webshims.addPolyfill('mediaelement-native-fix', { + f: 'mediaelement', + test: Modernizr.videoBuffered, + d: ['dom-support'] + }); + + webshims.reTest('mediaelement-native-fix'); + } + } + + if(hasNative && !options.preferFlash){ + var switchOptions = function(e){ + var parent = e.target.parentNode; + if(!options.preferFlash && ($(e.target).is('audio, video') || (parent && $('source:last', parent)[0] == e.target)) ){ + webshims.ready('DOM mediaelement', function(){ + if(hasSwf){ + loadSwf(); + } + webshims.ready('WINDOWLOAD '+swfType, function(){ + setTimeout(function(){ + if(hasSwf && !options.preferFlash && webshims.mediaelement.createSWF && !$(e.target).closest('audio, video').is('.nonnative-api-active')){ + options.preferFlash = true; + document.removeEventListener('error', switchOptions, true); + $('audio, video').mediaLoad(); + webshims.info("switching mediaelements option to 'preferFlash', due to an error with native player: "+e.target.src); + } else if(!hasSwf){ + document.removeEventListener('error', switchOptions, true); + } + }, 20); + }); + }); + } + }; + document.addEventListener('error', switchOptions, true); + $('audio, video').each(function(){ + if(this.error){ + switchOptions({target: this}); + } + }); + } + + bugs.track = false; + + if(Modernizr.track){ + (function(){ + + if(!bugs.track){ + bugs.track = typeof $('<track />')[0].readyState != 'number'; + } + + if(!bugs.track){ + try { + new TextTrackCue(2, 3, ''); + } catch(e){ + bugs.track = true; + } + } + + var trackOptions = webshims.cfg.track; + var trackListener = function(e){ + $(e.target).filter('track').each(changeApi); + }; + var changeApi = function(){ + if(bugs.track || (!trackOptions.override && $.prop(this, 'readyState') == 3)){ + trackOptions.override = true; + webshims.reTest('track'); + document.removeEventListener('error', trackListener, true); + if(this && $.nodeName(this, 'track')){ + webshims.error("track support was overwritten. Please check your vtt including your vtt mime-type"); + } else { + webshims.info("track support was overwritten. due to bad browser support"); + } + } + }; + var detectTrackError = function(){ + document.addEventListener('error', trackListener, true); + + if(bugs.track){ + changeApi(); + } else { + $('track').each(changeApi); + } + }; + if(!trackOptions.override){ + if(webshims.isReady('track')){ + detectTrackError(); + } else { + $(detectTrackError); + } + } + })(); + + } + +webshims.register('mediaelement-core', function($, webshims, window, document, undefined){ + hasSwf = swfobject.hasFlashPlayerVersion('9.0.115'); + + var mediaelement = webshims.mediaelement; + + var getSrcObj = function(elem, nodeName){ + elem = $(elem); + var src = {src: elem.attr('src') || '', elem: elem, srcProp: elem.prop('src')}; + if(!src.src){return src;} + var tmp = elem.attr('type'); + if(tmp){ + src.type = tmp; + src.container = $.trim(tmp.split(';')[0]); + } else { + if(!nodeName){ + nodeName = elem[0].nodeName.toLowerCase(); + if(nodeName == 'source'){ + nodeName = (elem.closest('video, audio')[0] || {nodeName: 'video'}).nodeName.toLowerCase(); + } + } + tmp = mediaelement.getTypeForSrc(src.src, nodeName ); + + if(tmp){ + src.type = tmp; + src.container = tmp; + } + } + tmp = elem.attr('media'); + if(tmp){ + src.media = tmp; + } + return src; + }; + + + + var hasYt = !hasSwf && ('postMessage' in window) && hasNative; + + var loadYt = (function(){ + var loaded; + return function(){ + if(loaded || !hasYt){return;} + loaded = true; + webshims.loader.loadScript("https://www.youtube.com/player_api"); + $(function(){ + webshims.polyfill("mediaelement-yt"); + }); + }; + })(); + var loadThird = function(){ + if(hasSwf){ + loadSwf(); + } else { + loadYt(); + } + }; + + webshims.addPolyfill('mediaelement-yt', { + test: !hasYt, + d: ['dom-support'] + }); + + mediaelement.mimeTypes = { + audio: { + //ogm shouldn´t be used! + 'audio/ogg': ['ogg','oga', 'ogm'], + 'audio/ogg;codecs="opus"': 'opus', + 'audio/mpeg': ['mp2','mp3','mpga','mpega'], + 'audio/mp4': ['mp4','mpg4', 'm4r', 'm4a', 'm4p', 'm4b', 'aac'], + 'audio/wav': ['wav'], + 'audio/3gpp': ['3gp','3gpp'], + 'audio/webm': ['webm'], + 'audio/fla': ['flv', 'f4a', 'fla'], + 'application/x-mpegURL': ['m3u8', 'm3u'] + }, + video: { + //ogm shouldn´t be used! + 'video/ogg': ['ogg','ogv', 'ogm'], + 'video/mpeg': ['mpg','mpeg','mpe'], + 'video/mp4': ['mp4','mpg4', 'm4v'], + 'video/quicktime': ['mov','qt'], + 'video/x-msvideo': ['avi'], + 'video/x-ms-asf': ['asf', 'asx'], + 'video/flv': ['flv', 'f4v'], + 'video/3gpp': ['3gp','3gpp'], + 'video/webm': ['webm'], + 'application/x-mpegURL': ['m3u8', 'm3u'], + 'video/MP2T': ['ts'] + } + } + ; + + mediaelement.mimeTypes.source = $.extend({}, mediaelement.mimeTypes.audio, mediaelement.mimeTypes.video); + + mediaelement.getTypeForSrc = function(src, nodeName){ + if(src.indexOf('youtube.com/watch?') != -1 || src.indexOf('youtube.com/v/') != -1){ + return 'video/youtube'; + } + src = src.split('?')[0].split('.'); + src = src[src.length - 1]; + var mt; + + $.each(mediaelement.mimeTypes[nodeName], function(mimeType, exts){ + if(exts.indexOf(src) !== -1){ + mt = mimeType; + return false; + } + }); + return mt; + }; + + + mediaelement.srces = function(mediaElem, srces){ + mediaElem = $(mediaElem); + if(!srces){ + srces = []; + var nodeName = mediaElem[0].nodeName.toLowerCase(); + var src = getSrcObj(mediaElem, nodeName); + + if(!src.src){ + + $('source', mediaElem).each(function(){ + src = getSrcObj(this, nodeName); + if(src.src){srces.push(src);} + }); + } else { + srces.push(src); + } + return srces; + } else { + mediaElem.removeAttr('src').removeAttr('type').find('source').remove(); + if(!$.isArray(srces)){ + srces = [srces]; + } + srces.forEach(function(src){ + var source = document.createElement('source'); + if(typeof src == 'string'){ + src = {src: src}; + } + source.setAttribute('src', src.src); + if(src.type){ + source.setAttribute('type', src.type); + } + if(src.media){ + source.setAttribute('media', src.media); + } + mediaElem.append(source); + }); + + } + }; + + + $.fn.loadMediaSrc = function(srces, poster){ + return this.each(function(){ + if(poster !== undefined){ + $(this).removeAttr('poster'); + if(poster){ + $.attr(this, 'poster', poster); + } + } + mediaelement.srces(this, srces); + $(this).mediaLoad(); + }); + }; + + mediaelement.swfMimeTypes = ['video/3gpp', 'video/x-msvideo', 'video/quicktime', 'video/x-m4v', 'video/mp4', 'video/m4p', 'video/x-flv', 'video/flv', 'audio/mpeg', 'audio/aac', 'audio/mp4', 'audio/x-m4a', 'audio/m4a', 'audio/mp3', 'audio/x-fla', 'audio/fla', 'youtube/flv', 'jwplayer/jwplayer', 'video/youtube']; + + mediaelement.canThirdPlaySrces = function(mediaElem, srces){ + var ret = ''; + if(hasSwf || hasYt){ + mediaElem = $(mediaElem); + srces = srces || mediaelement.srces(mediaElem); + $.each(srces, function(i, src){ + if(src.container && src.src && ((hasSwf && mediaelement.swfMimeTypes.indexOf(src.container) != -1) || (hasYt && src.container == 'video/youtube'))){ + ret = src; + return false; + } + }); + + } + + return ret; + }; + + var nativeCanPlayType = {}; + mediaelement.canNativePlaySrces = function(mediaElem, srces){ + var ret = ''; + if(hasNative){ + mediaElem = $(mediaElem); + var nodeName = (mediaElem[0].nodeName || '').toLowerCase(); + if(!nativeCanPlayType[nodeName]){return ret;} + srces = srces || mediaelement.srces(mediaElem); + + $.each(srces, function(i, src){ + if(src.type && nativeCanPlayType[nodeName].prop._supvalue.call(mediaElem[0], src.type) ){ + ret = src; + return false; + } + }); + } + return ret; + }; + + mediaelement.setError = function(elem, message){ + if(!message){ + message = "can't play sources"; + } + + $(elem).pause().data('mediaerror', message); + webshims.warn('mediaelementError: '+ message); + setTimeout(function(){ + if($(elem).data('mediaerror')){ + $(elem).trigger('mediaerror'); + } + }, 1); + }; + + var handleThird = (function(){ + var requested; + return function( mediaElem, ret, data ){ + webshims.ready(hasSwf ? swfType : 'mediaelement-yt', function(){ + if(mediaelement.createSWF){ + mediaelement.createSWF( mediaElem, ret, data ); + } else if(!requested) { + requested = true; + loadThird(); + //readd to ready + handleThird( mediaElem, ret, data ); + } + }); + if(!requested && hasYt && !mediaelement.createSWF){ + loadYt(); + } + }; + })(); + + var stepSources = function(elem, data, useSwf, _srces, _noLoop){ + var ret; + if(useSwf || (useSwf !== false && data && data.isActive == 'third')){ + ret = mediaelement.canThirdPlaySrces(elem, _srces); + if(!ret){ + if(_noLoop){ + mediaelement.setError(elem, false); + } else { + stepSources(elem, data, false, _srces, true); + } + } else { + handleThird(elem, ret, data); + } + } else { + ret = mediaelement.canNativePlaySrces(elem, _srces); + if(!ret){ + if(_noLoop){ + mediaelement.setError(elem, false); + if(data && data.isActive == 'third') { + mediaelement.setActive(elem, 'html5', data); + } + } else { + stepSources(elem, data, true, _srces, true); + } + } else if(data && data.isActive == 'third') { + mediaelement.setActive(elem, 'html5', data); + } + } + }; + var stopParent = /^(?:embed|object|datalist)$/i; + var selectSource = function(elem, data){ + var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {}); + var _srces = mediaelement.srces(elem); + var parent = elem.parentNode; + + clearTimeout(baseData.loadTimer); + $.data(elem, 'mediaerror', false); + + if(!_srces.length || !parent || parent.nodeType != 1 || stopParent.test(parent.nodeName || '')){return;} + data = data || webshims.data(elem, 'mediaelement'); + stepSources(elem, data, options.preferFlash || undefined, _srces); + }; + + + $(document).on('ended', function(e){ + var data = webshims.data(e.target, 'mediaelement'); + if( supportsLoop && (!data || data.isActive == 'html5') && !$.prop(e.target, 'loop')){return;} + setTimeout(function(){ + if( $.prop(e.target, 'paused') || !$.prop(e.target, 'loop') ){return;} + $(e.target).prop('currentTime', 0).play(); + }, 1); + + }); + if(!supportsLoop){ + webshims.defineNodeNamesBooleanProperty(['audio', 'video'], 'loop'); + } + + ['audio', 'video'].forEach(function(nodeName){ + var supLoad = webshims.defineNodeNameProperty(nodeName, 'load', { + prop: { + value: function(){ + var data = webshims.data(this, 'mediaelement'); + selectSource(this, data); + if(hasNative && (!data || data.isActive == 'html5') && supLoad.prop._supvalue){ + supLoad.prop._supvalue.apply(this, arguments); + } + } + } + }); + nativeCanPlayType[nodeName] = webshims.defineNodeNameProperty(nodeName, 'canPlayType', { + prop: { + value: function(type){ + var ret = ''; + if(hasNative && nativeCanPlayType[nodeName].prop._supvalue){ + ret = nativeCanPlayType[nodeName].prop._supvalue.call(this, type); + if(ret == 'no'){ + ret = ''; + } + } + if(!ret && hasSwf){ + type = $.trim((type || '').split(';')[0]); + if(mediaelement.swfMimeTypes.indexOf(type) != -1){ + ret = 'maybe'; + } + } + return ret; + } + } + }); + }); + webshims.onNodeNamesPropertyModify(['audio', 'video'], ['src', 'poster'], { + set: function(){ + var elem = this; + var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {}); + clearTimeout(baseData.loadTimer); + baseData.loadTimer = setTimeout(function(){ + selectSource(elem); + elem = null; + }, 9); + } + }); + + var initMediaElements = function(){ + + webshims.addReady(function(context, insertedElement){ + $('video, audio', context) + .add(insertedElement.filter('video, audio')) + .each(function(){ + if($.browser.msie && webshims.browserVersion > 8 && $.prop(this, 'paused') && !$.prop(this, 'readyState') && $(this).is('audio[preload="none"][controls]:not([autoplay])')){ + $(this).prop('preload', 'metadata').mediaLoad(); + } else { + selectSource(this); + } + + + + if(hasNative){ + var bufferTimer; + var lastBuffered; + var elem = this; + var getBufferedString = function(){ + var buffered = $.prop(elem, 'buffered'); + if(!buffered){return;} + var bufferString = ""; + for(var i = 0, len = buffered.length; i < len;i++){ + bufferString += buffered.end(i); + } + return bufferString; + }; + var testBuffer = function(){ + var buffered = getBufferedString(); + if(buffered != lastBuffered){ + lastBuffered = buffered; + $(elem).triggerHandler('progress'); + } + }; + + $(this) + .on({ + 'play loadstart progress': function(e){ + if(e.type == 'progress'){ + lastBuffered = getBufferedString(); + } + clearTimeout(bufferTimer); + bufferTimer = setTimeout(testBuffer, 999); + }, + 'emptied stalled mediaerror abort suspend': function(e){ + if(e.type == 'emptied'){ + lastBuffered = false; + } + clearTimeout(bufferTimer); + } + }) + ; + } + + }) + ; + }); + }; + + if(Modernizr.track && !bugs.track){ + webshims.defineProperty(TextTrack.prototype, 'shimActiveCues', { + get: function(){ + return this._shimActiveCues || this.activeCues; + } + }); + } + //set native implementation ready, before swf api is retested + if(hasNative){ + webshims.isReady('mediaelement-core', true); + initMediaElements(); + webshims.ready('WINDOWLOAD mediaelement', loadThird); + } else { + webshims.ready(swfType, initMediaElements); + } + $(function(){ + webshims.loader.loadList(['track-ui']); + }); + +}); })(jQuery, Modernizr, jQuery.webshims); \ No newline at end of file