vendor/assets/javascripts/webshims/shims/combos/27.js in webshims-rails-1.13.0 vs vendor/assets/javascripts/webshims/shims/combos/27.js in webshims-rails-1.14.1
- old
+ new
@@ -1,612 +1,1698 @@
-/*! SWFMini - a SWFObject 2.2 cut down version for webshims
- *
- * based on SWFObject v2.2 <http://code.google.com/p/swfobject/>
- is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
-*/
+webshims.register('form-shim-extend2', function($, webshims, window, document, undefined, options){
+ "use strict";
+ var isNumber = function(string){
+ return (typeof string == 'number' || (string && string == string * 1));
+ };
-var swfmini = function() {
- var wasRemoved = function(){webshims.error('This method was removed from swfmini');};
- var UNDEF = "undefined",
- OBJECT = "object",
- webshims = window.webshims,
- SHOCKWAVE_FLASH = "Shockwave Flash",
- SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
- FLASH_MIME_TYPE = "application/x-shockwave-flash",
-
- win = window,
- doc = document,
- nav = navigator,
-
- plugin = false,
- domLoadFnArr = [main],
+//support getSetAttribute
+ var supportGetSetAttribute = !(('getSetAttribute' in $.support) && !$.support.getSetAttribute);
+//submitbubbles for IE6-IE8
+ var supportSubmitBubbles = !('submitBubbles' in $.support) || $.support.submitBubbles;
+ var addSubmitBubbles = function(form){
+ if (!supportSubmitBubbles && form && typeof form == 'object' && !form._submit_attached ) {
- isDomLoaded = false,
- autoHideShow = true,
-
- /* Centralized function for browser feature detection
- - User agent string detection is only used when no good alternative is possible
- - Is executed directly for optimal performance
- */
- ua = function() {
- var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
- u = nav.userAgent.toLowerCase(),
- p = nav.platform.toLowerCase(),
- windows = p ? /win/.test(p) : /win/.test(u),
- mac = p ? /mac/.test(p) : /mac/.test(u),
- webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit
- ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
- playerVersion = [0,0,0],
- d = null;
- if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
- d = nav.plugins[SHOCKWAVE_FLASH].description;
- if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+
- plugin = true;
- ie = false; // cascaded feature detection for Internet Explorer
- d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
- playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
- playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
- playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
- }
+ $.event.add( form, 'submit._submit', function( event ) {
+ event._submit_bubble = true;
+ });
+
+ form._submit_attached = true;
}
- else if (typeof win.ActiveXObject != UNDEF) {
- try {
- var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
- if (a) { // a will return null when ActiveX is disabled
- d = a.GetVariable("$version");
- if (d) {
- ie = true; // cascaded feature detection for Internet Explorer
- d = d.split(" ")[1].split(",");
- playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
- }
- }
+ };
+ if(!supportSubmitBubbles && $.event.special.submit){
+
+ $.event.special.submit.setup = function() {
+ // Only need this for delegated form submit events
+ if ( $.nodeName( this, "form" ) ) {
+ return false;
}
- catch(e) {}
- }
- return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
- }();
-
-
- function callDomLoadFunctions() {
- if (isDomLoaded) { return; }
- isDomLoaded = true;
- var dl = domLoadFnArr.length;
- for (var i = 0; i < dl; i++) {
- domLoadFnArr[i]();
- }
- }
-
- function addDomLoadEvent(fn) {
- if (isDomLoaded) {
- fn();
- }
- else {
- domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+
- }
- }
-
- /* Main function
- - Will preferably execute onDomLoad, otherwise onload (as a fallback)
- */
- function main() {
- if (plugin) {
- testPlayerVersion();
- }
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
+ $.event.add( this, "click._submit keypress._submit", function( e ) {
+ // Node name check avoids a VML-related crash in IE (#9807)
+ var elem = e.target,
+ form = $.nodeName( elem, 'input' ) || $.nodeName( elem, 'button' ) ? $.prop(elem, 'form') : undefined;
+ addSubmitBubbles(form);
+
+ });
+ // return undefined since we don't need an event listener
+ };
}
-
- /* Detect the Flash Player version for non-Internet Explorer browsers
- - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:
- a. Both release and build numbers can be detected
- b. Avoid wrong descriptions by corrupt installers provided by Adobe
- c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports
- - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available
- */
- function testPlayerVersion() {
- var b = doc.getElementsByTagName("body")[0];
- var o = createElement(OBJECT);
- o.setAttribute("type", FLASH_MIME_TYPE);
- var t = b.appendChild(o);
- if (t) {
- var counter = 0;
- (function(){
- if (typeof t.GetVariable != UNDEF) {
- var d = t.GetVariable("$version");
- if (d) {
- d = d.split(" ")[1].split(",");
- ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
+
+ webshims.reflectProperties(['input'], ['pattern']);
+
+
+ if( !('maxLength' in document.createElement('textarea')) ){
+ var constrainMaxLength = (function(){
+ var timer;
+ var curLength = 0;
+ var lastElement = $([]);
+ var max = 1e9;
+ var constrainLength = function(){
+ var nowValue = lastElement.prop('value');
+ var nowLen = nowValue.length;
+ if(nowLen > curLength && nowLen > max){
+ nowLen = Math.max(curLength, max);
+ lastElement.prop('value', nowValue.substr(0, nowLen ));
+ }
+ curLength = nowLen;
+ };
+ var remove = function(){
+ clearTimeout(timer);
+ lastElement.off('.maxlengthconstraint');
+ };
+ return function(element, maxLength){
+ remove();
+ if(maxLength > -1){
+ max = maxLength;
+ curLength = $.prop(element, 'value').length;
+ lastElement = $(element);
+ lastElement.on({
+ 'keydown.maxlengthconstraint keypress.maxlengthconstraint paste.maxlengthconstraint cut.maxlengthconstraint': function(e){
+ setTimeout(constrainLength, 0);
+ },
+ 'keyup.maxlengthconstraint': constrainLength,
+ 'blur.maxlengthconstraint': remove
+ });
+ timer = setInterval(constrainLength, 200);
+ }
+ };
+ })();
+
+ constrainMaxLength.update = function(element, maxLength){
+ if($(element).is(':focus')){
+ if(!maxLength){
+ maxLength = $.prop(element, 'maxlength');
+ }
+ constrainMaxLength(element, maxLength);
+ }
+ };
+
+ $(document).on('focusin', function(e){
+ var maxLength;
+ if(e.target.nodeName == "TEXTAREA" && (maxLength = $.prop(e.target, 'maxlength')) > -1){
+ constrainMaxLength(e.target, maxLength);
+ }
+ });
+
+ webshims.defineNodeNameProperty('textarea', 'maxlength', {
+ attr: {
+ set: function(val){
+ this.setAttribute('maxlength', ''+val);
+ constrainMaxLength.update(this);
+ },
+ get: function(){
+ var ret = this.getAttribute('maxlength');
+ return ret == null ? undefined : ret;
+ }
+ },
+ prop: {
+ set: function(val){
+ if(isNumber(val)){
+ if(val < 0){
+ throw('INDEX_SIZE_ERR');
+ }
+ val = parseInt(val, 10);
+ this.setAttribute('maxlength', val);
+ constrainMaxLength.update(this, val);
+ return;
}
+ this.setAttribute('maxlength', '0');
+ constrainMaxLength.update(this, 0);
+ },
+ get: function(){
+ var val = this.getAttribute('maxlength');
+ return (isNumber(val) && val >= 0) ? parseInt(val, 10) : -1;
+
}
- else if (counter < 10) {
- counter++;
- setTimeout(arguments.callee, 10);
- return;
+ }
+ });
+ webshims.defineNodeNameProperty('textarea', 'maxLength', {
+ prop: {
+ set: function(val){
+ $.prop(this, 'maxlength', val);
+ },
+ get: function(){
+ return $.prop(this, 'maxlength');
}
- b.removeChild(o);
- t = null;
- })();
- }
+ }
+ });
}
-
- function createElement(el) {
- return doc.createElement(el);
+ if(!supportGetSetAttribute && $('<form novalidate></form>').attr('novalidate') == null){
+ webshims.defineNodeNameProperty('form', 'novalidate', {
+ attr: {
+ set: function(val){
+ this.setAttribute('novalidate', ''+val);
+ },
+ get: function(){
+ var ret = this.getAttribute('novalidate');
+ return ret == null ? undefined : ret;
+ }
+ }
+ });
}
-
- /* Flash Player and SWF content version matching
- */
- function hasPlayerVersion(rv) {
- var pv = ua.pv, v = rv.split(".");
- v[0] = parseInt(v[0], 10);
- v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
- v[2] = parseInt(v[2], 10) || 0;
- return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
- }
-
-
+ if(!Modernizr.formattribute || !Modernizr.fieldsetdisabled || !Modernizr.fieldsetelements){
+ (function(){
+ if(!Modernizr.fieldsetdisabled){
+ var isFieldsetGroup = {
+ fieldset: 1,
+ FIELDSET: 1
+ };
+ var disableElementsSel = 'input, textarea, select, button';
+ $.extend($.expr[":"], {
+ "enabled": function( elem ) {
+ return elem.disabled === false || (isFieldsetGroup[elem.nodeName] && webshims.contentAttr(elem, 'disabled') == null && !$(elem).is('fieldset[disabled] *')) ;
+ },
+ "disabled": function( elem ) {
+ return elem.disabled === true || (isFieldsetGroup[elem.nodeName] && (webshims.contentAttr(elem, 'disabled') != null || $(elem).is('fieldset[disabled] *')));
+ }
+ });
- webshims.ready('DOM', callDomLoadFunctions);
- webshims.loader.addModule('swfmini-embed', {d: ['swfmini']});
- var loadEmbed = hasPlayerVersion('9.0.0') ?
- function(){
- webshims.loader.loadList(['swfmini-embed']);
- return true;
- } :
- webshims.$.noop
- ;
+ var groupControl = {
+ disable: function(){
+ if(!this.disabled){
+ webshims.data(this, 'groupedisabled', true);
+ this.disabled = true;
+ }
+ },
+ enable: function(){
+ if(this.disabled && webshims.data(this, 'groupedisabled')){
+ webshims.data(this, 'groupedisabled', false);
+ this.disabled = false;
+ }
+ }
+ };
- if(!Modernizr.video){
- loadEmbed();
- } else {
- webshims.ready('WINDOWLOAD', loadEmbed);
- }
+ $(window).on('unload', function(){
+ $(disableElementsSel).each(groupControl.enable);
+ });
- return {
- /* Public API
- - Reference: http://code.google.com/p/swfobject/wiki/documentation
- */
- registerObject: wasRemoved,
-
- getObjectById: wasRemoved,
-
- embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
- var args = arguments;
- if(loadEmbed()){
- webshims.ready('swfmini-embed', function(){
- swfmini.embedSWF.apply(swfmini, args);
+ webshims.defineNodeNamesBooleanProperty(['fieldset'], 'disabled', {
+ set: function(value){
+ value = !!value;
+
+ if(value){
+ $(this.querySelectorAll(disableElementsSel)).each(groupControl.disable);
+ } else if(!$(this).is('fieldset[disabled] *')){
+ var elements = $(this.querySelectorAll(disableElementsSel));
+
+ if( this.querySelector('fieldset[disabled]') ){
+ elements = elements.not('fieldset[disabled] *');
+ }
+
+ elements.each(groupControl.enable);
+ }
+ },
+ initAttr: true,
+ useContentAttribute: true
});
- } else if(callbackFn) {
- callbackFn({success:false, id:replaceElemIdStr});
+
+ ['input', 'textarea', 'select', 'button'].forEach(function(nodeName){
+ var desc = webshims.defineNodeNameProperty(nodeName, 'disabled', {
+ prop: {
+ set: function(value){
+ if(value){
+ webshims.data(this, 'groupedisabled', false);
+ desc.prop._supset.call(this, value);
+ } else if($(this).is('fieldset[disabled] *')){
+ webshims.data(this, 'groupedisabled', true);
+ desc.prop._supset.call(this, true);
+ } else {
+ webshims.data(this, 'groupedisabled', false);
+ desc.prop._supset.call(this, value);
+ }
+ },
+ get: function(){
+ var ret = desc.prop._supget.call(this);
+ return ret ? !webshims.data(this, 'groupedisabled') : ret;
+ }
+ },
+ removeAttr: {
+ value: function(){
+ desc.prop.set.call(this, false);
+ }
+ }
+ });
+ });
+
+ webshims.addReady(function(context){
+
+ $(context)
+ .filter('fieldset[disabled], fieldset[disabled] *')
+ .find(disableElementsSel)
+ .each(groupControl.disable)
+ ;
+ });
}
- },
-
- switchOffAutoHideShow: function() {
- autoHideShow = false;
- },
-
- ua: ua,
-
- getFlashPlayerVersion: function() {
- return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
- },
-
- hasFlashPlayerVersion: hasPlayerVersion,
-
- createSWF: function(attObj, parObj, replaceElemIdStr) {
- if (ua.w3) {
- return createSWF(attObj, parObj, replaceElemIdStr);
- }
- else {
- return undefined;
- }
- },
-
- showExpressInstall: wasRemoved,
-
- removeSWF: wasRemoved,
-
- createCSS: wasRemoved,
-
- addDomLoadEvent: addDomLoadEvent,
-
- addLoadEvent: wasRemoved,
-
-
- // For internal usage only
- expressInstallCallback: wasRemoved
- };
-}();
-webshims.isReady('swfmini', true);
-;webshims.register('filereader', function( $, webshims ){
- "use strict";
- /**
- * Code is based on https://github.com/Jahdrien/FileReader
- *
- */
- (function(){
- var swfobject = window.swfmini || window.swfobject;
-
- var readyCallbacks = $.Callbacks('once unique memory'),
- inputsCount = 0,
- currentTarget = null;
-
- // if native FileReader support, then dont add the polyfill and make the plugin do nothing
- if (window.FileReader) {
- $.fn.fileReader = function () { return this; }
- return ;
- }
-
- /**
- * JQuery Plugin
- */
- $.fn.fileReader = function( options ) {
- if(this.length){
- options = $.extend($.fn.fileReader.defaults, options);
-
- var self = this;
- readyCallbacks.add(function() {
- return main(self, options);
+
+ if(!Modernizr.formattribute){
+ (function(prop, undefined){
+ var isForm = {form: 1, FORM: 1};
+ $.prop = function(elem, name, value){
+ var ret;
+ //TODO: cache + perftest
+ if(elem && elem.nodeType == 1 && value === undefined && isForm[elem.nodeName] && elem.id){
+ ret = document.getElementsByName(name);
+ if(!ret || !ret.length){
+ ret = document.getElementById(name);
+ }
+ if(ret){
+ ret = $(ret).filter(function(){
+ return $.prop(this, 'form') == elem;
+ }).get();
+ if(ret.length){
+ return ret.length == 1 ? ret[0] : ret;
+ }
+ }
+ }
+ return prop.apply(this, arguments);
+ };
+ })($.prop, undefined);
+
+ var removeAddedElements = function(form){
+ var elements = $.data(form, 'webshimsAddedElements');
+ if(elements){
+ elements.remove();
+ $.removeData(form, 'webshimsAddedElements');
+ }
+ };
+
+ var getAssociatedForm = function () {
+ var form = webshims.contentAttr(this, 'form');
+ if(form){
+ form = document.getElementById(form);
+ if(form && !$.nodeName(form, 'form')){
+ form = null;
+ }
+ }
+ return form || this.form;
+ };
+ webshims.defineNodeNamesProperty(['input', 'textarea', 'select', 'button', 'fieldset'], 'form', {
+ prop: {
+ get: getAssociatedForm,
+ writeable: false
+ }
});
- if ($.isFunction(options.callback)) readyCallbacks.add(options.callback);
-
- if (!FileAPIProxy.ready) {
- FileAPIProxy.init(options);
+
+ webshims.defineNodeNamesProperty(['form'], 'elements', {
+ prop: {
+ get: function(){
+ //TODO: cache + perftest
+ var sel, addElements, detachElements, formElements, i, len;
+ var id = this.id;
+ var elements = [];
+ if(id){
+ detachElements = $.data(this, 'webshimsAddedElements');
+ if(detachElements){
+ detachElements.detach();
+ }
+ }
+
+ formElements = this.elements;
+
+ if(this.querySelector('input[form], select[form], textarea[form]')){
+ for(i = 0, len = formElements.length; i < len; i++){
+ if(getAssociatedForm.call(formElements[i]) == this){
+ elements.push(formElements[i]);
+ }
+ }
+ } else {
+ elements = $.makeArray(formElements);
+ }
+
+ if(id){
+ sel = 'input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"], button[form="'+ id +'"], fieldset[form="'+ id +'"]';
+ addElements = document.querySelectorAll(sel) || [];
+ if(addElements.length){
+ elements = $(elements).add(addElements).get();
+
+ }
+ if(detachElements){
+ detachElements.appendTo(this);
+ }
+ }
+ return elements;
+ },
+ writeable: false
+ }
+ });
+
+
+
+ $(function(){
+ var stopPropagation = function(e){
+ e.stopPropagation();
+ };
+ var submitters = {
+ image: 1,
+ submit: 1
+ };
+ $(document).on('submit', function(e){
+
+ if(!e.isDefaultPrevented()){
+ var form = e.target;
+ var id = form.id;
+ var elements;
+
+
+ if(id){
+ removeAddedElements(form);
+ elements = document.querySelectorAll('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"]');
+ elements = $(elements)
+ .filter(function(){
+ return !this.disabled && this.name && this.form != form;
+ })
+ .clone()
+ ;
+ if(elements.length){
+ $.data(form, 'webshimsAddedElements', $('<div class="webshims-visual-hide" />').append(elements).appendTo(form));
+ setTimeout(function(){
+ removeAddedElements(form);
+ }, 9);
+ }
+ elements = null;
+ }
+ }
+ });
+
+
+ $(document).on('click', function(e){
+ if(submitters[e.target.type] && !e.isDefaultPrevented() && webshims.contentAttr(e.target, 'form')){
+ var trueForm = $.prop(e.target, 'form');
+ var formIn = e.target.form;
+ var clone;
+ if(trueForm && trueForm != formIn){
+ clone = $(e.target)
+ .clone()
+ .removeAttr('form')
+ .addClass('webshims-visual-hide')
+ .on('click', stopPropagation)
+ .appendTo(trueForm)
+ ;
+ if(formIn){
+ e.preventDefault();
+ }
+ addSubmitBubbles(trueForm);
+ clone.trigger('click');
+ setTimeout(function(){
+ clone.remove();
+ clone = null;
+ }, 9);
+ }
+ }
+ });
+ });
+
+ if(!$.fn.finish && parseFloat($.fn.jquery, 10) < 1.9){
+ var rCRLF = /\r?\n/g,
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+ rselectTextarea = /^(?:select|textarea)/i;
+ $.fn.serializeArray = function() {
+ return this.map(function(){
+ var elements = $.prop(this, 'elements');
+ return elements ? $.makeArray( elements ) : this;
+ })
+ .filter(function(){
+ return this.name && !$(this).is(':disabled') &&
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
+ rinput.test( this.type ) );
+ })
+ .map(function( i, elem ){
+ var val = $( this ).val();
+
+ return val == null ?
+ null :
+ $.isArray( val ) ?
+ $.map( val, function( val, i ){
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ };
}
}
- return this;
- };
-
- /**
- * Default options
- * allows user set default options
- */
- $.fn.fileReader.defaults = {
- id : 'fileReaderSWFObject', // ID for the created swf object container,
- multiple : null,
- accept : null,
- label : null,
- extensions : null,
- filereader : 'files/filereader.swf', // The path to the filereader swf file
- expressInstall : null, // The path to the express install swf file
- debugMode : false,
- callback : false // Callback function when Filereader is ready
- };
-
- /**
- * Plugin callback
- * adds an input to registry
- */
- var main = function(el, options) {
- return el.each(function(i, input) {
- input = $(input);
- var id = input.attr('id');
- var multiple, accept, label;
- if (!id) {
- id = 'flashFileInput' + inputsCount;
- input.attr('id', id);
- inputsCount++;
+
+ if(!Modernizr.fieldsetelements){
+ webshims.defineNodeNamesProperty(['fieldset'], 'elements', {
+ prop: {
+ get: function(){
+ //add listed elements without keygen, object, output
+ return this.querySelectorAll('input, select, textarea, button, fieldset') || [];
+ },
+ writeable: false
+ }
+ });
+ }
+
+ })();
+ }
+
+ if($('<input />').prop('labels') == null){
+ webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
+ prop: {
+ get: function(){
+ if(this.type == 'hidden'){return null;}
+ var id = this.id;
+ var labels = $(this)
+ .closest('label')
+ .filter(function(){
+ var hFor = (this.attributes['for'] || {});
+ return (!hFor.specified || hFor.value == id);
+ })
+ ;
+
+ if(id) {
+ labels = labels.add(document.querySelectorAll('label[for="'+ id +'"]'));
+ }
+ return labels.get();
+ },
+ writeable: false
+ }
+ });
+ }
+
+ if(!('value' in document.createElement('progress'))){
+ (function(){
+
+ var nan = parseInt('NaN', 10);
+
+ var updateProgress = function(progress){
+ var position = $.prop(progress, 'position');
+
+ $.attr(progress, 'data-position', position);
+ $('> span', progress).css({width: (position < 0 ? 100 : position * 100) +'%'});
+ };
+ var desc = {
+ position: {
+ prop: {
+ get: function(){
+ var max;
+ //jQuery 1.8.x try's to normalize "0" to 0
+ var val = this.getAttribute('value');
+ var ret = -1;
+
+ val = val ? (val * 1) : nan;
+ if(!isNaN(val)){
+ max = $.prop(this, 'max');
+ ret = Math.max(Math.min(val / max, 1), 0);
+ if(updateProgress.isInChange){
+ $.attr(this, 'aria-valuenow', ret * 100);
+ if(updateProgress.isInChange == 'max'){
+ $.attr(this, 'aria-valuemax', max);
+ }
+ }
+ $(this).removeClass('ws-indeterminate');
+ } else if(updateProgress.isInChange) {
+ $(this).removeAttr('aria-valuenow').addClass('ws-indeterminate');
+ }
+ return ret;
+ },
+ writeable: false
+ }
}
- multiple = input.prop('multiple');
- accept = input.data('swfaccept') || input.prop('accept') || options.accept;
- label = input.jProp('labels')
- .map(function(){
- return $(this).text();
- }).get().join(' ') ||
- input.data('swflabel') ||
- options.label;
+ };
- FileAPIProxy.inputs[id] = input;
- FileAPIProxy.swfObject.add(id, multiple, accept, label, options.extensions);
-
- input.css('z-index', 0)
- .mouseover(function (e) {
- if (id !== currentTarget) {
- e = e || window.event;
- currentTarget = id;
- FileAPIProxy.swfObject.mouseover(id);
- FileAPIProxy.container
- .height(input.outerHeight())
- .width(input.outerWidth())
- .css(input.offset());
+ $.each({value: 0, max: 1}, function(name, defValue){
+ var removeProp = (name == 'value' && !$.fn.finish);
+ desc[name] = {
+ attr: {
+ set: function(value){
+ var ret = desc[name].attr._supset.call(this, value);
+ updateProgress.isInChange = name;
+ updateProgress(this);
+ updateProgress.isInChange = false;
+ return ret;
}
- })
- .click(function(e) {
- e.preventDefault();
- e.stopPropagation();
- e.stopImmediatePropagation();
- return false;
- });
+ },
+ removeAttr: {
+ value: function(){
+ this.removeAttribute(name);
+ if(removeProp){
+ try {
+ delete this.value;
+ } catch(er){}
+ }
+ updateProgress.isInChange = name;
+ updateProgress(this);
+ updateProgress.isInChange = false;
+ }
+ },
+ prop: {
+ get: function(){
+ var max;
+ var ret = (desc[name].attr.get.call(this) * 1);
+ if(ret < 0 || isNaN(ret)){
+ ret = defValue;
+ } else if(name == 'value'){
+ ret = Math.min(ret, $.prop(this, 'max'));
+ } else if(ret === 0){
+ ret = defValue;
+ }
+ return ret;
+ },
+ set: function(value){
+ value = value * 1;
+ if(isNaN(value)){
+ webshims.error('Floating-point value is not finite.');
+ }
+ return desc[name].attr.set.call(this, value);
+ }
+ }
+ };
});
+
+ webshims.createElement(
+ 'progress',
+ function(){
+ var labels = $(this)
+ .attr({role: 'progressbar', 'aria-valuemin': '0'})
+ .html('<span class="progress-value" />')
+ .jProp('labels')
+ .map(function(){
+ return webshims.getID(this);
+ })
+ .get()
+ ;
+ if(labels.length){
+ $.attr(this, 'aria-labelledby', labels.join(' '));
+ } else {
+ webshims.info("you should use label elements for your prgogress elements");
+ }
+ if($(this).css('direction') == 'rtl'){
+ $(this).addClass('ws-is-rtl');
+ }
+ updateProgress.isInChange = 'max';
+ updateProgress(this);
+ updateProgress.isInChange = false;
+ },
+ desc
+ );
+
+ })();
+ }
+
+ if(!('setSelectionRange' in document.createElement('input'))){
+ (function(){
+ var getSelection = function(elem, getStart){
+ var range, value, normalizedValue, textInputRange, len, endRange;
+ var start = 0;
+ var end = 0;
+ if (document.selection && (range = document.selection.createRange()) && range.parentElement() == elem) {
+ value = $.prop(elem, 'value');
+ len = value.length;
+ normalizedValue = value.replace(/\r\n/g, "\n");
+
+ textInputRange = elem.createTextRange();
+ textInputRange.moveToBookmark(range.getBookmark());
+
+
+ endRange = elem.createTextRange();
+ endRange.collapse(false);
+
+ if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
+ start = end = len;
+ } else {
+ if(getStart){
+ start = -textInputRange.moveStart("character", -len);
+ start += normalizedValue.slice(0, start).split("\n").length - 1;
+ } else {
+ if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
+ end = len;
+ } else {
+ end = -textInputRange.moveEnd("character", -len);
+ end += normalizedValue.slice(0, end).split("\n").length - 1;
+ }
+ }
+
+ }
+ }
+ return {
+ start: start,
+ end: end
+ };
+ };
+
+ ['input', 'textarea'].forEach(function(name){
+ var isTextarea = name == 'textarea';
+ //email?
+ var allowedTypes = {text: 1, search: 1, url: 1, tel: 1, password: 1, email: 1};
+ var error = 'InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable. selection not allowed on this type';
+ webshims.defineNodeNameProperties(name, {
+ selectionStart: {
+ get: function(){
+ if(isTextarea || allowedTypes[$.prop(this, 'type')]){
+ return getSelection(this, true).start;
+ }
+ webshims.error(error);
+ },
+ set: function(v){
+ if(this.createTextRange && (isTextarea || allowedTypes[$.prop(this, 'type')])){
+ var range = this.createTextRange();
+ range.collapse(true);
+ range.moveStart('character', v);
+ range.moveEnd('character', $.prop(this, 'selectionEnd'));
+ if($(this).is(':focus')){
+ range.select();
+ }
+ } else {
+ webshims.error(error);
+ }
+ }
+ },
+ selectionEnd: {
+ get: function(){
+ if(isTextarea || allowedTypes[$.prop(this, 'type')]){
+ return getSelection(this).end;
+ }
+ webshims.error(error);
+ },
+ set: function(v){
+ if(this.createTextRange && (isTextarea || allowedTypes[$.prop(this, 'type')])){
+ var range = this.createTextRange();
+ var start;
+ range.collapse(true);
+ start = getSelection(this, true).start;
+ range.moveStart('character', start);
+ range.moveEnd('character', v - start);
+ if($(this).is(':focus')){
+ range.select();
+ }
+ } else {
+ webshims.error(error);
+ }
+ }
+ },
+ setSelectionRange: {
+ value: function(start, end, dir){
+ if(this.createTextRange && (isTextarea || allowedTypes[$.prop(this, 'type')])){
+ var range = this.createTextRange();
+ range.collapse(true);
+ range.moveStart('character', start);
+ range.moveEnd('character', end - start);
+ if($(this).is(':focus')){
+ range.select();
+ }
+ } else {
+ webshims.error(error);
+ }
+ }
+ }
+ }, 'prop');
+ });
+
+ })();
+ }
+
+ (function(){
+ if(options.noPlaceholderPolyfill){return;}
+ var bustedPlaceholder;
+ Modernizr.textareaPlaceholder = !!('placeholder' in $('<textarea />')[0]);
+ if(Modernizr.input.placeholder && options.overridePlaceholder){
+ bustedPlaceholder = true;
+ }
+ if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder && !bustedPlaceholder){
+ (function(){
+ var ua = navigator.userAgent;
+
+ if(ua.indexOf('Mobile') != -1 && ua.indexOf('Safari') != -1){
+ $(window).on('orientationchange', (function(){
+ var timer;
+ var retVal = function(i, value){
+ return value;
+ };
+
+ var set = function(){
+ $('input[placeholder], textarea[placeholder]').attr('placeholder', retVal);
+ };
+ return function(e){
+ clearTimeout(timer);
+ timer = setTimeout(set, 9);
+ };
+ })());
+ }
+ })();
+
+ //abort
+ return;
+ }
+
+ var isOver = (webshims.cfg.forms.placeholderType == 'over');
+ var isResponsive = (webshims.cfg.forms.responsivePlaceholder);
+ var polyfillElements = ['textarea'];
+ if(!Modernizr.input.placeholder || bustedPlaceholder){
+ polyfillElements.push('input');
+ }
+
+ var setSelection = function(elem){
+ try {
+ $(elem).setSelectionRange(0,0);
+ return true;
+ } catch(er){}
};
-
- /**
- * Flash FileReader Proxy
- */
- window.FileAPIProxy = {
- ready: false,
- _inititalized: false,
- init: function(o) {
- var self = this;
- this.debugMode = o.debugMode;
-
- if(!this.container){
- this.container = $('<div>').attr('id', o.id)
- .wrap('<div>')
- .parent()
- .css({
- position:'fixed',
- // top:'0px',
- width:'1px',
- height:'1px',
- display:'inline-block',
- background:'transparent',
- 'z-index':99999
- })
- // Hands over mouse events to original input for css styles
- .on('mouseover mouseout mousedown mouseup', function(evt) {
- if(currentTarget){
- $('#' + currentTarget).trigger(evt.type);
+
+ var hidePlaceholder = function(elem, data, value, _onFocus){
+ if(value === false){
+ value = $.prop(elem, 'value');
+ }
+
+ if(!isOver && elem.type != 'password'){
+ if(!value && _onFocus && setSelection(elem)){
+ var selectTimer = setTimeout(function(){
+ setSelection(elem);
+ }, 9);
+ $(elem)
+ .off('.placeholderremove')
+ .on({
+ 'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
+ if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
+ elem.value = $.prop(elem, 'value');
+ data.box.removeClass('placeholder-visible');
+ clearTimeout(selectTimer);
+ $(elem).off('.placeholderremove');
+ },
+ 'mousedown.placeholderremove drag.placeholderremove select.placeholderremove': function(e){
+ setSelection(elem);
+ clearTimeout(selectTimer);
+ selectTimer = setTimeout(function(){
+ setSelection(elem);
+ }, 9);
+ },
+ 'blur.placeholderremove': function(){
+ clearTimeout(selectTimer);
+ $(elem).off('.placeholderremove');
+ }
+ })
+ ;
+ return;
+ } else if(!_onFocus && !value && elem.value){ //especially on submit
+ elem.value = value;
+ }
+ } else if(!value && _onFocus){
+ $(elem)
+ .off('.placeholderremove')
+ .on({
+ 'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
+ if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
+ data.box.removeClass('placeholder-visible');
+ $(elem).off('.placeholderremove');
+ },
+ 'blur.placeholderremove': function(){
+ $(elem).off('.placeholderremove');
}
})
- .appendTo('body');
-
- swfobject.embedSWF(o.filereader, o.id, '100%', '100%', '10', o.expressInstall, {debugMode: o.debugMode ? true : ''}, {'wmode':'transparent','allowScriptAccess':'sameDomain'}, {}, function(e) {
- self.swfObject = e.ref;
- $(self.swfObject)
- .css({
- display: 'block',
- outline: 0
- })
- .attr('tabindex', 0);
-
- self.ready = e.success && typeof e.ref.add === "function";
-
- if (self.ready) {
- readyCallbacks.fire();
- }
- });
+ ;
+ return;
}
+ data.box.removeClass('placeholder-visible');
},
- swfObject: null,
- container: null,
- // Inputs Registry
- inputs: {},
- // Readers Registry
- readers: {},
- // Receives FileInput events
- onFileInputEvent: function(evt) {
- if (this.debugMode) console.info('FileInput Event ', evt.type, evt);
- if (evt.target in this.inputs) {
- var el = this.inputs[evt.target];
- evt.target = el[0];
- if( evt.type === 'change') {
- webshims.data(evt.target, 'fileList', new FileList(evt.files));
- }
- el.trigger(evt);
+ showPlaceholder = function(elem, data, placeholderTxt){
+ if(placeholderTxt === false){
+ placeholderTxt = $.prop(elem, 'placeholder');
}
- window.focus();
+
+ if(!isOver && elem.type != 'password'){
+ elem.value = placeholderTxt;
+ }
+ data.box.addClass('placeholder-visible');
},
- // Receives FileReader ProgressEvents
- onFileReaderEvent: function(evt) {
- if (this.debugMode) console.info('FileReader Event ', evt.type, evt, evt.target in this.readers);
- if (evt.target in this.readers) {
- var reader = this.readers[evt.target];
- evt.target = reader;
- reader._handleFlashEvent.call(reader, evt);
+ changePlaceholderVisibility = function(elem, value, placeholderTxt, data, type){
+ if(!data){
+ data = $.data(elem, 'placeHolder');
+ if(!data){return;}
}
+ var isVisible = $(elem).hasClass('placeholder-visible');
+ if(placeholderTxt === false){
+ placeholderTxt = $.attr(elem, 'placeholder') || '';
+ }
+
+ $(elem).off('.placeholderremove');
+
+ if(value === false){
+ value = $.prop(elem, 'value');
+ }
+
+ if(!value && (type == 'focus' || (!type && $(elem).is(':focus')))){
+ if(elem.type == 'password' || isOver || isVisible){
+ hidePlaceholder(elem, data, '', true);
+ }
+ return;
+ }
+
+ if(value){
+ hidePlaceholder(elem, data, value);
+ return;
+ }
+
+ if(placeholderTxt && !value){
+ showPlaceholder(elem, data, placeholderTxt);
+ } else {
+ hidePlaceholder(elem, data, value);
+ }
},
- // Receives flash FileReader Error Events
- onFileReaderError: function(error) {
- if (this.debugMode) console.log(error);
+ createPlaceholder = function(){
+ return $('<span class="placeholder-text"></span>');
},
- onSWFReady: function() {
- this.container.css({position: 'absolute'});
- this.ready = typeof this.swfObject.add === "function";
- if (this.ready) {
- readyCallbacks.fire();
+ pHolder = (function(){
+ var allowedPlaceholder = {
+ text: 1,
+ search: 1,
+ url: 1,
+ email: 1,
+ password: 1,
+ tel: 1,
+ number: 1
+ }
+ ;
+ if(webshims.modules["form-number-date-ui"].loaded){
+ delete allowedPlaceholder.number;
}
-
- return true;
- }
+
+ return {
+ create: function(elem){
+ var data = $.data(elem, 'placeHolder');
+ var form;
+ if(data){return data;}
+ data = $.data(elem, 'placeHolder', {});
+
+ $(elem).on('focus.placeholder blur.placeholder', function(e){
+ changePlaceholderVisibility(this, false, false, data, e.type );
+ data.box[e.type == 'focus' ? 'addClass' : 'removeClass']('placeholder-focused');
+ });
+
+ if((form = $.prop(elem, 'form'))){
+ $(elem).onWSOff('reset.placeholder', function(e){
+ setTimeout(function(){
+ changePlaceholderVisibility(elem, false, false, data, e.type );
+ }, 0);
+ }, false, form);
+ }
+
+ if(elem.type == 'password' || isOver){
+ data.text = createPlaceholder(elem);
+ if(isResponsive || $(elem).is('.responsive-width') || (elem.currentStyle || {width: ''}).width.indexOf('%') != -1){
+ data.box = data.text;
+ } else {
+ data.box = $('<span class="placeholder-box placeholder-box-'+ (elem.nodeName || '').toLowerCase() +' placeholder-box-'+$.css(elem, 'float')+'" />')
+ .insertAfter(elem)
+ ;
+ data.box.append(elem);
+ }
+ data.text
+ .insertAfter(elem)
+ .on('mousedown.placeholder', function(){
+ changePlaceholderVisibility(this, false, false, data, 'focus');
+ try {
+ setTimeout(function(){
+ elem.focus();
+ }, 0);
+ } catch(e){}
+ return false;
+ })
+ ;
+
+
+ $.each(['lineHeight', 'fontSize', 'fontFamily', 'fontWeight'], function(i, style){
+ var prop = $.css(elem, style);
+ if(data.text.css(style) != prop){
+ data.text.css(style, prop);
+ }
+ });
+ $.each(['Left', 'Top'], function(i, side){
+ var size = (parseInt($.css(elem, 'padding'+ side), 10) || 0) + Math.max((parseInt($.css(elem, 'margin'+ side), 10) || 0), 0) + (parseInt($.css(elem, 'border'+ side +'Width'), 10) || 0);
+ data.text.css('padding'+ side, size);
+ });
+
+ $(elem)
+ .onWSOff('updateshadowdom', (function(){
+ var lastWidth, init, timer;
+ var jelm = $(elem);
+ var lastPos = {};
+ return function(){
+ var width, fn;
+
+ if((width = elem.offsetWidth)){
+
+ fn = function(){
+ var pos = jelm.position();
+ if(width !== lastWidth){
+ lastWidth = width;
+ data.text[0].style.width = width +'px';
+ }
+ if(pos.top !== lastPos.top || pos.left !== lastPos.left){
+ lastPos = pos;
+ data.text[0].style.top = pos.top +'px';
+ data.text[0].style.left = pos.left +'px';
+ }
+ };
+ if(!init){
+ fn();
+ init = true;
+ } else {
+ clearTimeout(timer);
+ timer = setTimeout(fn, 99);
+ }
+ }
+ };
+ })(), true)
+ ;
+
+ } else {
+ var reset = function(e){
+ if($(elem).hasClass('placeholder-visible')){
+ hidePlaceholder(elem, data, '');
+
+ setTimeout(function(){
+ if(!e || e.type != 'submit' || e.isDefaultPrevented()){
+ changePlaceholderVisibility(elem, false, false, data );
+ }
+ }, 9);
+ }
+ };
+
+ $(elem).onWSOff('beforeunload', reset, false, window);
+ data.box = $(elem);
+ if(form){
+ $(elem).onWSOff('submit', reset, false, form);
+ }
+ }
+
+ return data;
+ },
+ update: function(elem, val){
+ var type = ($.attr(elem, 'type') || $.prop(elem, 'type') || '').toLowerCase();
+ if(!allowedPlaceholder[type] && !$.nodeName(elem, 'textarea')){
+ webshims.warn('placeholder not allowed on input[type="'+type+'"], but it is a good fallback :-)');
+ return;
+ }
+
+
+ var data = pHolder.create(elem);
+ if(data.text){
+ data.text.text(val);
+ }
+
+ changePlaceholderVisibility(elem, false, val, data);
+ }
+ };
+ })()
+ ;
+
+ $.webshims.publicMethods = {
+ pHolder: pHolder
};
-
-
- /**
- * Add FileReader to the window object
- */
- window.FileReader = function () {
- // states
- this.EMPTY = 0;
- this.LOADING = 1;
- this.DONE = 2;
-
- this.readyState = 0;
-
- // File or Blob data
- this.result = null;
-
- this.error = null;
-
- // event handler attributes
- this.onloadstart = null;
- this.onprogress = null;
- this.onload = null;
- this.onabort = null;
- this.onerror = null;
- this.onloadend = null;
-
- // Event Listeners handling using JQuery Callbacks
- this._callbacks = {
- loadstart : $.Callbacks( "unique" ),
- progress : $.Callbacks( "unique" ),
- abort : $.Callbacks( "unique" ),
- error : $.Callbacks( "unique" ),
- load : $.Callbacks( "unique" ),
- loadend : $.Callbacks( "unique" )
+ polyfillElements.forEach(function(nodeName){
+ webshims.defineNodeNameProperty(nodeName, 'placeholder', {
+ attr: {
+ set: function(val){
+ var elem = this;
+ if(bustedPlaceholder){
+ webshims.data(elem, 'bustedPlaceholder', val);
+ elem.placeholder = '';
+ } else {
+ webshims.contentAttr(elem, 'placeholder', val);
+ }
+ pHolder.update(elem, val);
+ },
+ get: function(){
+ var placeholder;
+ if(bustedPlaceholder){
+ placeholder = webshims.data(this, 'bustedPlaceholder');
+ }
+ return placeholder || webshims.contentAttr(this, 'placeholder');
+ }
+ },
+ reflect: true,
+ initAttr: true
+ });
+ });
+
+
+ polyfillElements.forEach(function(name){
+ var placeholderValueDesc = {};
+ var desc;
+ ['attr', 'prop'].forEach(function(propType){
+ placeholderValueDesc[propType] = {
+ set: function(val){
+ var elem = this;
+ var placeholder;
+ if(bustedPlaceholder){
+ placeholder = webshims.data(elem, 'bustedPlaceholder');
+ }
+ if(!placeholder){
+ placeholder = webshims.contentAttr(elem, 'placeholder');
+ }
+ $.removeData(elem, 'cachedValidity');
+ var ret = desc[propType]._supset.call(elem, val);
+ if(placeholder && 'value' in elem){
+ changePlaceholderVisibility(elem, val, placeholder);
+ }
+ return ret;
+ },
+ get: function(){
+ var placeholder;
+ var elem = this;
+ var curValue;
+
+ if($(elem).hasClass('placeholder-visible')){
+ if(webshims.cfg.debug && (curValue = desc[propType]._supget.call(elem)) && (placeholder = $.attr(elem, 'placeholder')) && placeholder != curValue){
+ webshims.error('value input[placeholder] was changed by input.value instead using $.val or $.prop.');
+ changePlaceholderVisibility(elem, curValue, placeholder);
+ } else {
+ curValue = '';
+ }
+ } else {
+ curValue = desc[propType]._supget.call(elem);
+ }
+ return curValue;
+ }
+ };
+ });
+ desc = webshims.defineNodeNameProperty(name, 'value', placeholderValueDesc);
+ });
+
+ })();
+
+ (function(){
+ var doc = document;
+ if( 'value' in document.createElement('output') ){return;}
+
+ webshims.defineNodeNameProperty('output', 'value', {
+ prop: {
+ set: function(value){
+ var setVal = $.data(this, 'outputShim');
+ if(!setVal){
+ setVal = outputCreate(this);
+ }
+ setVal(value);
+ },
+ get: function(){
+ return webshims.contentAttr(this, 'value') || $(this).text() || '';
+ }
+ }
+ });
+
+
+ webshims.onNodeNamesPropertyModify('input', 'value', function(value, boolVal, type){
+ if(type == 'removeAttr'){return;}
+ var setVal = $.data(this, 'outputShim');
+ if(setVal){
+ setVal(value);
+ }
+ });
+
+ var outputCreate = function(elem){
+ if($.data(elem, 'outputShim')){return;}
+ elem = $(elem);
+ var value = (elem.text() || '').trim();
+ var id = elem.prop('id');
+ var htmlFor = elem.attr('for');
+ var shim = $('<input class="output-shim" type="text" disabled name="'+ (elem.attr('name') || '')+'" value="'+value+'" style="display: none !important;" />').insertAfter(elem);
+ var setValue = function(val){
+ shim[0].value = val;
+ val = shim[0].value;
+ elem.text(val);
+ webshims.contentAttr(elem[0], 'value', val);
};
-
- // Custom properties
- this._id = null;
+
+ elem[0].defaultValue = value;
+ webshims.contentAttr(elem[0], 'value', value);
+
+ elem.attr({'aria-live': 'polite'});
+
+ if(id){
+ shim.attr('id', id);
+ elem.attr('aria-labelledby', elem.jProp('labels').map(function(){
+ return webshims.getID(this);
+ }).get().join(' '));
+ }
+ if(htmlFor){
+ id = webshims.getID(elem);
+ htmlFor.split(' ').forEach(function(control){
+ control = document.getElementById(control);
+ if(control){
+ control.setAttribute('aria-controls', id);
+ }
+ });
+ }
+ elem.data('outputShim', setValue );
+ shim.data('outputShim', setValue );
+ return setValue;
};
-
- window.FileReader.prototype = {
- // async read methods
- readAsBinaryString: function (file) {
- this._start(file);
- FileAPIProxy.swfObject.read(file.input, file.name, 'readAsBinaryString');
- },
- readAsText: function (file, encoding) {
- this._start(file);
- FileAPIProxy.swfObject.read(file.input, file.name, 'readAsText');
- },
- readAsDataURL: function (file) {
- this._start(file);
- FileAPIProxy.swfObject.read(file.input, file.name, 'readAsDataURL');
- },
- readAsArrayBuffer: function(file){
- throw("Whoops FileReader.readAsArrayBuffer is unimplemented");
- },
-
- abort: function () {
- this.result = null;
- if (this.readyState === this.EMPTY || this.readyState === this.DONE) return;
- FileAPIProxy.swfObject.abort(this._id);
- },
-
- // Event Target interface
- addEventListener: function (type, listener) {
- if (type in this._callbacks) this._callbacks[type].add(listener);
- },
- removeEventListener: function (type, listener) {
- if (type in this._callbacks) this._callbacks[type].remove(listener);
- },
- dispatchEvent: function (event) {
- event.target = this;
- if (event.type in this._callbacks) {
- var fn = this['on' + event.type];
- if ($.isFunction(fn)) fn(event);
- this._callbacks[event.type].fire(event);
+
+ webshims.addReady(function(context, contextElem){
+ $(context.getElementsByTagName('output')).add(contextElem.filter('output')).each(function(){
+ outputCreate(this);
+ });
+ });
+
+ /*
+ * Implements input event in all browsers
+ */
+ (function(){
+ var noInputTriggerEvts = {updateInput: 1, input: 1},
+ noInputTypes = {
+ radio: 1,
+ checkbox: 1,
+ submit: 1,
+ button: 1,
+ image: 1,
+ reset: 1,
+ file: 1
+
+ //pro forma
+ ,color: 1
+ },
+ inputElements = {
+ input: 1,
+ INPUT: 1,
+ textarea: 1,
+ TEXTAREA: 1
+ },
+ timer,
+ lastVal,
+ input,
+ trigger = function(e){
+ if(!input){return;}
+ var newVal = input.prop('value');
+ if(newVal !== lastVal){
+ lastVal = newVal;
+ if(!e || !noInputTriggerEvts[e.type]){
+ webshims.triggerInlineForm && webshims.triggerInlineForm(input[0], 'input');
+ }
+ }
+ },
+ extraTimer,
+ extraTest = function(){
+ clearTimeout(extraTimer);
+ extraTimer = setTimeout(trigger, 9);
+ },
+ unbind = function(){
+ clearTimeout(extraTimer);
+ clearInterval(timer);
+ if(input){
+ input.off('focusout', unbind).off('keyup keypress keydown paste cut', extraTest).off('input change updateInput triggerinput', trigger);
+ }
+
+
}
- return true;
- },
-
- // Custom private methods
-
- // Registers FileReader instance for flash callbacks
- _register: function(file) {
- this._id = file.input + '.' + file.name;
- FileAPIProxy.readers[this._id] = this;
- },
- _start: function(file) {
- this._register(file);
- if (this.readyState === this.LOADING) throw {type: 'InvalidStateError', code: 11, message: 'The object is in an invalid state.'};
- },
- _handleFlashEvent: function(evt) {
- switch (evt.type) {
- case 'loadstart':
- this.readyState = this.LOADING;
- break;
- case 'loadend':
- this.readyState = this.DONE;
- break;
- case 'load':
- this.readyState = this.DONE;
- this.result = FileAPIProxy.swfObject.result(this._id);
- break;
- case 'error':
- this.result = null;
- this.error = {
- name: 'NotReadableError',
- message: 'The File cannot be read!'
- };
+ ;
+ var observe = function(newInput){
+ unbind();
+
+ input = newInput;
+ lastVal = input.prop('value');
+ clearInterval(timer);
+ timer = setInterval(trigger, 200);
+ extraTest();
+ input.on({
+ 'keyup keypress keydown paste cut': extraTest,
+ 'focusout wswidgetfocusout': unbind,
+ 'input updateInput change triggerinput': trigger
+ });
+ };
+
+ $(doc)
+ .on('focusin wswidgetfocusin', function(e){
+ if( e.target && !e.target.readOnly && !e.target.disabled && inputElements[e.target.nodeName] && !noInputTypes[e.target.type] && !(webshims.data(e.target, 'implemented') || {}).inputwidgets){
+ observe($(e.target));
+ }
+ })
+ ;
+ })();
+ })();
+
+
+});
+;webshim.register('filereader', function($, webshim, window, document, undefined, featureOptions){
+ "use strict";
+ var mOxie, moxie, hasXDomain;
+ var FormData = $.noop;
+ var sel = 'input[type="file"].ws-filereader';
+ var loadMoxie = function (){
+ webshim.loader.loadList(['moxie']);
+ };
+ var _createFilePicker = function(){
+ var $input, picker, $parent, onReset;
+ var input = this;
+
+ if(webshim.implement(input, 'filepicker')){
+
+ input = this;
+ $input = $(this);
+ $parent = $input.parent();
+ onReset = function(){
+ if(!input.value){
+ $input.prop('value', '');
}
- this.dispatchEvent(new FileReaderEvent(evt));
+ };
+
+ $input.attr('tabindex', '-1').on('mousedown.filereaderwaiting click.filereaderwaiting', false);
+ $parent.addClass('ws-loading');
+ picker = new mOxie.FileInput({
+ browse_button: this,
+ accept: $.prop(this, 'accept'),
+ multiple: $.prop(this, 'multiple')
+ });
+
+ $input.jProp('form').on('reset', function(){
+ setTimeout(onReset);
+ });
+ picker.onready = function(){
+ $input.off('.fileraderwaiting');
+ $parent.removeClass('ws-waiting');
+ };
+
+ picker.onchange = function(e){
+ webshim.data(input, 'fileList', e.target.files);
+ $input.trigger('change');
+ };
+ picker.onmouseenter = function(){
+ $input.trigger('mouseover');
+ $parent.addClass('ws-mouseenter');
+ };
+ picker.onmouseleave = function(){
+ $input.trigger('mouseout');
+ $parent.removeClass('ws-mouseenter');
+ };
+ picker.onmousedown = function(){
+ $input.trigger('mousedown');
+ $parent.addClass('ws-active');
+ };
+ picker.onmouseup = function(){
+ $input.trigger('mouseup');
+ $parent.removeClass('ws-active');
+ };
+
+ webshim.data(input, 'filePicker', picker);
+
+ webshim.ready('WINDOWLOAD', function(){
+ var lastWidth;
+ $input.onWSOff('updateshadowdom', function(){
+ var curWitdth = input.offsetWidth;
+ if(curWitdth && lastWidth != curWitdth){
+ lastWidth = curWitdth;
+ picker.refresh();
+ }
+ });
+ });
+
+ webshim.addShadowDom();
+
+ picker.init();
+ if(input.disabled){
+ picker.disable(true);
}
- };
-
- /**
- * FileReader ProgressEvent implenting Event interface
- */
- window.FileReaderEvent = function (e) {
- this.initEvent(e);
- };
-
- window.FileReaderEvent.prototype = {
- initEvent: function (event) {
- $.extend(this, {
- type: null,
- target: null,
- currentTarget: null,
-
- eventPhase: 2,
-
- bubbles: false,
- cancelable: false,
-
- defaultPrevented: false,
-
- isTrusted: false,
- timeStamp: new Date().getTime()
- }, event);
- },
- stopPropagation: function (){
- },
- stopImmediatePropagation: function (){
- },
- preventDefault: function (){
+ }
+ };
+ var getFileNames = function(file){
+ return file.name;
+ };
+ var createFilePicker = function(){
+ var elem = this;
+ loadMoxie();
+ $(elem)
+ .on('mousedown.filereaderwaiting click.filereaderwaiting', false)
+ .parent()
+ .addClass('ws-loading')
+ ;
+ webshim.ready('moxie', function(){
+ createFilePicker.call(elem);
+ });
+ };
+ var noxhr = /^(?:script|jsonp)$/i;
+ var notReadyYet = function(){
+ loadMoxie();
+ webshim.error('filereader/formdata not ready yet. please wait for moxie to load `webshim.ready("moxie", callbackFn);`` or wait for the first change event on input[type="file"].ws-filereader.')
+ };
+ var inputValueDesc = webshim.defineNodeNameProperty('input', 'value', {
+ prop: {
+ get: function(){
+ var fileList = webshim.data(this, 'fileList');
+
+ if(fileList && fileList.map){
+ return fileList.map(getFileNames).join(', ');
+ }
+
+ return inputValueDesc.prop._supget.call(this);
+ },
+ set: function(val){
+ if(val === '' && this.type == 'file' && $(this).hasClass('ws-filereader')){
+ webshim.data(this, 'fileList', []);
+ }
+ inputValueDesc.prop._supset.call(this);
+ }
}
- };
-
- /**
- * FileList interface (Object with item function)
- */
- window.FileList = function(array) {
- if (array) {
- for (var i = 0; i < array.length; i++) {
- this[i] = array[i];
+ }
+ );
+ var shimMoxiePath = webshim.cfg.basePath+'moxie/';
+ var crossXMLMessage = 'You nedd a crossdomain.xml to get all "filereader" / "XHR2" / "CORS" features to work. Or host moxie.swf/moxie.xap on your server an configure filereader options: "swfpath"/"xappath"';
+ var testMoxie = function(options){
+ return (options.wsType == 'moxie' || (options.data && options.data instanceof mOxie.FormData) || (options.crossDomain && $.support.cors !== false && hasXDomain != 'no' && !noxhr.test(options.dataType || '')));
+ };
+ var createMoxieTransport = function (options){
+
+ if(testMoxie(options)){
+ var ajax;
+ webshim.info('moxie transfer used for $.ajax');
+ if(hasXDomain == 'no'){
+ webshim.error(crossXMLMessage);
+ }
+ return {
+ send: function( headers, completeCallback ) {
+
+ var proressEvent = function(obj, name){
+ if(options[name]){
+ var called = false;
+ ajax.addEventListener('load', function(e){
+ if(!called){
+ options[name]({type: 'progress', lengthComputable: true, total: 1, loaded: 1});
+ } else if(called.lengthComputable && called.total > called.loaded){
+ options[name]({type: 'progress', lengthComputable: true, total: called.total, loaded: called.total});
+ }
+ });
+ obj.addEventListener('progress', function(e){
+ called = e;
+ options[name](e);
+ });
+ }
+ };
+ ajax = new moxie.xhr.XMLHttpRequest();
+
+ ajax.open(options.type, options.url, options.async, options.username, options.password);
+
+ proressEvent(ajax.upload, featureOptions.uploadprogress);
+ proressEvent(ajax.upload, featureOptions.progress);
+
+ ajax.addEventListener('load', function(e){
+ var responses = {
+ text: ajax.responseText,
+ xml: ajax.responseXML
+ };
+ completeCallback(ajax.status, ajax.statusText, responses, ajax.getAllResponseHeaders());
+ });
+
+ if(options.xhrFields && options.xhrFields.withCredentials){
+ ajax.withCredentials = true;
+ }
+
+ if(options.timeout){
+ ajax.timeout = options.timeout;
+ }
+
+ $.each(headers, function(name, value){
+ ajax.setRequestHeader(name, value);
+ });
+
+
+ ajax.send(options.data);
+
+ },
+ abort: function() {
+ if(ajax){
+ ajax.abort();
+ }
}
- this.length = array.length;
- } else {
- this.length = 0;
+ };
+ }
+ };
+ var transports = {
+ //based on script: https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
+ xdomain: (function(){
+ var httpRegEx = /^https?:\/\//i;
+ var getOrPostRegEx = /^get|post$/i;
+ var sameSchemeRegEx = new RegExp('^'+location.protocol, 'i');
+ return function(options, userOptions, jqXHR) {
+
+ // Only continue if the request is: asynchronous, uses GET or POST method, has HTTP or HTTPS protocol, and has the same scheme as the calling page
+ if (!options.crossDomain || options.username || (options.xhrFields && options.xhrFields.withCredentials) || !options.async || !getOrPostRegEx.test(options.type) || !httpRegEx.test(options.url) || !sameSchemeRegEx.test(options.url) || (options.data && options.data instanceof mOxie.FormData) || noxhr.test(options.dataType || '')) {
+ return;
+ }
+
+ var xdr = null;
+ webshim.info('xdomain transport used.');
+
+ return {
+ send: function(headers, complete) {
+ var postData = '';
+ var userType = (userOptions.dataType || '').toLowerCase();
+
+ xdr = new XDomainRequest();
+ if (/^\d+$/.test(userOptions.timeout)) {
+ xdr.timeout = userOptions.timeout;
+ }
+
+ xdr.ontimeout = function() {
+ complete(500, 'timeout');
+ };
+
+ xdr.onload = function() {
+ var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType;
+ var status = {
+ code: xdr.status || 200,
+ message: xdr.statusText || 'OK'
+ };
+ var responses = {
+ text: xdr.responseText,
+ xml: xdr.responseXML
+ };
+ try {
+ if (userType === 'html' || /text\/html/i.test(xdr.contentType)) {
+ responses.html = xdr.responseText;
+ } else if (userType === 'json' || (userType !== 'text' && /\/json/i.test(xdr.contentType))) {
+ try {
+ responses.json = $.parseJSON(xdr.responseText);
+ } catch(e) {
+
+ }
+ } else if (userType === 'xml' && !xdr.responseXML) {
+ var doc;
+ try {
+ doc = new ActiveXObject('Microsoft.XMLDOM');
+ doc.async = false;
+ doc.loadXML(xdr.responseText);
+ } catch(e) {
+
+ }
+
+ responses.xml = doc;
+ }
+ } catch(parseMessage) {}
+ complete(status.code, status.message, responses, allResponseHeaders);
+ };
+
+ // set an empty handler for 'onprogress' so requests don't get aborted
+ xdr.onprogress = function(){};
+ xdr.onerror = function() {
+ complete(500, 'error', {
+ text: xdr.responseText
+ });
+ };
+
+ if (userOptions.data) {
+ postData = ($.type(userOptions.data) === 'string') ? userOptions.data : $.param(userOptions.data);
+ }
+ xdr.open(options.type, options.url);
+ xdr.send(postData);
+ },
+ abort: function() {
+ if (xdr) {
+ xdr.abort();
+ }
+ }
+ };
+ };
+ })(),
+ moxie: function (options, originalOptions, jqXHR){
+ if(testMoxie(options)){
+ loadMoxie(options);
+ var ajax;
+
+ var tmpTransport = {
+ send: function( headers, completeCallback ) {
+ ajax = true;
+ webshim.ready('moxie', function(){
+ if(ajax){
+ ajax = createMoxieTransport(options, originalOptions, jqXHR);
+ tmpTransport.send = ajax.send;
+ tmpTransport.abort = ajax.abort;
+ ajax.send(headers, completeCallback);
+ }
+ });
+ },
+ abort: function() {
+ ajax = false;
+ }
+ };
+ return tmpTransport;
}
- };
-
- window.FileList.prototype = {
- item: function(index) {
- return (index in this) ? this[index] : null;
+ }
+ };
+
+ if(!featureOptions.progress){
+ featureOptions.progress = 'onprogress';
+ }
+
+ if(!featureOptions.uploadprogress){
+ featureOptions.uploadprogress = 'onuploadprogress';
+ }
+
+ if(!featureOptions.swfpath){
+ featureOptions.swfpath = shimMoxiePath+'flash/Moxie.cdn.swf';
+ }
+ if(!featureOptions.xappath){
+ featureOptions.xappath = shimMoxiePath+'silverlight/Moxie.cdn.xap';
+ }
+
+ if($.support.cors !== false || !window.XDomainRequest){
+ delete transports.xdomain;
+ }
+
+
+ $.ajaxTransport("+*", function( options, originalOptions, jqXHR ) {
+ var ajax, type;
+
+ if(options.wsType || transports[transports]){
+ ajax = transports[transports](options, originalOptions, jqXHR);
+ }
+ if(!ajax){
+ for(type in transports){
+ ajax = transports[type](options, originalOptions, jqXHR);
+ if(ajax){break;}
}
- };
- })();
-
- webshims.defineNodeNameProperty('input', 'files', {
+ }
+ return ajax;
+ });
+
+ webshim.defineNodeNameProperty('input', 'files', {
prop: {
writeable: false,
get: function(){
if(this.type != 'file'){return null;}
if(!$(this).is('.ws-filereader')){
- webshims.error("please add the 'ws-filereader' class to your input[type='file'] to implement files-property");
+ webshim.info("please add the 'ws-filereader' class to your input[type='file'] to implement files-property");
}
- return webshims.data(this, 'fileList') || webshims.data(this, 'fileList', new FileList());
+ return webshim.data(this, 'fileList') || [];
}
}
}
);
-
- webshims.defineNodeNamesBooleanProperty('input', 'multiple');
- //webshims
- $.fn.fileReader.defaults.filereader = webshims.cfg.basePath +'swf/filereader.swf';
- var wait = ['DOM'];
- if(webshims.modules["form-core"].loaded){
- wait.push('forms');
+ webshim.reflectProperties(['input'], ['accept']);
+
+ if($('<input />').prop('multiple') == null){
+ webshim.defineNodeNamesBooleanProperty(['input'], ['multiple']);
}
- webshims.ready(wait, function(){
- webshims.addReady(function(context, contextElem){
- $('input[type="file"].ws-filereader', context).fileReader();
- });
+
+ webshim.onNodeNamesPropertyModify('input', 'disabled', function(value, boolVal, type){
+ var picker = webshim.data(this, 'filePicker');
+ if(picker){
+ picker.disable(boolVal);
+ }
});
+
+ window.FileReader = notReadyYet;
+ window.FormData = notReadyYet;
+ webshim.ready('moxie', function(){
+ var wsMimes = 'application/xml,xml';
+ moxie = window.moxie;
+ mOxie = window.mOxie;
+
+ mOxie.Env.swf_url = featureOptions.swfpath;
+ mOxie.Env.xap_url = featureOptions.xappath;
+
+ window.FileReader = mOxie.FileReader;
+
+ window.FormData = function(form){
+ var appendData, i, len, files, fileI, fileLen, inputName;
+ var moxieData = new mOxie.FormData();
+ if(form && $.nodeName(form, 'form')){
+ appendData = $(form).serializeArray();
+ for(i = 0; i < appendData.length; i++){
+ if(Array.isArray(appendData[i].value)){
+ appendData[i].value.forEach(function(val){
+ moxieData.append(appendData[i].name, val);
+ });
+ } else {
+ moxieData.append(appendData[i].name, appendData[i].value);
+ }
+ }
+
+ appendData = form.querySelectorAll('input[type="file"][name]');
+
+ for(i = 0, len = appendData.length; i < appendData.length; i++){
+ inputName = appendData[i].name;
+ if(inputName && !$(appendData[i]).is(':disabled')){
+ files = $.prop(appendData[i], 'files') || [];
+ if(files.length){
+ if(files.length > 1){
+ webshim.error('FormData shim can only handle one file per ajax. Use multiple ajax request. One per file.');
+ }
+ for(fileI = 0, fileLen = files.length; fileI < fileLen; fileI++){
+ moxieData.append(inputName, files[fileI]);
+ }
+ }
+ }
+ }
+ }
+
+ return moxieData;
+ };
+ FormData = window.FormData;
+
+ createFilePicker = _createFilePicker;
+ transports.moxie = createMoxieTransport;
+
+ featureOptions.mimeTypes = (featureOptions.mimeTypes) ? wsMimes+','+featureOptions.mimeTypes : wsMimes;
+ try {
+ mOxie.Mime.addMimeType(featureOptions.mimeTypes);
+ } catch(e){
+ webshim.warn('mimetype to moxie error: '+e);
+ }
+
+ });
+
+ webshim.addReady(function(context, contextElem){
+ $(context.querySelectorAll(sel)).add(contextElem.filter(sel)).each(createFilePicker);
+ });
+ webshim.ready('WINDOWLOAD', loadMoxie);
+
+ if(webshim.cfg.debug !== false && featureOptions.swfpath.indexOf((location.protocol+'//'+location.hostname)) && featureOptions.swfpath.indexOf(('https://'+location.hostname))){
+ webshim.ready('WINDOWLOAD', function(){
+
+ var printMessage = function(){
+ if(hasXDomain == 'no'){
+ webshim.error(crossXMLMessage);
+ }
+ };
+
+ try {
+ hasXDomain = sessionStorage.getItem('wsXdomain.xml');
+ } catch(e){}
+ printMessage();
+ if(hasXDomain == null){
+ $.ajax({
+ url: 'crossdomain.xml',
+ type: 'HEAD',
+ dataType: 'xml',
+ success: function(){
+ hasXDomain = 'yes';
+ },
+ error: function(){
+ hasXDomain = 'no';
+ },
+ complete: function(){
+ try {
+ sessionStorage.setItem('wsXdomain.xml', hasXDomain);
+ } catch(e){}
+ printMessage();
+ }
+ });
+ }
+ });
+ }
});