From c50b74372c398b0c85164ad01977c5118b55d418 Mon Sep 17 00:00:00 2001 From: Alex Sexton Date: Sun, 23 Jan 2011 21:19:33 -0600 Subject: [PATCH 001/123] Moved jQuery global leak to end of file so accidental gEBCN overrides in prototype don't get caught up in confusion. Fixed tests to reference jQuery variable instead of $ (best practice). Fixes #8033 --- src/core.js | 2 +- src/outro.js | 1 + test/data/offset/absolute.html | 2 +- test/data/offset/body.html | 4 ++-- test/data/offset/fixed.html | 4 ++-- test/data/offset/relative.html | 4 ++-- test/data/offset/scroll.html | 4 ++-- test/data/offset/static.html | 4 ++-- test/data/offset/table.html | 4 ++-- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/core.js b/src/core.js index 520db45e..92ebb13e 100644 --- a/src/core.js +++ b/src/core.js @@ -1054,6 +1054,6 @@ function doScrollCheck() { } // Expose jQuery to the global object -return (window.jQuery = window.$ = jQuery); +return jQuery; })(); diff --git a/src/outro.js b/src/outro.js index 7773a74f..32b0d087 100644 --- a/src/outro.js +++ b/src/outro.js @@ -1 +1,2 @@ +window.jQuery = window.$ = jQuery; })(window); diff --git a/test/data/offset/absolute.html b/test/data/offset/absolute.html index dc0ba22f..b4db30a6 100644 --- a/test/data/offset/absolute.html +++ b/test/data/offset/absolute.html @@ -26,7 +26,7 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From fa4c90987fc9aede4de3f41976cda91acad81736 Mon Sep 17 00:00:00 2001 From: rwldrn Date: Tue, 1 Feb 2011 17:54:02 -0500 Subject: [PATCH 044/123] Fixes #8129. Fix cloning multiple selected options in IE8. --- src/manipulation.js | 4 ++-- test/unit/manipulation.js | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index 1ef19f83..19a6c22b 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -503,6 +503,8 @@ jQuery.extend({ // proprietary methods to clear the events. Thanks to MooTools // guys for this hotness. + cloneFixAttributes( elem, clone ); + // Using Sizzle here is crazy slow, so we use getElementsByTagName // instead srcElements = elem.getElementsByTagName("*"); @@ -514,8 +516,6 @@ jQuery.extend({ for ( i = 0; srcElements[i]; ++i ) { cloneFixAttributes( srcElements[i], destElements[i] ); } - - cloneFixAttributes( elem, clone ); } // Copy the events from the original to the clone diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index e0710869..1313783e 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -1006,7 +1006,7 @@ test("clone()", function() { test("clone(form element) (Bug #3879, #6655)", function() { expect(6); - element = jQuery(""); + var element = jQuery(""); equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" ); @@ -1026,6 +1026,14 @@ test("clone(form element) (Bug #3879, #6655)", function() { equals( clone[0].defaultValue, "foo", "Textarea defaultValue cloned correctly" ); }); +test("clone(multiple selected options) (Bug #8129)", function() { + expect(1); + var element = jQuery(""); + + equals( element.clone().find("option:selected").length, element.find("option:selected").length, "Multiple selected options cloned correctly" ); + +}); + if (!isLocal) { test("clone() on XML nodes", function() { expect(2); From fdd4101fe93321f33b916a92b5def1328ea331b3 Mon Sep 17 00:00:00 2001 From: Anton Kovalyov Date: Wed, 2 Feb 2011 00:32:29 +0100 Subject: [PATCH 045/123] Fixes #7945. Make jQuery.param() serialize plain objects with a property named jquery correctly. --- src/ajax.js | 2 +- test/unit/ajax.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 4c3f1dd5..1a19d0ca 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -698,7 +698,7 @@ jQuery.extend({ } // If an array was passed in, assume that it is an array of form elements. - if ( jQuery.isArray( a ) || a.jquery ) { + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); diff --git a/test/unit/ajax.js b/test/unit/ajax.js index 30418347..b8103138 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -930,7 +930,7 @@ test("serialize()", function() { }); test("jQuery.param()", function() { - expect(23); + expect(25); equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" ); @@ -965,6 +965,11 @@ test("jQuery.param()", function() { equals( jQuery.param({"foo": {"bar": [], foo: 1} }), "foo%5Bbar%5D=&foo%5Bfoo%5D=1", "Empty array param" ); equals( jQuery.param({"foo": {"bar": {}} }), "foo%5Bbar%5D=", "Empty object param" ); + // #7945 + equals( jQuery.param({"jquery": "1.4.2"}), "jquery=1.4.2", "Check that object with a jQuery property get serialized correctly" ); + + equals( jQuery.param(jQuery("#form :input")), "action=Test&text2=Test&radio1=on&radio2=on&check=on&=on&hidden=&foo%5Bbar%5D=&name=name&search=search&button=&=foobar&select1=&select2=3&select3=1&select4=1&select5=3", "Make sure jQuery objects are properly serialized"); + jQuery.ajaxSetup({ traditional: true }); var params = {foo:"bar", baz:42, quux:"All your base are belong to us"}; From 462bb1f66abf239492ee33c60feee3402fe64f77 Mon Sep 17 00:00:00 2001 From: Mathias Bynens Date: Mon, 24 Jan 2011 11:18:57 +0100 Subject: [PATCH 046/123] Fixes #8098. Use the fast document.head when available. Don't set unneeded "script.type = text/javascript". --- speed/jquery-basis.js | 6 ++---- src/ajax/script.js | 2 +- src/core.js | 6 ++---- src/manipulation.js | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/speed/jquery-basis.js b/speed/jquery-basis.js index fff67764..6fe017c1 100644 --- a/speed/jquery-basis.js +++ b/speed/jquery-basis.js @@ -524,11 +524,9 @@ jQuery.extend({ if ( data && rnotwhite.test(data) ) { // Inspired by code by Andrea Giammarchi // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, + var head = document.head || document.getElementsByTagName("head")[0] || document.documentElement, script = document.createElement("script"); - script.type = "text/javascript"; - if ( jQuery.support.scriptEval ) { script.appendChild( document.createTextNode( data ) ); } else { @@ -5060,7 +5058,7 @@ jQuery.extend({ // If we're requesting a remote document // and trying to load JSON or Script with a GET if ( s.dataType === "script" && type === "GET" && remote ) { - var head = document.getElementsByTagName("head")[0] || document.documentElement; + var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; var script = document.createElement("script"); script.src = s.url; if ( s.scriptCharset ) { diff --git a/src/ajax/script.js b/src/ajax/script.js index 731f5b60..34ddd046 100644 --- a/src/ajax/script.js +++ b/src/ajax/script.js @@ -34,7 +34,7 @@ jQuery.ajaxTransport( "script", function(s) { if ( s.crossDomain ) { var script, - head = document.getElementsByTagName( "head" )[ 0 ] || document.documentElement; + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; return { diff --git a/src/core.js b/src/core.js index 915ac6ba..2e634723 100644 --- a/src/core.js +++ b/src/core.js @@ -574,10 +574,8 @@ jQuery.extend({ if ( data && rnotwhite.test(data) ) { // Inspired by code by Andrea Giammarchi // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; + var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement, + script = document.createElement( "script" ); if ( jQuery.support.scriptEval() ) { script.appendChild( document.createTextNode( data ) ); diff --git a/src/manipulation.js b/src/manipulation.js index 19a6c22b..841447fa 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -7,7 +7,7 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, rtbody = /", "" ], From b90369e8cb2b6f3cc0afa34d815958ff0b605874 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Wed, 2 Feb 2011 13:33:02 +0100 Subject: [PATCH 047/123] Fixes #8135. Makes sure any exception thrown by Firefox when trying to access an XMLHttpRequest property when a network error occured is caught and notified as an error. Added test/networkerror.html to test the behavior. --- src/ajax/xhr.js | 137 +++++++++++++++++++++++------------------ test/networkerror.html | 101 ++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 60 deletions(-) create mode 100644 test/networkerror.html diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 47cfc6c3..c0368b95 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -115,76 +115,93 @@ if ( jQuery.support.ajax ) { // Listener callback = function( _, isAbort ) { - // Was never called and is aborted or complete - if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + var status, + statusText, + responseHeaders, + responses, + xml; - // Only called once - callback = 0; + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occured + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { - // Do not keep as active anymore - if ( handle ) { - xhr.onreadystatechange = jQuery.noop; - delete xhrs[ handle ]; - } + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { - // If it's an abort - if ( isAbort ) { - // Abort it manually if needed - if ( xhr.readyState !== 4 ) { - xhr.abort(); + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + delete xhrs[ handle ]; } - } else { - // Get info - var status = xhr.status, - statusText, - responseHeaders = xhr.getAllResponseHeaders(), - responses = {}, + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + // Get info + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; xml = xhr.responseXML; - // Construct response list - if ( xml && xml.documentElement /* #4958 */ ) { - responses.xml = xml; - } - responses.text = xhr.responseText; + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + responses.text = xhr.responseText; - // Firefox throws an exception when accessing - // statusText for faulty cross-domain requests - try { - statusText = xhr.statusText; - } catch( e ) { - // We normalize with Webkit giving an empty statusText - statusText = ""; - } + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } - // Filter status for non standard behaviors - status = - // Most browsers return 0 when it should be 200 for local files - // Opera returns 0 when it should be 304 - // Webkit returns 0 for failing cross-domain no matter the real status - !status ? - // All: for local files, 0 is a success - ( location.protocol === "file:" ? 200 : ( - // Webkit, Firefox: filter out faulty cross-domain requests - !s.crossDomain || statusText ? + // Filter status for non standard behaviors + status = + // Most browsers return 0 when it should be 200 for local files + // Opera returns 0 when it should be 304 + // Webkit returns 0 for failing cross-domain no matter the real status + !status ? + // All: for local files, 0 is a success + ( location.protocol === "file:" ? 200 : ( + // Webkit, Firefox: filter out faulty cross-domain requests + !s.crossDomain || statusText ? + ( + // Opera: filter out real aborts #6060 + responseHeaders ? + 304 : + 0 + ) : + // We assume 302 but could be anything cross-domain related + 302 + ) ) : ( - // Opera: filter out real aborts #6060 - responseHeaders ? - 304 : - 0 - ) : - // We assume 302 but could be anything cross-domain related - 302 - ) ) : - ( - // IE sometimes returns 1223 when it should be 204 (see #1450) - status == 1223 ? - 204 : - status - ); - - // Call complete - complete( status, statusText, responses, responseHeaders ); + // IE sometimes returns 1223 when it should be 204 (see #1450) + status == 1223 ? + 204 : + status + ); + } } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); } }; diff --git a/test/networkerror.html b/test/networkerror.html new file mode 100644 index 00000000..b06a6ba4 --- /dev/null +++ b/test/networkerror.html @@ -0,0 +1,101 @@ + + + + + + jQuery Network Error Test for Firefox + + + + + + + + + + + + + + + + + + + + + + + +

+ jQuery Network Error Test for Firefox +

+
+ This is a test page for + + #8135 + + which was reported in Firefox when accessing properties + of an XMLHttpRequest object after a network error occured. +
+
Take the following steps:
+
    +
  1. + make sure you accessed this page through a web server, +
  2. +
  3. + stop the web server, +
  4. +
  5. + open the console, +
  6. +
  7. + click this + + , +
  8. +
  9. + wait for both requests to fail. +
  10. +
+
+ Test passes if you get two log lines: +
    +
  • + the first starting with "abort", +
  • +
  • + the second starting with "complete", +
  • +
+
+
+ Test fails if the browser notifies an exception. +
+ + \ No newline at end of file From e3cc440934fcb03bfeb10fb6281615409ad6f483 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Wed, 2 Feb 2011 20:52:26 +0100 Subject: [PATCH 048/123] Fixes #8138. Access to document.location is made only once at load time and if it fails (throwing an exception in IE when document.domain is already set), we use the href of an A element instead. --- src/ajax.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 1a19d0ca..2d20040a 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -34,7 +34,22 @@ var r20 = /%20/g, * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ - transports = {}; + transports = {}, + + // Stored document location array + ajaxLocation; + +// #8138, IE may throw an exception when accessing +// a field from document.location if document.domain has been set +try { + ajaxLocation = document.location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { @@ -260,7 +275,7 @@ jQuery.extend({ }, ajaxSettings: { - url: location.href, + url: ajaxLocation, global: true, type: "GET", contentType: "application/x-www-form-urlencoded", @@ -361,8 +376,6 @@ jQuery.extend({ // timeout handle timeoutTimer, // Cross-domain detection vars - loc = document.location, - protocol = loc.protocol || "http:", parts, // The jqXHR state state = 0, @@ -549,7 +562,7 @@ jQuery.extend({ // Remove hash character (#7531: and string promotion) // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) // We also use the url parameter if available - s.url = ( "" + ( url || s.url ) ).replace( rhash, "" ).replace( rprotocol, protocol + "//" ); + s.url = ( "" + ( url || s.url ) ).replace( rhash, "" ).replace( rprotocol, ajaxLocation[ 1 ] + "//" ); // Extract dataTypes list s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); @@ -558,9 +571,9 @@ jQuery.extend({ if ( !s.crossDomain ) { parts = rurl.exec( s.url.toLowerCase() ); s.crossDomain = !!( parts && - ( parts[ 1 ] != protocol || parts[ 2 ] != loc.hostname || + ( parts[ 1 ] != ajaxLocation[ 1 ] || parts[ 2 ] != ajaxLocation[ 2 ] || ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != - ( loc.port || ( protocol === "http:" ? 80 : 443 ) ) ) + ( ajaxLocation[ 3 ] || ( ajaxLocation[ 1 ] === "http:" ? 80 : 443 ) ) ) ); } @@ -717,6 +730,9 @@ jQuery.extend({ } }); +// Segment ajaxLocation into parts +ajaxLocation = rurl.exec( ajaxLocation.toLowerCase() ); + function buildParams( prefix, obj, traditional, add ) { if ( jQuery.isArray( obj ) && obj.length ) { // Serialize array item. From 5ef7ddc4c55f49cb7767bba99975f2c7ea5422d9 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Wed, 2 Feb 2011 21:16:26 +0100 Subject: [PATCH 049/123] Fixes #8146 by introducing the xhrFields option with is a map of fieldName/fieldValue to set on the native xhr. Can be used to set withCredentials to true for cross-domain requests if needed. --- src/ajax/xhr.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index c0368b95..3acdc66a 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -82,7 +82,15 @@ if ( jQuery.support.ajax ) { // Get a new xhr var xhr = s.xhr(), - handle; + handle, + i; + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } // Open the socket // Passing null username, generates a login popup on Opera (#2865) From d77a2a2274d34033da8609a26c9cc1f2bd14c879 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 3 Feb 2011 02:53:10 +0100 Subject: [PATCH 050/123] Fixes #8152 by applying the same special cases for protocol "chrome-extension:" as were for "file:" (needs tests). Re-organizes and fixes the handling of special cases for HTTP status code in the xhr transport. Also re-organizes the handling of document.location in ajax.js. --- src/ajax.js | 22 ++++++++++++++-------- src/ajax/xhr.js | 48 +++++++++++++++++++++++------------------------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 2d20040a..08bd9d11 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -6,6 +6,8 @@ var r20 = /%20/g, rhash = /#.*$/, rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + // #8125, #8152: local protocol detection + rlocalProtocol = /^(file|chrome\-extension):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rquery = /\?/, @@ -36,8 +38,11 @@ var r20 = /%20/g, */ transports = {}, - // Stored document location array - ajaxLocation; + // Document location + ajaxLocation, + + // Document location segments + ajaxLocParts; // #8138, IE may throw an exception when accessing // a field from document.location if document.domain has been set @@ -51,6 +56,9 @@ try { ajaxLocation = ajaxLocation.href; } +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ); + // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { @@ -276,6 +284,7 @@ jQuery.extend({ ajaxSettings: { url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), global: true, type: "GET", contentType: "application/x-www-form-urlencoded", @@ -562,7 +571,7 @@ jQuery.extend({ // Remove hash character (#7531: and string promotion) // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) // We also use the url parameter if available - s.url = ( "" + ( url || s.url ) ).replace( rhash, "" ).replace( rprotocol, ajaxLocation[ 1 ] + "//" ); + s.url = ( "" + ( url || s.url ) ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); // Extract dataTypes list s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); @@ -571,9 +580,9 @@ jQuery.extend({ if ( !s.crossDomain ) { parts = rurl.exec( s.url.toLowerCase() ); s.crossDomain = !!( parts && - ( parts[ 1 ] != ajaxLocation[ 1 ] || parts[ 2 ] != ajaxLocation[ 2 ] || + ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != - ( ajaxLocation[ 3 ] || ( ajaxLocation[ 1 ] === "http:" ? 80 : 443 ) ) ) + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) ); } @@ -730,9 +739,6 @@ jQuery.extend({ } }); -// Segment ajaxLocation into parts -ajaxLocation = rurl.exec( ajaxLocation.toLowerCase() ); - function buildParams( prefix, obj, traditional, add ) { if ( jQuery.isArray( obj ) && obj.length ) { // Serialize array item. diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 3acdc66a..d4c291fc 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -22,7 +22,7 @@ jQuery.ajaxSettings.xhr = window.ActiveXObject ? * we need a fallback. */ function() { - if ( window.location.protocol !== "file:" ) { + if ( !jQuery.ajaxSettings.isLocal ) { try { return new window.XMLHttpRequest(); } catch( xhrError ) {} @@ -175,30 +175,28 @@ if ( jQuery.support.ajax ) { } // Filter status for non standard behaviors - status = - // Most browsers return 0 when it should be 200 for local files - // Opera returns 0 when it should be 304 - // Webkit returns 0 for failing cross-domain no matter the real status - !status ? - // All: for local files, 0 is a success - ( location.protocol === "file:" ? 200 : ( - // Webkit, Firefox: filter out faulty cross-domain requests - !s.crossDomain || statusText ? - ( - // Opera: filter out real aborts #6060 - responseHeaders ? - 304 : - 0 - ) : - // We assume 302 but could be anything cross-domain related - 302 - ) ) : - ( - // IE sometimes returns 1223 when it should be 204 (see #1450) - status == 1223 ? - 204 : - status - ); + + // IE - #1450: sometimes returns 1223 when it should be 204 + if ( status === 1223 ) { + status = 204; + // Status 0 encompasses several cases + } else if ( !status ) { + // Cross-domain + if ( s.crossDomain ) { + if ( !s.statusText ) { + // FF, Webkit (other?): There is no status text for errors + // 302 is the most generic cross-domain status code + // for errors, could be anything really (even a real 0) + status = 302; + } + // All same-domain - #8125, #8152: for local files, 0 is a success + } else if( s.isLocal ) { + status = 200; + } + // Opera - #6060: sets status as 0 for 304 + // and there doesn't seem to be any way to + // detect this case. Patch VERY welcome. + } } } } catch( firefoxAccessException ) { From 823eecab9073b43a283a2500e9e43c3a06cc2495 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 3 Feb 2011 03:02:11 +0100 Subject: [PATCH 051/123] Fixes #8146. Custom fields in xhrFields are now set after the XMLHttpRequest object has been opened. --- src/ajax/xhr.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index d4c291fc..4adf8eb2 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -85,13 +85,6 @@ if ( jQuery.support.ajax ) { handle, i; - // Apply custom fields if provided - if ( s.xhrFields ) { - for ( i in s.xhrFields ) { - xhr[ i ] = s.xhrFields[ i ]; - } - } - // Open the socket // Passing null username, generates a login popup on Opera (#2865) if ( s.username ) { @@ -100,6 +93,13 @@ if ( jQuery.support.ajax ) { xhr.open( s.type, s.url, s.async ); } + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + // Requested-With header // Not set for crossDomain requests with no content // (see why at http://trac.dojotoolkit.org/ticket/9486) From 50e950a96e0fae23a1ae418951a298e2949ff351 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 3 Feb 2011 05:19:15 +0100 Subject: [PATCH 052/123] Fixes #7653. Changes regexp to detect local protocol so that it will accept any protocol finishing by -extension. --- src/ajax.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 08bd9d11..4b3ab768 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -6,8 +6,8 @@ var r20 = /%20/g, rhash = /#.*$/, rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, - // #8125, #8152: local protocol detection - rlocalProtocol = /^(file|chrome\-extension):$/, + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /(?:^file|\-extension):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rquery = /\?/, From ee22a59129e082a2bb9f5bc0b085191ab6faafc8 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 3 Feb 2011 06:12:47 +0100 Subject: [PATCH 053/123] Stores jQuery.ajaxSettings.isLocal locally at load time so that any change to it won't affect the transport. Fixes the url parsing regexp to deal with empty domains. Adds informative text into test/localfile.html and handles Opera's failure. Revises the way xhr are created by doing all tests at load time and normalizes all the xhr creation functions so that none of them may throw an exception. --- src/ajax.js | 2 +- src/ajax/xhr.js | 53 +++++++++++++++++++++++++-------------------- test/localfile.html | 36 +++++++++++++++++++++--------- 3 files changed, 57 insertions(+), 34 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 4b3ab768..2c61cf27 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -15,7 +15,7 @@ var r20 = /%20/g, rselectTextarea = /^(?:select|textarea)/i, rspacesAjax = /\s+/, rts = /([?&])_=[^&]*/, - rurl = /^(\w+:)\/\/([^\/?#:]+)(?::(\d+))?/, + rurl = /^(\w+:)\/\/([^\/?#:]*)(?::(\d+))?/, // Keep a copy of the old load method _load = jQuery.fn.load, diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 4adf8eb2..97db0795 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -1,5 +1,18 @@ (function( jQuery ) { +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject("Microsoft.XMLHTTP"); + } catch( e ) {} +} + var // Next active xhr id xhrId = jQuery.now(), @@ -10,7 +23,11 @@ var // Next active xhr id xhrUnloadAbortInstalled, // XHR used to determine supports properties - testXHR; + testXHR, + + // Keep track of isLocal in case it gets removed + // from ajaxSettings later on + protocolIsLocal = jQuery.ajaxSettings.isLocal; // Create the request object // (This is still attached to ajaxSettings for backward compatibility) @@ -21,28 +38,17 @@ jQuery.ajaxSettings.xhr = window.ActiveXObject ? * Additionally XMLHttpRequest can be disabled in IE7/IE8 so * we need a fallback. */ - function() { - if ( !jQuery.ajaxSettings.isLocal ) { - try { - return new window.XMLHttpRequest(); - } catch( xhrError ) {} + ( protocolIsLocal ? + createActiveXHR : + function() { + return createStandardXHR() || createActiveXHR(); } - - try { - return new window.ActiveXObject("Microsoft.XMLHTTP"); - } catch( activeError ) {} - } : + ) : // For all other browsers, use the standard XMLHttpRequest object - function() { - return new window.XMLHttpRequest(); - }; + createStandardXHR; // Test if we can create an xhr object -try { - testXHR = jQuery.ajaxSettings.xhr(); -} catch( xhrCreationException ) {} - -//Does this browser support XHR requests? +testXHR = jQuery.ajaxSettings.xhr(); jQuery.support.ajax = !!testXHR; // Does this browser support crossDomain XHR requests @@ -189,13 +195,14 @@ if ( jQuery.support.ajax ) { // for errors, could be anything really (even a real 0) status = 302; } - // All same-domain - #8125, #8152: for local files, 0 is a success - } else if( s.isLocal ) { + // All same-domain: for local files, 0 is a success + } else if( protocolIsLocal ) { status = 200; + // Opera: this notifies success for all requests + // (verified in 11.01). Patch welcome. } // Opera - #6060: sets status as 0 for 304 - // and there doesn't seem to be any way to - // detect this case. Patch VERY welcome. + // Patch welcome. } } } diff --git a/test/localfile.html b/test/localfile.html index 80216313..b354612a 100644 --- a/test/localfile.html +++ b/test/localfile.html @@ -25,16 +25,32 @@ +

jQuery Local File Test

+
    +
  • + Access this file using the "file:" protocol. +
  • +
  • + Two lines must appear below. +
  • +
  • + Opera will fail at detecting errors, it's a known issue. +
  • +
\ No newline at end of file From 0736db64a21d961263161c2392dc6a0161bd4e86 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 3 Feb 2011 17:17:56 +0100 Subject: [PATCH 054/123] Adds support for more complex protocol by having the url regexp closer to rfc1738. --- src/ajax.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ajax.js b/src/ajax.js index 2c61cf27..ce27d2de 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -15,7 +15,7 @@ var r20 = /%20/g, rselectTextarea = /^(?:select|textarea)/i, rspacesAjax = /\s+/, rts = /([?&])_=[^&]*/, - rurl = /^(\w+:)\/\/([^\/?#:]*)(?::(\d+))?/, + rurl = /^([\w\+\.\-]+:)\/\/([^\/?#:]*)(?::(\d+))?/, // Keep a copy of the old load method _load = jQuery.fn.load, From 4d808a3345f78fab963be96bf272951745b894e3 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 3 Feb 2011 18:22:37 +0100 Subject: [PATCH 055/123] Don't use a local copy of jQuery.ajaxSettings.isLocal anymore but use the current value so that it is possible to set isLocal to true for protocols unknown to jQuery. --- src/ajax/xhr.js | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 97db0795..91a71de8 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -23,11 +23,7 @@ var // Next active xhr id xhrUnloadAbortInstalled, // XHR used to determine supports properties - testXHR, - - // Keep track of isLocal in case it gets removed - // from ajaxSettings later on - protocolIsLocal = jQuery.ajaxSettings.isLocal; + testXHR; // Create the request object // (This is still attached to ajaxSettings for backward compatibility) @@ -38,12 +34,9 @@ jQuery.ajaxSettings.xhr = window.ActiveXObject ? * Additionally XMLHttpRequest can be disabled in IE7/IE8 so * we need a fallback. */ - ( protocolIsLocal ? - createActiveXHR : - function() { - return createStandardXHR() || createActiveXHR(); - } - ) : + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : // For all other browsers, use the standard XMLHttpRequest object createStandardXHR; @@ -196,7 +189,7 @@ if ( jQuery.support.ajax ) { status = 302; } // All same-domain: for local files, 0 is a success - } else if( protocolIsLocal ) { + } else if( s.isLocal ) { status = 200; // Opera: this notifies success for all requests // (verified in 11.01). Patch welcome. From 7eba4b76dfb4dde3b514281d614d7ac4fedc0289 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 3 Feb 2011 18:23:02 +0100 Subject: [PATCH 056/123] Adds widget as the list of local protocols. --- src/ajax.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ajax.js b/src/ajax.js index ce27d2de..b361a2a7 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -7,7 +7,7 @@ var r20 = /%20/g, rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /(?:^file|\-extension):$/, + rlocalProtocol = /(?:^file|^widget|\-extension):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rquery = /\?/, From d66cc553167c6b00d19aa62a4dd1e9affb20d395 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Fri, 4 Feb 2011 21:50:18 +0100 Subject: [PATCH 057/123] Disables dataType redirection while selecting transport. --- src/ajax.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index b361a2a7..f33bd49a 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -113,9 +113,9 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX for(; i < length && ( executeOnly || !selection ); i++ ) { selection = list[ i ]( options, originalOptions, jqXHR ); // If we got redirected to another dataType - // we try there if not done already + // we try there if executing only and not done already if ( typeof selection === "string" ) { - if ( inspected[ selection ] ) { + if ( !executeOnly || inspected[ selection ] ) { selection = undefined; } else { options.dataTypes.unshift( selection ); From 03bad0a9600f05e61a1464c55354d26fcd8f97a4 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Fri, 4 Feb 2011 22:19:23 +0100 Subject: [PATCH 058/123] Fixes abort in prefilter. No global event will be fired in that case even if the global option is set to true. Unit test added. --- src/ajax.js | 18 ++++++++++++++---- test/unit/ajax.js | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index f33bd49a..e56db83b 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -388,6 +388,8 @@ jQuery.extend({ parts, // The jqXHR state state = 0, + // To know if global events are to be dispatched + fireGlobals, // Loop variable i, // Fake xhr @@ -529,7 +531,7 @@ jQuery.extend({ jqXHR.statusCode( statusCode ); statusCode = undefined; - if ( s.global ) { + if ( fireGlobals ) { globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), [ jqXHR, s, isSuccess ? success : error ] ); } @@ -537,7 +539,7 @@ jQuery.extend({ // Complete completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] ); - if ( s.global ) { + if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { @@ -594,6 +596,14 @@ jQuery.extend({ // Apply prefilters inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + // If request was aborted inside a prefiler, stop there + if ( state === 2 ) { + return false; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + // Uppercase the type s.type = s.type.toUpperCase(); @@ -601,7 +611,7 @@ jQuery.extend({ s.hasContent = !rnoContent.test( s.type ); // Watch for a new set of requests - if ( s.global && jQuery.active++ === 0 ) { + if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } @@ -678,7 +688,7 @@ jQuery.extend({ // Set state as sending state = jqXHR.readyState = 1; // Send global event - if ( s.global ) { + if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // Timeout diff --git a/test/unit/ajax.js b/test/unit/ajax.js index b8103138..57e65124 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -2177,6 +2177,25 @@ test("jQuery.ajax - transitive conversions", function() { }); +test("jQuery.ajax - abort in prefilter", function() { + + expect( 1 ); + + jQuery.ajaxPrefilter(function( options, _, jqXHR ) { + if ( options.abortInPrefilter ) { + jqXHR.abort(); + } + }); + + strictEqual( jQuery.ajax({ + abortInPrefilter: true, + error: function() { + ok( false, "error callback called" ); + } + }), false, "Request was properly aborted early by the prefilter" ); + +}); + test("jQuery.ajax - active counter", function() { ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active ); }); From 8f8961de90453274ac194479272a8dfa99ffab17 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Fri, 4 Feb 2011 22:29:10 +0100 Subject: [PATCH 059/123] Reformats logic for early abort in beforeSend to limit block imbrication. --- src/ajax.js | 73 ++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index e56db83b..4830e3df 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -667,50 +667,49 @@ jQuery.extend({ // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { // Abort if not done already - done( 0, "abort" ); - // Return false - jqXHR = false; + jqXHR.abort(); + return false; + } + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); } else { - - // Install callbacks on deferreds - for ( i in { success: 1, error: 1, complete: 1 } ) { - jqXHR[ i ]( s[ i ] ); + // Set state as sending + state = jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); } - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - // Set state as sending - state = jqXHR.readyState = 1; - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = setTimeout( function(){ - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - transport.send( requestHeaders, done ); - } catch (e) { - // Propagate exception as error if not done - if ( status < 2 ) { - done( -1, e ); - // Simply rethrow otherwise - } else { - jQuery.error( e ); - } + try { + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( status < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + jQuery.error( e ); } } } + return jqXHR; }, From 08fcde6a59e5bb6ca9e58bf78aac64ff2c15c29d Mon Sep 17 00:00:00 2001 From: Anton M Date: Sat, 5 Feb 2011 00:20:23 +0100 Subject: [PATCH 060/123] Remove an invalid ajax test and some code that is no longer used by any test. --- test/data/name.php | 7 +------ test/data/notmodified.php | 1 - test/unit/ajax.js | 15 --------------- 3 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 test/data/notmodified.php diff --git a/test/data/name.php b/test/data/name.php index ee22e458..64028585 100644 --- a/test/data/name.php +++ b/test/data/name.php @@ -19,11 +19,6 @@ if($name == 'foo') { echo "pan"; die(); } -$request = apache_request_headers(); -$request = $request['X-Custom-Header']; -if(strlen($request) > 0) { - echo $request; - die(); -} + echo 'ERROR '; ?> \ No newline at end of file diff --git a/test/data/notmodified.php b/test/data/notmodified.php deleted file mode 100644 index 0309a6bc..00000000 --- a/test/data/notmodified.php +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/unit/ajax.js b/test/unit/ajax.js index 57e65124..c2d57290 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -524,21 +524,6 @@ test("jQuery ajax - cross-domain detection", function() { }); -test(".ajax() - 304", function() { - expect( 1 ); - stop(); - - jQuery.ajax({ - url: url("data/notmodified.php"), - success: function(){ ok(true, "304 ok"); }, - // Do this because opera simply refuses to implement 304 handling :( - // A feature-driven way of detecting this would be appreciated - // See: http://gist.github.com/599419 - error: function(){ ok(jQuery.browser.opera, "304 not ok "); }, - complete: function(xhr){ start(); } - }); -}); - test(".load()) - 404 error callbacks", function() { expect( 6 ); stop(); From 2c77704b145a24ad39648740466ed015fd4163dc Mon Sep 17 00:00:00 2001 From: jaubourg Date: Sat, 5 Feb 2011 03:06:21 +0100 Subject: [PATCH 061/123] Fixes a typo in the title of the load() unit test. --- test/unit/ajax.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/ajax.js b/test/unit/ajax.js index c2d57290..cf7c0ad0 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -524,7 +524,7 @@ test("jQuery ajax - cross-domain detection", function() { }); -test(".load()) - 404 error callbacks", function() { +test(".load() - 404 error callbacks", function() { expect( 6 ); stop(); From d6fbbe1080fdcaf8eb22753eddf000aeb7d99545 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Sat, 5 Feb 2011 03:08:35 +0100 Subject: [PATCH 062/123] Fixes #8177. XHR transport now considers 304 Not Modified responses as 200 OK if no conditional request header was provided (as per the XMLHttpRequest specification). --- src/ajax/xhr.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 91a71de8..b18274c4 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -178,6 +178,12 @@ if ( jQuery.support.ajax ) { // IE - #1450: sometimes returns 1223 when it should be 204 if ( status === 1223 ) { status = 204; + // Various - #8177: a Not Modified response was received + // yet no conditional request headers was provided + } else if ( status === 304 && + !headers[ "if-modified-since" ] && + !headers[ "if-none-match" ] ) { + status = 200; // Status 0 encompasses several cases } else if ( !status ) { // Cross-domain From 0c21c83e9691a08151f23a2c594568b07009f063 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Mon, 7 Feb 2011 06:11:52 +0100 Subject: [PATCH 063/123] Makes sure xhrs are actually aborted on unload in IE. Simplifies active xhrs caching in the process. --- src/ajax/xhr.js | 60 +++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index b18274c4..1f136c34 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -1,5 +1,22 @@ (function( jQuery ) { +var // #5280: next active xhr id and list of active xhrs' callbacks + xhrId = jQuery.now(), + xhrCallbacks, + + // XHR used to determine supports properties + testXHR; + +// #5280: Internet Explorer will keep connections alive if we don't abort on unload +function xhrOnUnloadAbort() { + jQuery( window ).unload(function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + }); +} + // Functions to create xhrs function createStandardXHR() { try { @@ -13,18 +30,6 @@ function createActiveXHR() { } catch( e ) {} } -var // Next active xhr id - xhrId = jQuery.now(), - - // active xhrs - xhrs = {}, - - // #5280: see below - xhrUnloadAbortInstalled, - - // XHR used to determine supports properties - testXHR; - // Create the request object // (This is still attached to ajaxSettings for backward compatibility) jQuery.ajaxSettings.xhr = window.ActiveXObject ? @@ -62,23 +67,6 @@ if ( jQuery.support.ajax ) { return { send: function( headers, complete ) { - // #5280: we need to abort on unload or IE will keep connections alive - if ( !xhrUnloadAbortInstalled ) { - - xhrUnloadAbortInstalled = 1; - - jQuery(window).bind( "unload", function() { - - // Abort all pending requests - jQuery.each( xhrs, function( _, xhr ) { - if ( xhr.onreadystatechange ) { - xhr.onreadystatechange( 1 ); - } - } ); - - } ); - } - // Get a new xhr var xhr = s.xhr(), handle, @@ -142,7 +130,7 @@ if ( jQuery.support.ajax ) { // Do not keep as active anymore if ( handle ) { xhr.onreadystatechange = jQuery.noop; - delete xhrs[ handle ]; + delete xhrCallbacks[ handle ]; } // If it's an abort @@ -152,7 +140,6 @@ if ( jQuery.support.ajax ) { xhr.abort(); } } else { - // Get info status = xhr.status; responseHeaders = xhr.getAllResponseHeaders(); responses = {}; @@ -223,10 +210,15 @@ if ( jQuery.support.ajax ) { if ( !s.async || xhr.readyState === 4 ) { callback(); } else { - // Add to list of active xhrs + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + xhrOnUnloadAbort(); + } + // Add to list of active xhrs callbacks handle = xhrId++; - xhrs[ handle ] = xhr; - xhr.onreadystatechange = callback; + xhr.onreadystatechange = xhrCallbacks[ handle ] = callback; } }, From a2dbdc1f5438a857c2a9898bd36e4b2de685742e Mon Sep 17 00:00:00 2001 From: jaubourg Date: Mon, 7 Feb 2011 16:35:32 +0100 Subject: [PATCH 064/123] Fixes a bug that prevented headers from being set in an ajaxSend callback. Unit test modified. --- src/ajax.js | 4 ++-- test/unit/ajax.js | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 4830e3df..2b6b80f9 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -684,8 +684,7 @@ jQuery.extend({ if ( !transport ) { done( -1, "No Transport" ); } else { - // Set state as sending - state = jqXHR.readyState = 1; + jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); @@ -698,6 +697,7 @@ jQuery.extend({ } try { + state = 1; transport.send( requestHeaders, done ); } catch (e) { // Propagate exception as error if not done diff --git a/test/unit/ajax.js b/test/unit/ajax.js index cf7c0ad0..59159c32 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -348,10 +348,14 @@ test(".ajax() - headers" , function() { stop(); + jQuery('#foo').ajaxSend(function( evt, xhr ) { + xhr.setRequestHeader( "ajax-send", "test" ); + }); + var requestHeaders = { - siMPle: "value", - "SometHing-elsE": "other value", - OthEr: "something else" + siMPle: "value", + "SometHing-elsE": "other value", + OthEr: "something else" }, list = [], i; @@ -359,22 +363,25 @@ test(".ajax() - headers" , function() { for( i in requestHeaders ) { list.push( i ); } + list.push( "ajax-send" ); jQuery.ajax(url("data/headers.php?keys="+list.join( "_" ) ), { + headers: requestHeaders, success: function( data , _ , xhr ) { var tmp = []; for ( i in requestHeaders ) { tmp.push( i , ": " , requestHeaders[ i ] , "\n" ); } + tmp.push( "ajax-send: test\n" ); tmp = tmp.join( "" ); equals( data , tmp , "Headers were sent" ); equals( xhr.getResponseHeader( "Sample-Header" ) , "Hello World" , "Sample header received" ); - start(); }, error: function(){ ok(false, "error"); } - }); + + }).then( start, start ); }); From 5b421fed003e6704bd0fbba2dea5c1b6add2cf52 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Mon, 7 Feb 2011 17:09:47 +0100 Subject: [PATCH 065/123] Adds jQuery collection to objects that will be used as global events context if provided in the ajax options. --- src/ajax.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 2b6b80f9..76f98349 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -365,9 +365,10 @@ jQuery.extend({ ( s.context = ( "context" in options ? options : jQuery.ajaxSettings ).context ) || s, // Context for global events // It's the callbackContext if one was provided in the options - // and if it's a DOM node - globalEventContext = callbackContext !== s && callbackContext.nodeType ? - jQuery( callbackContext ) : jQuery.event, + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery._Deferred(), From 7acb141ed7f2dedd950bb65acf878098640d081e Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Mon, 7 Feb 2011 10:48:38 -0600 Subject: [PATCH 066/123] Update $.data to use a function instead of an object when attaching to JS objects in order to hide attached metadata from JSON.stringify. Remove event.js code that was doing this before specifically for events, which is now redundant. Fixes #8108. 1.5-stable --- src/data.js | 6 +++-- src/event.js | 56 ++++++++++------------------------------------ test/unit/data.js | 23 +++++++++++++++---- test/unit/event.js | 5 ++--- 4 files changed, 37 insertions(+), 53 deletions(-) diff --git a/src/data.js b/src/data.js index 21f0e3a5..faa44f3d 100644 --- a/src/data.js +++ b/src/data.js @@ -63,12 +63,14 @@ jQuery.extend({ } if ( !cache[ id ] ) { - cache[ id ] = {}; + // Use a Function as the cache object instead of an Object on JS objects + // as a hack to prevent JSON.stringify from serializing it (#8108) + cache[ id ] = isNode ? {} : function () {}; } // An object can be passed to jQuery.data instead of a key/value pair; this gets // shallow copied over onto the existing cache - if ( typeof name === "object" ) { + if ( typeof name === "object" || typeof name === "function" ) { if ( pvt ) { cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); } else { diff --git a/src/event.js b/src/event.js index 2d53562a..f3a5d9f4 100644 --- a/src/event.js +++ b/src/event.js @@ -7,8 +7,7 @@ var rnamespaces = /\.(.*)$/, rescape = /[^\w\s.|`]/g, fcleanup = function( nm ) { return nm.replace(rescape, "\\$&"); - }, - eventKey = "events"; + }; /* * A number of helper functions used for managing events. @@ -58,23 +57,10 @@ jQuery.event = { return; } - var events = elemData[ eventKey ], + var events = elemData.events, eventHandle = elemData.handle; - if ( typeof events === "function" ) { - // On plain objects events is a fn that holds the the data - // which prevents this data from being JSON serialized - // the function does not need to be called, it just contains the data - eventHandle = events.handle; - events = events.events; - - } else if ( !events ) { - if ( !elem.nodeType ) { - // On plain objects, create a fn that acts as the holder - // of the values to avoid JSON serialization of event data - elemData[ eventKey ] = elemData = function(){}; - } - + if ( !events ) { elemData.events = events = {}; } @@ -175,17 +161,12 @@ jQuery.event = { var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - events = elemData && elemData[ eventKey ]; + events = elemData && elemData.events; if ( !elemData || !events ) { return; } - if ( typeof events === "function" ) { - elemData = events; - events = events.events; - } - // types is actually an event object here if ( types && types.type ) { handler = types.handler; @@ -285,10 +266,7 @@ jQuery.event = { delete elemData.events; delete elemData.handle; - if ( typeof elemData === "function" ) { - jQuery.removeData( elem, eventKey, true ); - - } else if ( jQuery.isEmptyObject( elemData ) ) { + if ( jQuery.isEmptyObject( elemData ) ) { jQuery.removeData( elem, undefined, true ); } } @@ -329,7 +307,7 @@ jQuery.event = { // points to jQuery.expando var internalKey = jQuery.expando, internalCache = this[ internalKey ]; - if ( internalCache && internalCache.events && internalCache.events[type] ) { + if ( internalCache && internalCache.events && internalCache.events[ type ] ) { jQuery.event.trigger( event, data, internalCache.handle.elem ); } }); @@ -355,9 +333,7 @@ jQuery.event = { event.currentTarget = elem; // Trigger the event, it is assumed that "handle" is a function - var handle = elem.nodeType ? - jQuery._data( elem, "handle" ) : - (jQuery._data( elem, eventKey ) || {}).handle; + var handle = jQuery._data( elem, "handle" ); if ( handle ) { handle.apply( elem, data ); @@ -435,11 +411,7 @@ jQuery.event = { event.namespace = event.namespace || namespace_sort.join("."); - events = jQuery._data(this, eventKey); - - if ( typeof events === "function" ) { - events = events.events; - } + events = jQuery._data(this, "events"); handlers = (events || {})[ event.type ]; @@ -606,7 +578,7 @@ jQuery.Event = function( src ) { // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || + this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; // Event type @@ -880,8 +852,8 @@ if ( document.addEventListener ) { jQuery.event.special[ fix ] = { setup: function() { this.addEventListener( orig, handler, true ); - }, - teardown: function() { + }, + teardown: function() { this.removeEventListener( orig, handler, true ); } }; @@ -1074,11 +1046,7 @@ function liveHandler( event ) { var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, elems = [], selectors = [], - events = jQuery._data( this, eventKey ); - - if ( typeof events === "function" ) { - events = events.events; - } + events = jQuery._data( this, "events" ); // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { diff --git a/test/unit/data.js b/test/unit/data.js index 889fc2da..1ce512c4 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -22,7 +22,7 @@ function dataTests (elem) { strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists initially" ); var dataObj = jQuery.data(elem); - equals( typeof dataObj, "object", "Calling data with no args gives us a data object reference" ); + equals( typeof dataObj, elem.nodeType ? "object" : "function", "Calling data with no args gives us a data object reference" ); strictEqual( jQuery.data(elem), dataObj, "Calling jQuery.data returns the same data object when called multiple times" ); strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists even when an empty data obj exists" ); @@ -187,8 +187,12 @@ test(".data()", function() { equals( nodiv.data(), null, "data() on empty set returns null" ); var obj = { foo: "bar" }; - deepEqual( jQuery(obj).data(), {}, "Retrieve data object from a wrapped JS object (#7524)" ); -}) + jQuery(obj).data("foo", "baz"); + + var dataObj = jQuery.extend(true, {}, jQuery(obj).data()); + + deepEqual( dataObj, { foo: "baz" }, "Retrieve data object from a wrapped JS object (#7524)" ); +}); test(".data(String) and .data(String, Object)", function() { expect(29); @@ -461,4 +465,15 @@ test(".removeData()", function() { div.removeData("test.foo"); equals( div.data("test.foo"), undefined, "Make sure data is intact" ); -}); \ No newline at end of file +}); + +if (window.JSON && window.JSON.stringify) { + test("JSON serialization (#8108)", function () { + expect(1); + + var obj = { foo: "bar" }; + jQuery.data(obj, "hidden", true); + + equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" ); + }); +} \ No newline at end of file diff --git a/test/unit/event.js b/test/unit/event.js index e4caee82..045ea73b 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -312,7 +312,7 @@ test("bind/delegate bubbling, isDefaultPrevented", function() { // Use a native click so we don't get jQuery simulated bubbling if ( document.createEvent ) { var e = document.createEvent( 'MouseEvents' ); - e.initEvent( "click", true, true ); + e.initEvent( "click", true, true ); $jq[0].dispatchEvent(e); } else if ( $jq[0].click ) { @@ -548,7 +548,7 @@ test("bind(name, false), unbind(name, false)", function() { }); test("bind()/trigger()/unbind() on plain object", function() { - expect( 8 ); + expect( 7 ); var obj = {}; @@ -570,7 +570,6 @@ test("bind()/trigger()/unbind() on plain object", function() { var events = jQuery._data(obj, "events"); ok( events, "Object has events bound." ); equals( obj.events, undefined, "Events object on plain objects is not events" ); - equals( typeof events, "function", "'events' expando is a function on plain objects." ); equals( obj.test, undefined, "Make sure that test event is not on the plain object." ); equals( obj.handle, undefined, "Make sure that the event handler is not on the plain object." ); From 534dbd660eaefbbc5827b1b61ba384e768562086 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Mon, 7 Feb 2011 10:56:48 -0600 Subject: [PATCH 067/123] Update jQuery.support.noCloneEvent test to function properly in IE9. Fixes #8052. 1.5-stable --- src/support.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/support.js b/src/support.js index 4807ce27..8b60abd2 100644 --- a/src/support.js +++ b/src/support.js @@ -114,7 +114,7 @@ jQuery.support.deleteExpando = false; } - if ( div.attachEvent && div.fireEvent ) { + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { div.attachEvent("onclick", function click() { // Cloning a node shouldn't copy over any // bound event handlers (IE does this) From 4a828c93d40eb67b2041b08bbed0f1973442bd03 Mon Sep 17 00:00:00 2001 From: Anton M Date: Tue, 8 Feb 2011 16:57:06 +0100 Subject: [PATCH 068/123] Make sure that mousing over Chrome "internal div" elements results in no trigger of a mouseleave. Fixes #8209. --- src/event.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/event.js b/src/event.js index f3a5d9f4..a17cf894 100644 --- a/src/event.js +++ b/src/event.js @@ -652,13 +652,15 @@ var withinElement = function( event ) { // Firefox sometimes assigns relatedTarget a XUL element // which we cannot access the parentNode property of + // Chrome does something similar, the parentNode property + // can be accessed but is null. try { // Traverse up the tree while ( parent && parent !== this ) { parent = parent.parentNode; } - if ( parent !== this ) { + if ( parent && parent !== this ) { // set the correct event type event.type = event.data; From 944e0e6498396bb1add67b9b0d0b13dc465d393b Mon Sep 17 00:00:00 2001 From: Anton M Date: Tue, 8 Feb 2011 17:08:25 +0100 Subject: [PATCH 069/123] Revert "Make sure that mousing over Chrome "internal div" elements results in no trigger of a mouseleave." This reverts commit 4a828c93d40eb67b2041b08bbed0f1973442bd03. --- src/event.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/event.js b/src/event.js index a17cf894..f3a5d9f4 100644 --- a/src/event.js +++ b/src/event.js @@ -652,15 +652,13 @@ var withinElement = function( event ) { // Firefox sometimes assigns relatedTarget a XUL element // which we cannot access the parentNode property of - // Chrome does something similar, the parentNode property - // can be accessed but is null. try { // Traverse up the tree while ( parent && parent !== this ) { parent = parent.parentNode; } - if ( parent && parent !== this ) { + if ( parent !== this ) { // set the correct event type event.type = event.data; From b46dff39c35ae05f92f6909ff8d07aa470e4a8d4 Mon Sep 17 00:00:00 2001 From: Anton M Date: Tue, 8 Feb 2011 17:15:55 +0100 Subject: [PATCH 070/123] Make sure that mousing over Chrome "internal div" doesn't trigger a mouseleave. Fixes #8209. Follow up to https://github.com/jquery/jquery/commit/4a828c93d40eb67b2041b08bbed0f1973442bd03 which was stupid and got reversed. --- src/event.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/event.js b/src/event.js index f3a5d9f4..a15603fc 100644 --- a/src/event.js +++ b/src/event.js @@ -653,6 +653,12 @@ var withinElement = function( event ) { // Firefox sometimes assigns relatedTarget a XUL element // which we cannot access the parentNode property of try { + + // Chrome does something similar, the parentNode property + // can be accessed but is null. + if ( parent !== document && !parent.parentNode ) { + return; + } // Traverse up the tree while ( parent && parent !== this ) { parent = parent.parentNode; From d92dc2902c1e49642ce5148f7e082d880e77a2c5 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Tue, 8 Feb 2011 12:13:27 -0600 Subject: [PATCH 071/123] Revert portions of 7acb141ed7f2dedd950bb65acf878098640d081e that attempt to use a function to hide jQuery metadata from JSON.stringify since this does not work reliably cross-browser (fails in Fx3.5, O11, Saf4). --- src/data.js | 4 +--- test/unit/data.js | 15 ++------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/data.js b/src/data.js index faa44f3d..9fee459a 100644 --- a/src/data.js +++ b/src/data.js @@ -63,9 +63,7 @@ jQuery.extend({ } if ( !cache[ id ] ) { - // Use a Function as the cache object instead of an Object on JS objects - // as a hack to prevent JSON.stringify from serializing it (#8108) - cache[ id ] = isNode ? {} : function () {}; + cache[ id ] = {}; } // An object can be passed to jQuery.data instead of a key/value pair; this gets diff --git a/test/unit/data.js b/test/unit/data.js index 1ce512c4..455b923a 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -22,7 +22,7 @@ function dataTests (elem) { strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists initially" ); var dataObj = jQuery.data(elem); - equals( typeof dataObj, elem.nodeType ? "object" : "function", "Calling data with no args gives us a data object reference" ); + equals( typeof dataObj, "object", "Calling data with no args gives us a data object reference" ); strictEqual( jQuery.data(elem), dataObj, "Calling jQuery.data returns the same data object when called multiple times" ); strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists even when an empty data obj exists" ); @@ -465,15 +465,4 @@ test(".removeData()", function() { div.removeData("test.foo"); equals( div.data("test.foo"), undefined, "Make sure data is intact" ); -}); - -if (window.JSON && window.JSON.stringify) { - test("JSON serialization (#8108)", function () { - expect(1); - - var obj = { foo: "bar" }; - jQuery.data(obj, "hidden", true); - - equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" ); - }); -} \ No newline at end of file +}); \ No newline at end of file From 2953d0481aacd38f1e2e1916ba6d18d2b10861d4 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Wed, 9 Feb 2011 15:26:34 +0100 Subject: [PATCH 072/123] Makes sure statusText always defaults to "error". --- src/ajax.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ajax.js b/src/ajax.js index 76f98349..15ad6a85 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -509,7 +509,7 @@ jQuery.extend({ // We extract error from statusText // then normalize statusText and status for non-aborts error = statusText; - if( status ) { + if( !statusText || status ) { statusText = "error"; if ( status < 0 ) { status = 0; From 806d9ce8111128c4f30c6559c325f8a4ad1018a3 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Wed, 9 Feb 2011 15:27:50 +0100 Subject: [PATCH 073/123] Makes local filesystem test for ajax more insightful. --- test/localfile.html | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/test/localfile.html b/test/localfile.html index b354612a..c27e946e 100644 --- a/test/localfile.html +++ b/test/localfile.html @@ -22,35 +22,57 @@ +

jQuery Local File Test

  • - Access this file using the "file:" protocol. + Access this file using the "file:" protocol,
  • - Two lines must appear below. + two "OK" strings must appear below,
  • Opera will fail at detecting errors, it's a known issue.
+
    +
  • + Success: + + +
  • +
  • + Error: + + +
  • +
\ No newline at end of file From f6e173437e9f94cd4e713e556c6fc8ca68be8384 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Wed, 9 Feb 2011 17:47:33 +0100 Subject: [PATCH 074/123] Fixes #8219. Introduces the mimeType option to override content-type header in conversion (and in native xhr when possible). Adds companion overrideMimeType method on jqXHR object (it simply sets the option). Unit test added. --- src/ajax.js | 10 +++++++++- src/ajax/xhr.js | 5 +++++ test/unit/ajax.js | 28 ++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/ajax.js b/src/ajax.js index 15ad6a85..5a6ac26a 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -426,6 +426,14 @@ jQuery.extend({ return match || null; }, + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( state === 0 ) { + s.mimeType = type; + } + return this; + }, + // Cancel the request abort: function( statusText ) { statusText = statusText || "abort"; @@ -827,7 +835,7 @@ function ajaxHandleResponses( s, jqXHR, responses ) { while( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { - ct = jqXHR.getResponseHeader( "content-type" ); + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); } } diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 1f136c34..fcea52c1 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -87,6 +87,11 @@ if ( jQuery.support.ajax ) { } } + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + // Requested-With header // Not set for crossDomain requests with no content // (see why at http://trac.dojotoolkit.org/ticket/9486) diff --git a/test/unit/ajax.js b/test/unit/ajax.js index 59159c32..74c6545c 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -2169,6 +2169,34 @@ test("jQuery.ajax - transitive conversions", function() { }); +test("jQuery.ajax - overrideMimeType", function() { + + expect( 2 ); + + stop(); + + jQuery.when( + + jQuery.ajax( url("data/json.php") , { + beforeSend: function( xhr ) { + xhr.overrideMimeType( "application/json" ); + }, + success: function( json ) { + ok( json.data , "Mimetype overriden using beforeSend" ); + } + }), + + jQuery.ajax( url("data/json.php") , { + mimeType: "application/json", + success: function( json ) { + ok( json.data , "Mimetype overriden using mimeType option" ); + } + }) + + ).then( start , start ); + +}); + test("jQuery.ajax - abort in prefilter", function() { expect( 1 ); From 6f4b36ed174b000701b9a40ef45f301b2b1505db Mon Sep 17 00:00:00 2001 From: jaubourg Date: Wed, 9 Feb 2011 17:50:45 +0100 Subject: [PATCH 075/123] Replaces jQuery.each loop for headers with a foreach loop. --- src/ajax/xhr.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index fcea52c1..f31fa702 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -102,9 +102,9 @@ if ( jQuery.support.ajax ) { // Need an extra try/catch for cross domain requests in Firefox 3 try { - jQuery.each( headers, function( key, value ) { - xhr.setRequestHeader( key, value ); - } ); + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } } catch( _ ) {} // Do send the request From f56b4a22a6cf37b3764939b0338bb545fa6b445f Mon Sep 17 00:00:00 2001 From: Anton M Date: Thu, 10 Feb 2011 01:29:18 +0100 Subject: [PATCH 076/123] Pull over tests from Sizzle. "Remove backslashes from tag name filter. Fixes #8220." --- test/unit/selector.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/unit/selector.js b/test/unit/selector.js index 3d83737a..035752e4 100644 --- a/test/unit/selector.js +++ b/test/unit/selector.js @@ -41,7 +41,7 @@ test("element", function() { if ( location.protocol != "file:" ) { test("XML Document Selectors", function() { - expect(8); + expect(9); stop(); jQuery.get("data/with_fries.xml", function(xml) { equals( jQuery("foo_bar", xml).length, 1, "Element Selector with underscore" ); @@ -52,6 +52,7 @@ if ( location.protocol != "file:" ) { equals( jQuery("#seite1", xml).length, 1, "Attribute selector with ID" ); equals( jQuery("component#seite1", xml).length, 1, "Attribute selector with ID" ); equals( jQuery("component", xml).filter("#seite1").length, 1, "Attribute selector filter with ID" ); + ok( jQuery( xml.lastChild ).is( "soap\\:Envelope" ), "Check for namespaced element" ); start(); }); }); @@ -337,7 +338,7 @@ test("attributes", function() { //#3279 var div = document.createElement("div"); div.innerHTML = "
"; - + deepEqual( jQuery( "[xml\\:test]", div ).get(), [ div.firstChild ], "Finding by attribute with escaped characters." ); }); From 3f036281dd52b27ae34be927162df8d078665202 Mon Sep 17 00:00:00 2001 From: John Resig Date: Thu, 10 Feb 2011 16:19:35 -0500 Subject: [PATCH 077/123] No need to duplicate Sizzle tests, just run them directly from Sizzle. --- test/index.html | 2 +- test/unit/selector.js | 517 ------------------------------------------ 2 files changed, 1 insertion(+), 518 deletions(-) delete mode 100644 test/unit/selector.js diff --git a/test/index.html b/test/index.html index fc5f667d..d6213153 100644 --- a/test/index.html +++ b/test/index.html @@ -35,7 +35,7 @@ - + diff --git a/test/unit/selector.js b/test/unit/selector.js deleted file mode 100644 index 035752e4..00000000 --- a/test/unit/selector.js +++ /dev/null @@ -1,517 +0,0 @@ -module("selector", { teardown: moduleTeardown }); - -test("element", function() { - expect(21); - QUnit.reset(); - - ok( jQuery("*").size() >= 30, "Select all" ); - var all = jQuery("*"), good = true; - for ( var i = 0; i < all.length; i++ ) - if ( all[i].nodeType == 8 ) - good = false; - ok( good, "Select all elements, no comment nodes" ); - t( "Element Selector", "p", ["firstp","ap","sndp","en","sap","first"] ); - t( "Element Selector", "body", ["body"] ); - t( "Element Selector", "html", ["html"] ); - t( "Parent Element", "div p", ["firstp","ap","sndp","en","sap","first"] ); - equals( jQuery("param", "#object1").length, 2, "Object/param as context" ); - - same( jQuery("p", document.getElementsByTagName("div")).get(), q("firstp","ap","sndp","en","sap","first"), "Finding elements with a context." ); - same( jQuery("p", "div").get(), q("firstp","ap","sndp","en","sap","first"), "Finding elements with a context." ); - same( jQuery("p", jQuery("div")).get(), q("firstp","ap","sndp","en","sap","first"), "Finding elements with a context." ); - same( jQuery("div").find("p").get(), q("firstp","ap","sndp","en","sap","first"), "Finding elements with a context." ); - - same( jQuery("#form").find("select").get(), q("select1","select2","select3","select4","select5"), "Finding selects with a context." ); - - ok( jQuery("#length").length, '<input name="length"> cannot be found under IE, see #945' ); - ok( jQuery("#lengthtest input").length, '<input name="length"> cannot be found under IE, see #945' ); - - // Check for unique-ness and sort order - same( jQuery("p, div p").get(), jQuery("p").get(), "Check for duplicates: p, div p" ); - - t( "Checking sort order", "h2, h1", ["qunit-header", "qunit-banner", "qunit-userAgent"] ); - t( "Checking sort order", "h2:first, h1:first", ["qunit-header", "qunit-banner"] ); - t( "Checking sort order", "p, p a", ["firstp", "simon1", "ap", "google", "groups", "anchor1", "mark", "sndp", "en", "yahoo", "sap", "anchor2", "simon", "first"] ); - - // Test Conflict ID - same( jQuery("#lengthtest").find("#idTest").get(), q("idTest"), "Finding element with id of ID." ); - same( jQuery("#lengthtest").find("[name='id']").get(), q("idTest"), "Finding element with id of ID." ); - same( jQuery("#lengthtest").find("input[id='idTest']").get(), q("idTest"), "Finding elements with a context." ); -}); - -if ( location.protocol != "file:" ) { - test("XML Document Selectors", function() { - expect(9); - stop(); - jQuery.get("data/with_fries.xml", function(xml) { - equals( jQuery("foo_bar", xml).length, 1, "Element Selector with underscore" ); - equals( jQuery(".component", xml).length, 1, "Class selector" ); - equals( jQuery("[class*=component]", xml).length, 1, "Attribute selector for class" ); - equals( jQuery("property[name=prop2]", xml).length, 1, "Attribute selector with name" ); - equals( jQuery("[name=prop2]", xml).length, 1, "Attribute selector with name" ); - equals( jQuery("#seite1", xml).length, 1, "Attribute selector with ID" ); - equals( jQuery("component#seite1", xml).length, 1, "Attribute selector with ID" ); - equals( jQuery("component", xml).filter("#seite1").length, 1, "Attribute selector filter with ID" ); - ok( jQuery( xml.lastChild ).is( "soap\\:Envelope" ), "Check for namespaced element" ); - start(); - }); - }); -} - -test("broken", function() { - expect(19); - - function broken(name, selector) { - try { - jQuery(selector); - ok( false, name + ": " + selector ); - } catch(e){ - ok( typeof e === "string" && e.indexOf("Syntax error") >= 0, - name + ": " + selector ); - } - } - - broken( "Broken Selector", "[", [] ); - broken( "Broken Selector", "(", [] ); - broken( "Broken Selector", "{", [] ); - broken( "Broken Selector", "<", [] ); - broken( "Broken Selector", "()", [] ); - broken( "Broken Selector", "<>", [] ); - broken( "Broken Selector", "{}", [] ); - broken( "Doesn't exist", ":visble", [] ); - broken( "Nth-child", ":nth-child", [] ); - broken( "Nth-child", ":nth-child(-)", [] ); - // Sigh. WebKit thinks this is a real selector in qSA - // They've already fixed this and it'll be coming into - // current browsers soon. - //broken( "Nth-child", ":nth-child(asdf)", [] ); - broken( "Nth-child", ":nth-child(2n+-0)", [] ); - broken( "Nth-child", ":nth-child(2+0)", [] ); - broken( "Nth-child", ":nth-child(- 1n)", [] ); - broken( "Nth-child", ":nth-child(-1 n)", [] ); - broken( "First-child", ":first-child(n)", [] ); - broken( "Last-child", ":last-child(n)", [] ); - broken( "Only-child", ":only-child(n)", [] ); - - // Make sure attribute value quoting works correctly. See: #6093 - var attrbad = jQuery('').appendTo("body"); - - broken( "Attribute not escaped", "input[name=foo.baz]", [] ); - broken( "Attribute not escaped", "input[name=foo[baz]]", [] ); - - attrbad.remove(); -}); - -test("id", function() { - expect(29); - t( "ID Selector", "#body", ["body"] ); - t( "ID Selector w/ Element", "body#body", ["body"] ); - t( "ID Selector w/ Element", "ul#first", [] ); - t( "ID selector with existing ID descendant", "#firstp #simon1", ["simon1"] ); - t( "ID selector with non-existant descendant", "#firstp #foobar", [] ); - t( "ID selector using UTF8", "#台北Táiběi", ["台北Táiběi"] ); - t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", ["台北Táiběi","台北"] ); - t( "Descendant ID selector using UTF8", "div #台北", ["台北"] ); - t( "Child ID selector using UTF8", "form > #台北", ["台北"] ); - - t( "Escaped ID", "#foo\\:bar", ["foo:bar"] ); - t( "Escaped ID", "#test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); - t( "Descendant escaped ID", "div #foo\\:bar", ["foo:bar"] ); - t( "Descendant escaped ID", "div #test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); - t( "Child escaped ID", "form > #foo\\:bar", ["foo:bar"] ); - t( "Child escaped ID", "form > #test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); - - t( "ID Selector, child ID present", "#form > #radio1", ["radio1"] ); // bug #267 - t( "ID Selector, not an ancestor ID", "#form #first", [] ); - t( "ID Selector, not a child ID", "#form > #option1a", [] ); - - t( "All Children of ID", "#foo > *", ["sndp", "en", "sap"] ); - t( "All Children of ID with no children", "#firstUL > *", [] ); - - var a = jQuery('').appendTo('#main'); - equals( jQuery("#tName1")[0].id, 'tName1', "ID selector with same value for a name attribute" ); - equals( jQuery("#tName2").length, 0, "ID selector non-existing but name attribute on an A tag" ); - a.remove(); - - t( "ID Selector on Form with an input that has a name of 'id'", "#lengthtest", ["lengthtest"] ); - - t( "ID selector with non-existant ancestor", "#asdfasdf #foobar", [] ); // bug #986 - - same( jQuery("body").find("div#form").get(), [], "ID selector within the context of another element" ); - - //#7533 - equal( jQuery("

foo

").find("p").length, 1, "Find where context root is a node and has an ID with CSS3 meta characters" ); - - t( "Underscore ID", "#types_all", ["types_all"] ); - t( "Dash ID", "#fx-queue", ["fx-queue"] ); - - t( "ID with weird characters in it", "#name\\+value", ["name+value"] ); -}); - -test("class", function() { - expect(22); - t( "Class Selector", ".blog", ["mark","simon"] ); - t( "Class Selector", ".GROUPS", ["groups"] ); - t( "Class Selector", ".blog.link", ["simon"] ); - t( "Class Selector w/ Element", "a.blog", ["mark","simon"] ); - t( "Parent Class Selector", "p .blog", ["mark","simon"] ); - - same( jQuery(".blog", document.getElementsByTagName("p")).get(), q("mark", "simon"), "Finding elements with a context." ); - same( jQuery(".blog", "p").get(), q("mark", "simon"), "Finding elements with a context." ); - same( jQuery(".blog", jQuery("p")).get(), q("mark", "simon"), "Finding elements with a context." ); - same( jQuery("p").find(".blog").get(), q("mark", "simon"), "Finding elements with a context." ); - - t( "Class selector using UTF8", ".台北Táiběi", ["utf8class1"] ); - //t( "Class selector using UTF8", ".台北", ["utf8class1","utf8class2"] ); - t( "Class selector using UTF8", ".台北Táiběi.台北", ["utf8class1"] ); - t( "Class selector using UTF8", ".台北Táiběi, .台北", ["utf8class1","utf8class2"] ); - t( "Descendant class selector using UTF8", "div .台北Táiběi", ["utf8class1"] ); - t( "Child class selector using UTF8", "form > .台北Táiběi", ["utf8class1"] ); - - t( "Escaped Class", ".foo\\:bar", ["foo:bar"] ); - t( "Escaped Class", ".test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); - t( "Descendant scaped Class", "div .foo\\:bar", ["foo:bar"] ); - t( "Descendant scaped Class", "div .test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); - t( "Child escaped Class", "form > .foo\\:bar", ["foo:bar"] ); - t( "Child escaped Class", "form > .test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); - - var div = document.createElement("div"); - div.innerHTML = "
"; - same( jQuery(".e", div).get(), [ div.firstChild ], "Finding a second class." ); - - div.lastChild.className = "e"; - - same( jQuery(".e", div).get(), [ div.firstChild, div.lastChild ], "Finding a modified class." ); -}); - -test("name", function() { - expect(15); - - t( "Name selector", "input[name=action]", ["text1"] ); - t( "Name selector with single quotes", "input[name='action']", ["text1"] ); - t( "Name selector with double quotes", 'input[name="action"]', ["text1"] ); - - t( "Name selector non-input", "[name=test]", ["length", "fx-queue"] ); - t( "Name selector non-input", "[name=div]", ["fadein"] ); - t( "Name selector non-input", "*[name=iframe]", ["iframe"] ); - - t( "Name selector for grouped input", "input[name='types[]']", ["types_all", "types_anime", "types_movie"] ) - - same( jQuery("#form").find("input[name=action]").get(), q("text1"), "Name selector within the context of another element" ); - same( jQuery("#form").find("input[name='foo[bar]']").get(), q("hidden2"), "Name selector for grouped form element within the context of another element" ); - - var form = jQuery("
").appendTo("body"); - - equals( form.find("input").length, 1, "Make sure that rooted queries on forms (with possible expandos) work." ); - - form.remove(); - - var a = jQuery('').appendTo('#main').children(); - - equals( a.length, 3, "Make sure the right number of elements were inserted." ); - equals( a[1].id, "tName2ID", "Make sure the right number of elements were inserted." ); - - equals( jQuery("[name=tName1]")[0], a[0], "Find elements that have similar IDs" ); - equals( jQuery("[name=tName2]")[0], a[1], "Find elements that have similar IDs" ); - t( "Find elements that have similar IDs", "#tName2ID", ["tName2ID"] ); - - a.remove(); -}); - -test("multiple", function() { - expect(4); - - t( "Comma Support", "h2, p", ["qunit-banner","qunit-userAgent","firstp","ap","sndp","en","sap","first"]); - t( "Comma Support", "h2 , p", ["qunit-banner","qunit-userAgent","firstp","ap","sndp","en","sap","first"]); - t( "Comma Support", "h2 , p", ["qunit-banner","qunit-userAgent","firstp","ap","sndp","en","sap","first"]); - t( "Comma Support", "h2,p", ["qunit-banner","qunit-userAgent","firstp","ap","sndp","en","sap","first"]); -}); - -test("child and adjacent", function() { - expect(29); - t( "Child", "p > a", ["simon1","google","groups","mark","yahoo","simon"] ); - t( "Child", "p> a", ["simon1","google","groups","mark","yahoo","simon"] ); - t( "Child", "p >a", ["simon1","google","groups","mark","yahoo","simon"] ); - t( "Child", "p>a", ["simon1","google","groups","mark","yahoo","simon"] ); - t( "Child w/ Class", "p > a.blog", ["mark","simon"] ); - t( "All Children", "code > *", ["anchor1","anchor2"] ); - t( "All Grandchildren", "p > * > *", ["anchor1","anchor2"] ); - t( "Adjacent", "#main a + a", ["groups"] ); - t( "Adjacent", "#main a +a", ["groups"] ); - t( "Adjacent", "#main a+ a", ["groups"] ); - t( "Adjacent", "#main a+a", ["groups"] ); - t( "Adjacent", "p + p", ["ap","en","sap"] ); - t( "Adjacent", "p#firstp + p", ["ap"] ); - t( "Adjacent", "p[lang=en] + p", ["sap"] ); - t( "Adjacent", "a.GROUPS + code + a", ["mark"] ); - t( "Comma, Child, and Adjacent", "#main a + a, code > a", ["groups","anchor1","anchor2"] ); - t( "Element Preceded By", "p ~ div", ["foo", "moretests","tabindex-tests", "liveHandlerOrder", "siblingTest"] ); - t( "Element Preceded By", "#first ~ div", ["moretests","tabindex-tests", "liveHandlerOrder", "siblingTest"] ); - t( "Element Preceded By", "#groups ~ a", ["mark"] ); - t( "Element Preceded By", "#length ~ input", ["idTest"] ); - t( "Element Preceded By", "#siblingfirst ~ em", ["siblingnext"] ); - same( jQuery("#siblingfirst").find("~ em").get(), q("siblingnext"), "Element Preceded By with a context." ); - same( jQuery("#siblingfirst").find("+ em").get(), q("siblingnext"), "Element Directly Preceded By with a context." ); - - t( "Verify deep class selector", "div.blah > p > a", [] ); - - t( "No element deep selector", "div.foo > span > a", [] ); - - same( jQuery("> :first", document.getElementById("nothiddendiv")).get(), q("nothiddendivchild"), "Verify child context positional selctor" ); - same( jQuery("> :eq(0)", document.getElementById("nothiddendiv")).get(), q("nothiddendivchild"), "Verify child context positional selctor" ); - same( jQuery("> *:first", document.getElementById("nothiddendiv")).get(), q("nothiddendivchild"), "Verify child context positional selctor" ); - - t( "Non-existant ancestors", ".fototab > .thumbnails > a", [] ); -}); - -test("attributes", function() { - expect(43); - - t( "Attribute Exists", "a[title]", ["google"] ); - t( "Attribute Exists", "*[title]", ["google"] ); - t( "Attribute Exists", "[title]", ["google"] ); - t( "Attribute Exists", "a[ title ]", ["google"] ); - - t( "Attribute Equals", "a[rel='bookmark']", ["simon1"] ); - t( "Attribute Equals", 'a[rel="bookmark"]', ["simon1"] ); - t( "Attribute Equals", "a[rel=bookmark]", ["simon1"] ); - t( "Attribute Equals", "a[href='http://www.google.com/']", ["google"] ); - t( "Attribute Equals", "a[ rel = 'bookmark' ]", ["simon1"] ); - - document.getElementById("anchor2").href = "#2"; - t( "href Attribute", "p a[href^=#]", ["anchor2"] ); - t( "href Attribute", "p a[href*=#]", ["simon1", "anchor2"] ); - - t( "for Attribute", "form label[for]", ["label-for"] ); - t( "for Attribute in form", "#form [for=action]", ["label-for"] ); - - t( "Attribute containing []", "input[name^='foo[']", ["hidden2"] ); - t( "Attribute containing []", "input[name^='foo[bar]']", ["hidden2"] ); - t( "Attribute containing []", "input[name*='[bar]']", ["hidden2"] ); - t( "Attribute containing []", "input[name$='bar]']", ["hidden2"] ); - t( "Attribute containing []", "input[name$='[bar]']", ["hidden2"] ); - t( "Attribute containing []", "input[name$='foo[bar]']", ["hidden2"] ); - t( "Attribute containing []", "input[name*='foo[bar]']", ["hidden2"] ); - - t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type='hidden']", ["radio1", "radio2", "hidden1"] ); - t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type=\"hidden\"]", ["radio1", "radio2", "hidden1"] ); - t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type=hidden]", ["radio1", "radio2", "hidden1"] ); - - t( "Attribute selector using UTF8", "span[lang=中文]", ["台北"] ); - - t( "Attribute Begins With", "a[href ^= 'http://www']", ["google","yahoo"] ); - t( "Attribute Ends With", "a[href $= 'org/']", ["mark"] ); - t( "Attribute Contains", "a[href *= 'google']", ["google","groups"] ); - t( "Attribute Is Not Equal", "#ap a[hreflang!='en']", ["google","groups","anchor1"] ); - - var opt = document.getElementById("option1a"), - match = (window.Sizzle || window.jQuery.find).matchesSelector; - - opt.setAttribute("test", ""); - - ok( match( opt, "[id*=option1][type!=checkbox]" ), "Attribute Is Not Equal Matches" ); - ok( match( opt, "[id*=option1]" ), "Attribute With No Quotes Contains Matches" ); - ok( match( opt, "[test=]" ), "Attribute With No Quotes No Content Matches" ); - ok( match( opt, "[id=option1a]" ), "Attribute With No Quotes Equals Matches" ); - ok( match( document.getElementById("simon1"), "a[href*=#]" ), "Attribute With No Quotes Href Contains Matches" ); - - t("Empty values", "#select1 option[value='']", ["option1a"]); - t("Empty values", "#select1 option[value!='']", ["option1b","option1c","option1d"]); - - t("Select options via :selected", "#select1 option:selected", ["option1a"] ); - t("Select options via :selected", "#select2 option:selected", ["option2d"] ); - t("Select options via :selected", "#select3 option:selected", ["option3b", "option3c"] ); - - t( "Grouped Form Elements", "input[name='foo[bar]']", ["hidden2"] ); - - // Make sure attribute value quoting works correctly. See: #6093 - var attrbad = jQuery('').appendTo("body"); - - t("Find escaped attribute value", "input[name=foo\\.baz]", ["attrbad1"]); - t("Find escaped attribute value", "input[name=foo\\[baz\\]]", ["attrbad2"]); - - attrbad.remove(); - - //#6428 - t("Find escaped attribute value", "#form input[name=foo\\[bar\\]]", ["hidden2"]); - - //#3279 - var div = document.createElement("div"); - div.innerHTML = "
"; - - deepEqual( jQuery( "[xml\\:test]", div ).get(), [ div.firstChild ], "Finding by attribute with escaped characters." ); -}); - -test("pseudo - child", function() { - expect(38); - t( "First Child", "p:first-child", ["firstp","sndp"] ); - t( "Last Child", "p:last-child", ["sap"] ); - t( "Only Child", "#main a:only-child", ["simon1","anchor1","yahoo","anchor2","liveLink1","liveLink2"] ); - t( "Empty", "ul:empty", ["firstUL"] ); - t( "Is A Parent", "p:parent", ["firstp","ap","sndp","en","sap","first"] ); - - t( "First Child", "p:first-child", ["firstp","sndp"] ); - t( "Nth Child", "p:nth-child(1)", ["firstp","sndp"] ); - t( "Nth Child With Whitespace", "p:nth-child( 1 )", ["firstp","sndp"] ); - t( "Not Nth Child", "p:not(:nth-child(1))", ["ap","en","sap","first"] ); - - // Verify that the child position isn't being cached improperly - jQuery("p:first-child").after("
"); - jQuery("p:first-child").before("
").next().remove(); - - t( "First Child", "p:first-child", [] ); - - QUnit.reset(); - - t( "Last Child", "p:last-child", ["sap"] ); - t( "Last Child", "#main a:last-child", ["simon1","anchor1","mark","yahoo","anchor2","simon","liveLink1","liveLink2"] ); - - t( "Nth-child", "#main form#form > *:nth-child(2)", ["text1"] ); - t( "Nth-child", "#main form#form > :nth-child(2)", ["text1"] ); - - t( "Nth-child", "#form select:first option:nth-child(-1)", [] ); - t( "Nth-child", "#form select:first option:nth-child(3)", ["option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(0n+3)", ["option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(1n+0)", ["option1a", "option1b", "option1c", "option1d"] ); - t( "Nth-child", "#form select:first option:nth-child(1n)", ["option1a", "option1b", "option1c", "option1d"] ); - t( "Nth-child", "#form select:first option:nth-child(n)", ["option1a", "option1b", "option1c", "option1d"] ); - t( "Nth-child", "#form select:first option:nth-child(+n)", ["option1a", "option1b", "option1c", "option1d"] ); - t( "Nth-child", "#form select:first option:nth-child(even)", ["option1b", "option1d"] ); - t( "Nth-child", "#form select:first option:nth-child(odd)", ["option1a", "option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(2n)", ["option1b", "option1d"] ); - t( "Nth-child", "#form select:first option:nth-child(2n+1)", ["option1a", "option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(2n + 1)", ["option1a", "option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(+2n + 1)", ["option1a", "option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(3n)", ["option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(3n+1)", ["option1a", "option1d"] ); - t( "Nth-child", "#form select:first option:nth-child(3n+2)", ["option1b"] ); - t( "Nth-child", "#form select:first option:nth-child(3n+3)", ["option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(3n-1)", ["option1b"] ); - t( "Nth-child", "#form select:first option:nth-child(3n-2)", ["option1a", "option1d"] ); - t( "Nth-child", "#form select:first option:nth-child(3n-3)", ["option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(3n+0)", ["option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(-1n+3)", ["option1a", "option1b", "option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(-n+3)", ["option1a", "option1b", "option1c"] ); - t( "Nth-child", "#form select:first option:nth-child(-1n + 3)", ["option1a", "option1b", "option1c"] ); -}); - -test("pseudo - misc", function() { - expect(7); - - t( "Headers", ":header", ["qunit-header", "qunit-banner", "qunit-userAgent"] ); - t( "Has Children - :has()", "p:has(a)", ["firstp","ap","en","sap"] ); - - var select = document.getElementById("select1"); - ok( (window.Sizzle || window.jQuery.find).matchesSelector( select, ":has(option)" ), "Has Option Matches" ); - - t( "Text Contains", "a:contains(Google)", ["google","groups"] ); - t( "Text Contains", "a:contains(Google Groups)", ["groups"] ); - - t( "Text Contains", "a:contains(Google Groups (Link))", ["groups"] ); - t( "Text Contains", "a:contains((Link))", ["groups"] ); -}); - - -test("pseudo - :not", function() { - expect(24); - t( "Not", "a.blog:not(.link)", ["mark"] ); - - t( "Not - multiple", "#form option:not(:contains(Nothing),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d", "option3e", "option4e", "option5b", "option5c"] ); - t( "Not - recursive", "#form option:not(:not(:selected))[id^='option3']", [ "option3b", "option3c"] ); - - t( ":not() failing interior", "p:not(.foo)", ["firstp","ap","sndp","en","sap","first"] ); - t( ":not() failing interior", "p:not(div.foo)", ["firstp","ap","sndp","en","sap","first"] ); - t( ":not() failing interior", "p:not(p.foo)", ["firstp","ap","sndp","en","sap","first"] ); - t( ":not() failing interior", "p:not(#blargh)", ["firstp","ap","sndp","en","sap","first"] ); - t( ":not() failing interior", "p:not(div#blargh)", ["firstp","ap","sndp","en","sap","first"] ); - t( ":not() failing interior", "p:not(p#blargh)", ["firstp","ap","sndp","en","sap","first"] ); - - t( ":not Multiple", "p:not(a)", ["firstp","ap","sndp","en","sap","first"] ); - t( ":not Multiple", "p:not(a, b)", ["firstp","ap","sndp","en","sap","first"] ); - t( ":not Multiple", "p:not(a, b, div)", ["firstp","ap","sndp","en","sap","first"] ); - t( ":not Multiple", "p:not(p)", [] ); - t( ":not Multiple", "p:not(a,p)", [] ); - t( ":not Multiple", "p:not(p,a)", [] ); - t( ":not Multiple", "p:not(a,p,b)", [] ); - t( ":not Multiple", ":input:not(:image,:input,:submit)", [] ); - - t( "No element not selector", ".container div:not(.excluded) div", [] ); - - t( ":not() Existing attribute", "#form select:not([multiple])", ["select1", "select2", "select5"]); - t( ":not() Equals attribute", "#form select:not([name=select1])", ["select2", "select3", "select4","select5"]); - t( ":not() Equals quoted attribute", "#form select:not([name='select1'])", ["select2", "select3", "select4", "select5"]); - - t( ":not() Multiple Class", "#foo a:not(.blog)", ["yahoo","anchor2"] ); - t( ":not() Multiple Class", "#foo a:not(.link)", ["yahoo","anchor2"] ); - t( ":not() Multiple Class", "#foo a:not(.blog.link)", ["yahoo","anchor2"] ); -}); - -test("pseudo - position", function() { - expect(25); - t( "nth Element", "p:nth(1)", ["ap"] ); - t( "First Element", "p:first", ["firstp"] ); - t( "Last Element", "p:last", ["first"] ); - t( "Even Elements", "p:even", ["firstp","sndp","sap"] ); - t( "Odd Elements", "p:odd", ["ap","en","first"] ); - t( "Position Equals", "p:eq(1)", ["ap"] ); - t( "Position Greater Than", "p:gt(0)", ["ap","sndp","en","sap","first"] ); - t( "Position Less Than", "p:lt(3)", ["firstp","ap","sndp"] ); - - t( "Check position filtering", "div#nothiddendiv:eq(0)", ["nothiddendiv"] ); - t( "Check position filtering", "div#nothiddendiv:last", ["nothiddendiv"] ); - t( "Check position filtering", "div#nothiddendiv:not(:gt(0))", ["nothiddendiv"] ); - t( "Check position filtering", "#foo > :not(:first)", ["en", "sap"] ); - t( "Check position filtering", "select > :not(:gt(2))", ["option1a", "option1b", "option1c"] ); - t( "Check position filtering", "select:lt(2) :not(:first)", ["option1b", "option1c", "option1d", "option2a", "option2b", "option2c", "option2d"] ); - t( "Check position filtering", "div.nothiddendiv:eq(0)", ["nothiddendiv"] ); - t( "Check position filtering", "div.nothiddendiv:last", ["nothiddendiv"] ); - t( "Check position filtering", "div.nothiddendiv:not(:lt(0))", ["nothiddendiv"] ); - - t( "Check element position", "div div:eq(0)", ["nothiddendivchild"] ); - t( "Check element position", "div div:eq(5)", ["t2037"] ); - t( "Check element position", "div div:eq(28)", ["hide"] ); - t( "Check element position", "div div:first", ["nothiddendivchild"] ); - t( "Check element position", "div > div:first", ["nothiddendivchild"] ); - t( "Check element position", "#dl div:first div:first", ["foo"] ); - t( "Check element position", "#dl div:first > div:first", ["foo"] ); - t( "Check element position", "div#nothiddendiv:first > div:first", ["nothiddendivchild"] ); -}); - -if ( (window.Sizzle || jQuery.find).selectors.filters.visibility ) { -test("pseudo - visibility", function() { - expect(11); - - t( "Is Visible", "#form input:visible", [] ); - t( "Is Visible", "div:visible:not(#qunit-testrunner-toolbar):lt(2)", ["nothiddendiv", "nothiddendivchild"] ); - t( "Is Hidden", "#form input:hidden", ["text1","text2","radio1","radio2","check1","check2","hidden1","hidden2","name","search"] ); - t( "Is Hidden", "#main:hidden", ["main"] ); - t( "Is Hidden", "#dl:hidden", ["dl"] ); - - var $div = jQuery('
').appendTo("body"); - $div.css({ fontSize: 0, lineHeight: 0 });// IE also needs to set font-size and line-height to 0 - $div.width(1).height(0); - t( "Is Visible", '#nothiddendivchild:visible', ['nothiddendivchild'] ); - t( "Is Not Visible", '#nothiddendivchild:hidden', [] ); - $div.width(0).height(1); - t( "Is Visible", '#nothiddendivchild:visible', ['nothiddendivchild'] ); - t( "Is Not Visible", '#nothiddendivchild:hidden', [] ); - $div.width(1).height(1); - t( "Is Visible", '#nothiddendivchild:visible', ['nothiddendivchild'] ); - t( "Is Not Visible", '#nothiddendivchild:hidden', [] ); - $div.remove(); -}); -} - -test("pseudo - form", function() { - expect(8); - - t( "Form element :input", "#form :input", ["text1", "text2", "radio1", "radio2", "check1", "check2", "hidden1", "hidden2", "name", "search", "button", "area1", "select1", "select2", "select3", "select4", "select5"] ); - t( "Form element :radio", "#form :radio", ["radio1", "radio2"] ); - t( "Form element :checkbox", "#form :checkbox", ["check1", "check2"] ); - t( "Form element :text", "#form :text:not(#search)", ["text1", "text2", "hidden2", "name"] ); - t( "Form element :radio:checked", "#form :radio:checked", ["radio2"] ); - t( "Form element :checkbox:checked", "#form :checkbox:checked", ["check1"] ); - t( "Form element :radio:checked, :checkbox:checked", "#form :radio:checked, #form :checkbox:checked", ["radio2", "check1"] ); - - t( "Selected Option Element", "#form option:selected", ["option1a","option2d","option3b","option3c","option4b","option4c","option4d","option5a"] ); -}); From 4490f4285cc4cdafba67fee726d3eba4a3d81a0f Mon Sep 17 00:00:00 2001 From: Anton M Date: Thu, 10 Feb 2011 03:15:32 +0100 Subject: [PATCH 078/123] Fix some whitespace issues. Improve and correct an events test. --- src/manipulation.js | 8 +++---- test/unit/event.js | 56 +++++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index 841447fa..1e4df48c 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -159,7 +159,7 @@ jQuery.fn.extend({ } if ( elem.parentNode ) { - elem.parentNode.removeChild( elem ); + elem.parentNode.removeChild( elem ); } } } @@ -353,8 +353,8 @@ function cloneCopyEvent( src, dest ) { } var internalKey = jQuery.expando, - oldData = jQuery.data( src ), - curData = jQuery.data( dest, oldData ); + oldData = jQuery.data( src ), + curData = jQuery.data( dest, oldData ); // Switch to use the internal data object, if it exists, for the next // stage of data copying @@ -537,7 +537,7 @@ jQuery.extend({ } // Return the cloned set return clone; - }, +}, clean: function( elems, context, fragment, scripts ) { context = context || document; diff --git a/test/unit/event.js b/test/unit/event.js index 045ea73b..21ed6316 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2,22 +2,16 @@ module("event", { teardown: moduleTeardown }); test("null or undefined handler", function() { expect(2); - // Supports Fixes bug #7229 - try { + // Supports Fixes bug #7229 + try { + jQuery("#firstp").click(null); + ok(true, "Passing a null handler will not throw an exception"); + } catch (e) {} - jQuery("#firstp").click(null); - - ok(true, "Passing a null handler will not throw an exception"); - - } catch (e) {} - - try { - - jQuery("#firstp").click(undefined); - - ok(true, "Passing an undefined handler will not throw an exception"); - - } catch (e) {} + try { + jQuery("#firstp").click(undefined); + ok(true, "Passing an undefined handler will not throw an exception"); + } catch (e) {} }); test("bind(), with data", function() { @@ -370,35 +364,37 @@ test("bind(), trigger change on select", function() { test("bind(), namespaced events, cloned events", function() { expect(6); - jQuery("#firstp").bind("custom.test",function(e){ - ok(true, "Custom event triggered"); + var firstp = jQuery( "#firstp" ); + + firstp.bind("custom.test",function(e){ + ok(false, "Custom event triggered"); }); - jQuery("#firstp").bind("click",function(e){ + firstp.bind("click",function(e){ ok(true, "Normal click triggered"); }); - jQuery("#firstp").bind("click.test",function(e){ - ok(true, "Namespaced click triggered"); + firstp.bind("click.test",function(e){ + ok( true, "Namespaced click triggered" ); }); // Trigger both bound fn (2) - jQuery("#firstp").trigger("click"); + firstp.trigger("click"); // Trigger one bound fn (1) - jQuery("#firstp").trigger("click.test"); + firstp.trigger("click.test"); // Remove only the one fn - jQuery("#firstp").unbind("click.test"); + firstp.unbind("click.test"); // Trigger the remaining fn (1) - jQuery("#firstp").trigger("click"); + firstp.trigger("click"); - // Remove the remaining fn - jQuery("#firstp").unbind(".test"); + // Remove the remaining namespaced fn + firstp.unbind(".test"); - // Trigger the remaining fn (0) - jQuery("#firstp").trigger("custom"); + // Try triggering the custom event (0) + firstp.trigger("custom"); // using contents will get comments regular, text, and comment nodes jQuery("#nonnodes").contents().bind("tester", function () { @@ -471,7 +467,7 @@ test("bind(), multi-namespaced events", function() { test("bind(), with same function", function() { expect(2) - var count = 0 , func = function(){ + var count = 0, func = function(){ count++; }; @@ -587,7 +583,7 @@ test("bind()/trigger()/unbind() on plain object", function() { jQuery(obj).unbind("test"); equals( obj && obj[ jQuery.expando ] && - obj[ jQuery.expando ][ jQuery.expando ] && + obj[ jQuery.expando ][ jQuery.expando ] && obj[ jQuery.expando ][ jQuery.expando ].events, undefined, "Make sure events object is removed" ); }); From 78fc79fad47ce2991c0a7148b65acd7221223eb9 Mon Sep 17 00:00:00 2001 From: Anton M Date: Thu, 10 Feb 2011 03:18:11 +0100 Subject: [PATCH 079/123] Make sure .clone(true) correctly clones namespaced events. Fixes #4537. --- src/manipulation.js | 2 +- test/unit/event.js | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index 1e4df48c..cd0732c3 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -368,7 +368,7 @@ function cloneCopyEvent( src, dest ) { for ( var type in events ) { for ( var i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ], events[ type ][ i ].data ); + jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data ); } } } diff --git a/test/unit/event.js b/test/unit/event.js index 21ed6316..1d9e2e11 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -361,9 +361,7 @@ test("bind(), trigger change on select", function() { }).trigger('change'); }); -test("bind(), namespaced events, cloned events", function() { - expect(6); - +test("bind(), namespaced events, cloned events", 18, function() { var firstp = jQuery( "#firstp" ); firstp.bind("custom.test",function(e){ @@ -372,22 +370,31 @@ test("bind(), namespaced events, cloned events", function() { firstp.bind("click",function(e){ ok(true, "Normal click triggered"); + equal( e.type + e.namespace, "click", "Check that only click events trigger this fn" ); }); firstp.bind("click.test",function(e){ + var check = "click"; ok( true, "Namespaced click triggered" ); + if ( e.namespace ) { + check += "test"; + } + equal( e.type + e.namespace, check, "Check that only click/click.test events trigger this fn" ); }); - // Trigger both bound fn (2) + //clone(true) element to verify events are cloned correctly + firstp = firstp.add( firstp.clone( true ).attr( "id", "firstp2" ).insertBefore( firstp ) ); + + // Trigger both bound fn (8) firstp.trigger("click"); - // Trigger one bound fn (1) + // Trigger one bound fn (4) firstp.trigger("click.test"); // Remove only the one fn firstp.unbind("click.test"); - // Trigger the remaining fn (1) + // Trigger the remaining fn (4) firstp.trigger("click"); // Remove the remaining namespaced fn From 43a41ba7ecef732b48dcfc930fa9df8835fc4944 Mon Sep 17 00:00:00 2001 From: rwldrn Date: Thu, 10 Feb 2011 23:50:02 +0100 Subject: [PATCH 080/123] Make sure .val() works after form.reset() in IE. Fixes #2551. --- src/attributes.js | 5 +++++ test/unit/attributes.js | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/attributes.js b/src/attributes.js index d37400a6..59972105 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -198,6 +198,11 @@ jQuery.fn.extend({ } } + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + return values; } diff --git a/test/unit/attributes.js b/test/unit/attributes.js index c58111de..8cf47bed 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -546,6 +546,25 @@ test("val(Function) with incoming value", function() { equals( jQuery("#select1").val(), "4", "Should be possible to set the val() to a newly created option" ); }); +// testing if a form.reset() breaks a subsequent call to a select element's .val() (in IE only) +test("val(select) after form.reset() (Bug #2551)", function() { + expect(3); + + jQuery('
').appendTo("#main"); + + jQuery("#kkk").val( "gf" ); + + document.kk.reset(); + + equal( jQuery("#kkk")[0].value, "cf", "Check value of select after form reset." ); + equal( jQuery("#kkk").val(), "cf", "Check value of select after form reset." ); + + // re-verify the multi-select is not broken (after form.reset) by our fix for single-select + same( jQuery('#select3').val(), ['1', '2'], 'Call val() on a multiple="multiple" select' ); + + jQuery("#kk").remove(); +}); + var testAddClass = function(valueObj) { expect(5); var div = jQuery("div"); From 3a1d7a3c7c5349021f6dae979ab9b8609ae8f105 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Fri, 11 Feb 2011 07:02:11 +0100 Subject: [PATCH 081/123] Simplifies status normalization in xhr transport. Local file test modified for clarity. --- src/ajax/xhr.js | 37 ++++++++----------------------------- test/localfile.html | 44 +++++++++++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index f31fa702..c48ac901 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -166,35 +166,14 @@ if ( jQuery.support.ajax ) { } // Filter status for non standard behaviors - - // IE - #1450: sometimes returns 1223 when it should be 204 - if ( status === 1223 ) { - status = 204; - // Various - #8177: a Not Modified response was received - // yet no conditional request headers was provided - } else if ( status === 304 && - !headers[ "if-modified-since" ] && - !headers[ "if-none-match" ] ) { - status = 200; - // Status 0 encompasses several cases - } else if ( !status ) { - // Cross-domain - if ( s.crossDomain ) { - if ( !s.statusText ) { - // FF, Webkit (other?): There is no status text for errors - // 302 is the most generic cross-domain status code - // for errors, could be anything really (even a real 0) - status = 302; - } - // All same-domain: for local files, 0 is a success - } else if( s.isLocal ) { - status = 200; - // Opera: this notifies success for all requests - // (verified in 11.01). Patch welcome. - } - // Opera - #6060: sets status as 0 for 304 - // Patch welcome. - } + status = + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + !status && s.isLocal ? + ( responses.text ? 200 : 404 ) : + // IE - #1450: sometimes returns 1223 when it should be 204 + ( status === 1223 ? 204 : status ); } } } catch( firefoxAccessException ) { diff --git a/test/localfile.html b/test/localfile.html index c27e946e..96e0f982 100644 --- a/test/localfile.html +++ b/test/localfile.html @@ -27,20 +27,25 @@ .success { color: green; } -

jQuery Local File Test

+

+ Introduction +

  • Access this file using the "file:" protocol,
  • - two "OK" strings must appear below, + two green "OK" strings must appear below,
  • - Opera will fail at detecting errors, it's a known issue. + Empty local files will issue errors, it's a known limitation.
+

+ Results +

  • Success: @@ -53,26 +58,35 @@
+

+ Logs: +

+
    +
\ No newline at end of file From f2e0ae1a3932d6089853e8c0eed6ecb446610c00 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Fri, 11 Feb 2011 07:07:06 +0100 Subject: [PATCH 082/123] Fixes #8245. Ajax now ensures header names are capitalized so that non-compliant xhr implementations don't override them. --- src/ajax.js | 19 +++++++++++-------- src/ajax/xhr.js | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 5a6ac26a..b35952f0 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -15,6 +15,7 @@ var r20 = /%20/g, rselectTextarea = /^(?:select|textarea)/i, rspacesAjax = /\s+/, rts = /([?&])_=[^&]*/, + rucWord = /(^|\-)([a-z])/g, rurl = /^([\w\+\.\-]+:)\/\/([^\/?#:]*)(?::(\d+))?/, // Keep a copy of the old load method @@ -400,8 +401,10 @@ jQuery.extend({ // Caches the header setRequestHeader: function( name, value ) { - if ( state === 0 ) { - requestHeaders[ name.toLowerCase() ] = value; + if ( !state ) { + requestHeaders[ name.toLowerCase().replace( rucWord, function( _, $1, $2 ) { + return $1 + $2.toUpperCase(); + } ) ] = value; } return this; }, @@ -428,7 +431,7 @@ jQuery.extend({ // Overrides response content-type header overrideMimeType: function( type ) { - if ( state === 0 ) { + if ( !state ) { s.mimeType = type; } return this; @@ -649,28 +652,28 @@ jQuery.extend({ // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - requestHeaders[ "content-type" ] = s.contentType; + requestHeaders[ "Content-Type" ] = s.contentType; } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { ifModifiedKey = ifModifiedKey || s.url; if ( jQuery.lastModified[ ifModifiedKey ] ) { - requestHeaders[ "if-modified-since" ] = jQuery.lastModified[ ifModifiedKey ]; + requestHeaders[ "If-Modified-Since" ] = jQuery.lastModified[ ifModifiedKey ]; } if ( jQuery.etag[ ifModifiedKey ] ) { - requestHeaders[ "if-none-match" ] = jQuery.etag[ ifModifiedKey ]; + requestHeaders[ "If-None-Match" ] = jQuery.etag[ ifModifiedKey ]; } } // Set the Accepts header for the server, depending on the dataType - requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + requestHeaders.Accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : s.accepts[ "*" ]; // Check for headers option for ( i in s.headers ) { - requestHeaders[ i.toLowerCase() ] = s.headers[ i ]; + jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index c48ac901..e21847aa 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -96,8 +96,8 @@ if ( jQuery.support.ajax ) { // Not set for crossDomain requests with no content // (see why at http://trac.dojotoolkit.org/ticket/9486) // Won't change header if already provided - if ( !( s.crossDomain && !s.hasContent ) && !headers["x-requested-with"] ) { - headers[ "x-requested-with" ] = "XMLHttpRequest"; + if ( !( s.crossDomain && !s.hasContent ) && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Need an extra try/catch for cross domain requests in Firefox 3 From 066304edf0a1ed0303d79712bfa9c8697d5fa4d3 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Fri, 11 Feb 2011 07:39:46 +0100 Subject: [PATCH 083/123] Adds missing crossDomain test. --- src/ajax/xhr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index e21847aa..9c8790ab 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -170,7 +170,7 @@ if ( jQuery.support.ajax ) { // If the request is local and we have data: assume a success // (success with no data won't get notified, that's the best we // can do given current implementations) - !status && s.isLocal ? + !status && s.isLocal && !s.crossDomain ? ( responses.text ? 200 : 404 ) : // IE - #1450: sometimes returns 1223 when it should be 204 ( status === 1223 ? 204 : status ); From 481d940e79f9d01e49218bf76575849158214e28 Mon Sep 17 00:00:00 2001 From: Anton M Date: Thu, 10 Feb 2011 23:57:06 +0100 Subject: [PATCH 084/123] Remove duplicate test. --- test/unit/ajax.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/unit/ajax.js b/test/unit/ajax.js index 74c6545c..c9c06111 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -922,7 +922,7 @@ test("serialize()", function() { }); test("jQuery.param()", function() { - expect(25); + expect(24); equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" ); @@ -960,8 +960,6 @@ test("jQuery.param()", function() { // #7945 equals( jQuery.param({"jquery": "1.4.2"}), "jquery=1.4.2", "Check that object with a jQuery property get serialized correctly" ); - equals( jQuery.param(jQuery("#form :input")), "action=Test&text2=Test&radio1=on&radio2=on&check=on&=on&hidden=&foo%5Bbar%5D=&name=name&search=search&button=&=foobar&select1=&select2=3&select3=1&select4=1&select5=3", "Make sure jQuery objects are properly serialized"); - jQuery.ajaxSetup({ traditional: true }); var params = {foo:"bar", baz:42, quux:"All your base are belong to us"}; From ea3e10a49207f76957b5bd87095634882d5d374b Mon Sep 17 00:00:00 2001 From: jaubourg Date: Sat, 12 Feb 2011 00:13:38 +0100 Subject: [PATCH 085/123] Minor changes to enforce JQuery Core Style Guidelines. --- src/ajax.js | 2 +- src/ajax/xhr.js | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index b35952f0..790585dd 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -451,7 +451,7 @@ jQuery.extend({ // Callback for when everything is done // It is defined here because jslint complains if it is declared // at the end of the function (which would be more logical and readable) - function done( status, statusText, responses, headers) { + function done( status, statusText, responses, headers ) { // Called once if ( state === 2 ) { diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 9c8790ab..a6473dd8 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -26,7 +26,7 @@ function createStandardXHR() { function createActiveXHR() { try { - return new window.ActiveXObject("Microsoft.XMLHTTP"); + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); } catch( e ) {} } @@ -166,14 +166,16 @@ if ( jQuery.support.ajax ) { } // Filter status for non standard behaviors - status = - // If the request is local and we have data: assume a success - // (success with no data won't get notified, that's the best we - // can do given current implementations) - !status && s.isLocal && !s.crossDomain ? - ( responses.text ? 200 : 404 ) : - // IE - #1450: sometimes returns 1223 when it should be 204 - ( status === 1223 ? 204 : status ); + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } } } } catch( firefoxAccessException ) { From 081562cebc63617d2c99adbcefa107dbea5c9bee Mon Sep 17 00:00:00 2001 From: jaubourg Date: Sat, 12 Feb 2011 01:08:24 +0100 Subject: [PATCH 086/123] Pulls out the callback function in setRequestHeader. Also renames the regexp so that what it's meant to do is a bit more obvious. --- src/ajax.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 790585dd..e6c9ac8a 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -15,7 +15,10 @@ var r20 = /%20/g, rselectTextarea = /^(?:select|textarea)/i, rspacesAjax = /\s+/, rts = /([?&])_=[^&]*/, - rucWord = /(^|\-)([a-z])/g, + rucHeaders = /(^|\-)([a-z])/g, + rucHeadersFunc = function( _, $1, $2 ) { + return $1 + $2.toUpperCase(); + }, rurl = /^([\w\+\.\-]+:)\/\/([^\/?#:]*)(?::(\d+))?/, // Keep a copy of the old load method @@ -402,9 +405,7 @@ jQuery.extend({ // Caches the header setRequestHeader: function( name, value ) { if ( !state ) { - requestHeaders[ name.toLowerCase().replace( rucWord, function( _, $1, $2 ) { - return $1 + $2.toUpperCase(); - } ) ] = value; + requestHeaders[ name.toLowerCase().replace( rucHeaders, rucHeadersFunc ) ] = value; } return this; }, From d4790116b8ff83786e82767cba23a4bff0236e58 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Sat, 12 Feb 2011 03:59:46 +0100 Subject: [PATCH 087/123] Enhances ajaxSetup so that it can take an optional target option, in which case target will be updated instead of ajaxSettings. That way, fields that shouldn't be deep extended can be listed and dealt with in one place. jQuery.ajax now makes use of ajaxSetup with target to create its internal settings object. Fixes #7531 in IE9RC. --- src/ajax.js | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index e6c9ac8a..7ef8dec1 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -279,11 +279,27 @@ jQuery.extend({ return jQuery.get( url, data, callback, "json" ); }, - ajaxSetup: function( settings ) { - jQuery.extend( true, jQuery.ajaxSettings, settings ); - if ( settings.context ) { - jQuery.ajaxSettings.context = settings.context; + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function ( target, settings ) { + if ( !settings ) { + // Only one parameter, we extend ajaxSettings + settings = target; + target = jQuery.extend( true, jQuery.ajaxSettings, settings ); + } else { + // target was provided, we extend into it + jQuery.extend( true, target, jQuery.ajaxSettings, settings ); } + // Flatten fields we don't want deep extended + for( var field in { context: 1, url: 1 } ) { + if ( field in settings ) { + target[ field ] = settings[ field ]; + } else if( field in jQuery.ajaxSettings ) { + target[ field ] = jQuery.ajaxSettings[ field ]; + } + } + return target; }, ajaxSettings: { @@ -360,13 +376,9 @@ jQuery.extend({ options = options || {}; var // Create the final options object - s = jQuery.extend( true, {}, jQuery.ajaxSettings, options ), + s = jQuery.ajaxSetup( {}, options ), // Callbacks context - // We force the original context if it exists - // or take it from jQuery.ajaxSettings otherwise - // (plain objects used as context get extended) - callbackContext = - ( s.context = ( "context" in options ? options : jQuery.ajaxSettings ).context ) || s, + callbackContext = s.context || s, // Context for global events // It's the callbackContext if one was provided in the options // and if it's a DOM node or a jQuery collection @@ -586,7 +598,7 @@ jQuery.extend({ // Remove hash character (#7531: and string promotion) // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) // We also use the url parameter if available - s.url = ( "" + ( url || s.url ) ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); // Extract dataTypes list s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); From f0999076723d85e77d4ba73d7c464466b5a7dba1 Mon Sep 17 00:00:00 2001 From: David Murdoch Date: Sat, 12 Feb 2011 03:05:19 +0100 Subject: [PATCH 088/123] Unexpose $.support._scriptEval as it's not needed. Use a private var instead. Fixes #8200. --- src/support.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/support.js b/src/support.js index 8b60abd2..7f2591b5 100644 --- a/src/support.js +++ b/src/support.js @@ -61,7 +61,6 @@ deleteExpando: true, optDisabled: false, checkClone: false, - _scriptEval: null, noCloneEvent: true, boxModel: null, inlineBlockNeedsLayout: false, @@ -74,8 +73,9 @@ select.disabled = true; jQuery.support.optDisabled = !opt.disabled; + var _scriptEval = null; jQuery.support.scriptEval = function() { - if ( jQuery.support._scriptEval === null ) { + if ( _scriptEval === null ) { var root = document.documentElement, script = document.createElement("script"), id = "script" + jQuery.now(); @@ -91,10 +91,10 @@ // tag with appendChild/createTextNode // (IE doesn't support this, fails, and uses .text instead) if ( window[ id ] ) { - jQuery.support._scriptEval = true; + _scriptEval = true; delete window[ id ]; } else { - jQuery.support._scriptEval = false; + _scriptEval = false; } root.removeChild( script ); @@ -102,7 +102,7 @@ root = script = id = null; } - return jQuery.support._scriptEval; + return _scriptEval; }; // Test to see if it's possible to delete an expando from an element From 3548ffaee244af2bd5e28e91ebfaa995adab93a7 Mon Sep 17 00:00:00 2001 From: David Murdoch Date: Sat, 12 Feb 2011 03:09:45 +0100 Subject: [PATCH 089/123] Remove unnecessary "script.type = text/javascript;". Fixes #8198. Follow up to 462bb1f66abf239492ee33c60feee3402fe64f77. --- src/support.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/support.js b/src/support.js index 7f2591b5..97b4a426 100644 --- a/src/support.js +++ b/src/support.js @@ -80,7 +80,6 @@ script = document.createElement("script"), id = "script" + jQuery.now(); - script.type = "text/javascript"; try { script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); } catch(e) {} From 2862f589db08b92c7b1f78fa961aff7354027c0b Mon Sep 17 00:00:00 2001 From: awgy Date: Sat, 12 Feb 2011 03:35:41 +0100 Subject: [PATCH 090/123] Remove sed from post-build code, due to portability issues between GNU and BSD versions. Follow up to ba43d37394b6018779d9a668c548e11579cd424a which apparently didn't fix the problem completly on Mac OS X. --- Makefile | 5 +++-- build/post-compile.js | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 build/post-compile.js diff --git a/Makefile b/Makefile index 48a885da..bf41bccc 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ DIST_DIR = ${PREFIX}/dist JS_ENGINE ?= `which node nodejs` COMPILER = ${JS_ENGINE} ${BUILD_DIR}/uglify.js --unsafe +POST_COMPILER = ${JS_ENGINE} ${BUILD_DIR}/post-compile.js BASE_FILES = ${SRC_DIR}/core.js\ ${SRC_DIR}/support.js\ @@ -106,8 +107,8 @@ ${JQ_MIN}: jquery @@if test ! -z ${JS_ENGINE}; then \ echo "Minifying jQuery" ${JQ_MIN}; \ ${COMPILER} ${JQ} > ${JQ_MIN}.tmp; \ - sed '$ s#^\( \*/\)\(.\+\)#\1\n\2;#' ${JQ_MIN}.tmp > ${JQ_MIN}; \ - rm -rf ${JQ_MIN}.tmp; \ + ${POST_COMPILER} ${JQ_MIN}.tmp > ${JQ_MIN}; \ + rm -f ${JQ_MIN}.tmp; \ else \ echo "You must have NodeJS installed in order to minify jQuery."; \ fi diff --git a/build/post-compile.js b/build/post-compile.js new file mode 100644 index 00000000..4bcafe81 --- /dev/null +++ b/build/post-compile.js @@ -0,0 +1,7 @@ +#!/usr/bin/env node + +var print = require("sys").print, + src = require("fs").readFileSync(process.argv[2], "utf8"); + +// Previously done in sed but reimplemented here due to portability issues +print(src.replace(/^(\s*\*\/)(.+)/m, "$1\n$2;")); From d99268a4b728e47d02b9b893e08796c8060a68e9 Mon Sep 17 00:00:00 2001 From: jrburke Date: Sat, 12 Feb 2011 03:42:35 +0100 Subject: [PATCH 091/123] Add readyWait tests. Fixes #8145. Adds tests for the fix to #6781. --- test/data/readywaitasset.js | 1 + test/data/readywaitloader.js | 25 +++++++++++ test/readywait.html | 85 ++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 test/data/readywaitasset.js create mode 100644 test/data/readywaitloader.js create mode 100644 test/readywait.html diff --git a/test/data/readywaitasset.js b/test/data/readywaitasset.js new file mode 100644 index 00000000..2308965c --- /dev/null +++ b/test/data/readywaitasset.js @@ -0,0 +1 @@ +var delayedMessage = "It worked!"; diff --git a/test/data/readywaitloader.js b/test/data/readywaitloader.js new file mode 100644 index 00000000..483e07c4 --- /dev/null +++ b/test/data/readywaitloader.js @@ -0,0 +1,25 @@ +// Simple script loader that uses jQuery.readyWait + +//Hold on jQuery! +jQuery.readyWait++; + +var readyRegExp = /^(complete|loaded)$/; + +function assetLoaded( evt ){ + var node = evt.currentTarget || evt.srcElement; + if ( evt.type === "load" || readyRegExp.test(node.readyState) ) { + jQuery.ready(true); + } +} + +setTimeout( function() { + var script = document.createElement("script"); + script.type = "text/javascript"; + if ( script.addEventListener ) { + script.addEventListener( "load", assetLoaded, false ); + } else { + script.attachEvent( "onreadystatechange", assetLoaded ); + } + script.src = "data/readywaitasset.js"; + document.getElementsByTagName("head")[0].appendChild(script); +}, 2000 ); diff --git a/test/readywait.html b/test/readywait.html new file mode 100644 index 00000000..8e0d3d53 --- /dev/null +++ b/test/readywait.html @@ -0,0 +1,85 @@ + + + + + + jQuery.readyWait Test + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ jQuery.readyWait Test +

+

+ This is a test page for jQuery.readyWait, that was + added due to this ticket + #6781. +

+

+ Test for jQuery.readyWait, which can be used + by plugins and other scripts to indicate something + important to the page is still loading and needs + to block the DOM ready callbacks that are registered + with jQuery. +

+

+ Script loaders are the most likely kind of script + to use jQuery.readyWait, but it could be used by + other things like a script that loads a CSS file + and wants to pause the DOM ready callbacks. +

+

+ Expected Result: The text + It Worked! + appears below after about 2 seconds. +

+

+ If there is an error in the console, + or the text does not show up, then the test failed. +

+
+ + From fbf79c0b495e08d67c3a4767f371ec7bcfc40a17 Mon Sep 17 00:00:00 2001 From: Anton M Date: Sun, 13 Feb 2011 01:34:31 +0100 Subject: [PATCH 092/123] Remove old cruft from test folder. Change "polluted" test suite loader to use CDN hosted libraries. --- test/data/css.php | 15 - test/data/json_assigned_obj.js | 1 - test/otherlibs/jquery/1.2.1/jquery.js | 11 - test/otherlibs/jquery/1.2.3/jquery.js | 11 - test/otherlibs/mootools/1.11/mootools.js | 1577 ------ test/otherlibs/prototype/1.6.0.2/prototype.js | 4221 ----------------- test/otherlibs/scriptaculous/1.7.0/builder.js | 131 - .../otherlibs/scriptaculous/1.7.0/controls.js | 835 ---- .../otherlibs/scriptaculous/1.7.0/dragdrop.js | 944 ---- test/otherlibs/scriptaculous/1.7.0/effects.js | 1090 ----- .../scriptaculous/1.7.0/scriptaculous.js | 51 - test/otherlibs/scriptaculous/1.7.0/slider.js | 278 -- .../otherlibs/scriptaculous/1.7.0/unittest.js | 564 --- test/otherlibs/scriptaculous/1.8.1/builder.js | 136 - .../otherlibs/scriptaculous/1.8.1/controls.js | 965 ---- .../otherlibs/scriptaculous/1.8.1/dragdrop.js | 974 ---- test/otherlibs/scriptaculous/1.8.1/effects.js | 1122 ----- .../scriptaculous/1.8.1/scriptaculous.js | 58 - test/otherlibs/scriptaculous/1.8.1/slider.js | 275 -- test/otherlibs/scriptaculous/1.8.1/sound.js | 55 - .../otherlibs/scriptaculous/1.8.1/unittest.js | 568 --- test/polluted.php | 105 +- test/test.js | 41 - 23 files changed, 70 insertions(+), 13958 deletions(-) delete mode 100644 test/data/css.php delete mode 100644 test/data/json_assigned_obj.js delete mode 100644 test/otherlibs/jquery/1.2.1/jquery.js delete mode 100644 test/otherlibs/jquery/1.2.3/jquery.js delete mode 100644 test/otherlibs/mootools/1.11/mootools.js delete mode 100644 test/otherlibs/prototype/1.6.0.2/prototype.js delete mode 100644 test/otherlibs/scriptaculous/1.7.0/builder.js delete mode 100644 test/otherlibs/scriptaculous/1.7.0/controls.js delete mode 100644 test/otherlibs/scriptaculous/1.7.0/dragdrop.js delete mode 100644 test/otherlibs/scriptaculous/1.7.0/effects.js delete mode 100644 test/otherlibs/scriptaculous/1.7.0/scriptaculous.js delete mode 100644 test/otherlibs/scriptaculous/1.7.0/slider.js delete mode 100644 test/otherlibs/scriptaculous/1.7.0/unittest.js delete mode 100644 test/otherlibs/scriptaculous/1.8.1/builder.js delete mode 100644 test/otherlibs/scriptaculous/1.8.1/controls.js delete mode 100644 test/otherlibs/scriptaculous/1.8.1/dragdrop.js delete mode 100644 test/otherlibs/scriptaculous/1.8.1/effects.js delete mode 100644 test/otherlibs/scriptaculous/1.8.1/scriptaculous.js delete mode 100644 test/otherlibs/scriptaculous/1.8.1/slider.js delete mode 100644 test/otherlibs/scriptaculous/1.8.1/sound.js delete mode 100644 test/otherlibs/scriptaculous/1.8.1/unittest.js delete mode 100644 test/test.js diff --git a/test/data/css.php b/test/data/css.php deleted file mode 100644 index 9d079e73..00000000 --- a/test/data/css.php +++ /dev/null @@ -1,15 +0,0 @@ - - div# { margin-left: 27px } - \ No newline at end of file diff --git a/test/data/json_assigned_obj.js b/test/data/json_assigned_obj.js deleted file mode 100644 index 867251da..00000000 --- a/test/data/json_assigned_obj.js +++ /dev/null @@ -1 +0,0 @@ -json_assigned_obj = { "test" : "worked" }; diff --git a/test/otherlibs/jquery/1.2.1/jquery.js b/test/otherlibs/jquery/1.2.1/jquery.js deleted file mode 100644 index d6468594..00000000 --- a/test/otherlibs/jquery/1.2.1/jquery.js +++ /dev/null @@ -1,11 +0,0 @@ -/* - * jQuery 1.2.1 - New Wave Javascript - * - * Copyright (c) 2007 John Resig (jquery.com) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $ - * $Rev: 3353 $ - */ -eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(G(){9(1m E!="W")H w=E;H E=18.15=G(a,b){I 6 7u E?6.5N(a,b):1u E(a,b)};9(1m $!="W")H D=$;18.$=E;H u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/;E.1b=E.3A={5N:G(c,a){c=c||U;9(1m c=="1M"){H m=u.2S(c);9(m&&(m[1]||!a)){9(m[1])c=E.4D([m[1]],a);J{H b=U.3S(m[3]);9(b)9(b.22!=m[3])I E().1Y(c);J{6[0]=b;6.K=1;I 6}J c=[]}}J I 1u E(a).1Y(c)}J 9(E.1n(c))I 1u E(U)[E.1b.2d?"2d":"39"](c);I 6.6v(c.1c==1B&&c||(c.4c||c.K&&c!=18&&!c.1y&&c[0]!=W&&c[0].1y)&&E.2h(c)||[c])},4c:"1.2.1",7Y:G(){I 6.K},K:0,21:G(a){I a==W?E.2h(6):6[a]},2o:G(a){H b=E(a);b.4Y=6;I b},6v:G(a){6.K=0;1B.3A.1a.16(6,a);I 6},N:G(a,b){I E.N(6,a,b)},4I:G(a){H b=-1;6.N(G(i){9(6==a)b=i});I b},1x:G(f,d,e){H c=f;9(f.1c==3X)9(d==W)I 6.K&&E[e||"1x"](6[0],f)||W;J{c={};c[f]=d}I 6.N(G(a){L(H b 1i c)E.1x(e?6.R:6,b,E.1e(6,c[b],e,a,b))})},17:G(b,a){I 6.1x(b,a,"3C")},2g:G(e){9(1m e!="5i"&&e!=S)I 6.4n().3g(U.6F(e));H t="";E.N(e||6,G(){E.N(6.3j,G(){9(6.1y!=8)t+=6.1y!=1?6.6x:E.1b.2g([6])})});I t},5m:G(b){9(6[0])E(b,6[0].3H).6u().3d(6[0]).1X(G(){H a=6;1W(a.1w)a=a.1w;I a}).3g(6);I 6},8m:G(a){I 6.N(G(){E(6).6q().5m(a)})},8d:G(a){I 6.N(G(){E(6).5m(a)})},3g:G(){I 6.3z(1q,Q,1,G(a){6.58(a)})},6j:G(){I 6.3z(1q,Q,-1,G(a){6.3d(a,6.1w)})},6g:G(){I 6.3z(1q,P,1,G(a){6.12.3d(a,6)})},50:G(){I 6.3z(1q,P,-1,G(a){6.12.3d(a,6.2q)})},2D:G(){I 6.4Y||E([])},1Y:G(t){H b=E.1X(6,G(a){I E.1Y(t,a)});I 6.2o(/[^+>] [^+>]/.14(t)||t.1g("..")>-1?E.4V(b):b)},6u:G(e){H f=6.1X(G(){I 6.67?E(6.67)[0]:6.4R(Q)});H d=f.1Y("*").4O().N(G(){9(6[F]!=W)6[F]=S});9(e===Q)6.1Y("*").4O().N(G(i){H c=E.M(6,"2P");L(H a 1i c)L(H b 1i c[a])E.1j.1f(d[i],a,c[a][b],c[a][b].M)});I f},1E:G(t){I 6.2o(E.1n(t)&&E.2W(6,G(b,a){I t.16(b,[a])})||E.3m(t,6))},5V:G(t){I 6.2o(t.1c==3X&&E.3m(t,6,Q)||E.2W(6,G(a){I(t.1c==1B||t.4c)?E.2A(a,t)<0:a!=t}))},1f:G(t){I 6.2o(E.1R(6.21(),t.1c==3X?E(t).21():t.K!=W&&(!t.11||E.11(t,"2Y"))?t:[t]))},3t:G(a){I a?E.3m(a,6).K>0:P},7c:G(a){I 6.3t("."+a)},3i:G(b){9(b==W){9(6.K){H c=6[0];9(E.11(c,"24")){H e=c.4Z,a=[],Y=c.Y,2G=c.O=="24-2G";9(e<0)I S;L(H i=2G?e:0,33=2G?e+1:Y.K;i<33;i++){H d=Y[i];9(d.26){H b=E.V.1h&&!d.9V["1Q"].9L?d.2g:d.1Q;9(2G)I b;a.1a(b)}}I a}J I 6[0].1Q.1p(/\\r/g,"")}}J I 6.N(G(){9(b.1c==1B&&/4k|5j/.14(6.O))6.2Q=(E.2A(6.1Q,b)>=0||E.2A(6.2H,b)>=0);J 9(E.11(6,"24")){H a=b.1c==1B?b:[b];E("9h",6).N(G(){6.26=(E.2A(6.1Q,a)>=0||E.2A(6.2g,a)>=0)});9(!a.K)6.4Z=-1}J 6.1Q=b})},4o:G(a){I a==W?(6.K?6[0].3O:S):6.4n().3g(a)},6H:G(a){I 6.50(a).28()},6E:G(i){I 6.2J(i,i+1)},2J:G(){I 6.2o(1B.3A.2J.16(6,1q))},1X:G(b){I 6.2o(E.1X(6,G(a,i){I b.2O(a,i,a)}))},4O:G(){I 6.1f(6.4Y)},3z:G(f,d,g,e){H c=6.K>1,a;I 6.N(G(){9(!a){a=E.4D(f,6.3H);9(g<0)a.8U()}H b=6;9(d&&E.11(6,"1I")&&E.11(a[0],"4m"))b=6.4l("1K")[0]||6.58(U.5B("1K"));E.N(a,G(){H a=c?6.4R(Q):6;9(!5A(0,a))e.2O(b,a)})})}};G 5A(i,b){H a=E.11(b,"1J");9(a){9(b.3k)E.3G({1d:b.3k,3e:P,1V:"1J"});J E.5f(b.2g||b.6s||b.3O||"");9(b.12)b.12.3b(b)}J 9(b.1y==1)E("1J",b).N(5A);I a}E.1k=E.1b.1k=G(){H c=1q[0]||{},a=1,2c=1q.K,5e=P;9(c.1c==8o){5e=c;c=1q[1]||{}}9(2c==1){c=6;a=0}H b;L(;a<2c;a++)9((b=1q[a])!=S)L(H i 1i b){9(c==b[i])6r;9(5e&&1m b[i]==\'5i\'&&c[i])E.1k(c[i],b[i]);J 9(b[i]!=W)c[i]=b[i]}I c};H F="15"+(1u 3D()).3B(),6p=0,5c={};E.1k({8a:G(a){18.$=D;9(a)18.15=w;I E},1n:G(a){I!!a&&1m a!="1M"&&!a.11&&a.1c!=1B&&/G/i.14(a+"")},4a:G(a){I a.2V&&!a.1G||a.37&&a.3H&&!a.3H.1G},5f:G(a){a=E.36(a);9(a){9(18.6l)18.6l(a);J 9(E.V.1N)18.56(a,0);J 3w.2O(18,a)}},11:G(b,a){I b.11&&b.11.27()==a.27()},1L:{},M:G(c,d,b){c=c==18?5c:c;H a=c[F];9(!a)a=c[F]=++6p;9(d&&!E.1L[a])E.1L[a]={};9(b!=W)E.1L[a][d]=b;I d?E.1L[a][d]:a},30:G(c,b){c=c==18?5c:c;H a=c[F];9(b){9(E.1L[a]){2E E.1L[a][b];b="";L(b 1i E.1L[a])1T;9(!b)E.30(c)}}J{2a{2E c[F]}29(e){9(c.53)c.53(F)}2E E.1L[a]}},N:G(a,b,c){9(c){9(a.K==W)L(H i 1i a)b.16(a[i],c);J L(H i=0,48=a.K;i<48;i++)9(b.16(a[i],c)===P)1T}J{9(a.K==W)L(H i 1i a)b.2O(a[i],i,a[i]);J L(H i=0,48=a.K,3i=a[0];i<48&&b.2O(3i,i,3i)!==P;3i=a[++i]){}}I a},1e:G(c,b,d,e,a){9(E.1n(b))b=b.2O(c,[e]);H f=/z-?4I|7T-?7Q|1r|69|7P-?1H/i;I b&&b.1c==4W&&d=="3C"&&!f.14(a)?b+"2T":b},1o:{1f:G(b,c){E.N((c||"").2l(/\\s+/),G(i,a){9(!E.1o.3K(b.1o,a))b.1o+=(b.1o?" ":"")+a})},28:G(b,c){b.1o=c!=W?E.2W(b.1o.2l(/\\s+/),G(a){I!E.1o.3K(c,a)}).66(" "):""},3K:G(t,c){I E.2A(c,(t.1o||t).3s().2l(/\\s+/))>-1}},2k:G(e,o,f){L(H i 1i o){e.R["3r"+i]=e.R[i];e.R[i]=o[i]}f.16(e,[]);L(H i 1i o)e.R[i]=e.R["3r"+i]},17:G(e,p){9(p=="1H"||p=="2N"){H b={},42,41,d=["7J","7I","7G","7F"];E.N(d,G(){b["7C"+6]=0;b["7B"+6+"5Z"]=0});E.2k(e,b,G(){9(E(e).3t(\':3R\')){42=e.7A;41=e.7w}J{e=E(e.4R(Q)).1Y(":4k").5W("2Q").2D().17({4C:"1P",2X:"4F",19:"2Z",7o:"0",1S:"0"}).5R(e.12)[0];H a=E.17(e.12,"2X")||"3V";9(a=="3V")e.12.R.2X="7g";42=e.7e;41=e.7b;9(a=="3V")e.12.R.2X="3V";e.12.3b(e)}});I p=="1H"?42:41}I E.3C(e,p)},3C:G(h,j,i){H g,2w=[],2k=[];G 3n(a){9(!E.V.1N)I P;H b=U.3o.3Z(a,S);I!b||b.4y("3n")==""}9(j=="1r"&&E.V.1h){g=E.1x(h.R,"1r");I g==""?"1":g}9(j.1t(/4u/i))j=y;9(!i&&h.R[j])g=h.R[j];J 9(U.3o&&U.3o.3Z){9(j.1t(/4u/i))j="4u";j=j.1p(/([A-Z])/g,"-$1").2p();H d=U.3o.3Z(h,S);9(d&&!3n(h))g=d.4y(j);J{L(H a=h;a&&3n(a);a=a.12)2w.4w(a);L(a=0;a<2w.K;a++)9(3n(2w[a])){2k[a]=2w[a].R.19;2w[a].R.19="2Z"}g=j=="19"&&2k[2w.K-1]!=S?"2s":U.3o.3Z(h,S).4y(j)||"";L(a=0;a<2k.K;a++)9(2k[a]!=S)2w[a].R.19=2k[a]}9(j=="1r"&&g=="")g="1"}J 9(h.3Q){H f=j.1p(/\\-(\\w)/g,G(m,c){I c.27()});g=h.3Q[j]||h.3Q[f];9(!/^\\d+(2T)?$/i.14(g)&&/^\\d/.14(g)){H k=h.R.1S;H e=h.4v.1S;h.4v.1S=h.3Q.1S;h.R.1S=g||0;g=h.R.71+"2T";h.R.1S=k;h.4v.1S=e}}I g},4D:G(a,e){H r=[];e=e||U;E.N(a,G(i,d){9(!d)I;9(d.1c==4W)d=d.3s();9(1m d=="1M"){d=d.1p(/(<(\\w+)[^>]*?)\\/>/g,G(m,a,b){I b.1t(/^(70|6Z|6Y|9Q|4t|9N|9K|3a|9G|9E)$/i)?m:a+">"});H s=E.36(d).2p(),1s=e.5B("1s"),2x=[];H c=!s.1g("<9y")&&[1,"<24>",""]||!s.1g("<9w")&&[1,"<6T>",""]||s.1t(/^<(9u|1K|9t|9r|9p)/)&&[1,"<1I>",""]||!s.1g("<4m")&&[2,"<1I><1K>",""]||(!s.1g("<9m")||!s.1g("<9k"))&&[3,"<1I><1K><4m>",""]||!s.1g("<6Y")&&[2,"<1I><1K><6L>",""]||E.V.1h&&[1,"1s<1s>",""]||[0,"",""];1s.3O=c[1]+d+c[2];1W(c[0]--)1s=1s.5p;9(E.V.1h){9(!s.1g("<1I")&&s.1g("<1K")<0)2x=1s.1w&&1s.1w.3j;J 9(c[1]=="<1I>"&&s.1g("<1K")<0)2x=1s.3j;L(H n=2x.K-1;n>=0;--n)9(E.11(2x[n],"1K")&&!2x[n].3j.K)2x[n].12.3b(2x[n]);9(/^\\s/.14(d))1s.3d(e.6F(d.1t(/^\\s*/)[0]),1s.1w)}d=E.2h(1s.3j)}9(0===d.K&&(!E.11(d,"2Y")&&!E.11(d,"24")))I;9(d[0]==W||E.11(d,"2Y")||d.Y)r.1a(d);J r=E.1R(r,d)});I r},1x:G(c,d,a){H e=E.4a(c)?{}:E.5o;9(d=="26"&&E.V.1N)c.12.4Z;9(e[d]){9(a!=W)c[e[d]]=a;I c[e[d]]}J 9(E.V.1h&&d=="R")I E.1x(c.R,"9e",a);J 9(a==W&&E.V.1h&&E.11(c,"2Y")&&(d=="9d"||d=="9a"))I c.97(d).6x;J 9(c.37){9(a!=W){9(d=="O"&&E.11(c,"4t")&&c.12)6G"O 94 93\'t 92 91";c.90(d,a)}9(E.V.1h&&/6C|3k/.14(d)&&!E.4a(c))I c.4p(d,2);I c.4p(d)}J{9(d=="1r"&&E.V.1h){9(a!=W){c.69=1;c.1E=(c.1E||"").1p(/6O\\([^)]*\\)/,"")+(3I(a).3s()=="8S"?"":"6O(1r="+a*6A+")")}I c.1E?(3I(c.1E.1t(/1r=([^)]*)/)[1])/6A).3s():""}d=d.1p(/-([a-z])/8Q,G(z,b){I b.27()});9(a!=W)c[d]=a;I c[d]}},36:G(t){I(t||"").1p(/^\\s+|\\s+$/g,"")},2h:G(a){H r=[];9(1m a!="8P")L(H i=0,2c=a.K;i<2c;i++)r.1a(a[i]);J r=a.2J(0);I r},2A:G(b,a){L(H i=0,2c=a.K;i<2c;i++)9(a[i]==b)I i;I-1},1R:G(a,b){9(E.V.1h){L(H i=0;b[i];i++)9(b[i].1y!=8)a.1a(b[i])}J L(H i=0;b[i];i++)a.1a(b[i]);I a},4V:G(b){H r=[],2f={};2a{L(H i=0,6y=b.K;i<6y;i++){H a=E.M(b[i]);9(!2f[a]){2f[a]=Q;r.1a(b[i])}}}29(e){r=b}I r},2W:G(b,a,c){9(1m a=="1M")a=3w("P||G(a,i){I "+a+"}");H d=[];L(H i=0,4g=b.K;i<4g;i++)9(!c&&a(b[i],i)||c&&!a(b[i],i))d.1a(b[i]);I d},1X:G(c,b){9(1m b=="1M")b=3w("P||G(a){I "+b+"}");H d=[];L(H i=0,4g=c.K;i<4g;i++){H a=b(c[i],i);9(a!==S&&a!=W){9(a.1c!=1B)a=[a];d=d.8M(a)}}I d}});H v=8K.8I.2p();E.V={4s:(v.1t(/.+(?:8F|8E|8C|8B)[\\/: ]([\\d.]+)/)||[])[1],1N:/6w/.14(v),34:/34/.14(v),1h:/1h/.14(v)&&!/34/.14(v),35:/35/.14(v)&&!/(8z|6w)/.14(v)};H y=E.V.1h?"4h":"5h";E.1k({5g:!E.V.1h||U.8y=="8x",4h:E.V.1h?"4h":"5h",5o:{"L":"8w","8v":"1o","4u":y,5h:y,4h:y,3O:"3O",1o:"1o",1Q:"1Q",3c:"3c",2Q:"2Q",8u:"8t",26:"26",8s:"8r"}});E.N({1D:"a.12",8q:"15.4e(a,\'12\')",8p:"15.2I(a,2,\'2q\')",8n:"15.2I(a,2,\'4d\')",8l:"15.4e(a,\'2q\')",8k:"15.4e(a,\'4d\')",8j:"15.5d(a.12.1w,a)",8i:"15.5d(a.1w)",6q:"15.11(a,\'8h\')?a.8f||a.8e.U:15.2h(a.3j)"},G(i,n){E.1b[i]=G(a){H b=E.1X(6,n);9(a&&1m a=="1M")b=E.3m(a,b);I 6.2o(E.4V(b))}});E.N({5R:"3g",8c:"6j",3d:"6g",8b:"50",89:"6H"},G(i,n){E.1b[i]=G(){H a=1q;I 6.N(G(){L(H j=0,2c=a.K;j<2c;j++)E(a[j])[n](6)})}});E.N({5W:G(a){E.1x(6,a,"");6.53(a)},88:G(c){E.1o.1f(6,c)},87:G(c){E.1o.28(6,c)},86:G(c){E.1o[E.1o.3K(6,c)?"28":"1f"](6,c)},28:G(a){9(!a||E.1E(a,[6]).r.K){E.30(6);6.12.3b(6)}},4n:G(){E("*",6).N(G(){E.30(6)});1W(6.1w)6.3b(6.1w)}},G(i,n){E.1b[i]=G(){I 6.N(n,1q)}});E.N(["85","5Z"],G(i,a){H n=a.2p();E.1b[n]=G(h){I 6[0]==18?E.V.1N&&3y["84"+a]||E.5g&&38.33(U.2V["5a"+a],U.1G["5a"+a])||U.1G["5a"+a]:6[0]==U?38.33(U.1G["6n"+a],U.1G["6m"+a]):h==W?(6.K?E.17(6[0],n):S):6.17(n,h.1c==3X?h:h+"2T")}});H C=E.V.1N&&3x(E.V.4s)<83?"(?:[\\\\w*57-]|\\\\\\\\.)":"(?:[\\\\w\\82-\\81*57-]|\\\\\\\\.)",6k=1u 47("^>\\\\s*("+C+"+)"),6i=1u 47("^("+C+"+)(#)("+C+"+)"),6h=1u 47("^([#.]?)("+C+"*)");E.1k({55:{"":"m[2]==\'*\'||15.11(a,m[2])","#":"a.4p(\'22\')==m[2]",":":{80:"im[3]-0",2I:"m[3]-0==i",6E:"m[3]-0==i",3v:"i==0",3u:"i==r.K-1",6f:"i%2==0",6e:"i%2","3v-46":"a.12.4l(\'*\')[0]==a","3u-46":"15.2I(a.12.5p,1,\'4d\')==a","7X-46":"!15.2I(a.12.5p,2,\'4d\')",1D:"a.1w",4n:"!a.1w",7W:"(a.6s||a.7V||15(a).2g()||\'\').1g(m[3])>=0",3R:\'"1P"!=a.O&&15.17(a,"19")!="2s"&&15.17(a,"4C")!="1P"\',1P:\'"1P"==a.O||15.17(a,"19")=="2s"||15.17(a,"4C")=="1P"\',7U:"!a.3c",3c:"a.3c",2Q:"a.2Q",26:"a.26||15.1x(a,\'26\')",2g:"\'2g\'==a.O",4k:"\'4k\'==a.O",5j:"\'5j\'==a.O",54:"\'54\'==a.O",52:"\'52\'==a.O",51:"\'51\'==a.O",6d:"\'6d\'==a.O",6c:"\'6c\'==a.O",2r:\'"2r"==a.O||15.11(a,"2r")\',4t:"/4t|24|6b|2r/i.14(a.11)",3K:"15.1Y(m[3],a).K",7S:"/h\\\\d/i.14(a.11)",7R:"15.2W(15.32,G(1b){I a==1b.T;}).K"}},6a:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,1u 47("^([:.#]*)("+C+"+)")],3m:G(a,c,b){H d,2b=[];1W(a&&a!=d){d=a;H f=E.1E(a,c,b);a=f.t.1p(/^\\s*,\\s*/,"");2b=b?c=f.r:E.1R(2b,f.r)}I 2b},1Y:G(t,o){9(1m t!="1M")I[t];9(o&&!o.1y)o=S;o=o||U;H d=[o],2f=[],3u;1W(t&&3u!=t){H r=[];3u=t;t=E.36(t);H l=P;H g=6k;H m=g.2S(t);9(m){H p=m[1].27();L(H i=0;d[i];i++)L(H c=d[i].1w;c;c=c.2q)9(c.1y==1&&(p=="*"||c.11.27()==p.27()))r.1a(c);d=r;t=t.1p(g,"");9(t.1g(" ")==0)6r;l=Q}J{g=/^([>+~])\\s*(\\w*)/i;9((m=g.2S(t))!=S){r=[];H p=m[2],1R={};m=m[1];L(H j=0,31=d.K;j<31;j++){H n=m=="~"||m=="+"?d[j].2q:d[j].1w;L(;n;n=n.2q)9(n.1y==1){H h=E.M(n);9(m=="~"&&1R[h])1T;9(!p||n.11.27()==p.27()){9(m=="~")1R[h]=Q;r.1a(n)}9(m=="+")1T}}d=r;t=E.36(t.1p(g,""));l=Q}}9(t&&!l){9(!t.1g(",")){9(o==d[0])d.44();2f=E.1R(2f,d);r=d=[o];t=" "+t.68(1,t.K)}J{H k=6i;H m=k.2S(t);9(m){m=[0,m[2],m[3],m[1]]}J{k=6h;m=k.2S(t)}m[2]=m[2].1p(/\\\\/g,"");H f=d[d.K-1];9(m[1]=="#"&&f&&f.3S&&!E.4a(f)){H q=f.3S(m[2]);9((E.V.1h||E.V.34)&&q&&1m q.22=="1M"&&q.22!=m[2])q=E(\'[@22="\'+m[2]+\'"]\',f)[0];d=r=q&&(!m[3]||E.11(q,m[3]))?[q]:[]}J{L(H i=0;d[i];i++){H a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];9(a=="*"&&d[i].11.2p()=="5i")a="3a";r=E.1R(r,d[i].4l(a))}9(m[1]==".")r=E.4X(r,m[2]);9(m[1]=="#"){H e=[];L(H i=0;r[i];i++)9(r[i].4p("22")==m[2]){e=[r[i]];1T}r=e}d=r}t=t.1p(k,"")}}9(t){H b=E.1E(t,r);d=r=b.r;t=E.36(b.t)}}9(t)d=[];9(d&&o==d[0])d.44();2f=E.1R(2f,d);I 2f},4X:G(r,m,a){m=" "+m+" ";H c=[];L(H i=0;r[i];i++){H b=(" "+r[i].1o+" ").1g(m)>=0;9(!a&&b||a&&!b)c.1a(r[i])}I c},1E:G(t,r,h){H d;1W(t&&t!=d){d=t;H p=E.6a,m;L(H i=0;p[i];i++){m=p[i].2S(t);9(m){t=t.7O(m[0].K);m[2]=m[2].1p(/\\\\/g,"");1T}}9(!m)1T;9(m[1]==":"&&m[2]=="5V")r=E.1E(m[3],r,Q).r;J 9(m[1]==".")r=E.4X(r,m[2],h);J 9(m[1]=="["){H g=[],O=m[3];L(H i=0,31=r.K;i<31;i++){H a=r[i],z=a[E.5o[m[2]]||m[2]];9(z==S||/6C|3k|26/.14(m[2]))z=E.1x(a,m[2])||\'\';9((O==""&&!!z||O=="="&&z==m[5]||O=="!="&&z!=m[5]||O=="^="&&z&&!z.1g(m[5])||O=="$="&&z.68(z.K-m[5].K)==m[5]||(O=="*="||O=="~=")&&z.1g(m[5])>=0)^h)g.1a(a)}r=g}J 9(m[1]==":"&&m[2]=="2I-46"){H e={},g=[],14=/(\\d*)n\\+?(\\d*)/.2S(m[3]=="6f"&&"2n"||m[3]=="6e"&&"2n+1"||!/\\D/.14(m[3])&&"n+"+m[3]||m[3]),3v=(14[1]||1)-0,d=14[2]-0;L(H i=0,31=r.K;i<31;i++){H j=r[i],12=j.12,22=E.M(12);9(!e[22]){H c=1;L(H n=12.1w;n;n=n.2q)9(n.1y==1)n.4U=c++;e[22]=Q}H b=P;9(3v==1){9(d==0||j.4U==d)b=Q}J 9((j.4U+d)%3v==0)b=Q;9(b^h)g.1a(j)}r=g}J{H f=E.55[m[1]];9(1m f!="1M")f=E.55[m[1]][m[2]];f=3w("P||G(a,i){I "+f+"}");r=E.2W(r,f,h)}}I{r:r,t:t}},4e:G(b,c){H d=[];H a=b[c];1W(a&&a!=U){9(a.1y==1)d.1a(a);a=a[c]}I d},2I:G(a,e,c,b){e=e||1;H d=0;L(;a;a=a[c])9(a.1y==1&&++d==e)1T;I a},5d:G(n,a){H r=[];L(;n;n=n.2q){9(n.1y==1&&(!a||n!=a))r.1a(n)}I r}});E.1j={1f:G(g,e,c,h){9(E.V.1h&&g.4j!=W)g=18;9(!c.2u)c.2u=6.2u++;9(h!=W){H d=c;c=G(){I d.16(6,1q)};c.M=h;c.2u=d.2u}H i=e.2l(".");e=i[0];c.O=i[1];H b=E.M(g,"2P")||E.M(g,"2P",{});H f=E.M(g,"2t",G(){H a;9(1m E=="W"||E.1j.4T)I a;a=E.1j.2t.16(g,1q);I a});H j=b[e];9(!j){j=b[e]={};9(g.4S)g.4S(e,f,P);J g.7N("43"+e,f)}j[c.2u]=c;6.1Z[e]=Q},2u:1,1Z:{},28:G(d,c,b){H e=E.M(d,"2P"),2L,4I;9(1m c=="1M"){H a=c.2l(".");c=a[0]}9(e){9(c&&c.O){b=c.4Q;c=c.O}9(!c){L(c 1i e)6.28(d,c)}J 9(e[c]){9(b)2E e[c][b.2u];J L(b 1i e[c])9(!a[1]||e[c][b].O==a[1])2E e[c][b];L(2L 1i e[c])1T;9(!2L){9(d.4P)d.4P(c,E.M(d,"2t"),P);J d.7M("43"+c,E.M(d,"2t"));2L=S;2E e[c]}}L(2L 1i e)1T;9(!2L){E.30(d,"2P");E.30(d,"2t")}}},1F:G(d,b,e,c,f){b=E.2h(b||[]);9(!e){9(6.1Z[d])E("*").1f([18,U]).1F(d,b)}J{H a,2L,1b=E.1n(e[d]||S),4N=!b[0]||!b[0].2M;9(4N)b.4w(6.4M({O:d,2m:e}));b[0].O=d;9(E.1n(E.M(e,"2t")))a=E.M(e,"2t").16(e,b);9(!1b&&e["43"+d]&&e["43"+d].16(e,b)===P)a=P;9(4N)b.44();9(f&&f.16(e,b)===P)a=P;9(1b&&c!==P&&a!==P&&!(E.11(e,\'a\')&&d=="4L")){6.4T=Q;e[d]()}6.4T=P}I a},2t:G(d){H a;d=E.1j.4M(d||18.1j||{});H b=d.O.2l(".");d.O=b[0];H c=E.M(6,"2P")&&E.M(6,"2P")[d.O],3q=1B.3A.2J.2O(1q,1);3q.4w(d);L(H j 1i c){3q[0].4Q=c[j];3q[0].M=c[j].M;9(!b[1]||c[j].O==b[1]){H e=c[j].16(6,3q);9(a!==P)a=e;9(e===P){d.2M();d.3p()}}}9(E.V.1h)d.2m=d.2M=d.3p=d.4Q=d.M=S;I a},4M:G(c){H a=c;c=E.1k({},a);c.2M=G(){9(a.2M)a.2M();a.7L=P};c.3p=G(){9(a.3p)a.3p();a.7K=Q};9(!c.2m&&c.65)c.2m=c.65;9(E.V.1N&&c.2m.1y==3)c.2m=a.2m.12;9(!c.4K&&c.4J)c.4K=c.4J==c.2m?c.7H:c.4J;9(c.64==S&&c.63!=S){H e=U.2V,b=U.1G;c.64=c.63+(e&&e.2R||b.2R||0);c.7E=c.7D+(e&&e.2B||b.2B||0)}9(!c.3Y&&(c.61||c.60))c.3Y=c.61||c.60;9(!c.5F&&c.5D)c.5F=c.5D;9(!c.3Y&&c.2r)c.3Y=(c.2r&1?1:(c.2r&2?3:(c.2r&4?2:0)));I c}};E.1b.1k({3W:G(c,a,b){I c=="5Y"?6.2G(c,a,b):6.N(G(){E.1j.1f(6,c,b||a,b&&a)})},2G:G(d,b,c){I 6.N(G(){E.1j.1f(6,d,G(a){E(6).5X(a);I(c||b).16(6,1q)},c&&b)})},5X:G(a,b){I 6.N(G(){E.1j.28(6,a,b)})},1F:G(c,a,b){I 6.N(G(){E.1j.1F(c,a,6,Q,b)})},7x:G(c,a,b){9(6[0])I E.1j.1F(c,a,6[0],P,b)},25:G(){H a=1q;I 6.4L(G(e){6.4H=0==6.4H?1:0;e.2M();I a[6.4H].16(6,[e])||P})},7v:G(f,g){G 4G(e){H p=e.4K;1W(p&&p!=6)2a{p=p.12}29(e){p=6};9(p==6)I P;I(e.O=="4x"?f:g).16(6,[e])}I 6.4x(4G).5U(4G)},2d:G(f){5T();9(E.3T)f.16(U,[E]);J E.3l.1a(G(){I f.16(6,[E])});I 6}});E.1k({3T:P,3l:[],2d:G(){9(!E.3T){E.3T=Q;9(E.3l){E.N(E.3l,G(){6.16(U)});E.3l=S}9(E.V.35||E.V.34)U.4P("5S",E.2d,P);9(!18.7t.K)E(18).39(G(){E("#4E").28()})}}});E.N(("7s,7r,39,7q,6n,5Y,4L,7p,"+"7n,7m,7l,4x,5U,7k,24,"+"51,7j,7i,7h,3U").2l(","),G(i,o){E.1b[o]=G(f){I f?6.3W(o,f):6.1F(o)}});H x=P;G 5T(){9(x)I;x=Q;9(E.V.35||E.V.34)U.4S("5S",E.2d,P);J 9(E.V.1h){U.7f("<7d"+"7y 22=4E 7z=Q "+"3k=//:><\\/1J>");H a=U.3S("4E");9(a)a.62=G(){9(6.2C!="1l")I;E.2d()};a=S}J 9(E.V.1N)E.4B=4j(G(){9(U.2C=="5Q"||U.2C=="1l"){4A(E.4B);E.4B=S;E.2d()}},10);E.1j.1f(18,"39",E.2d)}E.1b.1k({39:G(g,d,c){9(E.1n(g))I 6.3W("39",g);H e=g.1g(" ");9(e>=0){H i=g.2J(e,g.K);g=g.2J(0,e)}c=c||G(){};H f="4z";9(d)9(E.1n(d)){c=d;d=S}J{d=E.3a(d);f="5P"}H h=6;E.3G({1d:g,O:f,M:d,1l:G(a,b){9(b=="1C"||b=="5O")h.4o(i?E("<1s/>").3g(a.40.1p(/<1J(.|\\s)*?\\/1J>/g,"")).1Y(i):a.40);56(G(){h.N(c,[a.40,b,a])},13)}});I 6},7a:G(){I E.3a(6.5M())},5M:G(){I 6.1X(G(){I E.11(6,"2Y")?E.2h(6.79):6}).1E(G(){I 6.2H&&!6.3c&&(6.2Q||/24|6b/i.14(6.11)||/2g|1P|52/i.14(6.O))}).1X(G(i,c){H b=E(6).3i();I b==S?S:b.1c==1B?E.1X(b,G(a,i){I{2H:c.2H,1Q:a}}):{2H:c.2H,1Q:b}}).21()}});E.N("5L,5K,6t,5J,5I,5H".2l(","),G(i,o){E.1b[o]=G(f){I 6.3W(o,f)}});H B=(1u 3D).3B();E.1k({21:G(d,b,a,c){9(E.1n(b)){a=b;b=S}I E.3G({O:"4z",1d:d,M:b,1C:a,1V:c})},78:G(b,a){I E.21(b,S,a,"1J")},77:G(c,b,a){I E.21(c,b,a,"45")},76:G(d,b,a,c){9(E.1n(b)){a=b;b={}}I E.3G({O:"5P",1d:d,M:b,1C:a,1V:c})},75:G(a){E.1k(E.59,a)},59:{1Z:Q,O:"4z",2z:0,5G:"74/x-73-2Y-72",6o:Q,3e:Q,M:S},49:{},3G:G(s){H f,2y=/=(\\?|%3F)/g,1v,M;s=E.1k(Q,s,E.1k(Q,{},E.59,s));9(s.M&&s.6o&&1m s.M!="1M")s.M=E.3a(s.M);9(s.1V=="4b"){9(s.O.2p()=="21"){9(!s.1d.1t(2y))s.1d+=(s.1d.1t(/\\?/)?"&":"?")+(s.4b||"5E")+"=?"}J 9(!s.M||!s.M.1t(2y))s.M=(s.M?s.M+"&":"")+(s.4b||"5E")+"=?";s.1V="45"}9(s.1V=="45"&&(s.M&&s.M.1t(2y)||s.1d.1t(2y))){f="4b"+B++;9(s.M)s.M=s.M.1p(2y,"="+f);s.1d=s.1d.1p(2y,"="+f);s.1V="1J";18[f]=G(a){M=a;1C();1l();18[f]=W;2a{2E 18[f]}29(e){}}}9(s.1V=="1J"&&s.1L==S)s.1L=P;9(s.1L===P&&s.O.2p()=="21")s.1d+=(s.1d.1t(/\\?/)?"&":"?")+"57="+(1u 3D()).3B();9(s.M&&s.O.2p()=="21"){s.1d+=(s.1d.1t(/\\?/)?"&":"?")+s.M;s.M=S}9(s.1Z&&!E.5b++)E.1j.1F("5L");9(!s.1d.1g("8g")&&s.1V=="1J"){H h=U.4l("9U")[0];H g=U.5B("1J");g.3k=s.1d;9(!f&&(s.1C||s.1l)){H j=P;g.9R=g.62=G(){9(!j&&(!6.2C||6.2C=="5Q"||6.2C=="1l")){j=Q;1C();1l();h.3b(g)}}}h.58(g);I}H k=P;H i=18.6X?1u 6X("9P.9O"):1u 6W();i.9M(s.O,s.1d,s.3e);9(s.M)i.5C("9J-9I",s.5G);9(s.5y)i.5C("9H-5x-9F",E.49[s.1d]||"9D, 9C 9B 9A 5v:5v:5v 9z");i.5C("X-9x-9v","6W");9(s.6U)s.6U(i);9(s.1Z)E.1j.1F("5H",[i,s]);H c=G(a){9(!k&&i&&(i.2C==4||a=="2z")){k=Q;9(d){4A(d);d=S}1v=a=="2z"&&"2z"||!E.6S(i)&&"3U"||s.5y&&E.6R(i,s.1d)&&"5O"||"1C";9(1v=="1C"){2a{M=E.6Q(i,s.1V)}29(e){1v="5k"}}9(1v=="1C"){H b;2a{b=i.5s("6P-5x")}29(e){}9(s.5y&&b)E.49[s.1d]=b;9(!f)1C()}J E.5r(s,i,1v);1l();9(s.3e)i=S}};9(s.3e){H d=4j(c,13);9(s.2z>0)56(G(){9(i){i.9q();9(!k)c("2z")}},s.2z)}2a{i.9o(s.M)}29(e){E.5r(s,i,S,e)}9(!s.3e)c();I i;G 1C(){9(s.1C)s.1C(M,1v);9(s.1Z)E.1j.1F("5I",[i,s])}G 1l(){9(s.1l)s.1l(i,1v);9(s.1Z)E.1j.1F("6t",[i,s]);9(s.1Z&&!--E.5b)E.1j.1F("5K")}},5r:G(s,a,b,e){9(s.3U)s.3U(a,b,e);9(s.1Z)E.1j.1F("5J",[a,s,e])},5b:0,6S:G(r){2a{I!r.1v&&9n.9l=="54:"||(r.1v>=6N&&r.1v<9j)||r.1v==6M||E.V.1N&&r.1v==W}29(e){}I P},6R:G(a,c){2a{H b=a.5s("6P-5x");I a.1v==6M||b==E.49[c]||E.V.1N&&a.1v==W}29(e){}I P},6Q:G(r,b){H c=r.5s("9i-O");H d=b=="6K"||!b&&c&&c.1g("6K")>=0;H a=d?r.9g:r.40;9(d&&a.2V.37=="5k")6G"5k";9(b=="1J")E.5f(a);9(b=="45")a=3w("("+a+")");I a},3a:G(a){H s=[];9(a.1c==1B||a.4c)E.N(a,G(){s.1a(3f(6.2H)+"="+3f(6.1Q))});J L(H j 1i a)9(a[j]&&a[j].1c==1B)E.N(a[j],G(){s.1a(3f(j)+"="+3f(6))});J s.1a(3f(j)+"="+3f(a[j]));I s.66("&").1p(/%20/g,"+")}});E.1b.1k({1A:G(b,a){I b?6.1U({1H:"1A",2N:"1A",1r:"1A"},b,a):6.1E(":1P").N(G(){6.R.19=6.3h?6.3h:"";9(E.17(6,"19")=="2s")6.R.19="2Z"}).2D()},1z:G(b,a){I b?6.1U({1H:"1z",2N:"1z",1r:"1z"},b,a):6.1E(":3R").N(G(){6.3h=6.3h||E.17(6,"19");9(6.3h=="2s")6.3h="2Z";6.R.19="2s"}).2D()},6J:E.1b.25,25:G(a,b){I E.1n(a)&&E.1n(b)?6.6J(a,b):a?6.1U({1H:"25",2N:"25",1r:"25"},a,b):6.N(G(){E(6)[E(6).3t(":1P")?"1A":"1z"]()})},9c:G(b,a){I 6.1U({1H:"1A"},b,a)},9b:G(b,a){I 6.1U({1H:"1z"},b,a)},99:G(b,a){I 6.1U({1H:"25"},b,a)},98:G(b,a){I 6.1U({1r:"1A"},b,a)},96:G(b,a){I 6.1U({1r:"1z"},b,a)},95:G(c,a,b){I 6.1U({1r:a},c,b)},1U:G(k,i,h,g){H j=E.6D(i,h,g);I 6[j.3L===P?"N":"3L"](G(){j=E.1k({},j);H f=E(6).3t(":1P"),3y=6;L(H p 1i k){9(k[p]=="1z"&&f||k[p]=="1A"&&!f)I E.1n(j.1l)&&j.1l.16(6);9(p=="1H"||p=="2N"){j.19=E.17(6,"19");j.2U=6.R.2U}}9(j.2U!=S)6.R.2U="1P";j.3M=E.1k({},k);E.N(k,G(c,a){H e=1u E.2j(3y,j,c);9(/25|1A|1z/.14(a))e[a=="25"?f?"1A":"1z":a](k);J{H b=a.3s().1t(/^([+-]=)?([\\d+-.]+)(.*)$/),1O=e.2b(Q)||0;9(b){H d=3I(b[2]),2i=b[3]||"2T";9(2i!="2T"){3y.R[c]=(d||1)+2i;1O=((d||1)/e.2b(Q))*1O;3y.R[c]=1O+2i}9(b[1])d=((b[1]=="-="?-1:1)*d)+1O;e.3N(1O,d,2i)}J e.3N(1O,a,"")}});I Q})},3L:G(a,b){9(E.1n(a)){b=a;a="2j"}9(!a||(1m a=="1M"&&!b))I A(6[0],a);I 6.N(G(){9(b.1c==1B)A(6,a,b);J{A(6,a).1a(b);9(A(6,a).K==1)b.16(6)}})},9f:G(){H a=E.32;I 6.N(G(){L(H i=0;i-8O?r:3I(E.17(6.T,6.1e))||0},3N:G(c,b,e){6.5u=(1u 3D()).3B();6.1O=c;6.2D=b;6.2i=e||6.2i||"2T";6.2v=6.1O;6.4q=6.4i=0;6.4r();H f=6;G t(){I f.2F()}t.T=6.T;E.32.1a(t);9(E.32.K==1){H d=4j(G(){H a=E.32;L(H i=0;i6.Y.2e+6.5u){6.2v=6.2D;6.4q=6.4i=1;6.4r();6.Y.3M[6.1e]=Q;H a=Q;L(H i 1i 6.Y.3M)9(6.Y.3M[i]!==Q)a=P;9(a){9(6.Y.19!=S){6.T.R.2U=6.Y.2U;6.T.R.19=6.Y.19;9(E.17(6.T,"19")=="2s")6.T.R.19="2Z"}9(6.Y.1z)6.T.R.19="2s";9(6.Y.1z||6.Y.1A)L(H p 1i 6.Y.3M)E.1x(6.T.R,p,6.Y.3P[p])}9(a&&E.1n(6.Y.1l))6.Y.1l.16(6.T);I P}J{H n=t-6.5u;6.4i=n/6.Y.2e;6.4q=E.3J[6.Y.3J||(E.3J.5q?"5q":"6B")](6.4i,n,0,1,6.Y.2e);6.2v=6.1O+((6.2D-6.1O)*6.4q);6.4r()}I Q}};E.2j.2F={2R:G(a){a.T.2R=a.2v},2B:G(a){a.T.2B=a.2v},1r:G(a){E.1x(a.T.R,"1r",a.2v)},6z:G(a){a.T.R[a.1e]=a.2v+a.2i}};E.1b.6m=G(){H c=0,3E=0,T=6[0],5t;9(T)8L(E.V){H b=E.17(T,"2X")=="4F",1D=T.12,23=T.23,2K=T.3H,4f=1N&&3x(4s)<8J;9(T.6V){5w=T.6V();1f(5w.1S+38.33(2K.2V.2R,2K.1G.2R),5w.3E+38.33(2K.2V.2B,2K.1G.2B));9(1h){H d=E("4o").17("8H");d=(d=="8G"||E.5g&&3x(4s)>=7)&&2||d;1f(-d,-d)}}J{1f(T.5l,T.5z);1W(23){1f(23.5l,23.5z);9(35&&/^t[d|h]$/i.14(1D.37)||!4f)d(23);9(4f&&!b&&E.17(23,"2X")=="4F")b=Q;23=23.23}1W(1D.37&&!/^1G|4o$/i.14(1D.37)){9(!/^8D|1I-9S.*$/i.14(E.17(1D,"19")))1f(-1D.2R,-1D.2B);9(35&&E.17(1D,"2U")!="3R")d(1D);1D=1D.12}9(4f&&b)1f(-2K.1G.5l,-2K.1G.5z)}5t={3E:3E,1S:c}}I 5t;G d(a){1f(E.17(a,"9T"),E.17(a,"8A"))}G 1f(l,t){c+=3x(l)||0;3E+=3x(t)||0}}})();',62,616,'||||||this|||if|||||||||||||||||||||||||||||||||function|var|return|else|length|for|data|each|type|false|true|style|null|elem|document|browser|undefined||options|||nodeName|parentNode||test|jQuery|apply|css|window|display|push|fn|constructor|url|prop|add|indexOf|msie|in|event|extend|complete|typeof|isFunction|className|replace|arguments|opacity|div|match|new|status|firstChild|attr|nodeType|hide|show|Array|success|parent|filter|trigger|body|height|table|script|tbody|cache|string|safari|start|hidden|value|merge|left|break|animate|dataType|while|map|find|global||get|id|offsetParent|select|toggle|selected|toUpperCase|remove|catch|try|cur|al|ready|duration|done|text|makeArray|unit|fx|swap|split|target||pushStack|toLowerCase|nextSibling|button|none|handle|guid|now|stack|tb|jsre|timeout|inArray|scrollTop|readyState|end|delete|step|one|name|nth|slice|doc|ret|preventDefault|width|call|events|checked|scrollLeft|exec|px|overflow|documentElement|grep|position|form|block|removeData|rl|timers|max|opera|mozilla|trim|tagName|Math|load|param|removeChild|disabled|insertBefore|async|encodeURIComponent|append|oldblock|val|childNodes|src|readyList|multiFilter|color|defaultView|stopPropagation|args|old|toString|is|last|first|eval|parseInt|self|domManip|prototype|getTime|curCSS|Date|top||ajax|ownerDocument|parseFloat|easing|has|queue|curAnim|custom|innerHTML|orig|currentStyle|visible|getElementById|isReady|error|static|bind|String|which|getComputedStyle|responseText|oWidth|oHeight|on|shift|json|child|RegExp|ol|lastModified|isXMLDoc|jsonp|jquery|previousSibling|dir|safari2|el|styleFloat|state|setInterval|radio|getElementsByTagName|tr|empty|html|getAttribute|pos|update|version|input|float|runtimeStyle|unshift|mouseover|getPropertyValue|GET|clearInterval|safariTimer|visibility|clean|__ie_init|absolute|handleHover|lastToggle|index|fromElement|relatedTarget|click|fix|evt|andSelf|removeEventListener|handler|cloneNode|addEventListener|triggered|nodeIndex|unique|Number|classFilter|prevObject|selectedIndex|after|submit|password|removeAttribute|file|expr|setTimeout|_|appendChild|ajaxSettings|client|active|win|sibling|deep|globalEval|boxModel|cssFloat|object|checkbox|parsererror|offsetLeft|wrapAll|dequeue|props|lastChild|swing|handleError|getResponseHeader|results|startTime|00|box|Modified|ifModified|offsetTop|evalScript|createElement|setRequestHeader|ctrlKey|callback|metaKey|contentType|ajaxSend|ajaxSuccess|ajaxError|ajaxStop|ajaxStart|serializeArray|init|notmodified|POST|loaded|appendTo|DOMContentLoaded|bindReady|mouseout|not|removeAttr|unbind|unload|Width|keyCode|charCode|onreadystatechange|clientX|pageX|srcElement|join|outerHTML|substr|zoom|parse|textarea|reset|image|odd|even|before|quickClass|quickID|prepend|quickChild|execScript|offset|scroll|processData|uuid|contents|continue|textContent|ajaxComplete|clone|setArray|webkit|nodeValue|fl|_default|100|linear|href|speed|eq|createTextNode|throw|replaceWith|splice|_toggle|xml|colgroup|304|200|alpha|Last|httpData|httpNotModified|httpSuccess|fieldset|beforeSend|getBoundingClientRect|XMLHttpRequest|ActiveXObject|col|br|abbr|pixelLeft|urlencoded|www|application|ajaxSetup|post|getJSON|getScript|elements|serialize|clientWidth|hasClass|scr|clientHeight|write|relative|keyup|keypress|keydown|change|mousemove|mouseup|mousedown|right|dblclick|resize|focus|blur|frames|instanceof|hover|offsetWidth|triggerHandler|ipt|defer|offsetHeight|border|padding|clientY|pageY|Left|Right|toElement|Bottom|Top|cancelBubble|returnValue|detachEvent|attachEvent|substring|line|weight|animated|header|font|enabled|innerText|contains|only|size|gt|lt|uFFFF|u0128|417|inner|Height|toggleClass|removeClass|addClass|replaceAll|noConflict|insertAfter|prependTo|wrap|contentWindow|contentDocument|http|iframe|children|siblings|prevAll|nextAll|wrapInner|prev|Boolean|next|parents|maxLength|maxlength|readOnly|readonly|class|htmlFor|CSS1Compat|compatMode|compatible|borderTopWidth|ie|ra|inline|it|rv|medium|borderWidth|userAgent|522|navigator|with|concat|1px|10000|array|ig|PI|NaN|400|reverse|fast|600|slow|Function|Object|setAttribute|changed|be|can|property|fadeTo|fadeOut|getAttributeNode|fadeIn|slideToggle|method|slideUp|slideDown|action|cssText|stop|responseXML|option|content|300|th|protocol|td|location|send|cap|abort|colg|cos|tfoot|thead|With|leg|Requested|opt|GMT|1970|Jan|01|Thu|area|Since|hr|If|Type|Content|meta|specified|open|link|XMLHTTP|Microsoft|img|onload|row|borderLeftWidth|head|attributes'.split('|'),0,{})) \ No newline at end of file diff --git a/test/otherlibs/jquery/1.2.3/jquery.js b/test/otherlibs/jquery/1.2.3/jquery.js deleted file mode 100644 index 74cdfee1..00000000 --- a/test/otherlibs/jquery/1.2.3/jquery.js +++ /dev/null @@ -1,11 +0,0 @@ -/* - * jQuery 1.2.3 - New Wave Javascript - * - * Copyright (c) 2008 John Resig (jquery.com) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ - * $Rev: 4663 $ - */ -eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(J(){7(1e.3N)L w=1e.3N;L E=1e.3N=J(a,b){K 1B E.2l.4T(a,b)};7(1e.$)L D=1e.$;1e.$=E;L u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/;L G=/^.[^:#\\[\\.]*$/;E.1n=E.2l={4T:J(d,b){d=d||T;7(d.15){6[0]=d;6.M=1;K 6}N 7(1o d=="25"){L c=u.2O(d);7(c&&(c[1]||!b)){7(c[1])d=E.4a([c[1]],b);N{L a=T.5J(c[3]);7(a)7(a.2w!=c[3])K E().2s(d);N{6[0]=a;6.M=1;K 6}N d=[]}}N K 1B E(b).2s(d)}N 7(E.1q(d))K 1B E(T)[E.1n.21?"21":"3U"](d);K 6.6E(d.1k==1M&&d||(d.5h||d.M&&d!=1e&&!d.15&&d[0]!=10&&d[0].15)&&E.2I(d)||[d])},5h:"1.2.3",87:J(){K 6.M},M:0,22:J(a){K a==10?E.2I(6):6[a]},2F:J(b){L a=E(b);a.54=6;K a},6E:J(a){6.M=0;1M.2l.1g.1i(6,a);K 6},R:J(a,b){K E.R(6,a,b)},4X:J(b){L a=-1;6.R(J(i){7(6==b)a=i});K a},1J:J(c,a,b){L d=c;7(c.1k==4e)7(a==10)K 6.M&&E[b||"1J"](6[0],c)||10;N{d={};d[c]=a}K 6.R(J(i){Q(c 1p d)E.1J(b?6.W:6,c,E.1l(6,d[c],b,i,c))})},1j:J(b,a){7((b==\'27\'||b==\'1R\')&&2M(a)<0)a=10;K 6.1J(b,a,"2o")},1u:J(b){7(1o b!="3V"&&b!=V)K 6.4x().3t((6[0]&&6[0].2i||T).5r(b));L a="";E.R(b||6,J(){E.R(6.3p,J(){7(6.15!=8)a+=6.15!=1?6.6K:E.1n.1u([6])})});K a},5m:J(b){7(6[0])E(b,6[0].2i).5k().3o(6[0]).2c(J(){L a=6;2b(a.1C)a=a.1C;K a}).3t(6);K 6},8w:J(a){K 6.R(J(){E(6).6z().5m(a)})},8p:J(a){K 6.R(J(){E(6).5m(a)})},3t:J(){K 6.3O(18,P,S,J(a){7(6.15==1)6.38(a)})},6q:J(){K 6.3O(18,P,P,J(a){7(6.15==1)6.3o(a,6.1C)})},6o:J(){K 6.3O(18,S,S,J(a){6.1a.3o(a,6)})},5a:J(){K 6.3O(18,S,P,J(a){6.1a.3o(a,6.2B)})},3h:J(){K 6.54||E([])},2s:J(b){L c=E.2c(6,J(a){K E.2s(b,a)});K 6.2F(/[^+>] [^+>]/.17(b)||b.1f("..")>-1?E.57(c):c)},5k:J(e){L f=6.2c(J(){7(E.14.1d&&!E.3E(6)){L a=6.69(P),4Y=T.3s("1x");4Y.38(a);K E.4a([4Y.3d])[0]}N K 6.69(P)});L d=f.2s("*").4R().R(J(){7(6[F]!=10)6[F]=V});7(e===P)6.2s("*").4R().R(J(i){7(6.15==3)K;L c=E.O(6,"2R");Q(L a 1p c)Q(L b 1p c[a])E.16.1b(d[i],a,c[a][b],c[a][b].O)});K f},1E:J(b){K 6.2F(E.1q(b)&&E.3y(6,J(a,i){K b.1P(a,i)})||E.3e(b,6))},56:J(b){7(b.1k==4e)7(G.17(b))K 6.2F(E.3e(b,6,P));N b=E.3e(b,6);L a=b.M&&b[b.M-1]!==10&&!b.15;K 6.1E(J(){K a?E.33(6,b)<0:6!=b})},1b:J(a){K!a?6:6.2F(E.37(6.22(),a.1k==4e?E(a).22():a.M!=10&&(!a.12||E.12(a,"3u"))?a:[a]))},3H:J(a){K a?E.3e(a,6).M>0:S},7j:J(a){K 6.3H("."+a)},5O:J(b){7(b==10){7(6.M){L c=6[0];7(E.12(c,"2k")){L e=c.3T,5I=[],11=c.11,2X=c.U=="2k-2X";7(e<0)K V;Q(L i=2X?e:0,2f=2X?e+1:11.M;i<2f;i++){L d=11[i];7(d.2p){b=E.14.1d&&!d.9J.1A.9y?d.1u:d.1A;7(2X)K b;5I.1g(b)}}K 5I}N K(6[0].1A||"").1r(/\\r/g,"")}K 10}K 6.R(J(){7(6.15!=1)K;7(b.1k==1M&&/5u|5t/.17(6.U))6.3k=(E.33(6.1A,b)>=0||E.33(6.31,b)>=0);N 7(E.12(6,"2k")){L a=b.1k==1M?b:[b];E("98",6).R(J(){6.2p=(E.33(6.1A,a)>=0||E.33(6.1u,a)>=0)});7(!a.M)6.3T=-1}N 6.1A=b})},3q:J(a){K a==10?(6.M?6[0].3d:V):6.4x().3t(a)},6S:J(a){K 6.5a(a).1V()},6Z:J(i){K 6.2K(i,i+1)},2K:J(){K 6.2F(1M.2l.2K.1i(6,18))},2c:J(b){K 6.2F(E.2c(6,J(a,i){K b.1P(a,i,a)}))},4R:J(){K 6.1b(6.54)},O:J(d,b){L a=d.23(".");a[1]=a[1]?"."+a[1]:"";7(b==V){L c=6.5n("8P"+a[1]+"!",[a[0]]);7(c==10&&6.M)c=E.O(6[0],d);K c==V&&a[1]?6.O(a[0]):c}N K 6.1N("8K"+a[1]+"!",[a[0],b]).R(J(){E.O(6,d,b)})},35:J(a){K 6.R(J(){E.35(6,a)})},3O:J(g,f,h,d){L e=6.M>1,3n;K 6.R(J(){7(!3n){3n=E.4a(g,6.2i);7(h)3n.8D()}L b=6;7(f&&E.12(6,"1O")&&E.12(3n[0],"4v"))b=6.3S("1U")[0]||6.38(6.2i.3s("1U"));L c=E([]);E.R(3n,J(){L a=e?E(6).5k(P)[0]:6;7(E.12(a,"1m")){c=c.1b(a)}N{7(a.15==1)c=c.1b(E("1m",a).1V());d.1P(b,a)}});c.R(6A)})}};E.2l.4T.2l=E.2l;J 6A(i,a){7(a.3Q)E.3P({1c:a.3Q,3l:S,1H:"1m"});N E.5g(a.1u||a.6x||a.3d||"");7(a.1a)a.1a.34(a)}E.1s=E.1n.1s=J(){L b=18[0]||{},i=1,M=18.M,5c=S,11;7(b.1k==8d){5c=b;b=18[1]||{};i=2}7(1o b!="3V"&&1o b!="J")b={};7(M==1){b=6;i=0}Q(;i-1}},68:J(b,c,a){L e={};Q(L d 1p c){e[d]=b.W[d];b.W[d]=c[d]}a.1P(b);Q(L d 1p c)b.W[d]=e[d]},1j:J(d,e,c){7(e=="27"||e=="1R"){L b,46={43:"4W",4U:"1Z",19:"3D"},3c=e=="27"?["7O","7M"]:["7J","7I"];J 5E(){b=e=="27"?d.7H:d.7F;L a=0,2N=0;E.R(3c,J(){a+=2M(E.2o(d,"7E"+6,P))||0;2N+=2M(E.2o(d,"2N"+6+"5X",P))||0});b-=24.7C(a+2N)}7(E(d).3H(":4d"))5E();N E.68(d,46,5E);K 24.2f(0,b)}K E.2o(d,e,c)},2o:J(e,k,j){L d;J 3x(b){7(!E.14.2d)K S;L a=T.4c.4K(b,V);K!a||a.4M("3x")==""}7(k=="1w"&&E.14.1d){d=E.1J(e.W,"1w");K d==""?"1":d}7(E.14.2z&&k=="19"){L c=e.W.50;e.W.50="0 7r 7o";e.W.50=c}7(k.1D(/4g/i))k=y;7(!j&&e.W&&e.W[k])d=e.W[k];N 7(T.4c&&T.4c.4K){7(k.1D(/4g/i))k="4g";k=k.1r(/([A-Z])/g,"-$1").2h();L h=T.4c.4K(e,V);7(h&&!3x(e))d=h.4M(k);N{L f=[],2C=[];Q(L a=e;a&&3x(a);a=a.1a)2C.4J(a);Q(L i=0;i<2C.M;i++)7(3x(2C[i])){f[i]=2C[i].W.19;2C[i].W.19="3D"}d=k=="19"&&f[2C.M-1]!=V?"2H":(h&&h.4M(k))||"";Q(L i=0;i]*?)\\/>/g,J(b,a,c){K c.1D(/^(aa|a6|7e|a5|4D|7a|a0|3m|9W|9U|9S)$/i)?b:a+">"});L f=E.3g(d).2h(),1x=h.3s("1x");L e=!f.1f("<9P")&&[1,"<2k 74=\'74\'>",""]||!f.1f("<9M")&&[1,"<73>",""]||f.1D(/^<(9G|1U|9E|9B|9x)/)&&[1,"<1O>",""]||!f.1f("<4v")&&[2,"<1O><1U>",""]||(!f.1f("<9w")||!f.1f("<9v"))&&[3,"<1O><1U><4v>",""]||!f.1f("<7e")&&[2,"<1O><1U><6V>",""]||E.14.1d&&[1,"1x<1x>",""]||[0,"",""];1x.3d=e[1]+d+e[2];2b(e[0]--)1x=1x.5o;7(E.14.1d){L g=!f.1f("<1O")&&f.1f("<1U")<0?1x.1C&&1x.1C.3p:e[1]=="<1O>"&&f.1f("<1U")<0?1x.3p:[];Q(L j=g.M-1;j>=0;--j)7(E.12(g[j],"1U")&&!g[j].3p.M)g[j].1a.34(g[j]);7(/^\\s/.17(d))1x.3o(h.5r(d.1D(/^\\s*/)[0]),1x.1C)}d=E.2I(1x.3p)}7(d.M===0&&(!E.12(d,"3u")&&!E.12(d,"2k")))K;7(d[0]==10||E.12(d,"3u")||d.11)k.1g(d);N k=E.37(k,d)});K k},1J:J(d,e,c){7(!d||d.15==3||d.15==8)K 10;L f=E.3E(d)?{}:E.46;7(e=="2p"&&E.14.2d)d.1a.3T;7(f[e]){7(c!=10)d[f[e]]=c;K d[f[e]]}N 7(E.14.1d&&e=="W")K E.1J(d.W,"9u",c);N 7(c==10&&E.14.1d&&E.12(d,"3u")&&(e=="9r"||e=="9o"))K d.9m(e).6K;N 7(d.28){7(c!=10){7(e=="U"&&E.12(d,"4D")&&d.1a)6Q"U 9i 9h\'t 9g 9e";d.9b(e,""+c)}7(E.14.1d&&/6O|3Q/.17(e)&&!E.3E(d))K d.4z(e,2);K d.4z(e)}N{7(e=="1w"&&E.14.1d){7(c!=10){d.6k=1;d.1E=(d.1E||"").1r(/6M\\([^)]*\\)/,"")+(2M(c).3X()=="96"?"":"6M(1w="+c*6L+")")}K d.1E&&d.1E.1f("1w=")>=0?(2M(d.1E.1D(/1w=([^)]*)/)[1])/6L).3X():""}e=e.1r(/-([a-z])/95,J(a,b){K b.2E()});7(c!=10)d[e]=c;K d[e]}},3g:J(a){K(a||"").1r(/^\\s+|\\s+$/g,"")},2I:J(b){L a=[];7(1o b!="93")Q(L i=0,M=b.M;i*",6).1V();2b(6.1C)6.34(6.1C)}},J(a,b){E.1n[a]=J(){K 6.R(b,18)}});E.R(["8f","5X"],J(i,c){L b=c.2h();E.1n[b]=J(a){K 6[0]==1e?E.14.2z&&T.1h["5e"+c]||E.14.2d&&1e["8e"+c]||T.6F=="79"&&T.1F["5e"+c]||T.1h["5e"+c]:6[0]==T?24.2f(24.2f(T.1h["5d"+c],T.1F["5d"+c]),24.2f(T.1h["5L"+c],T.1F["5L"+c])):a==10?(6.M?E.1j(6[0],b):V):6.1j(b,a.1k==4e?a:a+"2S")}});L C=E.14.2d&&4s(E.14.5K)<8c?"(?:[\\\\w*4r-]|\\\\\\\\.)":"(?:[\\\\w\\8b-\\8a*4r-]|\\\\\\\\.)",6v=1B 4q("^>\\\\s*("+C+"+)"),6u=1B 4q("^("+C+"+)(#)("+C+"+)"),6s=1B 4q("^([#.]?)("+C+"*)");E.1s({6r:{"":J(a,i,m){K m[2]=="*"||E.12(a,m[2])},"#":J(a,i,m){K a.4z("2w")==m[2]},":":{89:J(a,i,m){K im[3]-0},2Z:J(a,i,m){K m[3]-0==i},6Z:J(a,i,m){K m[3]-0==i},3j:J(a,i){K i==0},3J:J(a,i,m,r){K i==r.M-1},6n:J(a,i){K i%2==0},6l:J(a,i){K i%2},"3j-4p":J(a){K a.1a.3S("*")[0]==a},"3J-4p":J(a){K E.2Z(a.1a.5o,1,"4t")==a},"83-4p":J(a){K!E.2Z(a.1a.5o,2,"4t")},6B:J(a){K a.1C},4x:J(a){K!a.1C},82:J(a,i,m){K(a.6x||a.81||E(a).1u()||"").1f(m[3])>=0},4d:J(a){K"1Z"!=a.U&&E.1j(a,"19")!="2H"&&E.1j(a,"4U")!="1Z"},1Z:J(a){K"1Z"==a.U||E.1j(a,"19")=="2H"||E.1j(a,"4U")=="1Z"},80:J(a){K!a.2Y},2Y:J(a){K a.2Y},3k:J(a){K a.3k},2p:J(a){K a.2p||E.1J(a,"2p")},1u:J(a){K"1u"==a.U},5u:J(a){K"5u"==a.U},5t:J(a){K"5t"==a.U},59:J(a){K"59"==a.U},3I:J(a){K"3I"==a.U},58:J(a){K"58"==a.U},6j:J(a){K"6j"==a.U},6i:J(a){K"6i"==a.U},2G:J(a){K"2G"==a.U||E.12(a,"2G")},4D:J(a){K/4D|2k|6h|2G/i.17(a.12)},3Y:J(a,i,m){K E.2s(m[3],a).M},7X:J(a){K/h\\d/i.17(a.12)},7W:J(a){K E.3y(E.3G,J(b){K a==b.Y}).M}}},6g:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,1B 4q("^([:.#]*)("+C+"+)")],3e:J(a,c,b){L d,2m=[];2b(a&&a!=d){d=a;L f=E.1E(a,c,b);a=f.t.1r(/^\\s*,\\s*/,"");2m=b?c=f.r:E.37(2m,f.r)}K 2m},2s:J(t,p){7(1o t!="25")K[t];7(p&&p.15!=1&&p.15!=9)K[];p=p||T;L d=[p],2r=[],3J,12;2b(t&&3J!=t){L r=[];3J=t;t=E.3g(t);L o=S;L g=6v;L m=g.2O(t);7(m){12=m[1].2E();Q(L i=0;d[i];i++)Q(L c=d[i].1C;c;c=c.2B)7(c.15==1&&(12=="*"||c.12.2E()==12))r.1g(c);d=r;t=t.1r(g,"");7(t.1f(" ")==0)6w;o=P}N{g=/^([>+~])\\s*(\\w*)/i;7((m=g.2O(t))!=V){r=[];L l={};12=m[2].2E();m=m[1];Q(L j=0,3f=d.M;j<3f;j++){L n=m=="~"||m=="+"?d[j].2B:d[j].1C;Q(;n;n=n.2B)7(n.15==1){L h=E.O(n);7(m=="~"&&l[h])1Q;7(!12||n.12.2E()==12){7(m=="~")l[h]=P;r.1g(n)}7(m=="+")1Q}}d=r;t=E.3g(t.1r(g,""));o=P}}7(t&&!o){7(!t.1f(",")){7(p==d[0])d.4l();2r=E.37(2r,d);r=d=[p];t=" "+t.6e(1,t.M)}N{L k=6u;L m=k.2O(t);7(m){m=[0,m[2],m[3],m[1]]}N{k=6s;m=k.2O(t)}m[2]=m[2].1r(/\\\\/g,"");L f=d[d.M-1];7(m[1]=="#"&&f&&f.5J&&!E.3E(f)){L q=f.5J(m[2]);7((E.14.1d||E.14.2z)&&q&&1o q.2w=="25"&&q.2w!=m[2])q=E(\'[@2w="\'+m[2]+\'"]\',f)[0];d=r=q&&(!m[3]||E.12(q,m[3]))?[q]:[]}N{Q(L i=0;d[i];i++){L a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];7(a=="*"&&d[i].12.2h()=="3V")a="3m";r=E.37(r,d[i].3S(a))}7(m[1]==".")r=E.55(r,m[2]);7(m[1]=="#"){L e=[];Q(L i=0;r[i];i++)7(r[i].4z("2w")==m[2]){e=[r[i]];1Q}r=e}d=r}t=t.1r(k,"")}}7(t){L b=E.1E(t,r);d=r=b.r;t=E.3g(b.t)}}7(t)d=[];7(d&&p==d[0])d.4l();2r=E.37(2r,d);K 2r},55:J(r,m,a){m=" "+m+" ";L c=[];Q(L i=0;r[i];i++){L b=(" "+r[i].1t+" ").1f(m)>=0;7(!a&&b||a&&!b)c.1g(r[i])}K c},1E:J(t,r,h){L d;2b(t&&t!=d){d=t;L p=E.6g,m;Q(L i=0;p[i];i++){m=p[i].2O(t);7(m){t=t.7V(m[0].M);m[2]=m[2].1r(/\\\\/g,"");1Q}}7(!m)1Q;7(m[1]==":"&&m[2]=="56")r=G.17(m[3])?E.1E(m[3],r,P).r:E(r).56(m[3]);N 7(m[1]==".")r=E.55(r,m[2],h);N 7(m[1]=="["){L g=[],U=m[3];Q(L i=0,3f=r.M;i<3f;i++){L a=r[i],z=a[E.46[m[2]]||m[2]];7(z==V||/6O|3Q|2p/.17(m[2]))z=E.1J(a,m[2])||\'\';7((U==""&&!!z||U=="="&&z==m[5]||U=="!="&&z!=m[5]||U=="^="&&z&&!z.1f(m[5])||U=="$="&&z.6e(z.M-m[5].M)==m[5]||(U=="*="||U=="~=")&&z.1f(m[5])>=0)^h)g.1g(a)}r=g}N 7(m[1]==":"&&m[2]=="2Z-4p"){L e={},g=[],17=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2O(m[3]=="6n"&&"2n"||m[3]=="6l"&&"2n+1"||!/\\D/.17(m[3])&&"7U+"+m[3]||m[3]),3j=(17[1]+(17[2]||1))-0,d=17[3]-0;Q(L i=0,3f=r.M;i<3f;i++){L j=r[i],1a=j.1a,2w=E.O(1a);7(!e[2w]){L c=1;Q(L n=1a.1C;n;n=n.2B)7(n.15==1)n.4k=c++;e[2w]=P}L b=S;7(3j==0){7(j.4k==d)b=P}N 7((j.4k-d)%3j==0&&(j.4k-d)/3j>=0)b=P;7(b^h)g.1g(j)}r=g}N{L f=E.6r[m[1]];7(1o f=="3V")f=f[m[2]];7(1o f=="25")f=6c("S||J(a,i){K "+f+";}");r=E.3y(r,J(a,i){K f(a,i,m,r)},h)}}K{r:r,t:t}},4u:J(b,c){L d=[];L a=b[c];2b(a&&a!=T){7(a.15==1)d.1g(a);a=a[c]}K d},2Z:J(a,e,c,b){e=e||1;L d=0;Q(;a;a=a[c])7(a.15==1&&++d==e)1Q;K a},5i:J(n,a){L r=[];Q(;n;n=n.2B){7(n.15==1&&(!a||n!=a))r.1g(n)}K r}});E.16={1b:J(f,i,g,e){7(f.15==3||f.15==8)K;7(E.14.1d&&f.53!=10)f=1e;7(!g.2D)g.2D=6.2D++;7(e!=10){L h=g;g=J(){K h.1i(6,18)};g.O=e;g.2D=h.2D}L j=E.O(f,"2R")||E.O(f,"2R",{}),1v=E.O(f,"1v")||E.O(f,"1v",J(){L a;7(1o E=="10"||E.16.5f)K a;a=E.16.1v.1i(18.3R.Y,18);K a});1v.Y=f;E.R(i.23(/\\s+/),J(c,b){L a=b.23(".");b=a[0];g.U=a[1];L d=j[b];7(!d){d=j[b]={};7(!E.16.2y[b]||E.16.2y[b].4j.1P(f)===S){7(f.3F)f.3F(b,1v,S);N 7(f.6b)f.6b("4i"+b,1v)}}d[g.2D]=g;E.16.2a[b]=P});f=V},2D:1,2a:{},1V:J(e,h,f){7(e.15==3||e.15==8)K;L i=E.O(e,"2R"),29,4X;7(i){7(h==10||(1o h=="25"&&h.7T(0)=="."))Q(L g 1p i)6.1V(e,g+(h||""));N{7(h.U){f=h.2q;h=h.U}E.R(h.23(/\\s+/),J(b,a){L c=a.23(".");a=c[0];7(i[a]){7(f)2V i[a][f.2D];N Q(f 1p i[a])7(!c[1]||i[a][f].U==c[1])2V i[a][f];Q(29 1p i[a])1Q;7(!29){7(!E.16.2y[a]||E.16.2y[a].4h.1P(e)===S){7(e.67)e.67(a,E.O(e,"1v"),S);N 7(e.66)e.66("4i"+a,E.O(e,"1v"))}29=V;2V i[a]}}})}Q(29 1p i)1Q;7(!29){L d=E.O(e,"1v");7(d)d.Y=V;E.35(e,"2R");E.35(e,"1v")}}},1N:J(g,c,d,f,h){c=E.2I(c||[]);7(g.1f("!")>=0){g=g.2K(0,-1);L a=P}7(!d){7(6.2a[g])E("*").1b([1e,T]).1N(g,c)}N{7(d.15==3||d.15==8)K 10;L b,29,1n=E.1q(d[g]||V),16=!c[0]||!c[0].36;7(16)c.4J(6.4Z({U:g,2L:d}));c[0].U=g;7(a)c[0].65=P;7(E.1q(E.O(d,"1v")))b=E.O(d,"1v").1i(d,c);7(!1n&&d["4i"+g]&&d["4i"+g].1i(d,c)===S)b=S;7(16)c.4l();7(h&&E.1q(h)){29=h.1i(d,b==V?c:c.71(b));7(29!==10)b=29}7(1n&&f!==S&&b!==S&&!(E.12(d,\'a\')&&g=="4V")){6.5f=P;1S{d[g]()}1X(e){}}6.5f=S}K b},1v:J(c){L a;c=E.16.4Z(c||1e.16||{});L b=c.U.23(".");c.U=b[0];L f=E.O(6,"2R")&&E.O(6,"2R")[c.U],42=1M.2l.2K.1P(18,1);42.4J(c);Q(L j 1p f){L d=f[j];42[0].2q=d;42[0].O=d.O;7(!b[1]&&!c.65||d.U==b[1]){L e=d.1i(6,42);7(a!==S)a=e;7(e===S){c.36();c.44()}}}7(E.14.1d)c.2L=c.36=c.44=c.2q=c.O=V;K a},4Z:J(c){L a=c;c=E.1s({},a);c.36=J(){7(a.36)a.36();a.7S=S};c.44=J(){7(a.44)a.44();a.7R=P};7(!c.2L)c.2L=c.7Q||T;7(c.2L.15==3)c.2L=a.2L.1a;7(!c.4S&&c.5w)c.4S=c.5w==c.2L?c.7P:c.5w;7(c.64==V&&c.63!=V){L b=T.1F,1h=T.1h;c.64=c.63+(b&&b.2v||1h&&1h.2v||0)-(b.62||0);c.7N=c.7L+(b&&b.2x||1h&&1h.2x||0)-(b.60||0)}7(!c.3c&&((c.4f||c.4f===0)?c.4f:c.5Z))c.3c=c.4f||c.5Z;7(!c.7b&&c.5Y)c.7b=c.5Y;7(!c.3c&&c.2G)c.3c=(c.2G&1?1:(c.2G&2?3:(c.2G&4?2:0)));K c},2y:{21:{4j:J(){5M();K},4h:J(){K}},3C:{4j:J(){7(E.14.1d)K S;E(6).2j("4P",E.16.2y.3C.2q);K P},4h:J(){7(E.14.1d)K S;E(6).3w("4P",E.16.2y.3C.2q);K P},2q:J(a){7(I(a,6))K P;18[0].U="3C";K E.16.1v.1i(6,18)}},3B:{4j:J(){7(E.14.1d)K S;E(6).2j("4O",E.16.2y.3B.2q);K P},4h:J(){7(E.14.1d)K S;E(6).3w("4O",E.16.2y.3B.2q);K P},2q:J(a){7(I(a,6))K P;18[0].U="3B";K E.16.1v.1i(6,18)}}}};E.1n.1s({2j:J(c,a,b){K c=="4H"?6.2X(c,a,b):6.R(J(){E.16.1b(6,c,b||a,b&&a)})},2X:J(d,b,c){K 6.R(J(){E.16.1b(6,d,J(a){E(6).3w(a);K(c||b).1i(6,18)},c&&b)})},3w:J(a,b){K 6.R(J(){E.16.1V(6,a,b)})},1N:J(c,a,b){K 6.R(J(){E.16.1N(c,a,6,P,b)})},5n:J(c,a,b){7(6[0])K E.16.1N(c,a,6[0],S,b);K 10},2g:J(){L b=18;K 6.4V(J(a){6.4N=0==6.4N?1:0;a.36();K b[6.4N].1i(6,18)||S})},7D:J(a,b){K 6.2j(\'3C\',a).2j(\'3B\',b)},21:J(a){5M();7(E.2Q)a.1P(T,E);N E.3A.1g(J(){K a.1P(6,E)});K 6}});E.1s({2Q:S,3A:[],21:J(){7(!E.2Q){E.2Q=P;7(E.3A){E.R(E.3A,J(){6.1i(T)});E.3A=V}E(T).5n("21")}}});L x=S;J 5M(){7(x)K;x=P;7(T.3F&&!E.14.2z)T.3F("5W",E.21,S);7(E.14.1d&&1e==3b)(J(){7(E.2Q)K;1S{T.1F.7B("26")}1X(3a){3z(18.3R,0);K}E.21()})();7(E.14.2z)T.3F("5W",J(){7(E.2Q)K;Q(L i=0;i=0){L i=g.2K(e,g.M);g=g.2K(0,e)}c=c||J(){};L f="4Q";7(d)7(E.1q(d)){c=d;d=V}N{d=E.3m(d);f="61"}L h=6;E.3P({1c:g,U:f,1H:"3q",O:d,1y:J(a,b){7(b=="1W"||b=="5U")h.3q(i?E("<1x/>").3t(a.4b.1r(/<1m(.|\\s)*?\\/1m>/g,"")).2s(i):a.4b);h.R(c,[a.4b,b,a])}});K 6},7n:J(){K E.3m(6.5T())},5T:J(){K 6.2c(J(){K E.12(6,"3u")?E.2I(6.7m):6}).1E(J(){K 6.31&&!6.2Y&&(6.3k||/2k|6h/i.17(6.12)||/1u|1Z|3I/i.17(6.U))}).2c(J(i,c){L b=E(6).5O();K b==V?V:b.1k==1M?E.2c(b,J(a,i){K{31:c.31,1A:a}}):{31:c.31,1A:b}}).22()}});E.R("5S,6d,5R,6D,5Q,6m".23(","),J(i,o){E.1n[o]=J(f){K 6.2j(o,f)}});L B=(1B 3v).3L();E.1s({22:J(d,b,a,c){7(E.1q(b)){a=b;b=V}K E.3P({U:"4Q",1c:d,O:b,1W:a,1H:c})},7l:J(b,a){K E.22(b,V,a,"1m")},7k:J(c,b,a){K E.22(c,b,a,"3i")},7i:J(d,b,a,c){7(E.1q(b)){a=b;b={}}K E.3P({U:"61",1c:d,O:b,1W:a,1H:c})},85:J(a){E.1s(E.4I,a)},4I:{2a:P,U:"4Q",2U:0,5P:"4o/x-7h-3u-7g",5N:P,3l:P,O:V,6p:V,3I:V,49:{3M:"4o/3M, 1u/3M",3q:"1u/3q",1m:"1u/4m, 4o/4m",3i:"4o/3i, 1u/4m",1u:"1u/a7",4G:"*/*"}},4F:{},3P:J(s){L f,2W=/=\\?(&|$)/g,1z,O;s=E.1s(P,s,E.1s(P,{},E.4I,s));7(s.O&&s.5N&&1o s.O!="25")s.O=E.3m(s.O);7(s.1H=="4E"){7(s.U.2h()=="22"){7(!s.1c.1D(2W))s.1c+=(s.1c.1D(/\\?/)?"&":"?")+(s.4E||"7d")+"=?"}N 7(!s.O||!s.O.1D(2W))s.O=(s.O?s.O+"&":"")+(s.4E||"7d")+"=?";s.1H="3i"}7(s.1H=="3i"&&(s.O&&s.O.1D(2W)||s.1c.1D(2W))){f="4E"+B++;7(s.O)s.O=(s.O+"").1r(2W,"="+f+"$1");s.1c=s.1c.1r(2W,"="+f+"$1");s.1H="1m";1e[f]=J(a){O=a;1W();1y();1e[f]=10;1S{2V 1e[f]}1X(e){}7(h)h.34(g)}}7(s.1H=="1m"&&s.1T==V)s.1T=S;7(s.1T===S&&s.U.2h()=="22"){L i=(1B 3v()).3L();L j=s.1c.1r(/(\\?|&)4r=.*?(&|$)/,"$a4="+i+"$2");s.1c=j+((j==s.1c)?(s.1c.1D(/\\?/)?"&":"?")+"4r="+i:"")}7(s.O&&s.U.2h()=="22"){s.1c+=(s.1c.1D(/\\?/)?"&":"?")+s.O;s.O=V}7(s.2a&&!E.5H++)E.16.1N("5S");7((!s.1c.1f("a3")||!s.1c.1f("//"))&&s.1H=="1m"&&s.U.2h()=="22"){L h=T.3S("6f")[0];L g=T.3s("1m");g.3Q=s.1c;7(s.7c)g.a2=s.7c;7(!f){L l=S;g.9Z=g.9Y=J(){7(!l&&(!6.39||6.39=="5V"||6.39=="1y")){l=P;1W();1y();h.34(g)}}}h.38(g);K 10}L m=S;L k=1e.78?1B 78("9X.9V"):1B 76();k.9T(s.U,s.1c,s.3l,s.6p,s.3I);1S{7(s.O)k.4C("9R-9Q",s.5P);7(s.5C)k.4C("9O-5A-9N",E.4F[s.1c]||"9L, 9K 9I 9H 5z:5z:5z 9F");k.4C("X-9C-9A","76");k.4C("9z",s.1H&&s.49[s.1H]?s.49[s.1H]+", */*":s.49.4G)}1X(e){}7(s.6Y)s.6Y(k);7(s.2a)E.16.1N("6m",[k,s]);L c=J(a){7(!m&&k&&(k.39==4||a=="2U")){m=P;7(d){6I(d);d=V}1z=a=="2U"&&"2U"||!E.6X(k)&&"3a"||s.5C&&E.6J(k,s.1c)&&"5U"||"1W";7(1z=="1W"){1S{O=E.6W(k,s.1H)}1X(e){1z="5x"}}7(1z=="1W"){L b;1S{b=k.5q("6U-5A")}1X(e){}7(s.5C&&b)E.4F[s.1c]=b;7(!f)1W()}N E.5v(s,k,1z);1y();7(s.3l)k=V}};7(s.3l){L d=53(c,13);7(s.2U>0)3z(J(){7(k){k.9t();7(!m)c("2U")}},s.2U)}1S{k.9s(s.O)}1X(e){E.5v(s,k,V,e)}7(!s.3l)c();J 1W(){7(s.1W)s.1W(O,1z);7(s.2a)E.16.1N("5Q",[k,s])}J 1y(){7(s.1y)s.1y(k,1z);7(s.2a)E.16.1N("5R",[k,s]);7(s.2a&&!--E.5H)E.16.1N("6d")}K k},5v:J(s,a,b,e){7(s.3a)s.3a(a,b,e);7(s.2a)E.16.1N("6D",[a,s,e])},5H:0,6X:J(r){1S{K!r.1z&&9q.9p=="59:"||(r.1z>=6T&&r.1z<9n)||r.1z==6R||r.1z==9l||E.14.2d&&r.1z==10}1X(e){}K S},6J:J(a,c){1S{L b=a.5q("6U-5A");K a.1z==6R||b==E.4F[c]||E.14.2d&&a.1z==10}1X(e){}K S},6W:J(r,b){L c=r.5q("9k-U");L d=b=="3M"||!b&&c&&c.1f("3M")>=0;L a=d?r.9j:r.4b;7(d&&a.1F.28=="5x")6Q"5x";7(b=="1m")E.5g(a);7(b=="3i")a=6c("("+a+")");K a},3m:J(a){L s=[];7(a.1k==1M||a.5h)E.R(a,J(){s.1g(3r(6.31)+"="+3r(6.1A))});N Q(L j 1p a)7(a[j]&&a[j].1k==1M)E.R(a[j],J(){s.1g(3r(j)+"="+3r(6))});N s.1g(3r(j)+"="+3r(a[j]));K s.6a("&").1r(/%20/g,"+")}});E.1n.1s({1G:J(c,b){K c?6.2e({1R:"1G",27:"1G",1w:"1G"},c,b):6.1E(":1Z").R(J(){6.W.19=6.5s||"";7(E.1j(6,"19")=="2H"){L a=E("<"+6.28+" />").6y("1h");6.W.19=a.1j("19");7(6.W.19=="2H")6.W.19="3D";a.1V()}}).3h()},1I:J(b,a){K b?6.2e({1R:"1I",27:"1I",1w:"1I"},b,a):6.1E(":4d").R(J(){6.5s=6.5s||E.1j(6,"19");6.W.19="2H"}).3h()},6N:E.1n.2g,2g:J(a,b){K E.1q(a)&&E.1q(b)?6.6N(a,b):a?6.2e({1R:"2g",27:"2g",1w:"2g"},a,b):6.R(J(){E(6)[E(6).3H(":1Z")?"1G":"1I"]()})},9f:J(b,a){K 6.2e({1R:"1G"},b,a)},9d:J(b,a){K 6.2e({1R:"1I"},b,a)},9c:J(b,a){K 6.2e({1R:"2g"},b,a)},9a:J(b,a){K 6.2e({1w:"1G"},b,a)},99:J(b,a){K 6.2e({1w:"1I"},b,a)},97:J(c,a,b){K 6.2e({1w:a},c,b)},2e:J(l,k,j,h){L i=E.6P(k,j,h);K 6[i.2P===S?"R":"2P"](J(){7(6.15!=1)K S;L g=E.1s({},i);L f=E(6).3H(":1Z"),4A=6;Q(L p 1p l){7(l[p]=="1I"&&f||l[p]=="1G"&&!f)K E.1q(g.1y)&&g.1y.1i(6);7(p=="1R"||p=="27"){g.19=E.1j(6,"19");g.32=6.W.32}}7(g.32!=V)6.W.32="1Z";g.40=E.1s({},l);E.R(l,J(c,a){L e=1B E.2t(4A,g,c);7(/2g|1G|1I/.17(a))e[a=="2g"?f?"1G":"1I":a](l);N{L b=a.3X().1D(/^([+-]=)?([\\d+-.]+)(.*)$/),1Y=e.2m(P)||0;7(b){L d=2M(b[2]),2A=b[3]||"2S";7(2A!="2S"){4A.W[c]=(d||1)+2A;1Y=((d||1)/e.2m(P))*1Y;4A.W[c]=1Y+2A}7(b[1])d=((b[1]=="-="?-1:1)*d)+1Y;e.45(1Y,d,2A)}N e.45(1Y,a,"")}});K P})},2P:J(a,b){7(E.1q(a)||(a&&a.1k==1M)){b=a;a="2t"}7(!a||(1o a=="25"&&!b))K A(6[0],a);K 6.R(J(){7(b.1k==1M)A(6,a,b);N{A(6,a).1g(b);7(A(6,a).M==1)b.1i(6)}})},94:J(b,c){L a=E.3G;7(b)6.2P([]);6.R(J(){Q(L i=a.M-1;i>=0;i--)7(a[i].Y==6){7(c)a[i](P);a.72(i,1)}});7(!c)6.5p();K 6}});L A=J(b,c,a){7(!b)K 10;c=c||"2t";L q=E.O(b,c+"2P");7(!q||a)q=E.O(b,c+"2P",a?E.2I(a):[]);K q};E.1n.5p=J(a){a=a||"2t";K 6.R(J(){L q=A(6,a);q.4l();7(q.M)q[0].1i(6)})};E.1s({6P:J(b,a,c){L d=b&&b.1k==92?b:{1y:c||!c&&a||E.1q(b)&&b,2u:b,3Z:c&&a||a&&a.1k!=91&&a};d.2u=(d.2u&&d.2u.1k==51?d.2u:{90:8Z,9D:6T}[d.2u])||8X;d.5y=d.1y;d.1y=J(){7(d.2P!==S)E(6).5p();7(E.1q(d.5y))d.5y.1i(6)};K d},3Z:{70:J(p,n,b,a){K b+a*p},5j:J(p,n,b,a){K((-24.8V(p*24.8U)/2)+0.5)*a+b}},3G:[],3W:V,2t:J(b,c,a){6.11=c;6.Y=b;6.1l=a;7(!c.47)c.47={}}});E.2t.2l={4y:J(){7(6.11.30)6.11.30.1i(6.Y,[6.2J,6]);(E.2t.30[6.1l]||E.2t.30.4G)(6);7(6.1l=="1R"||6.1l=="27")6.Y.W.19="3D"},2m:J(a){7(6.Y[6.1l]!=V&&6.Y.W[6.1l]==V)K 6.Y[6.1l];L r=2M(E.1j(6.Y,6.1l,a));K r&&r>-8Q?r:2M(E.2o(6.Y,6.1l))||0},45:J(c,b,d){6.5B=(1B 3v()).3L();6.1Y=c;6.3h=b;6.2A=d||6.2A||"2S";6.2J=6.1Y;6.4B=6.4w=0;6.4y();L e=6;J t(a){K e.30(a)}t.Y=6.Y;E.3G.1g(t);7(E.3W==V){E.3W=53(J(){L a=E.3G;Q(L i=0;i6.11.2u+6.5B){6.2J=6.3h;6.4B=6.4w=1;6.4y();6.11.40[6.1l]=P;L b=P;Q(L i 1p 6.11.40)7(6.11.40[i]!==P)b=S;7(b){7(6.11.19!=V){6.Y.W.32=6.11.32;6.Y.W.19=6.11.19;7(E.1j(6.Y,"19")=="2H")6.Y.W.19="3D"}7(6.11.1I)6.Y.W.19="2H";7(6.11.1I||6.11.1G)Q(L p 1p 6.11.40)E.1J(6.Y.W,p,6.11.47[p])}7(b&&E.1q(6.11.1y))6.11.1y.1i(6.Y);K S}N{L n=t-6.5B;6.4w=n/6.11.2u;6.4B=E.3Z[6.11.3Z||(E.3Z.5j?"5j":"70")](6.4w,n,0,1,6.11.2u);6.2J=6.1Y+((6.3h-6.1Y)*6.4B);6.4y()}K P}};E.2t.30={2v:J(a){a.Y.2v=a.2J},2x:J(a){a.Y.2x=a.2J},1w:J(a){E.1J(a.Y.W,"1w",a.2J)},4G:J(a){a.Y.W[a.1l]=a.2J+a.2A}};E.1n.5L=J(){L b=0,3b=0,Y=6[0],5l;7(Y)8M(E.14){L d=Y.1a,41=Y,1K=Y.1K,1L=Y.2i,5D=2d&&4s(5K)<8J&&!/a1/i.17(v),2T=E.1j(Y,"43")=="2T";7(Y.6G){L c=Y.6G();1b(c.26+24.2f(1L.1F.2v,1L.1h.2v),c.3b+24.2f(1L.1F.2x,1L.1h.2x));1b(-1L.1F.62,-1L.1F.60)}N{1b(Y.5G,Y.5F);2b(1K){1b(1K.5G,1K.5F);7(48&&!/^t(8H|d|h)$/i.17(1K.28)||2d&&!5D)2N(1K);7(!2T&&E.1j(1K,"43")=="2T")2T=P;41=/^1h$/i.17(1K.28)?41:1K;1K=1K.1K}2b(d&&d.28&&!/^1h|3q$/i.17(d.28)){7(!/^8G|1O.*$/i.17(E.1j(d,"19")))1b(-d.2v,-d.2x);7(48&&E.1j(d,"32")!="4d")2N(d);d=d.1a}7((5D&&(2T||E.1j(41,"43")=="4W"))||(48&&E.1j(41,"43")!="4W"))1b(-1L.1h.5G,-1L.1h.5F);7(2T)1b(24.2f(1L.1F.2v,1L.1h.2v),24.2f(1L.1F.2x,1L.1h.2x))}5l={3b:3b,26:b}}J 2N(a){1b(E.2o(a,"a8",P),E.2o(a,"a9",P))}J 1b(l,t){b+=4s(l)||0;3b+=4s(t)||0}K 5l}})();',62,631,'||||||this|if||||||||||||||||||||||||||||||||||||||function|return|var|length|else|data|true|for|each|false|document|type|null|style||elem||undefined|options|nodeName||browser|nodeType|event|test|arguments|display|parentNode|add|url|msie|window|indexOf|push|body|apply|css|constructor|prop|script|fn|typeof|in|isFunction|replace|extend|className|text|handle|opacity|div|complete|status|value|new|firstChild|match|filter|documentElement|show|dataType|hide|attr|offsetParent|doc|Array|trigger|table|call|break|height|try|cache|tbody|remove|success|catch|start|hidden||ready|get|split|Math|string|left|width|tagName|ret|global|while|map|safari|animate|max|toggle|toLowerCase|ownerDocument|bind|select|prototype|cur||curCSS|selected|handler|done|find|fx|duration|scrollLeft|id|scrollTop|special|opera|unit|nextSibling|stack|guid|toUpperCase|pushStack|button|none|makeArray|now|slice|target|parseFloat|border|exec|queue|isReady|events|px|fixed|timeout|delete|jsre|one|disabled|nth|step|name|overflow|inArray|removeChild|removeData|preventDefault|merge|appendChild|readyState|error|top|which|innerHTML|multiFilter|rl|trim|end|json|first|checked|async|param|elems|insertBefore|childNodes|html|encodeURIComponent|createElement|append|form|Date|unbind|color|grep|setTimeout|readyList|mouseleave|mouseenter|block|isXMLDoc|addEventListener|timers|is|password|last|runtimeStyle|getTime|xml|jQuery|domManip|ajax|src|callee|getElementsByTagName|selectedIndex|load|object|timerId|toString|has|easing|curAnim|offsetChild|args|position|stopPropagation|custom|props|orig|mozilla|accepts|clean|responseText|defaultView|visible|String|charCode|float|teardown|on|setup|nodeIndex|shift|javascript|currentStyle|application|child|RegExp|_|parseInt|previousSibling|dir|tr|state|empty|update|getAttribute|self|pos|setRequestHeader|input|jsonp|lastModified|_default|unload|ajaxSettings|unshift|getComputedStyle|styleSheets|getPropertyValue|lastToggle|mouseout|mouseover|GET|andSelf|relatedTarget|init|visibility|click|absolute|index|container|fix|outline|Number|removeAttribute|setInterval|prevObject|classFilter|not|unique|submit|file|after|windowData|deep|scroll|client|triggered|globalEval|jquery|sibling|swing|clone|results|wrapAll|triggerHandler|lastChild|dequeue|getResponseHeader|createTextNode|oldblock|checkbox|radio|handleError|fromElement|parsererror|old|00|Modified|startTime|ifModified|safari2|getWH|offsetTop|offsetLeft|active|values|getElementById|version|offset|bindReady|processData|val|contentType|ajaxSuccess|ajaxComplete|ajaxStart|serializeArray|notmodified|loaded|DOMContentLoaded|Width|ctrlKey|keyCode|clientTop|POST|clientLeft|clientX|pageX|exclusive|detachEvent|removeEventListener|swap|cloneNode|join|attachEvent|eval|ajaxStop|substr|head|parse|textarea|reset|image|zoom|odd|ajaxSend|even|before|username|prepend|expr|quickClass|uuid|quickID|quickChild|continue|textContent|appendTo|contents|evalScript|parent|defaultValue|ajaxError|setArray|compatMode|getBoundingClientRect|styleFloat|clearInterval|httpNotModified|nodeValue|100|alpha|_toggle|href|speed|throw|304|replaceWith|200|Last|colgroup|httpData|httpSuccess|beforeSend|eq|linear|concat|splice|fieldset|multiple|cssFloat|XMLHttpRequest|webkit|ActiveXObject|CSS1Compat|link|metaKey|scriptCharset|callback|col|pixelLeft|urlencoded|www|post|hasClass|getJSON|getScript|elements|serialize|black|keyup|keypress|solid|change|mousemove|mouseup|dblclick|resize|focus|blur|stylesheet|rel|doScroll|round|hover|padding|offsetHeight|mousedown|offsetWidth|Bottom|Top|keydown|clientY|Right|pageY|Left|toElement|srcElement|cancelBubble|returnValue|charAt|0n|substring|animated|header|noConflict|line|enabled|innerText|contains|only|weight|ajaxSetup|font|size|gt|lt|uFFFF|u0128|417|Boolean|inner|Height|toggleClass|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|contentWindow|contentDocument|wrap|iframe|children|siblings|prevAll|nextAll|prev|wrapInner|next|parents|maxLength|maxlength|readOnly|readonly|reverse|class|htmlFor|inline|able|boxModel|522|setData|compatible|with|1px|ie|getData|10000|ra|it|rv|PI|cos|userAgent|400|navigator|600|slow|Function|Object|array|stop|ig|NaN|fadeTo|option|fadeOut|fadeIn|setAttribute|slideToggle|slideUp|changed|slideDown|be|can|property|responseXML|content|1223|getAttributeNode|300|method|protocol|location|action|send|abort|cssText|th|td|cap|specified|Accept|With|colg|Requested|fast|tfoot|GMT|thead|1970|Jan|attributes|01|Thu|leg|Since|If|opt|Type|Content|embed|open|area|XMLHTTP|hr|Microsoft|onreadystatechange|onload|meta|adobeair|charset|http|1_|img|br|plain|borderLeftWidth|borderTopWidth|abbr'.split('|'),0,{})) \ No newline at end of file diff --git a/test/otherlibs/mootools/1.11/mootools.js b/test/otherlibs/mootools/1.11/mootools.js deleted file mode 100644 index 16fb3b0c..00000000 --- a/test/otherlibs/mootools/1.11/mootools.js +++ /dev/null @@ -1,1577 +0,0 @@ -//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006-2007 Valerio Proietti, , MIT Style License. - -var MooTools = { - version: '1.11' -}; - -function $defined(obj){ - return (obj != undefined); -}; - -function $type(obj){ - if (!$defined(obj)) return false; - if (obj.htmlElement) return 'element'; - var type = typeof obj; - if (type == 'object' && obj.nodeName){ - switch(obj.nodeType){ - case 1: return 'element'; - case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; - } - } - if (type == 'object' || type == 'function'){ - switch(obj.constructor){ - case Array: return 'array'; - case RegExp: return 'regexp'; - case Class: return 'class'; - } - if (typeof obj.length == 'number'){ - if (obj.item) return 'collection'; - if (obj.callee) return 'arguments'; - } - } - return type; -}; - -function $merge(){ - var mix = {}; - for (var i = 0; i < arguments.length; i++){ - for (var property in arguments[i]){ - var ap = arguments[i][property]; - var mp = mix[property]; - if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap); - else mix[property] = ap; - } - } - return mix; -}; - -var $extend = function(){ - var args = arguments; - if (!args[1]) args = [this, args[0]]; - for (var property in args[1]) args[0][property] = args[1][property]; - return args[0]; -}; - -var $native = function(){ - for (var i = 0, l = arguments.length; i < l; i++){ - arguments[i].extend = function(props){ - for (var prop in props){ - if (!this.prototype[prop]) this.prototype[prop] = props[prop]; - if (!this[prop]) this[prop] = $native.generic(prop); - } - }; - } -}; - -$native.generic = function(prop){ - return function(bind){ - return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1)); - }; -}; - -$native(Function, Array, String, Number); - -function $chk(obj){ - return !!(obj || obj === 0); -}; - -function $pick(obj, picked){ - return $defined(obj) ? obj : picked; -}; - -function $random(min, max){ - return Math.floor(Math.random() * (max - min + 1) + min); -}; - -function $time(){ - return new Date().getTime(); -}; - -function $clear(timer){ - clearTimeout(timer); - clearInterval(timer); - return null; -}; - -var Abstract = function(obj){ - obj = obj || {}; - obj.extend = $extend; - return obj; -}; - -var Window = new Abstract(window); -var Document = new Abstract(document); -document.head = document.getElementsByTagName('head')[0]; - -window.xpath = !!(document.evaluate); -if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true; -else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true; -else if (document.getBoxObjectFor != null) window.gecko = true; - -window.khtml = window.webkit; - -Object.extend = $extend; - -if (typeof HTMLElement == 'undefined'){ - var HTMLElement = function(){}; - if (window.webkit) document.createElement("iframe"); - HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {}; -} -HTMLElement.prototype.htmlElement = function(){}; - -if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch(e){}; - -var Class = function(properties){ - var klass = function(){ - return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this; - }; - $extend(klass, this); - klass.prototype = properties; - klass.constructor = Class; - return klass; -}; - -Class.empty = function(){}; - -Class.prototype = { - - extend: function(properties){ - var proto = new this(null); - for (var property in properties){ - var pp = proto[property]; - proto[property] = Class.Merge(pp, properties[property]); - } - return new Class(proto); - }, - - implement: function(){ - for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]); - } - -}; - -Class.Merge = function(previous, current){ - if (previous && previous != current){ - var type = $type(current); - if (type != $type(previous)) return current; - switch(type){ - case 'function': - var merged = function(){ - this.parent = arguments.callee.parent; - return current.apply(this, arguments); - }; - merged.parent = previous; - return merged; - case 'object': return $merge(previous, current); - } - } - return current; -}; - -var Chain = new Class({ - - chain: function(fn){ - this.chains = this.chains || []; - this.chains.push(fn); - return this; - }, - - callChain: function(){ - if (this.chains && this.chains.length) this.chains.shift().delay(10, this); - }, - - clearChain: function(){ - this.chains = []; - } - -}); - -var Events = new Class({ - - addEvent: function(type, fn){ - if (fn != Class.empty){ - this.$events = this.$events || {}; - this.$events[type] = this.$events[type] || []; - this.$events[type].include(fn); - } - return this; - }, - - fireEvent: function(type, args, delay){ - if (this.$events && this.$events[type]){ - this.$events[type].each(function(fn){ - fn.create({'bind': this, 'delay': delay, 'arguments': args})(); - }, this); - } - return this; - }, - - removeEvent: function(type, fn){ - if (this.$events && this.$events[type]) this.$events[type].remove(fn); - return this; - } - -}); - -var Options = new Class({ - - setOptions: function(){ - this.options = $merge.apply(null, [this.options].extend(arguments)); - if (this.addEvent){ - for (var option in this.options){ - if ($type(this.options[option] == 'function') && (/^on[A-Z]/).test(option)) this.addEvent(option, this.options[option]); - } - } - return this; - } - -}); - -Array.extend({ - - forEach: function(fn, bind){ - for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this); - }, - - filter: function(fn, bind){ - var results = []; - for (var i = 0, j = this.length; i < j; i++){ - if (fn.call(bind, this[i], i, this)) results.push(this[i]); - } - return results; - }, - - map: function(fn, bind){ - var results = []; - for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this); - return results; - }, - - every: function(fn, bind){ - for (var i = 0, j = this.length; i < j; i++){ - if (!fn.call(bind, this[i], i, this)) return false; - } - return true; - }, - - some: function(fn, bind){ - for (var i = 0, j = this.length; i < j; i++){ - if (fn.call(bind, this[i], i, this)) return true; - } - return false; - }, - - indexOf: function(item, from){ - var len = this.length; - for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ - if (this[i] === item) return i; - } - return -1; - }, - - copy: function(start, length){ - start = start || 0; - if (start < 0) start = this.length + start; - length = length || (this.length - start); - var newArray = []; - for (var i = 0; i < length; i++) newArray[i] = this[start++]; - return newArray; - }, - - remove: function(item){ - var i = 0; - var len = this.length; - while (i < len){ - if (this[i] === item){ - this.splice(i, 1); - len--; - } else { - i++; - } - } - return this; - }, - - contains: function(item, from){ - return this.indexOf(item, from) != -1; - }, - - associate: function(keys){ - var obj = {}, length = Math.min(this.length, keys.length); - for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; - return obj; - }, - - extend: function(array){ - for (var i = 0, j = array.length; i < j; i++) this.push(array[i]); - return this; - }, - - merge: function(array){ - for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); - return this; - }, - - include: function(item){ - if (!this.contains(item)) this.push(item); - return this; - }, - - getRandom: function(){ - return this[$random(0, this.length - 1)] || null; - }, - - getLast: function(){ - return this[this.length - 1] || null; - } - -}); - -Array.prototype.each = Array.prototype.forEach; -Array.each = Array.forEach; - -function $A(array){ - return Array.copy(array); -}; - -function $each(iterable, fn, bind){ - if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object'){ - Array.forEach(iterable, fn, bind); - } else { - for (var name in iterable) fn.call(bind || iterable, iterable[name], name); - } -}; - -Array.prototype.test = Array.prototype.contains; - -String.extend({ - - test: function(regex, params){ - return (($type(regex) == 'string') ? new RegExp(regex, params) : regex).test(this); - }, - - toInt: function(){ - return parseInt(this, 10); - }, - - toFloat: function(){ - return parseFloat(this); - }, - - camelCase: function(){ - return this.replace(/-\D/g, function(match){ - return match.charAt(1).toUpperCase(); - }); - }, - - hyphenate: function(){ - return this.replace(/\w[A-Z]/g, function(match){ - return (match.charAt(0) + '-' + match.charAt(1).toLowerCase()); - }); - }, - - capitalize: function(){ - return this.replace(/\b[a-z]/g, function(match){ - return match.toUpperCase(); - }); - }, - - trim: function(){ - return this.replace(/^\s+|\s+$/g, ''); - }, - - clean: function(){ - return this.replace(/\s{2,}/g, ' ').trim(); - }, - - rgbToHex: function(array){ - var rgb = this.match(/\d{1,3}/g); - return (rgb) ? rgb.rgbToHex(array) : false; - }, - - hexToRgb: function(array){ - var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); - return (hex) ? hex.slice(1).hexToRgb(array) : false; - }, - - contains: function(string, s){ - return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1; - }, - - escapeRegExp: function(){ - return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); - } - -}); - -Array.extend({ - - rgbToHex: function(array){ - if (this.length < 3) return false; - if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; - var hex = []; - for (var i = 0; i < 3; i++){ - var bit = (this[i] - 0).toString(16); - hex.push((bit.length == 1) ? '0' + bit : bit); - } - return array ? hex : '#' + hex.join(''); - }, - - hexToRgb: function(array){ - if (this.length != 3) return false; - var rgb = []; - for (var i = 0; i < 3; i++){ - rgb.push(parseInt((this[i].length == 1) ? this[i] + this[i] : this[i], 16)); - } - return array ? rgb : 'rgb(' + rgb.join(',') + ')'; - } - -}); - -Function.extend({ - - create: function(options){ - var fn = this; - options = $merge({ - 'bind': fn, - 'event': false, - 'arguments': null, - 'delay': false, - 'periodical': false, - 'attempt': false - }, options); - if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments]; - return function(event){ - var args; - if (options.event){ - event = event || window.event; - args = [(options.event === true) ? event : new options.event(event)]; - if (options.arguments) args.extend(options.arguments); - } - else args = options.arguments || arguments; - var returns = function(){ - return fn.apply($pick(options.bind, fn), args); - }; - if (options.delay) return setTimeout(returns, options.delay); - if (options.periodical) return setInterval(returns, options.periodical); - if (options.attempt) try {return returns();} catch(err){return false;}; - return returns(); - }; - }, - - pass: function(args, bind){ - return this.create({'arguments': args, 'bind': bind}); - }, - - attempt: function(args, bind){ - return this.create({'arguments': args, 'bind': bind, 'attempt': true})(); - }, - - bind: function(bind, args){ - return this.create({'bind': bind, 'arguments': args}); - }, - - bindAsEventListener: function(bind, args){ - return this.create({'bind': bind, 'event': true, 'arguments': args}); - }, - - delay: function(delay, bind, args){ - return this.create({'delay': delay, 'bind': bind, 'arguments': args})(); - }, - - periodical: function(interval, bind, args){ - return this.create({'periodical': interval, 'bind': bind, 'arguments': args})(); - } - -}); - -Number.extend({ - - toInt: function(){ - return parseInt(this); - }, - - toFloat: function(){ - return parseFloat(this); - }, - - limit: function(min, max){ - return Math.min(max, Math.max(min, this)); - }, - - round: function(precision){ - precision = Math.pow(10, precision || 0); - return Math.round(this * precision) / precision; - }, - - times: function(fn){ - for (var i = 0; i < this; i++) fn(i); - } - -}); - -var Element = new Class({ - - initialize: function(el, props){ - if ($type(el) == 'string'){ - if (window.ie && props && (props.name || props.type)){ - var name = (props.name) ? ' name="' + props.name + '"' : ''; - var type = (props.type) ? ' type="' + props.type + '"' : ''; - delete props.name; - delete props.type; - el = '<' + el + name + type + '>'; - } - el = document.createElement(el); - } - el = $(el); - return (!props || !el) ? el : el.set(props); - } - -}); - -var Elements = new Class({ - - initialize: function(elements){ - return (elements) ? $extend(elements, this) : this; - } - -}); - -Elements.extend = function(props){ - for (var prop in props){ - this.prototype[prop] = props[prop]; - this[prop] = $native.generic(prop); - } -}; - -function $(el){ - if (!el) return null; - if (el.htmlElement) return Garbage.collect(el); - if ([window, document].contains(el)) return el; - var type = $type(el); - if (type == 'string'){ - el = document.getElementById(el); - type = (el) ? 'element' : false; - } - if (type != 'element') return null; - if (el.htmlElement) return Garbage.collect(el); - if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el; - $extend(el, Element.prototype); - el.htmlElement = function(){}; - return Garbage.collect(el); -}; - -document.getElementsBySelector = document.getElementsByTagName; - -function $$(){ - var elements = []; - for (var i = 0, j = arguments.length; i < j; i++){ - var selector = arguments[i]; - switch($type(selector)){ - case 'element': elements.push(selector); - case 'boolean': break; - case false: break; - case 'string': selector = document.getElementsBySelector(selector, true); - default: elements.extend(selector); - } - } - return $$.unique(elements); -}; - -$$.unique = function(array){ - var elements = []; - for (var i = 0, l = array.length; i < l; i++){ - if (array[i].$included) continue; - var element = $(array[i]); - if (element && !element.$included){ - element.$included = true; - elements.push(element); - } - } - for (var n = 0, d = elements.length; n < d; n++) elements[n].$included = null; - return new Elements(elements); -}; - -Elements.Multi = function(property){ - return function(){ - var args = arguments; - var items = []; - var elements = true; - for (var i = 0, j = this.length, returns; i < j; i++){ - returns = this[i][property].apply(this[i], args); - if ($type(returns) != 'element') elements = false; - items.push(returns); - }; - return (elements) ? $$.unique(items) : items; - }; -}; - -Element.extend = function(properties){ - for (var property in properties){ - HTMLElement.prototype[property] = properties[property]; - Element.prototype[property] = properties[property]; - Element[property] = $native.generic(property); - var elementsProperty = (Array.prototype[property]) ? property + 'Elements' : property; - Elements.prototype[elementsProperty] = Elements.Multi(property); - } -}; - -Element.extend({ - - set: function(props){ - for (var prop in props){ - var val = props[prop]; - switch(prop){ - case 'styles': this.setStyles(val); break; - case 'events': if (this.addEvents) this.addEvents(val); break; - case 'properties': this.setProperties(val); break; - default: this.setProperty(prop, val); - } - } - return this; - }, - - inject: function(el, where){ - el = $(el); - switch(where){ - case 'before': el.parentNode.insertBefore(this, el); break; - case 'after': - var next = el.getNext(); - if (!next) el.parentNode.appendChild(this); - else el.parentNode.insertBefore(this, next); - break; - case 'top': - var first = el.firstChild; - if (first){ - el.insertBefore(this, first); - break; - } - default: el.appendChild(this); - } - return this; - }, - - injectBefore: function(el){ - return this.inject(el, 'before'); - }, - - injectAfter: function(el){ - return this.inject(el, 'after'); - }, - - injectInside: function(el){ - return this.inject(el, 'bottom'); - }, - - injectTop: function(el){ - return this.inject(el, 'top'); - }, - - adopt: function(){ - var elements = []; - $each(arguments, function(argument){ - elements = elements.concat(argument); - }); - $$(elements).inject(this); - return this; - }, - - remove: function(){ - return this.parentNode.removeChild(this); - }, - - clone: function(contents){ - var el = $(this.cloneNode(contents !== false)); - if (!el.$events) return el; - el.$events = {}; - for (var type in this.$events) el.$events[type] = { - 'keys': $A(this.$events[type].keys), - 'values': $A(this.$events[type].values) - }; - return el.removeEvents(); - }, - - replaceWith: function(el){ - el = $(el); - this.parentNode.replaceChild(el, this); - return el; - }, - - appendText: function(text){ - this.appendChild(document.createTextNode(text)); - return this; - }, - - hasClass: function(className){ - return this.className.contains(className, ' '); - }, - - addClass: function(className){ - if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); - return this; - }, - - removeClass: function(className){ - this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean(); - return this; - }, - - toggleClass: function(className){ - return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); - }, - - setStyle: function(property, value){ - switch(property){ - case 'opacity': return this.setOpacity(parseFloat(value)); - case 'float': property = (window.ie) ? 'styleFloat' : 'cssFloat'; - } - property = property.camelCase(); - switch($type(value)){ - case 'number': if (!['zIndex', 'zoom'].contains(property)) value += 'px'; break; - case 'array': value = 'rgb(' + value.join(',') + ')'; - } - this.style[property] = value; - return this; - }, - - setStyles: function(source){ - switch($type(source)){ - case 'object': Element.setMany(this, 'setStyle', source); break; - case 'string': this.style.cssText = source; - } - return this; - }, - - setOpacity: function(opacity){ - if (opacity == 0){ - if (this.style.visibility != "hidden") this.style.visibility = "hidden"; - } else { - if (this.style.visibility != "visible") this.style.visibility = "visible"; - } - if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; - if (window.ie) this.style.filter = (opacity == 1) ? '' : "alpha(opacity=" + opacity * 100 + ")"; - this.style.opacity = this.$tmp.opacity = opacity; - return this; - }, - - getStyle: function(property){ - property = property.camelCase(); - var result = this.style[property]; - if (!$chk(result)){ - if (property == 'opacity') return this.$tmp.opacity; - result = []; - for (var style in Element.Styles){ - if (property == style){ - Element.Styles[style].each(function(s){ - var style = this.getStyle(s); - result.push(parseInt(style) ? style : '0px'); - }, this); - if (property == 'border'){ - var every = result.every(function(bit){ - return (bit == result[0]); - }); - return (every) ? result[0] : false; - } - return result.join(' '); - } - } - if (property.contains('border')){ - if (Element.Styles.border.contains(property)){ - return ['Width', 'Style', 'Color'].map(function(p){ - return this.getStyle(property + p); - }, this).join(' '); - } else if (Element.borderShort.contains(property)){ - return ['Top', 'Right', 'Bottom', 'Left'].map(function(p){ - return this.getStyle('border' + p + property.replace('border', '')); - }, this).join(' '); - } - } - if (document.defaultView) result = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate()); - else if (this.currentStyle) result = this.currentStyle[property]; - } - if (window.ie) result = Element.fixStyle(property, result, this); - if (result && property.test(/color/i) && result.contains('rgb')){ - return result.split('rgb').splice(1,4).map(function(color){ - return color.rgbToHex(); - }).join(' '); - } - return result; - }, - - getStyles: function(){ - return Element.getMany(this, 'getStyle', arguments); - }, - - walk: function(brother, start){ - brother += 'Sibling'; - var el = (start) ? this[start] : this[brother]; - while (el && $type(el) != 'element') el = el[brother]; - return $(el); - }, - - getPrevious: function(){ - return this.walk('previous'); - }, - - getNext: function(){ - return this.walk('next'); - }, - - getFirst: function(){ - return this.walk('next', 'firstChild'); - }, - - getLast: function(){ - return this.walk('previous', 'lastChild'); - }, - - getParent: function(){ - return $(this.parentNode); - }, - - getChildren: function(){ - return $$(this.childNodes); - }, - - hasChild: function(el){ - return !!$A(this.getElementsByTagName('*')).contains(el); - }, - - getProperty: function(property){ - var index = Element.Properties[property]; - if (index) return this[index]; - var flag = Element.PropertiesIFlag[property] || 0; - if (!window.ie || flag) return this.getAttribute(property, flag); - var node = this.attributes[property]; - return (node) ? node.nodeValue : null; - }, - - removeProperty: function(property){ - var index = Element.Properties[property]; - if (index) this[index] = ''; - else this.removeAttribute(property); - return this; - }, - - getProperties: function(){ - return Element.getMany(this, 'getProperty', arguments); - }, - - setProperty: function(property, value){ - var index = Element.Properties[property]; - if (index) this[index] = value; - else this.setAttribute(property, value); - return this; - }, - - setProperties: function(source){ - return Element.setMany(this, 'setProperty', source); - }, - - setHTML: function(){ - this.innerHTML = $A(arguments).join(''); - return this; - }, - - setText: function(text){ - var tag = this.getTag(); - if (['style', 'script'].contains(tag)){ - if (window.ie){ - if (tag == 'style') this.styleSheet.cssText = text; - else if (tag == 'script') this.setProperty('text', text); - return this; - } else { - this.removeChild(this.firstChild); - return this.appendText(text); - } - } - this[$defined(this.innerText) ? 'innerText' : 'textContent'] = text; - return this; - }, - - getText: function(){ - var tag = this.getTag(); - if (['style', 'script'].contains(tag)){ - if (window.ie){ - if (tag == 'style') return this.styleSheet.cssText; - else if (tag == 'script') return this.getProperty('text'); - } else { - return this.innerHTML; - } - } - return ($pick(this.innerText, this.textContent)); - }, - - getTag: function(){ - return this.tagName.toLowerCase(); - }, - - empty: function(){ - Garbage.trash(this.getElementsByTagName('*')); - return this.setHTML(''); - } - -}); - -Element.fixStyle = function(property, result, element){ - if ($chk(parseInt(result))) return result; - if (['height', 'width'].contains(property)){ - var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom']; - var size = 0; - values.each(function(value){ - size += element.getStyle('border-' + value + '-width').toInt() + element.getStyle('padding-' + value).toInt(); - }); - return element['offset' + property.capitalize()] - size + 'px'; - } else if (property.test(/border(.+)Width|margin|padding/)){ - return '0px'; - } - return result; -}; - -Element.Styles = {'border': [], 'padding': [], 'margin': []}; -['Top', 'Right', 'Bottom', 'Left'].each(function(direction){ - for (var style in Element.Styles) Element.Styles[style].push(style + direction); -}); - -Element.borderShort = ['borderWidth', 'borderStyle', 'borderColor']; - -Element.getMany = function(el, method, keys){ - var result = {}; - $each(keys, function(key){ - result[key] = el[method](key); - }); - return result; -}; - -Element.setMany = function(el, method, pairs){ - for (var key in pairs) el[method](key, pairs[key]); - return el; -}; - -Element.Properties = new Abstract({ - 'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan', - 'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength', - 'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value', - 'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected' -}); -Element.PropertiesIFlag = { - 'href': 2, 'src': 2 -}; - -Element.Methods = { - Listeners: { - addListener: function(type, fn){ - if (this.addEventListener) this.addEventListener(type, fn, false); - else this.attachEvent('on' + type, fn); - return this; - }, - - removeListener: function(type, fn){ - if (this.removeEventListener) this.removeEventListener(type, fn, false); - else this.detachEvent('on' + type, fn); - return this; - } - } -}; - -window.extend(Element.Methods.Listeners); -document.extend(Element.Methods.Listeners); -Element.extend(Element.Methods.Listeners); - -var Garbage = { - - elements: [], - - collect: function(el){ - if (!el.$tmp){ - Garbage.elements.push(el); - el.$tmp = {'opacity': 1}; - } - return el; - }, - - trash: function(elements){ - for (var i = 0, j = elements.length, el; i < j; i++){ - if (!(el = elements[i]) || !el.$tmp) continue; - if (el.$events) el.fireEvent('trash').removeEvents(); - for (var p in el.$tmp) el.$tmp[p] = null; - for (var d in Element.prototype) el[d] = null; - Garbage.elements[Garbage.elements.indexOf(el)] = null; - el.htmlElement = el.$tmp = el = null; - } - Garbage.elements.remove(null); - }, - - empty: function(){ - Garbage.collect(window); - Garbage.collect(document); - Garbage.trash(Garbage.elements); - } - -}; - -window.addListener('beforeunload', function(){ - window.addListener('unload', Garbage.empty); - if (window.ie) window.addListener('unload', CollectGarbage); -}); - -var Event = new Class({ - - initialize: function(event){ - if (event && event.$extended) return event; - this.$extended = true; - event = event || window.event; - this.event = event; - this.type = event.type; - this.target = event.target || event.srcElement; - if (this.target.nodeType == 3) this.target = this.target.parentNode; - this.shift = event.shiftKey; - this.control = event.ctrlKey; - this.alt = event.altKey; - this.meta = event.metaKey; - if (['DOMMouseScroll', 'mousewheel'].contains(this.type)){ - this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3; - } else if (this.type.contains('key')){ - this.code = event.which || event.keyCode; - for (var name in Event.keys){ - if (Event.keys[name] == this.code){ - this.key = name; - break; - } - } - if (this.type == 'keydown'){ - var fKey = this.code - 111; - if (fKey > 0 && fKey < 13) this.key = 'f' + fKey; - } - this.key = this.key || String.fromCharCode(this.code).toLowerCase(); - } else if (this.type.test(/(click|mouse|menu)/)){ - this.page = { - 'x': event.pageX || event.clientX + document.documentElement.scrollLeft, - 'y': event.pageY || event.clientY + document.documentElement.scrollTop - }; - this.client = { - 'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX, - 'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY - }; - this.rightClick = (event.which == 3) || (event.button == 2); - switch(this.type){ - case 'mouseover': this.relatedTarget = event.relatedTarget || event.fromElement; break; - case 'mouseout': this.relatedTarget = event.relatedTarget || event.toElement; - } - this.fixRelatedTarget(); - } - return this; - }, - - stop: function(){ - return this.stopPropagation().preventDefault(); - }, - - stopPropagation: function(){ - if (this.event.stopPropagation) this.event.stopPropagation(); - else this.event.cancelBubble = true; - return this; - }, - - preventDefault: function(){ - if (this.event.preventDefault) this.event.preventDefault(); - else this.event.returnValue = false; - return this; - } - -}); - -Event.fix = { - - relatedTarget: function(){ - if (this.relatedTarget && this.relatedTarget.nodeType == 3) this.relatedTarget = this.relatedTarget.parentNode; - }, - - relatedTargetGecko: function(){ - try {Event.fix.relatedTarget.call(this);} catch(e){this.relatedTarget = this.target;} - } - -}; - -Event.prototype.fixRelatedTarget = (window.gecko) ? Event.fix.relatedTargetGecko : Event.fix.relatedTarget; - -Event.keys = new Abstract({ - 'enter': 13, - 'up': 38, - 'down': 40, - 'left': 37, - 'right': 39, - 'esc': 27, - 'space': 32, - 'backspace': 8, - 'tab': 9, - 'delete': 46 -}); - -Element.Methods.Events = { - - addEvent: function(type, fn){ - this.$events = this.$events || {}; - this.$events[type] = this.$events[type] || {'keys': [], 'values': []}; - if (this.$events[type].keys.contains(fn)) return this; - this.$events[type].keys.push(fn); - var realType = type; - var custom = Element.Events[type]; - if (custom){ - if (custom.add) custom.add.call(this, fn); - if (custom.map) fn = custom.map; - if (custom.type) realType = custom.type; - } - if (!this.addEventListener) fn = fn.create({'bind': this, 'event': true}); - this.$events[type].values.push(fn); - return (Element.NativeEvents.contains(realType)) ? this.addListener(realType, fn) : this; - }, - - removeEvent: function(type, fn){ - if (!this.$events || !this.$events[type]) return this; - var pos = this.$events[type].keys.indexOf(fn); - if (pos == -1) return this; - var key = this.$events[type].keys.splice(pos,1)[0]; - var value = this.$events[type].values.splice(pos,1)[0]; - var custom = Element.Events[type]; - if (custom){ - if (custom.remove) custom.remove.call(this, fn); - if (custom.type) type = custom.type; - } - return (Element.NativeEvents.contains(type)) ? this.removeListener(type, value) : this; - }, - - addEvents: function(source){ - return Element.setMany(this, 'addEvent', source); - }, - - removeEvents: function(type){ - if (!this.$events) return this; - if (!type){ - for (var evType in this.$events) this.removeEvents(evType); - this.$events = null; - } else if (this.$events[type]){ - this.$events[type].keys.each(function(fn){ - this.removeEvent(type, fn); - }, this); - this.$events[type] = null; - } - return this; - }, - - fireEvent: function(type, args, delay){ - if (this.$events && this.$events[type]){ - this.$events[type].keys.each(function(fn){ - fn.create({'bind': this, 'delay': delay, 'arguments': args})(); - }, this); - } - return this; - }, - - cloneEvents: function(from, type){ - if (!from.$events) return this; - if (!type){ - for (var evType in from.$events) this.cloneEvents(from, evType); - } else if (from.$events[type]){ - from.$events[type].keys.each(function(fn){ - this.addEvent(type, fn); - }, this); - } - return this; - } - -}; - -window.extend(Element.Methods.Events); -document.extend(Element.Methods.Events); -Element.extend(Element.Methods.Events); - -Element.Events = new Abstract({ - - 'mouseenter': { - type: 'mouseover', - map: function(event){ - event = new Event(event); - if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseenter', event); - } - }, - - 'mouseleave': { - type: 'mouseout', - map: function(event){ - event = new Event(event); - if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseleave', event); - } - }, - - 'mousewheel': { - type: (window.gecko) ? 'DOMMouseScroll' : 'mousewheel' - } - -}); - -Element.NativeEvents = [ - 'click', 'dblclick', 'mouseup', 'mousedown', - 'mousewheel', 'DOMMouseScroll', - 'mouseover', 'mouseout', 'mousemove', - 'keydown', 'keypress', 'keyup', - 'load', 'unload', 'beforeunload', 'resize', 'move', - 'focus', 'blur', 'change', 'submit', 'reset', 'select', - 'error', 'abort', 'contextmenu', 'scroll' -]; - -Function.extend({ - - bindWithEvent: function(bind, args){ - return this.create({'bind': bind, 'arguments': args, 'event': Event}); - } - -}); - -Elements.extend({ - - filterByTag: function(tag){ - return new Elements(this.filter(function(el){ - return (Element.getTag(el) == tag); - })); - }, - - filterByClass: function(className, nocash){ - var elements = this.filter(function(el){ - return (el.className && el.className.contains(className, ' ')); - }); - return (nocash) ? elements : new Elements(elements); - }, - - filterById: function(id, nocash){ - var elements = this.filter(function(el){ - return (el.id == id); - }); - return (nocash) ? elements : new Elements(elements); - }, - - filterByAttribute: function(name, operator, value, nocash){ - var elements = this.filter(function(el){ - var current = Element.getProperty(el, name); - if (!current) return false; - if (!operator) return true; - switch(operator){ - case '=': return (current == value); - case '*=': return (current.contains(value)); - case '^=': return (current.substr(0, value.length) == value); - case '$=': return (current.substr(current.length - value.length) == value); - case '!=': return (current != value); - case '~=': return current.contains(value, ' '); - } - return false; - }); - return (nocash) ? elements : new Elements(elements); - } - -}); - -function $E(selector, filter){ - return ($(filter) || document).getElement(selector); -}; - -function $ES(selector, filter){ - return ($(filter) || document).getElementsBySelector(selector); -}; - -$$.shared = { - - 'regexp': /^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/, - - 'xpath': { - - getParam: function(items, context, param, i){ - var temp = [context.namespaceURI ? 'xhtml:' : '', param[1]]; - if (param[2]) temp.push('[@id="', param[2], '"]'); - if (param[3]) temp.push('[contains(concat(" ", @class, " "), " ', param[3], ' ")]'); - if (param[4]){ - if (param[5] && param[6]){ - switch(param[5]){ - case '*=': temp.push('[contains(@', param[4], ', "', param[6], '")]'); break; - case '^=': temp.push('[starts-with(@', param[4], ', "', param[6], '")]'); break; - case '$=': temp.push('[substring(@', param[4], ', string-length(@', param[4], ') - ', param[6].length, ' + 1) = "', param[6], '"]'); break; - case '=': temp.push('[@', param[4], '="', param[6], '"]'); break; - case '!=': temp.push('[@', param[4], '!="', param[6], '"]'); - } - } else { - temp.push('[@', param[4], ']'); - } - } - items.push(temp.join('')); - return items; - }, - - getItems: function(items, context, nocash){ - var elements = []; - var xpath = document.evaluate('.//' + items.join('//'), context, $$.shared.resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); - for (var i = 0, j = xpath.snapshotLength; i < j; i++) elements.push(xpath.snapshotItem(i)); - return (nocash) ? elements : new Elements(elements.map($)); - } - - }, - - 'normal': { - - getParam: function(items, context, param, i){ - if (i == 0){ - if (param[2]){ - var el = context.getElementById(param[2]); - if (!el || ((param[1] != '*') && (Element.getTag(el) != param[1]))) return false; - items = [el]; - } else { - items = $A(context.getElementsByTagName(param[1])); - } - } else { - items = $$.shared.getElementsByTagName(items, param[1]); - if (param[2]) items = Elements.filterById(items, param[2], true); - } - if (param[3]) items = Elements.filterByClass(items, param[3], true); - if (param[4]) items = Elements.filterByAttribute(items, param[4], param[5], param[6], true); - return items; - }, - - getItems: function(items, context, nocash){ - return (nocash) ? items : $$.unique(items); - } - - }, - - resolver: function(prefix){ - return (prefix == 'xhtml') ? 'http://www.w3.org/1999/xhtml' : false; - }, - - getElementsByTagName: function(context, tagName){ - var found = []; - for (var i = 0, j = context.length; i < j; i++) found.extend(context[i].getElementsByTagName(tagName)); - return found; - } - -}; - -$$.shared.method = (window.xpath) ? 'xpath' : 'normal'; - -Element.Methods.Dom = { - - getElements: function(selector, nocash){ - var items = []; - selector = selector.trim().split(' '); - for (var i = 0, j = selector.length; i < j; i++){ - var sel = selector[i]; - var param = sel.match($$.shared.regexp); - if (!param) break; - param[1] = param[1] || '*'; - var temp = $$.shared[$$.shared.method].getParam(items, this, param, i); - if (!temp) break; - items = temp; - } - return $$.shared[$$.shared.method].getItems(items, this, nocash); - }, - - getElement: function(selector){ - return $(this.getElements(selector, true)[0] || false); - }, - - getElementsBySelector: function(selector, nocash){ - var elements = []; - selector = selector.split(','); - for (var i = 0, j = selector.length; i < j; i++) elements = elements.concat(this.getElements(selector[i], true)); - return (nocash) ? elements : $$.unique(elements); - } - -}; - -Element.extend({ - - getElementById: function(id){ - var el = document.getElementById(id); - if (!el) return false; - for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ - if (!parent) return false; - } - return el; - }/*compatibility*/, - - getElementsByClassName: function(className){ - return this.getElements('.' + className); - } - -}); - -document.extend(Element.Methods.Dom); -Element.extend(Element.Methods.Dom); - -Element.extend({ - - getValue: function(){ - switch(this.getTag()){ - case 'select': - var values = []; - $each(this.options, function(option){ - if (option.selected) values.push($pick(option.value, option.text)); - }); - return (this.multiple) ? values : values[0]; - case 'input': if (!(this.checked && ['checkbox', 'radio'].contains(this.type)) && !['hidden', 'text', 'password'].contains(this.type)) break; - case 'textarea': return this.value; - } - return false; - }, - - getFormElements: function(){ - return $$(this.getElementsByTagName('input'), this.getElementsByTagName('select'), this.getElementsByTagName('textarea')); - }, - - toQueryString: function(){ - var queryString = []; - this.getFormElements().each(function(el){ - var name = el.name; - var value = el.getValue(); - if (value === false || !name || el.disabled) return; - var qs = function(val){ - queryString.push(name + '=' + encodeURIComponent(val)); - }; - if ($type(value) == 'array') value.each(qs); - else qs(value); - }); - return queryString.join('&'); - } - -}); - -Element.extend({ - - scrollTo: function(x, y){ - this.scrollLeft = x; - this.scrollTop = y; - }, - - getSize: function(){ - return { - 'scroll': {'x': this.scrollLeft, 'y': this.scrollTop}, - 'size': {'x': this.offsetWidth, 'y': this.offsetHeight}, - 'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight} - }; - }, - - getPosition: function(overflown){ - overflown = overflown || []; - var el = this, left = 0, top = 0; - do { - left += el.offsetLeft || 0; - top += el.offsetTop || 0; - el = el.offsetParent; - } while (el); - overflown.each(function(element){ - left -= element.scrollLeft || 0; - top -= element.scrollTop || 0; - }); - return {'x': left, 'y': top}; - }, - - getTop: function(overflown){ - return this.getPosition(overflown).y; - }, - - getLeft: function(overflown){ - return this.getPosition(overflown).x; - }, - - getCoordinates: function(overflown){ - var position = this.getPosition(overflown); - var obj = { - 'width': this.offsetWidth, - 'height': this.offsetHeight, - 'left': position.x, - 'top': position.y - }; - obj.right = obj.left + obj.width; - obj.bottom = obj.top + obj.height; - return obj; - } - -}); - -Element.Events.domready = { - - add: function(fn){ - if (window.loaded){ - fn.call(this); - return; - } - var domReady = function(){ - if (window.loaded) return; - window.loaded = true; - window.timer = $clear(window.timer); - this.fireEvent('domready'); - }.bind(this); - if (document.readyState && window.webkit){ - window.timer = function(){ - if (['loaded','complete'].contains(document.readyState)) domReady(); - }.periodical(50); - } else if (document.readyState && window.ie){ - if (!$('ie_ready')){ - var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)'; - document.write(''); - }, - load: function() { - if((typeof Prototype=='undefined') || - (typeof Element == 'undefined') || - (typeof Element.Methods=='undefined') || - parseFloat(Prototype.Version.split(".")[0] + "." + - Prototype.Version.split(".")[1]) < 1.5) - throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0"); - - $A(document.getElementsByTagName("script")).findAll( function(s) { - return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/)) - }).each( function(s) { - var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,''); - var includes = s.src.match(/\?.*load=([a-z,]*)/); - (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each( - function(include) { Scriptaculous.require(path+include+'.js') }); - }); - } -} - -Scriptaculous.load(); \ No newline at end of file diff --git a/test/otherlibs/scriptaculous/1.7.0/slider.js b/test/otherlibs/scriptaculous/1.7.0/slider.js deleted file mode 100644 index f24f2823..00000000 --- a/test/otherlibs/scriptaculous/1.7.0/slider.js +++ /dev/null @@ -1,278 +0,0 @@ -// script.aculo.us slider.js v1.7.0, Fri Jan 19 19:16:36 CET 2007 - -// Copyright (c) 2005, 2006 Marty Haught, Thomas Fuchs -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -if(!Control) var Control = {}; -Control.Slider = Class.create(); - -// options: -// axis: 'vertical', or 'horizontal' (default) -// -// callbacks: -// onChange(value) -// onSlide(value) -Control.Slider.prototype = { - initialize: function(handle, track, options) { - var slider = this; - - if(handle instanceof Array) { - this.handles = handle.collect( function(e) { return $(e) }); - } else { - this.handles = [$(handle)]; - } - - this.track = $(track); - this.options = options || {}; - - this.axis = this.options.axis || 'horizontal'; - this.increment = this.options.increment || 1; - this.step = parseInt(this.options.step || '1'); - this.range = this.options.range || $R(0,1); - - this.value = 0; // assure backwards compat - this.values = this.handles.map( function() { return 0 }); - this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false; - this.options.startSpan = $(this.options.startSpan || null); - this.options.endSpan = $(this.options.endSpan || null); - - this.restricted = this.options.restricted || false; - - this.maximum = this.options.maximum || this.range.end; - this.minimum = this.options.minimum || this.range.start; - - // Will be used to align the handle onto the track, if necessary - this.alignX = parseInt(this.options.alignX || '0'); - this.alignY = parseInt(this.options.alignY || '0'); - - this.trackLength = this.maximumOffset() - this.minimumOffset(); - - this.handleLength = this.isVertical() ? - (this.handles[0].offsetHeight != 0 ? - this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : - (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : - this.handles[0].style.width.replace(/px$/,"")); - - this.active = false; - this.dragging = false; - this.disabled = false; - - if(this.options.disabled) this.setDisabled(); - - // Allowed values array - this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false; - if(this.allowedValues) { - this.minimum = this.allowedValues.min(); - this.maximum = this.allowedValues.max(); - } - - this.eventMouseDown = this.startDrag.bindAsEventListener(this); - this.eventMouseUp = this.endDrag.bindAsEventListener(this); - this.eventMouseMove = this.update.bindAsEventListener(this); - - // Initialize handles in reverse (make sure first handle is active) - this.handles.each( function(h,i) { - i = slider.handles.length-1-i; - slider.setValue(parseFloat( - (slider.options.sliderValue instanceof Array ? - slider.options.sliderValue[i] : slider.options.sliderValue) || - slider.range.start), i); - Element.makePositioned(h); // fix IE - Event.observe(h, "mousedown", slider.eventMouseDown); - }); - - Event.observe(this.track, "mousedown", this.eventMouseDown); - Event.observe(document, "mouseup", this.eventMouseUp); - Event.observe(document, "mousemove", this.eventMouseMove); - - this.initialized = true; - }, - dispose: function() { - var slider = this; - Event.stopObserving(this.track, "mousedown", this.eventMouseDown); - Event.stopObserving(document, "mouseup", this.eventMouseUp); - Event.stopObserving(document, "mousemove", this.eventMouseMove); - this.handles.each( function(h) { - Event.stopObserving(h, "mousedown", slider.eventMouseDown); - }); - }, - setDisabled: function(){ - this.disabled = true; - }, - setEnabled: function(){ - this.disabled = false; - }, - getNearestValue: function(value){ - if(this.allowedValues){ - if(value >= this.allowedValues.max()) return(this.allowedValues.max()); - if(value <= this.allowedValues.min()) return(this.allowedValues.min()); - - var offset = Math.abs(this.allowedValues[0] - value); - var newValue = this.allowedValues[0]; - this.allowedValues.each( function(v) { - var currentOffset = Math.abs(v - value); - if(currentOffset <= offset){ - newValue = v; - offset = currentOffset; - } - }); - return newValue; - } - if(value > this.range.end) return this.range.end; - if(value < this.range.start) return this.range.start; - return value; - }, - setValue: function(sliderValue, handleIdx){ - if(!this.active) { - this.activeHandleIdx = handleIdx || 0; - this.activeHandle = this.handles[this.activeHandleIdx]; - this.updateStyles(); - } - handleIdx = handleIdx || this.activeHandleIdx || 0; - if(this.initialized && this.restricted) { - if((handleIdx>0) && (sliderValuethis.values[handleIdx+1])) - sliderValue = this.values[handleIdx+1]; - } - sliderValue = this.getNearestValue(sliderValue); - this.values[handleIdx] = sliderValue; - this.value = this.values[0]; // assure backwards compat - - this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = - this.translateToPx(sliderValue); - - this.drawSpans(); - if(!this.dragging || !this.event) this.updateFinished(); - }, - setValueBy: function(delta, handleIdx) { - this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, - handleIdx || this.activeHandleIdx || 0); - }, - translateToPx: function(value) { - return Math.round( - ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * - (value - this.range.start)) + "px"; - }, - translateToValue: function(offset) { - return ((offset/(this.trackLength-this.handleLength) * - (this.range.end-this.range.start)) + this.range.start); - }, - getRange: function(range) { - var v = this.values.sortBy(Prototype.K); - range = range || 0; - return $R(v[range],v[range+1]); - }, - minimumOffset: function(){ - return(this.isVertical() ? this.alignY : this.alignX); - }, - maximumOffset: function(){ - return(this.isVertical() ? - (this.track.offsetHeight != 0 ? this.track.offsetHeight : - this.track.style.height.replace(/px$/,"")) - this.alignY : - (this.track.offsetWidth != 0 ? this.track.offsetWidth : - this.track.style.width.replace(/px$/,"")) - this.alignY); - }, - isVertical: function(){ - return (this.axis == 'vertical'); - }, - drawSpans: function() { - var slider = this; - if(this.spans) - $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) }); - if(this.options.startSpan) - this.setSpan(this.options.startSpan, - $R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); - if(this.options.endSpan) - this.setSpan(this.options.endSpan, - $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); - }, - setSpan: function(span, range) { - if(this.isVertical()) { - span.style.top = this.translateToPx(range.start); - span.style.height = this.translateToPx(range.end - range.start + this.range.start); - } else { - span.style.left = this.translateToPx(range.start); - span.style.width = this.translateToPx(range.end - range.start + this.range.start); - } - }, - updateStyles: function() { - this.handles.each( function(h){ Element.removeClassName(h, 'selected') }); - Element.addClassName(this.activeHandle, 'selected'); - }, - startDrag: function(event) { - if(Event.isLeftClick(event)) { - if(!this.disabled){ - this.active = true; - - var handle = Event.element(event); - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var track = handle; - if(track==this.track) { - var offsets = Position.cumulativeOffset(this.track); - this.event = event; - this.setValue(this.translateToValue( - (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) - )); - var offsets = Position.cumulativeOffset(this.activeHandle); - this.offsetX = (pointer[0] - offsets[0]); - this.offsetY = (pointer[1] - offsets[1]); - } else { - // find the handle (prevents issues with Safari) - while((this.handles.indexOf(handle) == -1) && handle.parentNode) - handle = handle.parentNode; - - if(this.handles.indexOf(handle)!=-1) { - this.activeHandle = handle; - this.activeHandleIdx = this.handles.indexOf(this.activeHandle); - this.updateStyles(); - - var offsets = Position.cumulativeOffset(this.activeHandle); - this.offsetX = (pointer[0] - offsets[0]); - this.offsetY = (pointer[1] - offsets[1]); - } - } - } - Event.stop(event); - } - }, - update: function(event) { - if(this.active) { - if(!this.dragging) this.dragging = true; - this.draw(event); - // fix AppleWebKit rendering - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); - Event.stop(event); - } - }, - draw: function(event) { - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var offsets = Position.cumulativeOffset(this.track); - pointer[0] -= this.offsetX + offsets[0]; - pointer[1] -= this.offsetY + offsets[1]; - this.event = event; - this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] )); - if(this.initialized && this.options.onSlide) - this.options.onSlide(this.values.length>1 ? this.values : this.value, this); - }, - endDrag: function(event) { - if(this.active && this.dragging) { - this.finishDrag(event, true); - Event.stop(event); - } - this.active = false; - this.dragging = false; - }, - finishDrag: function(event, success) { - this.active = false; - this.dragging = false; - this.updateFinished(); - }, - updateFinished: function() { - if(this.initialized && this.options.onChange) - this.options.onChange(this.values.length>1 ? this.values : this.value, this); - this.event = null; - } -} \ No newline at end of file diff --git a/test/otherlibs/scriptaculous/1.7.0/unittest.js b/test/otherlibs/scriptaculous/1.7.0/unittest.js deleted file mode 100644 index a4478855..00000000 --- a/test/otherlibs/scriptaculous/1.7.0/unittest.js +++ /dev/null @@ -1,564 +0,0 @@ -// script.aculo.us unittest.js v1.7.0, Fri Jan 19 19:16:36 CET 2007 - -// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com) -// (c) 2005, 2006 Michael Schuerig (http://www.schuerig.de/michael/) -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -// experimental, Firefox-only -Event.simulateMouse = function(element, eventName) { - var options = Object.extend({ - pointerX: 0, - pointerY: 0, - buttons: 0, - ctrlKey: false, - altKey: false, - shiftKey: false, - metaKey: false - }, arguments[2] || {}); - var oEvent = document.createEvent("MouseEvents"); - oEvent.initMouseEvent(eventName, true, true, document.defaultView, - options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, - options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element)); - - if(this.mark) Element.remove(this.mark); - this.mark = document.createElement('div'); - this.mark.appendChild(document.createTextNode(" ")); - document.body.appendChild(this.mark); - this.mark.style.position = 'absolute'; - this.mark.style.top = options.pointerY + "px"; - this.mark.style.left = options.pointerX + "px"; - this.mark.style.width = "5px"; - this.mark.style.height = "5px;"; - this.mark.style.borderTop = "1px solid red;" - this.mark.style.borderLeft = "1px solid red;" - - if(this.step) - alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options)); - - $(element).dispatchEvent(oEvent); -}; - -// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2. -// You need to downgrade to 1.0.4 for now to get this working -// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much -Event.simulateKey = function(element, eventName) { - var options = Object.extend({ - ctrlKey: false, - altKey: false, - shiftKey: false, - metaKey: false, - keyCode: 0, - charCode: 0 - }, arguments[2] || {}); - - var oEvent = document.createEvent("KeyEvents"); - oEvent.initKeyEvent(eventName, true, true, window, - options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, - options.keyCode, options.charCode ); - $(element).dispatchEvent(oEvent); -}; - -Event.simulateKeys = function(element, command) { - for(var i=0; i
' + - '' + - '' + - '' + - '
StatusTestMessage
'; - this.logsummary = $('logsummary') - this.loglines = $('loglines'); - }, - _toHTML: function(txt) { - return txt.escapeHTML().replace(/\n/g,"
"); - }, - addLinksToResults: function(){ - $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log - td.title = "Run only this test" - Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;}); - }); - $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log - td.title = "Run all tests" - Event.observe(td, 'click', function(){ window.location.search = "";}); - }); - } -} - -Test.Unit.Runner = Class.create(); -Test.Unit.Runner.prototype = { - initialize: function(testcases) { - this.options = Object.extend({ - testLog: 'testlog' - }, arguments[1] || {}); - this.options.resultsURL = this.parseResultsURLQueryParameter(); - this.options.tests = this.parseTestsQueryParameter(); - if (this.options.testLog) { - this.options.testLog = $(this.options.testLog) || null; - } - if(this.options.tests) { - this.tests = []; - for(var i = 0; i < this.options.tests.length; i++) { - if(/^test/.test(this.options.tests[i])) { - this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"])); - } - } - } else { - if (this.options.test) { - this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])]; - } else { - this.tests = []; - for(var testcase in testcases) { - if(/^test/.test(testcase)) { - this.tests.push( - new Test.Unit.Testcase( - this.options.context ? ' -> ' + this.options.titles[testcase] : testcase, - testcases[testcase], testcases["setup"], testcases["teardown"] - )); - } - } - } - } - this.currentTest = 0; - this.logger = new Test.Unit.Logger(this.options.testLog); - setTimeout(this.runTests.bind(this), 1000); - }, - parseResultsURLQueryParameter: function() { - return window.location.search.parseQuery()["resultsURL"]; - }, - parseTestsQueryParameter: function(){ - if (window.location.search.parseQuery()["tests"]){ - return window.location.search.parseQuery()["tests"].split(','); - }; - }, - // Returns: - // "ERROR" if there was an error, - // "FAILURE" if there was a failure, or - // "SUCCESS" if there was neither - getResult: function() { - var hasFailure = false; - for(var i=0;i 0) { - return "ERROR"; - } - if (this.tests[i].failures > 0) { - hasFailure = true; - } - } - if (hasFailure) { - return "FAILURE"; - } else { - return "SUCCESS"; - } - }, - postResults: function() { - if (this.options.resultsURL) { - new Ajax.Request(this.options.resultsURL, - { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false }); - } - }, - runTests: function() { - var test = this.tests[this.currentTest]; - if (!test) { - // finished! - this.postResults(); - this.logger.summary(this.summary()); - return; - } - if(!test.isWaiting) { - this.logger.start(test.name); - } - test.run(); - if(test.isWaiting) { - this.logger.message("Waiting for " + test.timeToWait + "ms"); - setTimeout(this.runTests.bind(this), test.timeToWait || 1000); - } else { - this.logger.finish(test.status(), test.summary()); - this.currentTest++; - // tail recursive, hopefully the browser will skip the stackframe - this.runTests(); - } - }, - summary: function() { - var assertions = 0; - var failures = 0; - var errors = 0; - var messages = []; - for(var i=0;i 0) return 'failed'; - if (this.errors > 0) return 'error'; - return 'passed'; - }, - assert: function(expression) { - var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"'; - try { expression ? this.pass() : - this.fail(message); } - catch(e) { this.error(e); } - }, - assertEqual: function(expected, actual) { - var message = arguments[2] || "assertEqual"; - try { (expected == actual) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertInspect: function(expected, actual) { - var message = arguments[2] || "assertInspect"; - try { (expected == actual.inspect()) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertEnumEqual: function(expected, actual) { - var message = arguments[2] || "assertEnumEqual"; - try { $A(expected).length == $A(actual).length && - expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ? - this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + - ', actual ' + Test.Unit.inspect(actual)); } - catch(e) { this.error(e); } - }, - assertNotEqual: function(expected, actual) { - var message = arguments[2] || "assertNotEqual"; - try { (expected != actual) ? this.pass() : - this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertIdentical: function(expected, actual) { - var message = arguments[2] || "assertIdentical"; - try { (expected === actual) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertNotIdentical: function(expected, actual) { - var message = arguments[2] || "assertNotIdentical"; - try { !(expected === actual) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertNull: function(obj) { - var message = arguments[1] || 'assertNull' - try { (obj==null) ? this.pass() : - this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } - catch(e) { this.error(e); } - }, - assertMatch: function(expected, actual) { - var message = arguments[2] || 'assertMatch'; - var regex = new RegExp(expected); - try { (regex.exec(actual)) ? this.pass() : - this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertHidden: function(element) { - var message = arguments[1] || 'assertHidden'; - this.assertEqual("none", element.style.display, message); - }, - assertNotNull: function(object) { - var message = arguments[1] || 'assertNotNull'; - this.assert(object != null, message); - }, - assertType: function(expected, actual) { - var message = arguments[2] || 'assertType'; - try { - (actual.constructor == expected) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + (actual.constructor) + '"'); } - catch(e) { this.error(e); } - }, - assertNotOfType: function(expected, actual) { - var message = arguments[2] || 'assertNotOfType'; - try { - (actual.constructor != expected) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + (actual.constructor) + '"'); } - catch(e) { this.error(e); } - }, - assertInstanceOf: function(expected, actual) { - var message = arguments[2] || 'assertInstanceOf'; - try { - (actual instanceof expected) ? this.pass() : - this.fail(message + ": object was not an instance of the expected type"); } - catch(e) { this.error(e); } - }, - assertNotInstanceOf: function(expected, actual) { - var message = arguments[2] || 'assertNotInstanceOf'; - try { - !(actual instanceof expected) ? this.pass() : - this.fail(message + ": object was an instance of the not expected type"); } - catch(e) { this.error(e); } - }, - assertRespondsTo: function(method, obj) { - var message = arguments[2] || 'assertRespondsTo'; - try { - (obj[method] && typeof obj[method] == 'function') ? this.pass() : - this.fail(message + ": object doesn't respond to [" + method + "]"); } - catch(e) { this.error(e); } - }, - assertReturnsTrue: function(method, obj) { - var message = arguments[2] || 'assertReturnsTrue'; - try { - var m = obj[method]; - if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; - m() ? this.pass() : - this.fail(message + ": method returned false"); } - catch(e) { this.error(e); } - }, - assertReturnsFalse: function(method, obj) { - var message = arguments[2] || 'assertReturnsFalse'; - try { - var m = obj[method]; - if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; - !m() ? this.pass() : - this.fail(message + ": method returned true"); } - catch(e) { this.error(e); } - }, - assertRaise: function(exceptionName, method) { - var message = arguments[2] || 'assertRaise'; - try { - method(); - this.fail(message + ": exception expected but none was raised"); } - catch(e) { - ((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e); - } - }, - assertElementsMatch: function() { - var expressions = $A(arguments), elements = $A(expressions.shift()); - if (elements.length != expressions.length) { - this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions'); - return false; - } - elements.zip(expressions).all(function(pair, index) { - var element = $(pair.first()), expression = pair.last(); - if (element.match(expression)) return true; - this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect()); - }.bind(this)) && this.pass(); - }, - assertElementMatches: function(element, expression) { - this.assertElementsMatch([element], expression); - }, - benchmark: function(operation, iterations) { - var startAt = new Date(); - (iterations || 1).times(operation); - var timeTaken = ((new Date())-startAt); - this.info((arguments[2] || 'Operation') + ' finished ' + - iterations + ' iterations in ' + (timeTaken/1000)+'s' ); - return timeTaken; - }, - _isVisible: function(element) { - element = $(element); - if(!element.parentNode) return true; - this.assertNotNull(element); - if(element.style && Element.getStyle(element, 'display') == 'none') - return false; - - return this._isVisible(element.parentNode); - }, - assertNotVisible: function(element) { - this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1])); - }, - assertVisible: function(element) { - this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1])); - }, - benchmark: function(operation, iterations) { - var startAt = new Date(); - (iterations || 1).times(operation); - var timeTaken = ((new Date())-startAt); - this.info((arguments[2] || 'Operation') + ' finished ' + - iterations + ' iterations in ' + (timeTaken/1000)+'s' ); - return timeTaken; - } -} - -Test.Unit.Testcase = Class.create(); -Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), { - initialize: function(name, test, setup, teardown) { - Test.Unit.Assertions.prototype.initialize.bind(this)(); - this.name = name; - - if(typeof test == 'string') { - test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,'); - test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)'); - this.test = function() { - eval('with(this){'+test+'}'); - } - } else { - this.test = test || function() {}; - } - - this.setup = setup || function() {}; - this.teardown = teardown || function() {}; - this.isWaiting = false; - this.timeToWait = 1000; - }, - wait: function(time, nextPart) { - this.isWaiting = true; - this.test = nextPart; - this.timeToWait = time; - }, - run: function() { - try { - try { - if (!this.isWaiting) this.setup.bind(this)(); - this.isWaiting = false; - this.test.bind(this)(); - } finally { - if(!this.isWaiting) { - this.teardown.bind(this)(); - } - } - } - catch(e) { this.error(e); } - } -}); - -// *EXPERIMENTAL* BDD-style testing to please non-technical folk -// This draws many ideas from RSpec http://rspec.rubyforge.org/ - -Test.setupBDDExtensionMethods = function(){ - var METHODMAP = { - shouldEqual: 'assertEqual', - shouldNotEqual: 'assertNotEqual', - shouldEqualEnum: 'assertEnumEqual', - shouldBeA: 'assertType', - shouldNotBeA: 'assertNotOfType', - shouldBeAn: 'assertType', - shouldNotBeAn: 'assertNotOfType', - shouldBeNull: 'assertNull', - shouldNotBeNull: 'assertNotNull', - - shouldBe: 'assertReturnsTrue', - shouldNotBe: 'assertReturnsFalse', - shouldRespondTo: 'assertRespondsTo' - }; - Test.BDDMethods = {}; - for(m in METHODMAP) { - Test.BDDMethods[m] = eval( - 'function(){'+ - 'var args = $A(arguments);'+ - 'var scope = args.shift();'+ - 'scope.'+METHODMAP[m]+'.apply(scope,(args || []).concat([this])); }'); - } - [Array.prototype, String.prototype, Number.prototype].each( - function(p){ Object.extend(p, Test.BDDMethods) } - ); -} - -Test.context = function(name, spec, log){ - Test.setupBDDExtensionMethods(); - - var compiledSpec = {}; - var titles = {}; - for(specName in spec) { - switch(specName){ - case "setup": - case "teardown": - compiledSpec[specName] = spec[specName]; - break; - default: - var testName = 'test'+specName.gsub(/\s+/,'-').camelize(); - var body = spec[specName].toString().split('\n').slice(1); - if(/^\{/.test(body[0])) body = body.slice(1); - body.pop(); - body = body.map(function(statement){ - return statement.strip() - }); - compiledSpec[testName] = body.join('\n'); - titles[testName] = specName; - } - } - new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name }); -}; \ No newline at end of file diff --git a/test/otherlibs/scriptaculous/1.8.1/builder.js b/test/otherlibs/scriptaculous/1.8.1/builder.js deleted file mode 100644 index 83019994..00000000 --- a/test/otherlibs/scriptaculous/1.8.1/builder.js +++ /dev/null @@ -1,136 +0,0 @@ -// script.aculo.us builder.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 - -// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -var Builder = { - NODEMAP: { - AREA: 'map', - CAPTION: 'table', - COL: 'table', - COLGROUP: 'table', - LEGEND: 'fieldset', - OPTGROUP: 'select', - OPTION: 'select', - PARAM: 'object', - TBODY: 'table', - TD: 'table', - TFOOT: 'table', - TH: 'table', - THEAD: 'table', - TR: 'table' - }, - // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken, - // due to a Firefox bug - node: function(elementName) { - elementName = elementName.toUpperCase(); - - // try innerHTML approach - var parentTag = this.NODEMAP[elementName] || 'div'; - var parentElement = document.createElement(parentTag); - try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 - parentElement.innerHTML = "<" + elementName + ">"; - } catch(e) {} - var element = parentElement.firstChild || null; - - // see if browser added wrapping tags - if(element && (element.tagName.toUpperCase() != elementName)) - element = element.getElementsByTagName(elementName)[0]; - - // fallback to createElement approach - if(!element) element = document.createElement(elementName); - - // abort if nothing could be created - if(!element) return; - - // attributes (or text) - if(arguments[1]) - if(this._isStringOrNumber(arguments[1]) || - (arguments[1] instanceof Array) || - arguments[1].tagName) { - this._children(element, arguments[1]); - } else { - var attrs = this._attributes(arguments[1]); - if(attrs.length) { - try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 - parentElement.innerHTML = "<" +elementName + " " + - attrs + ">"; - } catch(e) {} - element = parentElement.firstChild || null; - // workaround firefox 1.0.X bug - if(!element) { - element = document.createElement(elementName); - for(attr in arguments[1]) - element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; - } - if(element.tagName.toUpperCase() != elementName) - element = parentElement.getElementsByTagName(elementName)[0]; - } - } - - // text, or array of children - if(arguments[2]) - this._children(element, arguments[2]); - - return element; - }, - _text: function(text) { - return document.createTextNode(text); - }, - - ATTR_MAP: { - 'className': 'class', - 'htmlFor': 'for' - }, - - _attributes: function(attributes) { - var attrs = []; - for(attribute in attributes) - attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) + - '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'"') + '"'); - return attrs.join(" "); - }, - _children: function(element, children) { - if(children.tagName) { - element.appendChild(children); - return; - } - if(typeof children=='object') { // array can hold nodes and text - children.flatten().each( function(e) { - if(typeof e=='object') - element.appendChild(e) - else - if(Builder._isStringOrNumber(e)) - element.appendChild(Builder._text(e)); - }); - } else - if(Builder._isStringOrNumber(children)) - element.appendChild(Builder._text(children)); - }, - _isStringOrNumber: function(param) { - return(typeof param=='string' || typeof param=='number'); - }, - build: function(html) { - var element = this.node('div'); - $(element).update(html.strip()); - return element.down(); - }, - dump: function(scope) { - if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope - - var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " + - "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " + - "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+ - "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+ - "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+ - "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/); - - tags.each( function(tag){ - scope[tag] = function() { - return Builder.node.apply(Builder, [tag].concat($A(arguments))); - } - }); - } -} diff --git a/test/otherlibs/scriptaculous/1.8.1/controls.js b/test/otherlibs/scriptaculous/1.8.1/controls.js deleted file mode 100644 index 5012cb81..00000000 --- a/test/otherlibs/scriptaculous/1.8.1/controls.js +++ /dev/null @@ -1,965 +0,0 @@ -// script.aculo.us controls.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 - -// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan) -// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) -// Contributors: -// Richard Livsey -// Rahul Bhargava -// Rob Wills -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -// Autocompleter.Base handles all the autocompletion functionality -// that's independent of the data source for autocompletion. This -// includes drawing the autocompletion menu, observing keyboard -// and mouse events, and similar. -// -// Specific autocompleters need to provide, at the very least, -// a getUpdatedChoices function that will be invoked every time -// the text inside the monitored textbox changes. This method -// should get the text for which to provide autocompletion by -// invoking this.getToken(), NOT by directly accessing -// this.element.value. This is to allow incremental tokenized -// autocompletion. Specific auto-completion logic (AJAX, etc) -// belongs in getUpdatedChoices. -// -// Tokenized incremental autocompletion is enabled automatically -// when an autocompleter is instantiated with the 'tokens' option -// in the options parameter, e.g.: -// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); -// will incrementally autocomplete with a comma as the token. -// Additionally, ',' in the above example can be replaced with -// a token array, e.g. { tokens: [',', '\n'] } which -// enables autocompletion on multiple tokens. This is most -// useful when one of the tokens is \n (a newline), as it -// allows smart autocompletion after linebreaks. - -if(typeof Effect == 'undefined') - throw("controls.js requires including script.aculo.us' effects.js library"); - -var Autocompleter = { } -Autocompleter.Base = Class.create({ - baseInitialize: function(element, update, options) { - element = $(element) - this.element = element; - this.update = $(update); - this.hasFocus = false; - this.changed = false; - this.active = false; - this.index = 0; - this.entryCount = 0; - this.oldElementValue = this.element.value; - - if(this.setOptions) - this.setOptions(options); - else - this.options = options || { }; - - this.options.paramName = this.options.paramName || this.element.name; - this.options.tokens = this.options.tokens || []; - this.options.frequency = this.options.frequency || 0.4; - this.options.minChars = this.options.minChars || 1; - this.options.onShow = this.options.onShow || - function(element, update){ - if(!update.style.position || update.style.position=='absolute') { - update.style.position = 'absolute'; - Position.clone(element, update, { - setHeight: false, - offsetTop: element.offsetHeight - }); - } - Effect.Appear(update,{duration:0.15}); - }; - this.options.onHide = this.options.onHide || - function(element, update){ new Effect.Fade(update,{duration:0.15}) }; - - if(typeof(this.options.tokens) == 'string') - this.options.tokens = new Array(this.options.tokens); - // Force carriage returns as token delimiters anyway - if (!this.options.tokens.include('\n')) - this.options.tokens.push('\n'); - - this.observer = null; - - this.element.setAttribute('autocomplete','off'); - - Element.hide(this.update); - - Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this)); - Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this)); - }, - - show: function() { - if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); - if(!this.iefix && - (Prototype.Browser.IE) && - (Element.getStyle(this.update, 'position')=='absolute')) { - new Insertion.After(this.update, - ''); - this.iefix = $(this.update.id+'_iefix'); - } - if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); - }, - - fixIEOverlapping: function() { - Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); - this.iefix.style.zIndex = 1; - this.update.style.zIndex = 2; - Element.show(this.iefix); - }, - - hide: function() { - this.stopIndicator(); - if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); - if(this.iefix) Element.hide(this.iefix); - }, - - startIndicator: function() { - if(this.options.indicator) Element.show(this.options.indicator); - }, - - stopIndicator: function() { - if(this.options.indicator) Element.hide(this.options.indicator); - }, - - onKeyPress: function(event) { - if(this.active) - switch(event.keyCode) { - case Event.KEY_TAB: - case Event.KEY_RETURN: - this.selectEntry(); - Event.stop(event); - case Event.KEY_ESC: - this.hide(); - this.active = false; - Event.stop(event); - return; - case Event.KEY_LEFT: - case Event.KEY_RIGHT: - return; - case Event.KEY_UP: - this.markPrevious(); - this.render(); - Event.stop(event); - return; - case Event.KEY_DOWN: - this.markNext(); - this.render(); - Event.stop(event); - return; - } - else - if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || - (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; - - this.changed = true; - this.hasFocus = true; - - if(this.observer) clearTimeout(this.observer); - this.observer = - setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); - }, - - activate: function() { - this.changed = false; - this.hasFocus = true; - this.getUpdatedChoices(); - }, - - onHover: function(event) { - var element = Event.findElement(event, 'LI'); - if(this.index != element.autocompleteIndex) - { - this.index = element.autocompleteIndex; - this.render(); - } - Event.stop(event); - }, - - onClick: function(event) { - var element = Event.findElement(event, 'LI'); - this.index = element.autocompleteIndex; - this.selectEntry(); - this.hide(); - }, - - onBlur: function(event) { - // needed to make click events working - setTimeout(this.hide.bind(this), 250); - this.hasFocus = false; - this.active = false; - }, - - render: function() { - if(this.entryCount > 0) { - for (var i = 0; i < this.entryCount; i++) - this.index==i ? - Element.addClassName(this.getEntry(i),"selected") : - Element.removeClassName(this.getEntry(i),"selected"); - if(this.hasFocus) { - this.show(); - this.active = true; - } - } else { - this.active = false; - this.hide(); - } - }, - - markPrevious: function() { - if(this.index > 0) this.index-- - else this.index = this.entryCount-1; - this.getEntry(this.index).scrollIntoView(true); - }, - - markNext: function() { - if(this.index < this.entryCount-1) this.index++ - else this.index = 0; - this.getEntry(this.index).scrollIntoView(false); - }, - - getEntry: function(index) { - return this.update.firstChild.childNodes[index]; - }, - - getCurrentEntry: function() { - return this.getEntry(this.index); - }, - - selectEntry: function() { - this.active = false; - this.updateElement(this.getCurrentEntry()); - }, - - updateElement: function(selectedElement) { - if (this.options.updateElement) { - this.options.updateElement(selectedElement); - return; - } - var value = ''; - if (this.options.select) { - var nodes = $(selectedElement).select('.' + this.options.select) || []; - if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); - } else - value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); - - var bounds = this.getTokenBounds(); - if (bounds[0] != -1) { - var newValue = this.element.value.substr(0, bounds[0]); - var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); - if (whitespace) - newValue += whitespace[0]; - this.element.value = newValue + value + this.element.value.substr(bounds[1]); - } else { - this.element.value = value; - } - this.oldElementValue = this.element.value; - this.element.focus(); - - if (this.options.afterUpdateElement) - this.options.afterUpdateElement(this.element, selectedElement); - }, - - updateChoices: function(choices) { - if(!this.changed && this.hasFocus) { - this.update.innerHTML = choices; - Element.cleanWhitespace(this.update); - Element.cleanWhitespace(this.update.down()); - - if(this.update.firstChild && this.update.down().childNodes) { - this.entryCount = - this.update.down().childNodes.length; - for (var i = 0; i < this.entryCount; i++) { - var entry = this.getEntry(i); - entry.autocompleteIndex = i; - this.addObservers(entry); - } - } else { - this.entryCount = 0; - } - - this.stopIndicator(); - this.index = 0; - - if(this.entryCount==1 && this.options.autoSelect) { - this.selectEntry(); - this.hide(); - } else { - this.render(); - } - } - }, - - addObservers: function(element) { - Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); - Event.observe(element, "click", this.onClick.bindAsEventListener(this)); - }, - - onObserverEvent: function() { - this.changed = false; - this.tokenBounds = null; - if(this.getToken().length>=this.options.minChars) { - this.getUpdatedChoices(); - } else { - this.active = false; - this.hide(); - } - this.oldElementValue = this.element.value; - }, - - getToken: function() { - var bounds = this.getTokenBounds(); - return this.element.value.substring(bounds[0], bounds[1]).strip(); - }, - - getTokenBounds: function() { - if (null != this.tokenBounds) return this.tokenBounds; - var value = this.element.value; - if (value.strip().empty()) return [-1, 0]; - var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue); - var offset = (diff == this.oldElementValue.length ? 1 : 0); - var prevTokenPos = -1, nextTokenPos = value.length; - var tp; - for (var index = 0, l = this.options.tokens.length; index < l; ++index) { - tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1); - if (tp > prevTokenPos) prevTokenPos = tp; - tp = value.indexOf(this.options.tokens[index], diff + offset); - if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp; - } - return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); - } -}); - -Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) { - var boundary = Math.min(newS.length, oldS.length); - for (var index = 0; index < boundary; ++index) - if (newS[index] != oldS[index]) - return index; - return boundary; -}; - -Ajax.Autocompleter = Class.create(Autocompleter.Base, { - initialize: function(element, update, url, options) { - this.baseInitialize(element, update, options); - this.options.asynchronous = true; - this.options.onComplete = this.onComplete.bind(this); - this.options.defaultParams = this.options.parameters || null; - this.url = url; - }, - - getUpdatedChoices: function() { - this.startIndicator(); - - var entry = encodeURIComponent(this.options.paramName) + '=' + - encodeURIComponent(this.getToken()); - - this.options.parameters = this.options.callback ? - this.options.callback(this.element, entry) : entry; - - if(this.options.defaultParams) - this.options.parameters += '&' + this.options.defaultParams; - - new Ajax.Request(this.url, this.options); - }, - - onComplete: function(request) { - this.updateChoices(request.responseText); - } -}); - -// The local array autocompleter. Used when you'd prefer to -// inject an array of autocompletion options into the page, rather -// than sending out Ajax queries, which can be quite slow sometimes. -// -// The constructor takes four parameters. The first two are, as usual, -// the id of the monitored textbox, and id of the autocompletion menu. -// The third is the array you want to autocomplete from, and the fourth -// is the options block. -// -// Extra local autocompletion options: -// - choices - How many autocompletion choices to offer -// -// - partialSearch - If false, the autocompleter will match entered -// text only at the beginning of strings in the -// autocomplete array. Defaults to true, which will -// match text at the beginning of any *word* in the -// strings in the autocomplete array. If you want to -// search anywhere in the string, additionally set -// the option fullSearch to true (default: off). -// -// - fullSsearch - Search anywhere in autocomplete array strings. -// -// - partialChars - How many characters to enter before triggering -// a partial match (unlike minChars, which defines -// how many characters are required to do any match -// at all). Defaults to 2. -// -// - ignoreCase - Whether to ignore case when autocompleting. -// Defaults to true. -// -// It's possible to pass in a custom function as the 'selector' -// option, if you prefer to write your own autocompletion logic. -// In that case, the other options above will not apply unless -// you support them. - -Autocompleter.Local = Class.create(Autocompleter.Base, { - initialize: function(element, update, array, options) { - this.baseInitialize(element, update, options); - this.options.array = array; - }, - - getUpdatedChoices: function() { - this.updateChoices(this.options.selector(this)); - }, - - setOptions: function(options) { - this.options = Object.extend({ - choices: 10, - partialSearch: true, - partialChars: 2, - ignoreCase: true, - fullSearch: false, - selector: function(instance) { - var ret = []; // Beginning matches - var partial = []; // Inside matches - var entry = instance.getToken(); - var count = 0; - - for (var i = 0; i < instance.options.array.length && - ret.length < instance.options.choices ; i++) { - - var elem = instance.options.array[i]; - var foundPos = instance.options.ignoreCase ? - elem.toLowerCase().indexOf(entry.toLowerCase()) : - elem.indexOf(entry); - - while (foundPos != -1) { - if (foundPos == 0 && elem.length != entry.length) { - ret.push("
  • " + elem.substr(0, entry.length) + "" + - elem.substr(entry.length) + "
  • "); - break; - } else if (entry.length >= instance.options.partialChars && - instance.options.partialSearch && foundPos != -1) { - if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { - partial.push("
  • " + elem.substr(0, foundPos) + "" + - elem.substr(foundPos, entry.length) + "" + elem.substr( - foundPos + entry.length) + "
  • "); - break; - } - } - - foundPos = instance.options.ignoreCase ? - elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : - elem.indexOf(entry, foundPos + 1); - - } - } - if (partial.length) - ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) - return "
      " + ret.join('') + "
    "; - } - }, options || { }); - } -}); - -// AJAX in-place editor and collection editor -// Full rewrite by Christophe Porteneuve (April 2007). - -// Use this if you notice weird scrolling problems on some browsers, -// the DOM might be a bit confused when this gets called so do this -// waits 1 ms (with setTimeout) until it does the activation -Field.scrollFreeActivate = function(field) { - setTimeout(function() { - Field.activate(field); - }, 1); -} - -Ajax.InPlaceEditor = Class.create({ - initialize: function(element, url, options) { - this.url = url; - this.element = element = $(element); - this.prepareOptions(); - this._controls = { }; - arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!! - Object.extend(this.options, options || { }); - if (!this.options.formId && this.element.id) { - this.options.formId = this.element.id + '-inplaceeditor'; - if ($(this.options.formId)) - this.options.formId = ''; - } - if (this.options.externalControl) - this.options.externalControl = $(this.options.externalControl); - if (!this.options.externalControl) - this.options.externalControlOnly = false; - this._originalBackground = this.element.getStyle('background-color') || 'transparent'; - this.element.title = this.options.clickToEditText; - this._boundCancelHandler = this.handleFormCancellation.bind(this); - this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this); - this._boundFailureHandler = this.handleAJAXFailure.bind(this); - this._boundSubmitHandler = this.handleFormSubmission.bind(this); - this._boundWrapperHandler = this.wrapUp.bind(this); - this.registerListeners(); - }, - checkForEscapeOrReturn: function(e) { - if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; - if (Event.KEY_ESC == e.keyCode) - this.handleFormCancellation(e); - else if (Event.KEY_RETURN == e.keyCode) - this.handleFormSubmission(e); - }, - createControl: function(mode, handler, extraClasses) { - var control = this.options[mode + 'Control']; - var text = this.options[mode + 'Text']; - if ('button' == control) { - var btn = document.createElement('input'); - btn.type = 'submit'; - btn.value = text; - btn.className = 'editor_' + mode + '_button'; - if ('cancel' == mode) - btn.onclick = this._boundCancelHandler; - this._form.appendChild(btn); - this._controls[mode] = btn; - } else if ('link' == control) { - var link = document.createElement('a'); - link.href = '#'; - link.appendChild(document.createTextNode(text)); - link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; - link.className = 'editor_' + mode + '_link'; - if (extraClasses) - link.className += ' ' + extraClasses; - this._form.appendChild(link); - this._controls[mode] = link; - } - }, - createEditField: function() { - var text = (this.options.loadTextURL ? this.options.loadingText : this.getText()); - var fld; - if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) { - fld = document.createElement('input'); - fld.type = 'text'; - var size = this.options.size || this.options.cols || 0; - if (0 < size) fld.size = size; - } else { - fld = document.createElement('textarea'); - fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); - fld.cols = this.options.cols || 40; - } - fld.name = this.options.paramName; - fld.value = text; // No HTML breaks conversion anymore - fld.className = 'editor_field'; - if (this.options.submitOnBlur) - fld.onblur = this._boundSubmitHandler; - this._controls.editor = fld; - if (this.options.loadTextURL) - this.loadExternalText(); - this._form.appendChild(this._controls.editor); - }, - createForm: function() { - var ipe = this; - function addText(mode, condition) { - var text = ipe.options['text' + mode + 'Controls']; - if (!text || condition === false) return; - ipe._form.appendChild(document.createTextNode(text)); - }; - this._form = $(document.createElement('form')); - this._form.id = this.options.formId; - this._form.addClassName(this.options.formClassName); - this._form.onsubmit = this._boundSubmitHandler; - this.createEditField(); - if ('textarea' == this._controls.editor.tagName.toLowerCase()) - this._form.appendChild(document.createElement('br')); - if (this.options.onFormCustomization) - this.options.onFormCustomization(this, this._form); - addText('Before', this.options.okControl || this.options.cancelControl); - this.createControl('ok', this._boundSubmitHandler); - addText('Between', this.options.okControl && this.options.cancelControl); - this.createControl('cancel', this._boundCancelHandler, 'editor_cancel'); - addText('After', this.options.okControl || this.options.cancelControl); - }, - destroy: function() { - if (this._oldInnerHTML) - this.element.innerHTML = this._oldInnerHTML; - this.leaveEditMode(); - this.unregisterListeners(); - }, - enterEditMode: function(e) { - if (this._saving || this._editing) return; - this._editing = true; - this.triggerCallback('onEnterEditMode'); - if (this.options.externalControl) - this.options.externalControl.hide(); - this.element.hide(); - this.createForm(); - this.element.parentNode.insertBefore(this._form, this.element); - if (!this.options.loadTextURL) - this.postProcessEditField(); - if (e) Event.stop(e); - }, - enterHover: function(e) { - if (this.options.hoverClassName) - this.element.addClassName(this.options.hoverClassName); - if (this._saving) return; - this.triggerCallback('onEnterHover'); - }, - getText: function() { - return this.element.innerHTML; - }, - handleAJAXFailure: function(transport) { - this.triggerCallback('onFailure', transport); - if (this._oldInnerHTML) { - this.element.innerHTML = this._oldInnerHTML; - this._oldInnerHTML = null; - } - }, - handleFormCancellation: function(e) { - this.wrapUp(); - if (e) Event.stop(e); - }, - handleFormSubmission: function(e) { - var form = this._form; - var value = $F(this._controls.editor); - this.prepareSubmission(); - var params = this.options.callback(form, value) || ''; - if (Object.isString(params)) - params = params.toQueryParams(); - params.editorId = this.element.id; - if (this.options.htmlResponse) { - var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions); - Object.extend(options, { - parameters: params, - onComplete: this._boundWrapperHandler, - onFailure: this._boundFailureHandler - }); - new Ajax.Updater({ success: this.element }, this.url, options); - } else { - var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); - Object.extend(options, { - parameters: params, - onComplete: this._boundWrapperHandler, - onFailure: this._boundFailureHandler - }); - new Ajax.Request(this.url, options); - } - if (e) Event.stop(e); - }, - leaveEditMode: function() { - this.element.removeClassName(this.options.savingClassName); - this.removeForm(); - this.leaveHover(); - this.element.style.backgroundColor = this._originalBackground; - this.element.show(); - if (this.options.externalControl) - this.options.externalControl.show(); - this._saving = false; - this._editing = false; - this._oldInnerHTML = null; - this.triggerCallback('onLeaveEditMode'); - }, - leaveHover: function(e) { - if (this.options.hoverClassName) - this.element.removeClassName(this.options.hoverClassName); - if (this._saving) return; - this.triggerCallback('onLeaveHover'); - }, - loadExternalText: function() { - this._form.addClassName(this.options.loadingClassName); - this._controls.editor.disabled = true; - var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); - Object.extend(options, { - parameters: 'editorId=' + encodeURIComponent(this.element.id), - onComplete: Prototype.emptyFunction, - onSuccess: function(transport) { - this._form.removeClassName(this.options.loadingClassName); - var text = transport.responseText; - if (this.options.stripLoadedTextTags) - text = text.stripTags(); - this._controls.editor.value = text; - this._controls.editor.disabled = false; - this.postProcessEditField(); - }.bind(this), - onFailure: this._boundFailureHandler - }); - new Ajax.Request(this.options.loadTextURL, options); - }, - postProcessEditField: function() { - var fpc = this.options.fieldPostCreation; - if (fpc) - $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate'](); - }, - prepareOptions: function() { - this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions); - Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); - [this._extraDefaultOptions].flatten().compact().each(function(defs) { - Object.extend(this.options, defs); - }.bind(this)); - }, - prepareSubmission: function() { - this._saving = true; - this.removeForm(); - this.leaveHover(); - this.showSaving(); - }, - registerListeners: function() { - this._listeners = { }; - var listener; - $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { - listener = this[pair.value].bind(this); - this._listeners[pair.key] = listener; - if (!this.options.externalControlOnly) - this.element.observe(pair.key, listener); - if (this.options.externalControl) - this.options.externalControl.observe(pair.key, listener); - }.bind(this)); - }, - removeForm: function() { - if (!this._form) return; - this._form.remove(); - this._form = null; - this._controls = { }; - }, - showSaving: function() { - this._oldInnerHTML = this.element.innerHTML; - this.element.innerHTML = this.options.savingText; - this.element.addClassName(this.options.savingClassName); - this.element.style.backgroundColor = this._originalBackground; - this.element.show(); - }, - triggerCallback: function(cbName, arg) { - if ('function' == typeof this.options[cbName]) { - this.options[cbName](this, arg); - } - }, - unregisterListeners: function() { - $H(this._listeners).each(function(pair) { - if (!this.options.externalControlOnly) - this.element.stopObserving(pair.key, pair.value); - if (this.options.externalControl) - this.options.externalControl.stopObserving(pair.key, pair.value); - }.bind(this)); - }, - wrapUp: function(transport) { - this.leaveEditMode(); - // Can't use triggerCallback due to backward compatibility: requires - // binding + direct element - this._boundComplete(transport, this.element); - } -}); - -Object.extend(Ajax.InPlaceEditor.prototype, { - dispose: Ajax.InPlaceEditor.prototype.destroy -}); - -Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, { - initialize: function($super, element, url, options) { - this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions; - $super(element, url, options); - }, - - createEditField: function() { - var list = document.createElement('select'); - list.name = this.options.paramName; - list.size = 1; - this._controls.editor = list; - this._collection = this.options.collection || []; - if (this.options.loadCollectionURL) - this.loadCollection(); - else - this.checkForExternalText(); - this._form.appendChild(this._controls.editor); - }, - - loadCollection: function() { - this._form.addClassName(this.options.loadingClassName); - this.showLoadingText(this.options.loadingCollectionText); - var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); - Object.extend(options, { - parameters: 'editorId=' + encodeURIComponent(this.element.id), - onComplete: Prototype.emptyFunction, - onSuccess: function(transport) { - var js = transport.responseText.strip(); - if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check - throw 'Server returned an invalid collection representation.'; - this._collection = eval(js); - this.checkForExternalText(); - }.bind(this), - onFailure: this.onFailure - }); - new Ajax.Request(this.options.loadCollectionURL, options); - }, - - showLoadingText: function(text) { - this._controls.editor.disabled = true; - var tempOption = this._controls.editor.firstChild; - if (!tempOption) { - tempOption = document.createElement('option'); - tempOption.value = ''; - this._controls.editor.appendChild(tempOption); - tempOption.selected = true; - } - tempOption.update((text || '').stripScripts().stripTags()); - }, - - checkForExternalText: function() { - this._text = this.getText(); - if (this.options.loadTextURL) - this.loadExternalText(); - else - this.buildOptionList(); - }, - - loadExternalText: function() { - this.showLoadingText(this.options.loadingText); - var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); - Object.extend(options, { - parameters: 'editorId=' + encodeURIComponent(this.element.id), - onComplete: Prototype.emptyFunction, - onSuccess: function(transport) { - this._text = transport.responseText.strip(); - this.buildOptionList(); - }.bind(this), - onFailure: this.onFailure - }); - new Ajax.Request(this.options.loadTextURL, options); - }, - - buildOptionList: function() { - this._form.removeClassName(this.options.loadingClassName); - this._collection = this._collection.map(function(entry) { - return 2 === entry.length ? entry : [entry, entry].flatten(); - }); - var marker = ('value' in this.options) ? this.options.value : this._text; - var textFound = this._collection.any(function(entry) { - return entry[0] == marker; - }.bind(this)); - this._controls.editor.update(''); - var option; - this._collection.each(function(entry, index) { - option = document.createElement('option'); - option.value = entry[0]; - option.selected = textFound ? entry[0] == marker : 0 == index; - option.appendChild(document.createTextNode(entry[1])); - this._controls.editor.appendChild(option); - }.bind(this)); - this._controls.editor.disabled = false; - Field.scrollFreeActivate(this._controls.editor); - } -}); - -//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** -//**** This only exists for a while, in order to let **** -//**** users adapt to the new API. Read up on the new **** -//**** API and convert your code to it ASAP! **** - -Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) { - if (!options) return; - function fallback(name, expr) { - if (name in options || expr === undefined) return; - options[name] = expr; - }; - fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' : - options.cancelLink == options.cancelButton == false ? false : undefined))); - fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' : - options.okLink == options.okButton == false ? false : undefined))); - fallback('highlightColor', options.highlightcolor); - fallback('highlightEndColor', options.highlightendcolor); -}; - -Object.extend(Ajax.InPlaceEditor, { - DefaultOptions: { - ajaxOptions: { }, - autoRows: 3, // Use when multi-line w/ rows == 1 - cancelControl: 'link', // 'link'|'button'|false - cancelText: 'cancel', - clickToEditText: 'Click to edit', - externalControl: null, // id|elt - externalControlOnly: false, - fieldPostCreation: 'activate', // 'activate'|'focus'|false - formClassName: 'inplaceeditor-form', - formId: null, // id|elt - highlightColor: '#ffff99', - highlightEndColor: '#ffffff', - hoverClassName: '', - htmlResponse: true, - loadingClassName: 'inplaceeditor-loading', - loadingText: 'Loading...', - okControl: 'button', // 'link'|'button'|false - okText: 'ok', - paramName: 'value', - rows: 1, // If 1 and multi-line, uses autoRows - savingClassName: 'inplaceeditor-saving', - savingText: 'Saving...', - size: 0, - stripLoadedTextTags: false, - submitOnBlur: false, - textAfterControls: '', - textBeforeControls: '', - textBetweenControls: '' - }, - DefaultCallbacks: { - callback: function(form) { - return Form.serialize(form); - }, - onComplete: function(transport, element) { - // For backward compatibility, this one is bound to the IPE, and passes - // the element directly. It was too often customized, so we don't break it. - new Effect.Highlight(element, { - startcolor: this.options.highlightColor, keepBackgroundImage: true }); - }, - onEnterEditMode: null, - onEnterHover: function(ipe) { - ipe.element.style.backgroundColor = ipe.options.highlightColor; - if (ipe._effect) - ipe._effect.cancel(); - }, - onFailure: function(transport, ipe) { - alert('Error communication with the server: ' + transport.responseText.stripTags()); - }, - onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls. - onLeaveEditMode: null, - onLeaveHover: function(ipe) { - ipe._effect = new Effect.Highlight(ipe.element, { - startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor, - restorecolor: ipe._originalBackground, keepBackgroundImage: true - }); - } - }, - Listeners: { - click: 'enterEditMode', - keydown: 'checkForEscapeOrReturn', - mouseover: 'enterHover', - mouseout: 'leaveHover' - } -}); - -Ajax.InPlaceCollectionEditor.DefaultOptions = { - loadingCollectionText: 'Loading options...' -}; - -// Delayed observer, like Form.Element.Observer, -// but waits for delay after last key input -// Ideal for live-search fields - -Form.Element.DelayedObserver = Class.create({ - initialize: function(element, delay, callback) { - this.delay = delay || 0.5; - this.element = $(element); - this.callback = callback; - this.timer = null; - this.lastValue = $F(this.element); - Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); - }, - delayedListener: function(event) { - if(this.lastValue == $F(this.element)) return; - if(this.timer) clearTimeout(this.timer); - this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); - this.lastValue = $F(this.element); - }, - onTimerEvent: function() { - this.timer = null; - this.callback(this.element, $F(this.element)); - } -}); diff --git a/test/otherlibs/scriptaculous/1.8.1/dragdrop.js b/test/otherlibs/scriptaculous/1.8.1/dragdrop.js deleted file mode 100644 index bf429c26..00000000 --- a/test/otherlibs/scriptaculous/1.8.1/dragdrop.js +++ /dev/null @@ -1,974 +0,0 @@ -// script.aculo.us dragdrop.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 - -// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -if(Object.isUndefined(Effect)) - throw("dragdrop.js requires including script.aculo.us' effects.js library"); - -var Droppables = { - drops: [], - - remove: function(element) { - this.drops = this.drops.reject(function(d) { return d.element==$(element) }); - }, - - add: function(element) { - element = $(element); - var options = Object.extend({ - greedy: true, - hoverclass: null, - tree: false - }, arguments[1] || { }); - - // cache containers - if(options.containment) { - options._containers = []; - var containment = options.containment; - if(Object.isArray(containment)) { - containment.each( function(c) { options._containers.push($(c)) }); - } else { - options._containers.push($(containment)); - } - } - - if(options.accept) options.accept = [options.accept].flatten(); - - Element.makePositioned(element); // fix IE - options.element = element; - - this.drops.push(options); - }, - - findDeepestChild: function(drops) { - deepest = drops[0]; - - for (i = 1; i < drops.length; ++i) - if (Element.isParent(drops[i].element, deepest.element)) - deepest = drops[i]; - - return deepest; - }, - - isContained: function(element, drop) { - var containmentNode; - if(drop.tree) { - containmentNode = element.treeNode; - } else { - containmentNode = element.parentNode; - } - return drop._containers.detect(function(c) { return containmentNode == c }); - }, - - isAffected: function(point, element, drop) { - return ( - (drop.element!=element) && - ((!drop._containers) || - this.isContained(element, drop)) && - ((!drop.accept) || - (Element.classNames(element).detect( - function(v) { return drop.accept.include(v) } ) )) && - Position.within(drop.element, point[0], point[1]) ); - }, - - deactivate: function(drop) { - if(drop.hoverclass) - Element.removeClassName(drop.element, drop.hoverclass); - this.last_active = null; - }, - - activate: function(drop) { - if(drop.hoverclass) - Element.addClassName(drop.element, drop.hoverclass); - this.last_active = drop; - }, - - show: function(point, element) { - if(!this.drops.length) return; - var drop, affected = []; - - this.drops.each( function(drop) { - if(Droppables.isAffected(point, element, drop)) - affected.push(drop); - }); - - if(affected.length>0) - drop = Droppables.findDeepestChild(affected); - - if(this.last_active && this.last_active != drop) this.deactivate(this.last_active); - if (drop) { - Position.within(drop.element, point[0], point[1]); - if(drop.onHover) - drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); - - if (drop != this.last_active) Droppables.activate(drop); - } - }, - - fire: function(event, element) { - if(!this.last_active) return; - Position.prepare(); - - if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) - if (this.last_active.onDrop) { - this.last_active.onDrop(element, this.last_active.element, event); - return true; - } - }, - - reset: function() { - if(this.last_active) - this.deactivate(this.last_active); - } -} - -var Draggables = { - drags: [], - observers: [], - - register: function(draggable) { - if(this.drags.length == 0) { - this.eventMouseUp = this.endDrag.bindAsEventListener(this); - this.eventMouseMove = this.updateDrag.bindAsEventListener(this); - this.eventKeypress = this.keyPress.bindAsEventListener(this); - - Event.observe(document, "mouseup", this.eventMouseUp); - Event.observe(document, "mousemove", this.eventMouseMove); - Event.observe(document, "keypress", this.eventKeypress); - } - this.drags.push(draggable); - }, - - unregister: function(draggable) { - this.drags = this.drags.reject(function(d) { return d==draggable }); - if(this.drags.length == 0) { - Event.stopObserving(document, "mouseup", this.eventMouseUp); - Event.stopObserving(document, "mousemove", this.eventMouseMove); - Event.stopObserving(document, "keypress", this.eventKeypress); - } - }, - - activate: function(draggable) { - if(draggable.options.delay) { - this._timeout = setTimeout(function() { - Draggables._timeout = null; - window.focus(); - Draggables.activeDraggable = draggable; - }.bind(this), draggable.options.delay); - } else { - window.focus(); // allows keypress events if window isn't currently focused, fails for Safari - this.activeDraggable = draggable; - } - }, - - deactivate: function() { - this.activeDraggable = null; - }, - - updateDrag: function(event) { - if(!this.activeDraggable) return; - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - // Mozilla-based browsers fire successive mousemove events with - // the same coordinates, prevent needless redrawing (moz bug?) - if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; - this._lastPointer = pointer; - - this.activeDraggable.updateDrag(event, pointer); - }, - - endDrag: function(event) { - if(this._timeout) { - clearTimeout(this._timeout); - this._timeout = null; - } - if(!this.activeDraggable) return; - this._lastPointer = null; - this.activeDraggable.endDrag(event); - this.activeDraggable = null; - }, - - keyPress: function(event) { - if(this.activeDraggable) - this.activeDraggable.keyPress(event); - }, - - addObserver: function(observer) { - this.observers.push(observer); - this._cacheObserverCallbacks(); - }, - - removeObserver: function(element) { // element instead of observer fixes mem leaks - this.observers = this.observers.reject( function(o) { return o.element==element }); - this._cacheObserverCallbacks(); - }, - - notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' - if(this[eventName+'Count'] > 0) - this.observers.each( function(o) { - if(o[eventName]) o[eventName](eventName, draggable, event); - }); - if(draggable.options[eventName]) draggable.options[eventName](draggable, event); - }, - - _cacheObserverCallbacks: function() { - ['onStart','onEnd','onDrag'].each( function(eventName) { - Draggables[eventName+'Count'] = Draggables.observers.select( - function(o) { return o[eventName]; } - ).length; - }); - } -} - -/*--------------------------------------------------------------------------*/ - -var Draggable = Class.create({ - initialize: function(element) { - var defaults = { - handle: false, - reverteffect: function(element, top_offset, left_offset) { - var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; - new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, - queue: {scope:'_draggable', position:'end'} - }); - }, - endeffect: function(element) { - var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; - new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, - queue: {scope:'_draggable', position:'end'}, - afterFinish: function(){ - Draggable._dragging[element] = false - } - }); - }, - zindex: 1000, - revert: false, - quiet: false, - scroll: false, - scrollSensitivity: 20, - scrollSpeed: 15, - snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } - delay: 0 - }; - - if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) - Object.extend(defaults, { - starteffect: function(element) { - element._opacity = Element.getOpacity(element); - Draggable._dragging[element] = true; - new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); - } - }); - - var options = Object.extend(defaults, arguments[1] || { }); - - this.element = $(element); - - if(options.handle && Object.isString(options.handle)) - this.handle = this.element.down('.'+options.handle, 0); - - if(!this.handle) this.handle = $(options.handle); - if(!this.handle) this.handle = this.element; - - if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { - options.scroll = $(options.scroll); - this._isScrollChild = Element.childOf(this.element, options.scroll); - } - - Element.makePositioned(this.element); // fix IE - - this.options = options; - this.dragging = false; - - this.eventMouseDown = this.initDrag.bindAsEventListener(this); - Event.observe(this.handle, "mousedown", this.eventMouseDown); - - Draggables.register(this); - }, - - destroy: function() { - Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); - Draggables.unregister(this); - }, - - currentDelta: function() { - return([ - parseInt(Element.getStyle(this.element,'left') || '0'), - parseInt(Element.getStyle(this.element,'top') || '0')]); - }, - - initDrag: function(event) { - if(!Object.isUndefined(Draggable._dragging[this.element]) && - Draggable._dragging[this.element]) return; - if(Event.isLeftClick(event)) { - // abort on form elements, fixes a Firefox issue - var src = Event.element(event); - if((tag_name = src.tagName.toUpperCase()) && ( - tag_name=='INPUT' || - tag_name=='SELECT' || - tag_name=='OPTION' || - tag_name=='BUTTON' || - tag_name=='TEXTAREA')) return; - - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var pos = Position.cumulativeOffset(this.element); - this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); - - Draggables.activate(this); - Event.stop(event); - } - }, - - startDrag: function(event) { - this.dragging = true; - if(!this.delta) - this.delta = this.currentDelta(); - - if(this.options.zindex) { - this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); - this.element.style.zIndex = this.options.zindex; - } - - if(this.options.ghosting) { - this._clone = this.element.cloneNode(true); - this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); - if (!this.element._originallyAbsolute) - Position.absolutize(this.element); - this.element.parentNode.insertBefore(this._clone, this.element); - } - - if(this.options.scroll) { - if (this.options.scroll == window) { - var where = this._getWindowScroll(this.options.scroll); - this.originalScrollLeft = where.left; - this.originalScrollTop = where.top; - } else { - this.originalScrollLeft = this.options.scroll.scrollLeft; - this.originalScrollTop = this.options.scroll.scrollTop; - } - } - - Draggables.notify('onStart', this, event); - - if(this.options.starteffect) this.options.starteffect(this.element); - }, - - updateDrag: function(event, pointer) { - if(!this.dragging) this.startDrag(event); - - if(!this.options.quiet){ - Position.prepare(); - Droppables.show(pointer, this.element); - } - - Draggables.notify('onDrag', this, event); - - this.draw(pointer); - if(this.options.change) this.options.change(this); - - if(this.options.scroll) { - this.stopScrolling(); - - var p; - if (this.options.scroll == window) { - with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } - } else { - p = Position.page(this.options.scroll); - p[0] += this.options.scroll.scrollLeft + Position.deltaX; - p[1] += this.options.scroll.scrollTop + Position.deltaY; - p.push(p[0]+this.options.scroll.offsetWidth); - p.push(p[1]+this.options.scroll.offsetHeight); - } - var speed = [0,0]; - if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); - if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); - if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); - if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); - this.startScrolling(speed); - } - - // fix AppleWebKit rendering - if(Prototype.Browser.WebKit) window.scrollBy(0,0); - - Event.stop(event); - }, - - finishDrag: function(event, success) { - this.dragging = false; - - if(this.options.quiet){ - Position.prepare(); - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - Droppables.show(pointer, this.element); - } - - if(this.options.ghosting) { - if (!this.element._originallyAbsolute) - Position.relativize(this.element); - delete this.element._originallyAbsolute; - Element.remove(this._clone); - this._clone = null; - } - - var dropped = false; - if(success) { - dropped = Droppables.fire(event, this.element); - if (!dropped) dropped = false; - } - if(dropped && this.options.onDropped) this.options.onDropped(this.element); - Draggables.notify('onEnd', this, event); - - var revert = this.options.revert; - if(revert && Object.isFunction(revert)) revert = revert(this.element); - - var d = this.currentDelta(); - if(revert && this.options.reverteffect) { - if (dropped == 0 || revert != 'failure') - this.options.reverteffect(this.element, - d[1]-this.delta[1], d[0]-this.delta[0]); - } else { - this.delta = d; - } - - if(this.options.zindex) - this.element.style.zIndex = this.originalZ; - - if(this.options.endeffect) - this.options.endeffect(this.element); - - Draggables.deactivate(this); - Droppables.reset(); - }, - - keyPress: function(event) { - if(event.keyCode!=Event.KEY_ESC) return; - this.finishDrag(event, false); - Event.stop(event); - }, - - endDrag: function(event) { - if(!this.dragging) return; - this.stopScrolling(); - this.finishDrag(event, true); - Event.stop(event); - }, - - draw: function(point) { - var pos = Position.cumulativeOffset(this.element); - if(this.options.ghosting) { - var r = Position.realOffset(this.element); - pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; - } - - var d = this.currentDelta(); - pos[0] -= d[0]; pos[1] -= d[1]; - - if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { - pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; - pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; - } - - var p = [0,1].map(function(i){ - return (point[i]-pos[i]-this.offset[i]) - }.bind(this)); - - if(this.options.snap) { - if(Object.isFunction(this.options.snap)) { - p = this.options.snap(p[0],p[1],this); - } else { - if(Object.isArray(this.options.snap)) { - p = p.map( function(v, i) { - return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)) - } else { - p = p.map( function(v) { - return (v/this.options.snap).round()*this.options.snap }.bind(this)) - } - }} - - var style = this.element.style; - if((!this.options.constraint) || (this.options.constraint=='horizontal')) - style.left = p[0] + "px"; - if((!this.options.constraint) || (this.options.constraint=='vertical')) - style.top = p[1] + "px"; - - if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering - }, - - stopScrolling: function() { - if(this.scrollInterval) { - clearInterval(this.scrollInterval); - this.scrollInterval = null; - Draggables._lastScrollPointer = null; - } - }, - - startScrolling: function(speed) { - if(!(speed[0] || speed[1])) return; - this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; - this.lastScrolled = new Date(); - this.scrollInterval = setInterval(this.scroll.bind(this), 10); - }, - - scroll: function() { - var current = new Date(); - var delta = current - this.lastScrolled; - this.lastScrolled = current; - if(this.options.scroll == window) { - with (this._getWindowScroll(this.options.scroll)) { - if (this.scrollSpeed[0] || this.scrollSpeed[1]) { - var d = delta / 1000; - this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); - } - } - } else { - this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; - this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; - } - - Position.prepare(); - Droppables.show(Draggables._lastPointer, this.element); - Draggables.notify('onDrag', this); - if (this._isScrollChild) { - Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); - Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; - Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; - if (Draggables._lastScrollPointer[0] < 0) - Draggables._lastScrollPointer[0] = 0; - if (Draggables._lastScrollPointer[1] < 0) - Draggables._lastScrollPointer[1] = 0; - this.draw(Draggables._lastScrollPointer); - } - - if(this.options.change) this.options.change(this); - }, - - _getWindowScroll: function(w) { - var T, L, W, H; - with (w.document) { - if (w.document.documentElement && documentElement.scrollTop) { - T = documentElement.scrollTop; - L = documentElement.scrollLeft; - } else if (w.document.body) { - T = body.scrollTop; - L = body.scrollLeft; - } - if (w.innerWidth) { - W = w.innerWidth; - H = w.innerHeight; - } else if (w.document.documentElement && documentElement.clientWidth) { - W = documentElement.clientWidth; - H = documentElement.clientHeight; - } else { - W = body.offsetWidth; - H = body.offsetHeight - } - } - return { top: T, left: L, width: W, height: H }; - } -}); - -Draggable._dragging = { }; - -/*--------------------------------------------------------------------------*/ - -var SortableObserver = Class.create({ - initialize: function(element, observer) { - this.element = $(element); - this.observer = observer; - this.lastValue = Sortable.serialize(this.element); - }, - - onStart: function() { - this.lastValue = Sortable.serialize(this.element); - }, - - onEnd: function() { - Sortable.unmark(); - if(this.lastValue != Sortable.serialize(this.element)) - this.observer(this.element) - } -}); - -var Sortable = { - SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, - - sortables: { }, - - _findRootElement: function(element) { - while (element.tagName.toUpperCase() != "BODY") { - if(element.id && Sortable.sortables[element.id]) return element; - element = element.parentNode; - } - }, - - options: function(element) { - element = Sortable._findRootElement($(element)); - if(!element) return; - return Sortable.sortables[element.id]; - }, - - destroy: function(element){ - var s = Sortable.options(element); - - if(s) { - Draggables.removeObserver(s.element); - s.droppables.each(function(d){ Droppables.remove(d) }); - s.draggables.invoke('destroy'); - - delete Sortable.sortables[s.element.id]; - } - }, - - create: function(element) { - element = $(element); - var options = Object.extend({ - element: element, - tag: 'li', // assumes li children, override with tag: 'tagname' - dropOnEmpty: false, - tree: false, - treeTag: 'ul', - overlap: 'vertical', // one of 'vertical', 'horizontal' - constraint: 'vertical', // one of 'vertical', 'horizontal', false - containment: element, // also takes array of elements (or id's); or false - handle: false, // or a CSS class - only: false, - delay: 0, - hoverclass: null, - ghosting: false, - quiet: false, - scroll: false, - scrollSensitivity: 20, - scrollSpeed: 15, - format: this.SERIALIZE_RULE, - - // these take arrays of elements or ids and can be - // used for better initialization performance - elements: false, - handles: false, - - onChange: Prototype.emptyFunction, - onUpdate: Prototype.emptyFunction - }, arguments[1] || { }); - - // clear any old sortable with same element - this.destroy(element); - - // build options for the draggables - var options_for_draggable = { - revert: true, - quiet: options.quiet, - scroll: options.scroll, - scrollSpeed: options.scrollSpeed, - scrollSensitivity: options.scrollSensitivity, - delay: options.delay, - ghosting: options.ghosting, - constraint: options.constraint, - handle: options.handle }; - - if(options.starteffect) - options_for_draggable.starteffect = options.starteffect; - - if(options.reverteffect) - options_for_draggable.reverteffect = options.reverteffect; - else - if(options.ghosting) options_for_draggable.reverteffect = function(element) { - element.style.top = 0; - element.style.left = 0; - }; - - if(options.endeffect) - options_for_draggable.endeffect = options.endeffect; - - if(options.zindex) - options_for_draggable.zindex = options.zindex; - - // build options for the droppables - var options_for_droppable = { - overlap: options.overlap, - containment: options.containment, - tree: options.tree, - hoverclass: options.hoverclass, - onHover: Sortable.onHover - } - - var options_for_tree = { - onHover: Sortable.onEmptyHover, - overlap: options.overlap, - containment: options.containment, - hoverclass: options.hoverclass - } - - // fix for gecko engine - Element.cleanWhitespace(element); - - options.draggables = []; - options.droppables = []; - - // drop on empty handling - if(options.dropOnEmpty || options.tree) { - Droppables.add(element, options_for_tree); - options.droppables.push(element); - } - - (options.elements || this.findElements(element, options) || []).each( function(e,i) { - var handle = options.handles ? $(options.handles[i]) : - (options.handle ? $(e).select('.' + options.handle)[0] : e); - options.draggables.push( - new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); - Droppables.add(e, options_for_droppable); - if(options.tree) e.treeNode = element; - options.droppables.push(e); - }); - - if(options.tree) { - (Sortable.findTreeElements(element, options) || []).each( function(e) { - Droppables.add(e, options_for_tree); - e.treeNode = element; - options.droppables.push(e); - }); - } - - // keep reference - this.sortables[element.id] = options; - - // for onupdate - Draggables.addObserver(new SortableObserver(element, options.onUpdate)); - - }, - - // return all suitable-for-sortable elements in a guaranteed order - findElements: function(element, options) { - return Element.findChildren( - element, options.only, options.tree ? true : false, options.tag); - }, - - findTreeElements: function(element, options) { - return Element.findChildren( - element, options.only, options.tree ? true : false, options.treeTag); - }, - - onHover: function(element, dropon, overlap) { - if(Element.isParent(dropon, element)) return; - - if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { - return; - } else if(overlap>0.5) { - Sortable.mark(dropon, 'before'); - if(dropon.previousSibling != element) { - var oldParentNode = element.parentNode; - element.style.visibility = "hidden"; // fix gecko rendering - dropon.parentNode.insertBefore(element, dropon); - if(dropon.parentNode!=oldParentNode) - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon.parentNode).onChange(element); - } - } else { - Sortable.mark(dropon, 'after'); - var nextElement = dropon.nextSibling || null; - if(nextElement != element) { - var oldParentNode = element.parentNode; - element.style.visibility = "hidden"; // fix gecko rendering - dropon.parentNode.insertBefore(element, nextElement); - if(dropon.parentNode!=oldParentNode) - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon.parentNode).onChange(element); - } - } - }, - - onEmptyHover: function(element, dropon, overlap) { - var oldParentNode = element.parentNode; - var droponOptions = Sortable.options(dropon); - - if(!Element.isParent(dropon, element)) { - var index; - - var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); - var child = null; - - if(children) { - var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); - - for (index = 0; index < children.length; index += 1) { - if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { - offset -= Element.offsetSize (children[index], droponOptions.overlap); - } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { - child = index + 1 < children.length ? children[index + 1] : null; - break; - } else { - child = children[index]; - break; - } - } - } - - dropon.insertBefore(element, child); - - Sortable.options(oldParentNode).onChange(element); - droponOptions.onChange(element); - } - }, - - unmark: function() { - if(Sortable._marker) Sortable._marker.hide(); - }, - - mark: function(dropon, position) { - // mark on ghosting only - var sortable = Sortable.options(dropon.parentNode); - if(sortable && !sortable.ghosting) return; - - if(!Sortable._marker) { - Sortable._marker = - ($('dropmarker') || Element.extend(document.createElement('DIV'))). - hide().addClassName('dropmarker').setStyle({position:'absolute'}); - document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); - } - var offsets = Position.cumulativeOffset(dropon); - Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); - - if(position=='after') - if(sortable.overlap == 'horizontal') - Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); - else - Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); - - Sortable._marker.show(); - }, - - _tree: function(element, options, parent) { - var children = Sortable.findElements(element, options) || []; - - for (var i = 0; i < children.length; ++i) { - var match = children[i].id.match(options.format); - - if (!match) continue; - - var child = { - id: encodeURIComponent(match ? match[1] : null), - element: element, - parent: parent, - children: [], - position: parent.children.length, - container: $(children[i]).down(options.treeTag) - } - - /* Get the element containing the children and recurse over it */ - if (child.container) - this._tree(child.container, options, child) - - parent.children.push (child); - } - - return parent; - }, - - tree: function(element) { - element = $(element); - var sortableOptions = this.options(element); - var options = Object.extend({ - tag: sortableOptions.tag, - treeTag: sortableOptions.treeTag, - only: sortableOptions.only, - name: element.id, - format: sortableOptions.format - }, arguments[1] || { }); - - var root = { - id: null, - parent: null, - children: [], - container: element, - position: 0 - } - - return Sortable._tree(element, options, root); - }, - - /* Construct a [i] index for a particular node */ - _constructIndex: function(node) { - var index = ''; - do { - if (node.id) index = '[' + node.position + ']' + index; - } while ((node = node.parent) != null); - return index; - }, - - sequence: function(element) { - element = $(element); - var options = Object.extend(this.options(element), arguments[1] || { }); - - return $(this.findElements(element, options) || []).map( function(item) { - return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; - }); - }, - - setSequence: function(element, new_sequence) { - element = $(element); - var options = Object.extend(this.options(element), arguments[2] || { }); - - var nodeMap = { }; - this.findElements(element, options).each( function(n) { - if (n.id.match(options.format)) - nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; - n.parentNode.removeChild(n); - }); - - new_sequence.each(function(ident) { - var n = nodeMap[ident]; - if (n) { - n[1].appendChild(n[0]); - delete nodeMap[ident]; - } - }); - }, - - serialize: function(element) { - element = $(element); - var options = Object.extend(Sortable.options(element), arguments[1] || { }); - var name = encodeURIComponent( - (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); - - if (options.tree) { - return Sortable.tree(element, arguments[1]).children.map( function (item) { - return [name + Sortable._constructIndex(item) + "[id]=" + - encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); - }).flatten().join('&'); - } else { - return Sortable.sequence(element, arguments[1]).map( function(item) { - return name + "[]=" + encodeURIComponent(item); - }).join('&'); - } - } -} - -// Returns true if child is contained within element -Element.isParent = function(child, element) { - if (!child.parentNode || child == element) return false; - if (child.parentNode == element) return true; - return Element.isParent(child.parentNode, element); -} - -Element.findChildren = function(element, only, recursive, tagName) { - if(!element.hasChildNodes()) return null; - tagName = tagName.toUpperCase(); - if(only) only = [only].flatten(); - var elements = []; - $A(element.childNodes).each( function(e) { - if(e.tagName && e.tagName.toUpperCase()==tagName && - (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) - elements.push(e); - if(recursive) { - var grandchildren = Element.findChildren(e, only, recursive, tagName); - if(grandchildren) elements.push(grandchildren); - } - }); - - return (elements.length>0 ? elements.flatten() : []); -} - -Element.offsetSize = function (element, type) { - return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; -} diff --git a/test/otherlibs/scriptaculous/1.8.1/effects.js b/test/otherlibs/scriptaculous/1.8.1/effects.js deleted file mode 100644 index b8c0259f..00000000 --- a/test/otherlibs/scriptaculous/1.8.1/effects.js +++ /dev/null @@ -1,1122 +0,0 @@ -// script.aculo.us effects.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 - -// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// Contributors: -// Justin Palmer (http://encytemedia.com/) -// Mark Pilgrim (http://diveintomark.org/) -// Martin Bialasinki -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -// converts rgb() and #xxx to #xxxxxx format, -// returns self (or first argument) if not convertable -String.prototype.parseColor = function() { - var color = '#'; - if (this.slice(0,4) == 'rgb(') { - var cols = this.slice(4,this.length-1).split(','); - var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); - } else { - if (this.slice(0,1) == '#') { - if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); - if (this.length==7) color = this.toLowerCase(); - } - } - return (color.length==7 ? color : (arguments[0] || this)); -}; - -/*--------------------------------------------------------------------------*/ - -Element.collectTextNodes = function(element) { - return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : - (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); - }).flatten().join(''); -}; - -Element.collectTextNodesIgnoreClass = function(element, className) { - return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : - ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? - Element.collectTextNodesIgnoreClass(node, className) : '')); - }).flatten().join(''); -}; - -Element.setContentZoom = function(element, percent) { - element = $(element); - element.setStyle({fontSize: (percent/100) + 'em'}); - if (Prototype.Browser.WebKit) window.scrollBy(0,0); - return element; -}; - -Element.getInlineOpacity = function(element){ - return $(element).style.opacity || ''; -}; - -Element.forceRerendering = function(element) { - try { - element = $(element); - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch(e) { } -}; - -/*--------------------------------------------------------------------------*/ - -var Effect = { - _elementDoesNotExistError: { - name: 'ElementDoesNotExistError', - message: 'The specified DOM element does not exist, but is required for this effect to operate' - }, - Transitions: { - linear: Prototype.K, - sinoidal: function(pos) { - return (-Math.cos(pos*Math.PI)/2) + 0.5; - }, - reverse: function(pos) { - return 1-pos; - }, - flicker: function(pos) { - var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; - return pos > 1 ? 1 : pos; - }, - wobble: function(pos) { - return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; - }, - pulse: function(pos, pulses) { - pulses = pulses || 5; - return ( - ((pos % (1/pulses)) * pulses).round() == 0 ? - ((pos * pulses * 2) - (pos * pulses * 2).floor()) : - 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor()) - ); - }, - spring: function(pos) { - return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); - }, - none: function(pos) { - return 0; - }, - full: function(pos) { - return 1; - } - }, - DefaultOptions: { - duration: 1.0, // seconds - fps: 100, // 100= assume 66fps max. - sync: false, // true for combining - from: 0.0, - to: 1.0, - delay: 0.0, - queue: 'parallel' - }, - tagifyText: function(element) { - var tagifyStyle = 'position:relative'; - if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; - - element = $(element); - $A(element.childNodes).each( function(child) { - if (child.nodeType==3) { - child.nodeValue.toArray().each( function(character) { - element.insertBefore( - new Element('span', {style: tagifyStyle}).update( - character == ' ' ? String.fromCharCode(160) : character), - child); - }); - Element.remove(child); - } - }); - }, - multiple: function(element, effect) { - var elements; - if (((typeof element == 'object') || - Object.isFunction(element)) && - (element.length)) - elements = element; - else - elements = $(element).childNodes; - - var options = Object.extend({ - speed: 0.1, - delay: 0.0 - }, arguments[2] || { }); - var masterDelay = options.delay; - - $A(elements).each( function(element, index) { - new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); - }); - }, - PAIRS: { - 'slide': ['SlideDown','SlideUp'], - 'blind': ['BlindDown','BlindUp'], - 'appear': ['Appear','Fade'] - }, - toggle: function(element, effect) { - element = $(element); - effect = (effect || 'appear').toLowerCase(); - var options = Object.extend({ - queue: { position:'end', scope:(element.id || 'global'), limit: 1 } - }, arguments[2] || { }); - Effect[element.visible() ? - Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); - } -}; - -Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; - -/* ------------- core effects ------------- */ - -Effect.ScopedQueue = Class.create(Enumerable, { - initialize: function() { - this.effects = []; - this.interval = null; - }, - _each: function(iterator) { - this.effects._each(iterator); - }, - add: function(effect) { - var timestamp = new Date().getTime(); - - var position = Object.isString(effect.options.queue) ? - effect.options.queue : effect.options.queue.position; - - switch(position) { - case 'front': - // move unstarted effects after this effect - this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { - e.startOn += effect.finishOn; - e.finishOn += effect.finishOn; - }); - break; - case 'with-last': - timestamp = this.effects.pluck('startOn').max() || timestamp; - break; - case 'end': - // start effect after last queued effect has finished - timestamp = this.effects.pluck('finishOn').max() || timestamp; - break; - } - - effect.startOn += timestamp; - effect.finishOn += timestamp; - - if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) - this.effects.push(effect); - - if (!this.interval) - this.interval = setInterval(this.loop.bind(this), 15); - }, - remove: function(effect) { - this.effects = this.effects.reject(function(e) { return e==effect }); - if (this.effects.length == 0) { - clearInterval(this.interval); - this.interval = null; - } - }, - loop: function() { - var timePos = new Date().getTime(); - for(var i=0, len=this.effects.length;i= this.startOn) { - if (timePos >= this.finishOn) { - this.render(1.0); - this.cancel(); - this.event('beforeFinish'); - if (this.finish) this.finish(); - this.event('afterFinish'); - return; - } - var pos = (timePos - this.startOn) / this.totalTime, - frame = (pos * this.totalFrames).round(); - if (frame > this.currentFrame) { - this.render(pos); - this.currentFrame = frame; - } - } - }, - cancel: function() { - if (!this.options.sync) - Effect.Queues.get(Object.isString(this.options.queue) ? - 'global' : this.options.queue.scope).remove(this); - this.state = 'finished'; - }, - event: function(eventName) { - if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); - if (this.options[eventName]) this.options[eventName](this); - }, - inspect: function() { - var data = $H(); - for(property in this) - if (!Object.isFunction(this[property])) data.set(property, this[property]); - return '#'; - } -}); - -Effect.Parallel = Class.create(Effect.Base, { - initialize: function(effects) { - this.effects = effects || []; - this.start(arguments[1]); - }, - update: function(position) { - this.effects.invoke('render', position); - }, - finish: function(position) { - this.effects.each( function(effect) { - effect.render(1.0); - effect.cancel(); - effect.event('beforeFinish'); - if (effect.finish) effect.finish(position); - effect.event('afterFinish'); - }); - } -}); - -Effect.Tween = Class.create(Effect.Base, { - initialize: function(object, from, to) { - object = Object.isString(object) ? $(object) : object; - var args = $A(arguments), method = args.last(), - options = args.length == 5 ? args[3] : null; - this.method = Object.isFunction(method) ? method.bind(object) : - Object.isFunction(object[method]) ? object[method].bind(object) : - function(value) { object[method] = value }; - this.start(Object.extend({ from: from, to: to }, options || { })); - }, - update: function(position) { - this.method(position); - } -}); - -Effect.Event = Class.create(Effect.Base, { - initialize: function() { - this.start(Object.extend({ duration: 0 }, arguments[0] || { })); - }, - update: Prototype.emptyFunction -}); - -Effect.Opacity = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - // make this work on IE on elements without 'layout' - if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) - this.element.setStyle({zoom: 1}); - var options = Object.extend({ - from: this.element.getOpacity() || 0.0, - to: 1.0 - }, arguments[1] || { }); - this.start(options); - }, - update: function(position) { - this.element.setOpacity(position); - } -}); - -Effect.Move = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ - x: 0, - y: 0, - mode: 'relative' - }, arguments[1] || { }); - this.start(options); - }, - setup: function() { - this.element.makePositioned(); - this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); - this.originalTop = parseFloat(this.element.getStyle('top') || '0'); - if (this.options.mode == 'absolute') { - this.options.x = this.options.x - this.originalLeft; - this.options.y = this.options.y - this.originalTop; - } - }, - update: function(position) { - this.element.setStyle({ - left: (this.options.x * position + this.originalLeft).round() + 'px', - top: (this.options.y * position + this.originalTop).round() + 'px' - }); - } -}); - -// for backwards compatibility -Effect.MoveBy = function(element, toTop, toLeft) { - return new Effect.Move(element, - Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); -}; - -Effect.Scale = Class.create(Effect.Base, { - initialize: function(element, percent) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ - scaleX: true, - scaleY: true, - scaleContent: true, - scaleFromCenter: false, - scaleMode: 'box', // 'box' or 'contents' or { } with provided values - scaleFrom: 100.0, - scaleTo: percent - }, arguments[2] || { }); - this.start(options); - }, - setup: function() { - this.restoreAfterFinish = this.options.restoreAfterFinish || false; - this.elementPositioning = this.element.getStyle('position'); - - this.originalStyle = { }; - ['top','left','width','height','fontSize'].each( function(k) { - this.originalStyle[k] = this.element.style[k]; - }.bind(this)); - - this.originalTop = this.element.offsetTop; - this.originalLeft = this.element.offsetLeft; - - var fontSize = this.element.getStyle('font-size') || '100%'; - ['em','px','%','pt'].each( function(fontSizeType) { - if (fontSize.indexOf(fontSizeType)>0) { - this.fontSize = parseFloat(fontSize); - this.fontSizeType = fontSizeType; - } - }.bind(this)); - - this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; - - this.dims = null; - if (this.options.scaleMode=='box') - this.dims = [this.element.offsetHeight, this.element.offsetWidth]; - if (/^content/.test(this.options.scaleMode)) - this.dims = [this.element.scrollHeight, this.element.scrollWidth]; - if (!this.dims) - this.dims = [this.options.scaleMode.originalHeight, - this.options.scaleMode.originalWidth]; - }, - update: function(position) { - var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); - if (this.options.scaleContent && this.fontSize) - this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); - this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); - }, - finish: function(position) { - if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); - }, - setDimensions: function(height, width) { - var d = { }; - if (this.options.scaleX) d.width = width.round() + 'px'; - if (this.options.scaleY) d.height = height.round() + 'px'; - if (this.options.scaleFromCenter) { - var topd = (height - this.dims[0])/2; - var leftd = (width - this.dims[1])/2; - if (this.elementPositioning == 'absolute') { - if (this.options.scaleY) d.top = this.originalTop-topd + 'px'; - if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; - } else { - if (this.options.scaleY) d.top = -topd + 'px'; - if (this.options.scaleX) d.left = -leftd + 'px'; - } - } - this.element.setStyle(d); - } -}); - -Effect.Highlight = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { }); - this.start(options); - }, - setup: function() { - // Prevent executing on elements not in the layout flow - if (this.element.getStyle('display')=='none') { this.cancel(); return; } - // Disable background image during the effect - this.oldStyle = { }; - if (!this.options.keepBackgroundImage) { - this.oldStyle.backgroundImage = this.element.getStyle('background-image'); - this.element.setStyle({backgroundImage: 'none'}); - } - if (!this.options.endcolor) - this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); - if (!this.options.restorecolor) - this.options.restorecolor = this.element.getStyle('background-color'); - // init color calculations - this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); - this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); - }, - update: function(position) { - this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ - return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) }); - }, - finish: function() { - this.element.setStyle(Object.extend(this.oldStyle, { - backgroundColor: this.options.restorecolor - })); - } -}); - -Effect.ScrollTo = function(element) { - var options = arguments[1] || { }, - scrollOffsets = document.viewport.getScrollOffsets(), - elementOffsets = $(element).cumulativeOffset(), - max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); - - if (options.offset) elementOffsets[1] += options.offset; - - return new Effect.Tween(null, - scrollOffsets.top, - elementOffsets[1] > max ? max : elementOffsets[1], - options, - function(p){ scrollTo(scrollOffsets.left, p.round()) } - ); -}; - -/* ------------- combination effects ------------- */ - -Effect.Fade = function(element) { - element = $(element); - var oldOpacity = element.getInlineOpacity(); - var options = Object.extend({ - from: element.getOpacity() || 1.0, - to: 0.0, - afterFinishInternal: function(effect) { - if (effect.options.to!=0) return; - effect.element.hide().setStyle({opacity: oldOpacity}); - } - }, arguments[1] || { }); - return new Effect.Opacity(element,options); -}; - -Effect.Appear = function(element) { - element = $(element); - var options = Object.extend({ - from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), - to: 1.0, - // force Safari to render floated elements properly - afterFinishInternal: function(effect) { - effect.element.forceRerendering(); - }, - beforeSetup: function(effect) { - effect.element.setOpacity(effect.options.from).show(); - }}, arguments[1] || { }); - return new Effect.Opacity(element,options); -}; - -Effect.Puff = function(element) { - element = $(element); - var oldStyle = { - opacity: element.getInlineOpacity(), - position: element.getStyle('position'), - top: element.style.top, - left: element.style.left, - width: element.style.width, - height: element.style.height - }; - return new Effect.Parallel( - [ new Effect.Scale(element, 200, - { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], - Object.extend({ duration: 1.0, - beforeSetupInternal: function(effect) { - Position.absolutize(effect.effects[0].element) - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide().setStyle(oldStyle); } - }, arguments[1] || { }) - ); -}; - -Effect.BlindUp = function(element) { - element = $(element); - element.makeClipping(); - return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, - restoreAfterFinish: true, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping(); - } - }, arguments[1] || { }) - ); -}; - -Effect.BlindDown = function(element) { - element = $(element); - var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, 100, Object.extend({ - scaleContent: false, - scaleX: false, - scaleFrom: 0, - scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, - restoreAfterFinish: true, - afterSetup: function(effect) { - effect.element.makeClipping().setStyle({height: '0px'}).show(); - }, - afterFinishInternal: function(effect) { - effect.element.undoClipping(); - } - }, arguments[1] || { })); -}; - -Effect.SwitchOff = function(element) { - element = $(element); - var oldOpacity = element.getInlineOpacity(); - return new Effect.Appear(element, Object.extend({ - duration: 0.4, - from: 0, - transition: Effect.Transitions.flicker, - afterFinishInternal: function(effect) { - new Effect.Scale(effect.element, 1, { - duration: 0.3, scaleFromCenter: true, - scaleX: false, scaleContent: false, restoreAfterFinish: true, - beforeSetup: function(effect) { - effect.element.makePositioned().makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); - } - }) - } - }, arguments[1] || { })); -}; - -Effect.DropOut = function(element) { - element = $(element); - var oldStyle = { - top: element.getStyle('top'), - left: element.getStyle('left'), - opacity: element.getInlineOpacity() }; - return new Effect.Parallel( - [ new Effect.Move(element, {x: 0, y: 100, sync: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 }) ], - Object.extend( - { duration: 0.5, - beforeSetup: function(effect) { - effect.effects[0].element.makePositioned(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); - } - }, arguments[1] || { })); -}; - -Effect.Shake = function(element) { - element = $(element); - var options = Object.extend({ - distance: 20, - duration: 0.5 - }, arguments[1] || {}); - var distance = parseFloat(options.distance); - var split = parseFloat(options.duration) / 10.0; - var oldStyle = { - top: element.getStyle('top'), - left: element.getStyle('left') }; - return new Effect.Move(element, - { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) { - effect.element.undoPositioned().setStyle(oldStyle); - }}) }}) }}) }}) }}) }}); -}; - -Effect.SlideDown = function(element) { - element = $(element).cleanWhitespace(); - // SlideDown need to have the content of the element wrapped in a container element with fixed height! - var oldInnerBottom = element.down().getStyle('bottom'); - var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, 100, Object.extend({ - scaleContent: false, - scaleX: false, - scaleFrom: window.opera ? 0 : 1, - scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, - restoreAfterFinish: true, - afterSetup: function(effect) { - effect.element.makePositioned(); - effect.element.down().makePositioned(); - if (window.opera) effect.element.setStyle({top: ''}); - effect.element.makeClipping().setStyle({height: '0px'}).show(); - }, - afterUpdateInternal: function(effect) { - effect.element.down().setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); - }, - afterFinishInternal: function(effect) { - effect.element.undoClipping().undoPositioned(); - effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } - }, arguments[1] || { }) - ); -}; - -Effect.SlideUp = function(element) { - element = $(element).cleanWhitespace(); - var oldInnerBottom = element.down().getStyle('bottom'); - var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, window.opera ? 0 : 1, - Object.extend({ scaleContent: false, - scaleX: false, - scaleMode: 'box', - scaleFrom: 100, - scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, - restoreAfterFinish: true, - afterSetup: function(effect) { - effect.element.makePositioned(); - effect.element.down().makePositioned(); - if (window.opera) effect.element.setStyle({top: ''}); - effect.element.makeClipping().show(); - }, - afterUpdateInternal: function(effect) { - effect.element.down().setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().undoPositioned(); - effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); - } - }, arguments[1] || { }) - ); -}; - -// Bug in opera makes the TD containing this element expand for a instance after finish -Effect.Squish = function(element) { - return new Effect.Scale(element, window.opera ? 1 : 0, { - restoreAfterFinish: true, - beforeSetup: function(effect) { - effect.element.makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping(); - } - }); -}; - -Effect.Grow = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransition: Effect.Transitions.sinoidal, - scaleTransition: Effect.Transitions.sinoidal, - opacityTransition: Effect.Transitions.full - }, arguments[1] || { }); - var oldStyle = { - top: element.style.top, - left: element.style.left, - height: element.style.height, - width: element.style.width, - opacity: element.getInlineOpacity() }; - - var dims = element.getDimensions(); - var initialMoveX, initialMoveY; - var moveX, moveY; - - switch (options.direction) { - case 'top-left': - initialMoveX = initialMoveY = moveX = moveY = 0; - break; - case 'top-right': - initialMoveX = dims.width; - initialMoveY = moveY = 0; - moveX = -dims.width; - break; - case 'bottom-left': - initialMoveX = moveX = 0; - initialMoveY = dims.height; - moveY = -dims.height; - break; - case 'bottom-right': - initialMoveX = dims.width; - initialMoveY = dims.height; - moveX = -dims.width; - moveY = -dims.height; - break; - case 'center': - initialMoveX = dims.width / 2; - initialMoveY = dims.height / 2; - moveX = -dims.width / 2; - moveY = -dims.height / 2; - break; - } - - return new Effect.Move(element, { - x: initialMoveX, - y: initialMoveY, - duration: 0.01, - beforeSetup: function(effect) { - effect.element.hide().makeClipping().makePositioned(); - }, - afterFinishInternal: function(effect) { - new Effect.Parallel( - [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), - new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), - new Effect.Scale(effect.element, 100, { - scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, - sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) - ], Object.extend({ - beforeSetup: function(effect) { - effect.effects[0].element.setStyle({height: '0px'}).show(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); - } - }, options) - ) - } - }); -}; - -Effect.Shrink = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransition: Effect.Transitions.sinoidal, - scaleTransition: Effect.Transitions.sinoidal, - opacityTransition: Effect.Transitions.none - }, arguments[1] || { }); - var oldStyle = { - top: element.style.top, - left: element.style.left, - height: element.style.height, - width: element.style.width, - opacity: element.getInlineOpacity() }; - - var dims = element.getDimensions(); - var moveX, moveY; - - switch (options.direction) { - case 'top-left': - moveX = moveY = 0; - break; - case 'top-right': - moveX = dims.width; - moveY = 0; - break; - case 'bottom-left': - moveX = 0; - moveY = dims.height; - break; - case 'bottom-right': - moveX = dims.width; - moveY = dims.height; - break; - case 'center': - moveX = dims.width / 2; - moveY = dims.height / 2; - break; - } - - return new Effect.Parallel( - [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), - new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), - new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) - ], Object.extend({ - beforeStartInternal: function(effect) { - effect.effects[0].element.makePositioned().makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } - }, options) - ); -}; - -Effect.Pulsate = function(element) { - element = $(element); - var options = arguments[1] || { }; - var oldOpacity = element.getInlineOpacity(); - var transition = options.transition || Effect.Transitions.sinoidal; - var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; - reverser.bind(transition); - return new Effect.Opacity(element, - Object.extend(Object.extend({ duration: 2.0, from: 0, - afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } - }, options), {transition: reverser})); -}; - -Effect.Fold = function(element) { - element = $(element); - var oldStyle = { - top: element.style.top, - left: element.style.left, - width: element.style.width, - height: element.style.height }; - element.makeClipping(); - return new Effect.Scale(element, 5, Object.extend({ - scaleContent: false, - scaleX: false, - afterFinishInternal: function(effect) { - new Effect.Scale(element, 1, { - scaleContent: false, - scaleY: false, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().setStyle(oldStyle); - } }); - }}, arguments[1] || { })); -}; - -Effect.Morph = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ - style: { } - }, arguments[1] || { }); - - if (!Object.isString(options.style)) this.style = $H(options.style); - else { - if (options.style.include(':')) - this.style = options.style.parseStyle(); - else { - this.element.addClassName(options.style); - this.style = $H(this.element.getStyles()); - this.element.removeClassName(options.style); - var css = this.element.getStyles(); - this.style = this.style.reject(function(style) { - return style.value == css[style.key]; - }); - options.afterFinishInternal = function(effect) { - effect.element.addClassName(effect.options.style); - effect.transforms.each(function(transform) { - effect.element.style[transform.style] = ''; - }); - } - } - } - this.start(options); - }, - - setup: function(){ - function parseColor(color){ - if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; - color = color.parseColor(); - return $R(0,2).map(function(i){ - return parseInt( color.slice(i*2+1,i*2+3), 16 ) - }); - } - this.transforms = this.style.map(function(pair){ - var property = pair[0], value = pair[1], unit = null; - - if (value.parseColor('#zzzzzz') != '#zzzzzz') { - value = value.parseColor(); - unit = 'color'; - } else if (property == 'opacity') { - value = parseFloat(value); - if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) - this.element.setStyle({zoom: 1}); - } else if (Element.CSS_LENGTH.test(value)) { - var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); - value = parseFloat(components[1]); - unit = (components.length == 3) ? components[2] : null; - } - - var originalValue = this.element.getStyle(property); - return { - style: property.camelize(), - originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), - targetValue: unit=='color' ? parseColor(value) : value, - unit: unit - }; - }.bind(this)).reject(function(transform){ - return ( - (transform.originalValue == transform.targetValue) || - ( - transform.unit != 'color' && - (isNaN(transform.originalValue) || isNaN(transform.targetValue)) - ) - ) - }); - }, - update: function(position) { - var style = { }, transform, i = this.transforms.length; - while(i--) - style[(transform = this.transforms[i]).style] = - transform.unit=='color' ? '#'+ - (Math.round(transform.originalValue[0]+ - (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + - (Math.round(transform.originalValue[1]+ - (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() + - (Math.round(transform.originalValue[2]+ - (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : - (transform.originalValue + - (transform.targetValue - transform.originalValue) * position).toFixed(3) + - (transform.unit === null ? '' : transform.unit); - this.element.setStyle(style, true); - } -}); - -Effect.Transform = Class.create({ - initialize: function(tracks){ - this.tracks = []; - this.options = arguments[1] || { }; - this.addTracks(tracks); - }, - addTracks: function(tracks){ - tracks.each(function(track){ - track = $H(track); - var data = track.values().first(); - this.tracks.push($H({ - ids: track.keys().first(), - effect: Effect.Morph, - options: { style: data } - })); - }.bind(this)); - return this; - }, - play: function(){ - return new Effect.Parallel( - this.tracks.map(function(track){ - var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options'); - var elements = [$(ids) || $$(ids)].flatten(); - return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) }); - }).flatten(), - this.options - ); - } -}); - -Element.CSS_PROPERTIES = $w( - 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + - 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + - 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + - 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + - 'fontSize fontWeight height left letterSpacing lineHeight ' + - 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+ - 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + - 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + - 'right textIndent top width wordSpacing zIndex'); - -Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; - -String.__parseStyleElement = document.createElement('div'); -String.prototype.parseStyle = function(){ - var style, styleRules = $H(); - if (Prototype.Browser.WebKit) - style = new Element('div',{style:this}).style; - else { - String.__parseStyleElement.innerHTML = '
    '; - style = String.__parseStyleElement.childNodes[0].style; - } - - Element.CSS_PROPERTIES.each(function(property){ - if (style[property]) styleRules.set(property, style[property]); - }); - - if (Prototype.Browser.IE && this.include('opacity')) - styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); - - return styleRules; -}; - -if (document.defaultView && document.defaultView.getComputedStyle) { - Element.getStyles = function(element) { - var css = document.defaultView.getComputedStyle($(element), null); - return Element.CSS_PROPERTIES.inject({ }, function(styles, property) { - styles[property] = css[property]; - return styles; - }); - }; -} else { - Element.getStyles = function(element) { - element = $(element); - var css = element.currentStyle, styles; - styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) { - results[property] = css[property]; - return results; - }); - if (!styles.opacity) styles.opacity = element.getOpacity(); - return styles; - }; -}; - -Effect.Methods = { - morph: function(element, style) { - element = $(element); - new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { })); - return element; - }, - visualEffect: function(element, effect, options) { - element = $(element) - var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); - new Effect[klass](element, options); - return element; - }, - highlight: function(element, options) { - element = $(element); - new Effect.Highlight(element, options); - return element; - } -}; - -$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ - 'pulsate shake puff squish switchOff dropOut').each( - function(effect) { - Effect.Methods[effect] = function(element, options){ - element = $(element); - Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); - return element; - } - } -); - -$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( - function(f) { Effect.Methods[f] = Element[f]; } -); - -Element.addMethods(Effect.Methods); diff --git a/test/otherlibs/scriptaculous/1.8.1/scriptaculous.js b/test/otherlibs/scriptaculous/1.8.1/scriptaculous.js deleted file mode 100644 index 6cfe36e8..00000000 --- a/test/otherlibs/scriptaculous/1.8.1/scriptaculous.js +++ /dev/null @@ -1,58 +0,0 @@ -// script.aculo.us scriptaculous.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 - -// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -var Scriptaculous = { - Version: '1.8.1', - require: function(libraryName) { - // inserting via DOM fails in Safari 2.0, so brute force approach - document.write('\n"; - if( $lib == 'prototype' ) // prototype must be included first + foreach( $_POST as $name => $ver ){ + $url = $libraries[ $name ][ "url" ]; + if( $name == "YUI" && $ver[0] == "2" ) { + $url = str_replace( "/yui", "/yuiloader", $url, $count = 2 ); + } + $include = "\n"; + if( $lib == "prototype" ) { // prototype must be included first array_unshift( $includes, $include ); - else + } else { array_push( $includes, $include ); + } } $includes = implode( "\n", $includes ); - $suite = file_get_contents('index.html'); - echo str_replace( '', $includes, $suite ); + $suite = file_get_contents( "index.html" ); + echo str_replace( "", $includes, $suite ); exit; } ?> - - - + + - - jQuery Test Suite - - + + Run jQuery Test Suite Polluted @@ -44,21 +80,20 @@

    Choose other libraries to include

    -
    + $lib"; - $vers = scandir( "otherlibs/$lib"); - foreach( $vers as $ver ){ - if( $ver[0] != '.' ) - echo ""; + foreach( $libraries as $name => $data ) { + echo "
    $name"; + $i = 0; + foreach( $data[ "versions" ] as $ver ) { + $i++; + echo ""; + if( !($i % 4) ) echo "
    "; } + echo "
    "; } ?> - +
    diff --git a/test/test.js b/test/test.js deleted file mode 100644 index e76b795a..00000000 --- a/test/test.js +++ /dev/null @@ -1,41 +0,0 @@ -load( "build/js/writeFile.js", "build/js/parse.js" ); - -function addParams(name, params) { - if(params.length > 0) { - name += "("; - for ( var i = 0; i < params.length; i++) { - name += params[i].type + ", "; - } - return name.substring(0, name.length - 2) + ")"; - } else { - return name + "()"; - } -} -function addTestWrapper(name, test) { - return 'test("' + name + '", function() {\n' + test + '\n});'; -} - -var dir = arguments[1]; -var jq = parse( read(arguments[0]) ); - -var testFile = []; - -String.prototype.decode = function() { - return this.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); -}; - -for ( var i = 0; i < jq.length; i++ ) { - if ( jq[i].tests.length > 0 ) { - var method = jq[i]; - var name = addParams(method.name, method.params); - for(var j = 0; j < method.tests.length; j++) { - if(j > 0) { - name += "x"; - } - testFile[testFile.length] = addTestWrapper(name, method.tests[j].decode()) + "\n"; - } - } -} - -var indexFile = readFile( "build/test/index.html" ); -writeFile( dir + "/index.html", indexFile.replace( /{TESTS}/g, testFile.join("\n") ) ); From 3930afa3ad10440ecb6571c0840d576b9979bff5 Mon Sep 17 00:00:00 2001 From: Anton M Date: Sun, 13 Feb 2011 01:48:48 +0100 Subject: [PATCH 093/123] Follow up to fbf79c0b495e08d67c3a4767f371ec7bcfc40a17. Fix stupid error. --- test/polluted.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/polluted.php b/test/polluted.php index 746bcefd..50fc7cd6 100644 --- a/test/polluted.php +++ b/test/polluted.php @@ -5,7 +5,7 @@ "versions" => array( "1.1.1", "1.2.0", "1.2.3", "1.3.0", "1.3.1", "1.3.2", "1.4.0", "1.4.1", "1.4.3", "1.5.0" ), "url" => "dojo/XYZ/dojo/dojo.xd.js" ), - "Ext Core" => array( + "ExtCore" => array( "versions" => array( "3.0.0", "3.1.0" ), "url" => "ext-core/XYZ/ext-core.js" ), @@ -13,7 +13,7 @@ "versions" => array( "1.2.3", "1.2.6", "1.3.0", "1.3.1", "1.3.2", "1.4.0", "1.4.1", "1.4.2", "1.4.3", "1.4.4", "1.5.0" ), "url" => "jquery/XYZ/jquery.min.js" ), - "jQuery UI" => array( + "jQueryUI" => array( "versions" => array( "1.5.2", "1.5.3", "1.6.0", "1.7.0", "1.7.1", "1.7.2", "1.7.3", "1.8.0", "1.8.1", "1.8.2", "1.8.4", "1.8.5", "1.8.6", "1.8.7", "1.8.8", "1.8.9" ), "url" => "jqueryui/XYZ/jquery-ui.min.js" ), @@ -25,7 +25,7 @@ "versions" => array( "1.6.0.2", "1.6.0.3", "1.6.1.0", "1.7.0.0" ), "url" => "prototype/XYZ/prototype.js" ), - "script.aculo.us" => array( + "scriptaculous" => array( "versions" => array( "1.8.1", "1.8.2", "1.8.3" ), "url" => "scriptaculous/XYZ/scriptaculous.js" ), From dba8c20b4bfdeb95b6fb8c9555355babf1daa539 Mon Sep 17 00:00:00 2001 From: Anton M Date: Sun, 13 Feb 2011 23:02:14 +0100 Subject: [PATCH 094/123] Clean up whitespace in test/unit/effects.js --- test/unit/effects.js | 81 ++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/test/unit/effects.js b/test/unit/effects.js index b1dd2884..bab4f256 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -39,24 +39,23 @@ test("show()", function() { ok( pass, "Show" ); var speeds = { - "null speed": null, - "undefined speed": undefined, - "empty string speed": "", - "false speed": false + "null speed": null, + "undefined speed": undefined, + "empty string speed": "", + "false speed": false }; jQuery.each(speeds, function(name, speed) { - pass = true; - div.hide().show(speed).each(function() { - if ( this.style.display == "none" ) pass = false; - }); - ok( pass, "Show with " + name); - }); - + pass = true; + div.hide().show(speed).each(function() { + if ( this.style.display == "none" ) pass = false; + }); + ok( pass, "Show with " + name); + }); jQuery.each(speeds, function(name, speed) { - pass = true; - div.hide().show(speed, function() { + pass = true; + div.hide().show(speed, function() { pass = false; }); ok( pass, "Show with " + name + " does not call animate callback" ); @@ -132,9 +131,9 @@ test("show(Number) - other displays", function() { -// Supports #7397 +// Supports #7397 test("Persist correct display value", function() { - expect(3); + expect(3); QUnit.reset(); stop(); @@ -142,31 +141,25 @@ test("Persist correct display value", function() { jQuery("#main").append('
    foo
    '); var $span = jQuery("#show-tests span"), - displayNone = $span.css("display"), - display = '', num = 0; + displayNone = $span.css("display"), + display = '', num = 0; - $span.show(); + $span.show(); - display = $span.css("display"); + display = $span.css("display"); - $span.hide(); + $span.hide(); - $span.fadeIn(100, function() { - - equals($span.css("display"), display, "Expecting display: " + display); - - $span.fadeOut(100, function () { - - equals($span.css("display"), displayNone, "Expecting display: " + displayNone); - - $span.fadeIn(100, function() { - - equals($span.css("display"), display, "Expecting display: " + display); - - start(); - }); - }); - }); + $span.fadeIn(100, function() { + equals($span.css("display"), display, "Expecting display: " + display); + $span.fadeOut(100, function () { + equals($span.css("display"), displayNone, "Expecting display: " + displayNone); + $span.fadeIn(100, function() { + equals($span.css("display"), display, "Expecting display: " + display); + start(); + }); + }); + }); }); test("animate(Hash, Object, Function)", function() { @@ -574,7 +567,7 @@ test("support negative values < -10000 (bug #7193)", function () { equals( fx.cur(), -11000, "Element has margin-bottom of -11000" ); delete jQuery.fx.step.marginBottom; } - }); + }); jQuery("#main").css("marginBottom", "-11000px").animate({ marginBottom: "-11001px" }, { duration: 1, @@ -803,7 +796,7 @@ test("Chain toggle out", function() { jQuery('#toggleout div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast',jQuery.checkState); }); test("Chain toggle out with easing and callback", function() { - jQuery('#toggleout div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast','linear',jQuery.checkState); + jQuery('#toggleout div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast','linear',jQuery.checkState); }); test("Chain slideDown slideUp", function() { jQuery('#slidedown div').saveState(jQuery.support.shrinkWrapBlocks).slideDown('fast').slideUp('fast',jQuery.checkState); @@ -850,16 +843,16 @@ jQuery.makeTest.id = 1; test("jQuery.show('fast') doesn't clear radio buttons (bug #1095)", function () { expect(4); - stop(); + stop(); var $checkedtest = jQuery("#checkedtest"); // IE6 was clearing "checked" in jQuery(elem).show("fast"); $checkedtest.hide().show("fast", function() { - ok( !! jQuery(":radio:first", $checkedtest).attr("checked"), "Check first radio still checked." ); - ok( ! jQuery(":radio:last", $checkedtest).attr("checked"), "Check last radio still NOT checked." ); - ok( !! jQuery(":checkbox:first", $checkedtest).attr("checked"), "Check first checkbox still checked." ); - ok( ! jQuery(":checkbox:last", $checkedtest).attr("checked"), "Check last checkbox still NOT checked." ); - start(); + ok( !! jQuery(":radio:first", $checkedtest).attr("checked"), "Check first radio still checked." ); + ok( ! jQuery(":radio:last", $checkedtest).attr("checked"), "Check last radio still NOT checked." ); + ok( !! jQuery(":checkbox:first", $checkedtest).attr("checked"), "Check first checkbox still checked." ); + ok( ! jQuery(":checkbox:last", $checkedtest).attr("checked"), "Check last checkbox still NOT checked." ); + start(); }); }); From c5edf982d59977c506fececd504a3dbfd1a398dc Mon Sep 17 00:00:00 2001 From: Anton M Date: Sun, 13 Feb 2011 23:03:46 +0100 Subject: [PATCH 095/123] Don't add "px" to unit-less properties when animating them. Fixes #4966. --- src/effects.js | 4 ++-- test/unit/effects.js | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/effects.js b/src/effects.js index b0675395..0b08bc2d 100644 --- a/src/effects.js +++ b/src/effects.js @@ -189,7 +189,7 @@ jQuery.fn.extend({ if ( parts ) { var end = parseFloat( parts[2] ), - unit = parts[3] || "px"; + unit = parts[3] || jQuery.cssNumber[ name ] ? "" : "px"; // We need to compute starting value if ( unit !== "px" ) { @@ -348,7 +348,7 @@ jQuery.fx.prototype = { this.startTime = jQuery.now(); this.start = from; this.end = to; - this.unit = unit || this.unit || "px"; + this.unit = unit || this.unit || jQuery.cssNumber[ this.prop ] ? "" : "px"; this.now = this.start; this.pos = this.state = 0; diff --git a/test/unit/effects.js b/test/unit/effects.js index bab4f256..7fb1c7d8 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -919,3 +919,13 @@ test("hide hidden elements, with animation (bug #7141)", function() { }); }); }); + +test("animate unit-less properties (#4966)", 2, function() { + stop(); + var div = jQuery( "
    " ).appendTo( "body" ); + equal( div.css( "z-index" ), "0", "z-index is 0" ); + div.animate({ zIndex: 2 }, function() { + equal( div.css( "z-index" ), "2", "z-index is 2" ); + start(); + }); +}); From 659773348f1fca0fb609f92271013f2a087f3247 Mon Sep 17 00:00:00 2001 From: Anton M Date: Mon, 14 Feb 2011 00:37:07 +0100 Subject: [PATCH 096/123] Fix breaking test in Chrome. --- src/effects.js | 4 ++-- test/unit/effects.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/effects.js b/src/effects.js index 0b08bc2d..fd832ce4 100644 --- a/src/effects.js +++ b/src/effects.js @@ -189,7 +189,7 @@ jQuery.fn.extend({ if ( parts ) { var end = parseFloat( parts[2] ), - unit = parts[3] || jQuery.cssNumber[ name ] ? "" : "px"; + unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" ); // We need to compute starting value if ( unit !== "px" ) { @@ -348,7 +348,7 @@ jQuery.fx.prototype = { this.startTime = jQuery.now(); this.start = from; this.end = to; - this.unit = unit || this.unit || jQuery.cssNumber[ this.prop ] ? "" : "px"; + this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); this.now = this.start; this.pos = this.state = 0; diff --git a/test/unit/effects.js b/test/unit/effects.js index 7fb1c7d8..a07c076d 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -922,7 +922,7 @@ test("hide hidden elements, with animation (bug #7141)", function() { test("animate unit-less properties (#4966)", 2, function() { stop(); - var div = jQuery( "
    " ).appendTo( "body" ); + var div = jQuery( "
    " ).appendTo( "#main" ); equal( div.css( "z-index" ), "0", "z-index is 0" ); div.animate({ zIndex: 2 }, function() { equal( div.css( "z-index" ), "2", "z-index is 2" ); From 217a9919c3adcde198774301aa082e5be8a6489d Mon Sep 17 00:00:00 2001 From: Anton M Date: Mon, 14 Feb 2011 22:38:19 +0100 Subject: [PATCH 097/123] Add missing semicolon. --- src/effects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects.js b/src/effects.js index 09aba14c..bebcc431 100644 --- a/src/effects.js +++ b/src/effects.js @@ -524,7 +524,7 @@ function defaultDisplay( nodeName ) { // create a temp element and check it's default display, this // will ensure that the value returned is not a user-tampered // value. - elem = jQuery("<" + nodeName + ">").appendTo("body"), + elem = jQuery("<" + nodeName + ">").appendTo("body"); display = elem.css("display"); // Remove temp element From 2ed81708bdacfd4b97b77baef67ad8b75205dd20 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Mon, 14 Feb 2011 16:22:23 -0600 Subject: [PATCH 098/123] Hide metadata when serializing JS objects using JSON.stringify via a toJSON hack. Fixes #8108. --- src/data.js | 26 +++++++++++++++++++++++--- test/unit/data.js | 32 +++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/data.js b/src/data.js index 9fee459a..66d22925 100644 --- a/src/data.js +++ b/src/data.js @@ -24,7 +24,7 @@ jQuery.extend({ hasData: function( elem ) { elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !jQuery.isEmptyObject(elem); + return !!elem && !isEmptyDataObject( elem ); }, data: function( elem, name, data, pvt /* Internal Use Only */ ) { @@ -64,6 +64,13 @@ jQuery.extend({ if ( !cache[ id ] ) { cache[ id ] = {}; + + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + cache[ id ].toJSON = function () { + return undefined; + }; } // An object can be passed to jQuery.data instead of a key/value pair; this gets @@ -130,7 +137,7 @@ jQuery.extend({ // If there is no data left in the cache, we want to continue // and let the cache object itself get destroyed - if ( !jQuery.isEmptyObject(thisCache) ) { + if ( !isEmptyDataObject(thisCache) ) { return; } } @@ -142,7 +149,7 @@ jQuery.extend({ // Don't destroy the parent cache unless the internal data object // had been the only thing left in it - if ( !jQuery.isEmptyObject(cache[ id ]) ) { + if ( !isEmptyDataObject(cache[ id ]) ) { return; } } @@ -291,4 +298,17 @@ function dataAttr( elem, key, data ) { return data; } +// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON +// property to be considered empty objects; this property always exists in +// order to make sure JSON.stringify does not expose internal metadata +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + })( jQuery ); diff --git a/test/unit/data.js b/test/unit/data.js index 455b923a..c6ef843a 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -180,7 +180,13 @@ test(".data()", function() { var div = jQuery("#foo"); strictEqual( div.data("foo"), undefined, "Make sure that missing result is undefined" ); div.data("test", "success"); - same( div.data(), {test: "success"}, "data() get the entire data object" ); + + var dataObj = div.data(); + + // TODO: Remove this hack which was introduced in 1.5.1 + delete dataObj.toJSON; + + same( dataObj, {test: "success"}, "data() get the entire data object" ); strictEqual( div.data("foo"), undefined, "Make sure that missing result is still undefined" ); var nodiv = jQuery("#unfound"); @@ -189,7 +195,10 @@ test(".data()", function() { var obj = { foo: "bar" }; jQuery(obj).data("foo", "baz"); - var dataObj = jQuery.extend(true, {}, jQuery(obj).data()); + dataObj = jQuery.extend(true, {}, jQuery(obj).data()); + + // TODO: Remove this hack which was introduced for 1.5.1 + delete dataObj.toJSON; deepEqual( dataObj, { foo: "baz" }, "Retrieve data object from a wrapped JS object (#7524)" ); }); @@ -329,12 +338,18 @@ test("data-* attributes", function() { num++; } + // TODO: Remove this hack which was introduced for 1.5.1 + num--; + equals( num, check.length, "Make sure that the right number of properties came through." ); for ( var prop in obj2 ) { num2++; } + // TODO: Remove this hack which was introduced for 1.5.1 + num2--; + equals( num2, check.length, "Make sure that the right number of properties came through." ); child.attr("data-other", "newvalue"); @@ -465,4 +480,15 @@ test(".removeData()", function() { div.removeData("test.foo"); equals( div.data("test.foo"), undefined, "Make sure data is intact" ); -}); \ No newline at end of file +}); + +if (window.JSON && window.JSON.stringify) { + test("JSON serialization (#8108)", function () { + expect(1); + + var obj = { foo: "bar" }; + jQuery.data(obj, "hidden", true); + + equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" ); + }); +} \ No newline at end of file From 2cc03a86fc046e81013d32a662f4043f1c10b436 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Mon, 14 Feb 2011 16:30:18 -0600 Subject: [PATCH 099/123] Update jQuery.data to use jQuery.noop for toJSON hack instead of an additional superfluous function. --- src/data.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/data.js b/src/data.js index 66d22925..6efe7b01 100644 --- a/src/data.js +++ b/src/data.js @@ -68,9 +68,7 @@ jQuery.extend({ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery // metadata on plain JS objects when the object is serialized using // JSON.stringify - cache[ id ].toJSON = function () { - return undefined; - }; + cache[ id ].toJSON = jQuery.noop; } // An object can be passed to jQuery.data instead of a key/value pair; this gets From 8e40a84c24271c0a9253902ceb97185f243a3318 Mon Sep 17 00:00:00 2001 From: Anton M Date: Tue, 15 Feb 2011 21:01:52 +0100 Subject: [PATCH 100/123] Fix some unscoped tests which failed after recent changes to QUnit. --- test/unit/core.js | 10 +++++----- test/unit/event.js | 2 +- test/unit/traversing.js | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/unit/core.js b/test/unit/core.js index a7b3b48d..16700e4d 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -537,29 +537,29 @@ test("end()", function() { test("length", function() { expect(1); - equals( jQuery("p").length, 6, "Get Number of Elements Found" ); + equals( jQuery("#main p").length, 6, "Get Number of Elements Found" ); }); test("size()", function() { expect(1); - equals( jQuery("p").size(), 6, "Get Number of Elements Found" ); + equals( jQuery("#main p").size(), 6, "Get Number of Elements Found" ); }); test("get()", function() { expect(1); - same( jQuery("p").get(), q("firstp","ap","sndp","en","sap","first"), "Get All Elements" ); + same( jQuery("#main p").get(), q("firstp","ap","sndp","en","sap","first"), "Get All Elements" ); }); test("toArray()", function() { expect(1); - same( jQuery("p").toArray(), + same( jQuery("#main p").toArray(), q("firstp","ap","sndp","en","sap","first"), "Convert jQuery object to an Array" ); }); test("get(Number)", function() { expect(2); - equals( jQuery("p").get(0), document.getElementById("firstp"), "Get A Single Element" ); + equals( jQuery("#main p").get(0), document.getElementById("firstp"), "Get A Single Element" ); strictEqual( jQuery("#firstp").get(1), undefined, "Try get with index larger elements count" ); }); diff --git a/test/unit/event.js b/test/unit/event.js index 1d9e2e11..8d69807e 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -409,7 +409,7 @@ test("bind(), namespaced events, cloned events", 18, function() { }).trigger("tester"); // Make sure events stick with appendTo'd elements (which are cloned) #2027 - jQuery("test").click(function(){ return false; }).appendTo("p"); + jQuery("test").click(function(){ return false; }).appendTo("#main"); ok( jQuery("a.test:first").triggerHandler("click") === false, "Handler is bound to appendTo'd elements" ); }); diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 56fed220..f5108bde 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -97,9 +97,9 @@ test("filter(Selector)", function() { test("filter(Function)", function() { expect(2); - same( jQuery("p").filter(function() { return !jQuery("a", this).length }).get(), q("sndp", "first"), "filter(Function)" ); + same( jQuery("#main p").filter(function() { return !jQuery("a", this).length }).get(), q("sndp", "first"), "filter(Function)" ); - same( jQuery("p").filter(function(i, elem) { return !jQuery("a", elem).length }).get(), q("sndp", "first"), "filter(Function) using arg" ); + same( jQuery("#main p").filter(function(i, elem) { return !jQuery("a", elem).length }).get(), q("sndp", "first"), "filter(Function) using arg" ); }); test("filter(Element)", function() { @@ -178,7 +178,7 @@ test("not(Element)", function() { }); test("not(Function)", function() { - same( jQuery("p").not(function() { return jQuery("a", this).length }).get(), q("sndp", "first"), "not(Function)" ); + same( jQuery("#main p").not(function() { return jQuery("a", this).length }).get(), q("sndp", "first"), "not(Function)" ); }); test("not(Array)", function() { From 1ddfdabbb983e2d3bf7f7200a3da5051f274e6fe Mon Sep 17 00:00:00 2001 From: jaubourg Date: Tue, 15 Feb 2011 21:47:52 +0100 Subject: [PATCH 101/123] Fixes #8277. Sets data to undefined rather than null when it is not provided in ajax helpers so that it won't revent data set in ajaxSettings from being used. Unit test added. --- src/ajax.js | 6 +++--- test/unit/ajax.js | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 7ef8dec1..76a2dc81 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -164,7 +164,7 @@ jQuery.fn.extend({ if ( jQuery.isFunction( params ) ) { // We assume that it's the callback callback = params; - params = null; + params = undefined; // Otherwise, build a param string } else if ( typeof params === "object" ) { @@ -256,7 +256,7 @@ jQuery.each( [ "get", "post" ], function( i, method ) { if ( jQuery.isFunction( data ) ) { type = type || callback; callback = data; - data = null; + data = undefined; } return jQuery.ajax({ @@ -272,7 +272,7 @@ jQuery.each( [ "get", "post" ], function( i, method ) { jQuery.extend({ getScript: function( url, callback ) { - return jQuery.get( url, null, callback, "script" ); + return jQuery.get( url, undefined, callback, "script" ); }, getJSON: function( url, data, callback ) { diff --git a/test/unit/ajax.js b/test/unit/ajax.js index c9c06111..80da7f8f 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -1196,6 +1196,21 @@ test("load(String, String, Function)", function() { }); }); +test("jQuery.get(String, Function) - data in ajaxSettings (#8277)", function() { + expect(1); + stop(); + jQuery.ajaxSetup({ + data: "helloworld" + }); + jQuery.get(url('data/echoQuery.php'), function(data) { + ok( /helloworld$/.test( data ), 'Data from ajaxSettings was used'); + jQuery.ajaxSetup({ + data: null + }); + start(); + }); +}); + test("jQuery.get(String, Hash, Function) - parse xml and use text() on nodes", function() { expect(2); stop(); From 12c0e1a692aa045e9d3cf166a41748d7f5fe31cc Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Wed, 9 Feb 2011 21:25:29 -0500 Subject: [PATCH 102/123] Fixes #7922. Copy the donor event when simulating a bubbling submit in IE so that we don't accidentally stop propagation on it. Remove a bunch of return statements that could also cancel the event. DRY out the liveFired change from #6359 by moving it to the trigger() function. --- src/event.js | 26 +++++++++++++++++--------- test/unit/event.js | 11 +++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/event.js b/src/event.js index a15603fc..758c8f56 100644 --- a/src/event.js +++ b/src/event.js @@ -709,8 +709,7 @@ if ( !jQuery.support.submitBubbles ) { type = elem.type; if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { - e.liveFired = undefined; - return trigger( "submit", this, arguments ); + trigger( "submit", this, arguments ); } }); @@ -719,8 +718,7 @@ if ( !jQuery.support.submitBubbles ) { type = elem.type; if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { - e.liveFired = undefined; - return trigger( "submit", this, arguments ); + trigger( "submit", this, arguments ); } }); @@ -783,7 +781,7 @@ if ( !jQuery.support.changeBubbles ) { if ( data != null || val ) { e.type = "change"; e.liveFired = undefined; - return jQuery.event.trigger( e, arguments[1], elem ); + jQuery.event.trigger( e, arguments[1], elem ); } }; @@ -797,7 +795,7 @@ if ( !jQuery.support.changeBubbles ) { var elem = e.target, type = elem.type; if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { - return testChange.call( this, e ); + testChange.call( this, e ); } }, @@ -809,7 +807,7 @@ if ( !jQuery.support.changeBubbles ) { if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || type === "select-multiple" ) { - return testChange.call( this, e ); + testChange.call( this, e ); } }, @@ -848,8 +846,18 @@ if ( !jQuery.support.changeBubbles ) { } function trigger( type, elem, args ) { - args[0].type = type; - return jQuery.event.handle.apply( elem, args ); + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + // Don't pass args or remember liveFired; they apply to the donor event. + var event = jQuery.extend( {}, args[ 0 ] ); + event.type = type; + event.originalEvent = {}; + event.liveFired = undefined; + jQuery.event.handle.call( elem, event ); + if ( event.isDefaultPrevented() ) { + args[ 0 ].preventDefault(); + } } // Create "bubbling" focus and blur events diff --git a/test/unit/event.js b/test/unit/event.js index 8d69807e..6b78a249 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -1455,6 +1455,8 @@ test("live with change", function(){ }); test("live with submit", function() { + expect(5); + var count1 = 0, count2 = 0; jQuery("#testForm").live("submit", function(ev) { @@ -1471,7 +1473,16 @@ test("live with submit", function() { equals( count1, 1, "Verify form submit." ); equals( count2, 1, "Verify body submit." ); + jQuery("#testForm input[name=sub1]").live("click", function(ev) { + ok( true, "cancelling submit still calls click handler" ); + }); + + jQuery("#testForm input[name=sub1]")[0].click(); + equals( count1, 2, "Verify form submit." ); + equals( count2, 2, "Verify body submit." ); + jQuery("#testForm").die("submit"); + jQuery("#testForm input[name=sub1]").die("click"); jQuery("body").die("submit"); }); From 6b08d88d04f4a41849753999e6e18126895086d0 Mon Sep 17 00:00:00 2001 From: Anton M Date: Tue, 15 Feb 2011 22:03:23 +0100 Subject: [PATCH 103/123] Fix some whitespace issues. --- src/core.js | 2 +- src/css.js | 2 +- src/effects.js | 8 ++++---- src/event.js | 2 +- src/offset.js | 2 +- src/traversing.js | 10 +++++----- test/unit/event.js | 12 ++++++------ 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/core.js b/src/core.js index 1e1bd3ef..586e372d 100644 --- a/src/core.js +++ b/src/core.js @@ -302,7 +302,7 @@ jQuery.fn = jQuery.prototype = { jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, + var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, diff --git a/src/css.js b/src/css.js index 19c6342d..8a982312 100644 --- a/src/css.js +++ b/src/css.js @@ -263,7 +263,7 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) { if ( document.documentElement.currentStyle ) { currentStyle = function( elem, name ) { - var left, + var left, ret = elem.currentStyle && elem.currentStyle[ name ], rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ], style = elem.style; diff --git a/src/effects.js b/src/effects.js index bebcc431..58a15139 100644 --- a/src/effects.js +++ b/src/effects.js @@ -519,21 +519,21 @@ function defaultDisplay( nodeName ) { disabled[ idx ] = style.disabled; style.disabled = true; } - - // To accurately check an element's default display value, + + // To accurately check an element's default display value, // create a temp element and check it's default display, this // will ensure that the value returned is not a user-tampered // value. elem = jQuery("<" + nodeName + ">").appendTo("body"); display = elem.css("display"); - + // Remove temp element elem.remove(); if ( display === "none" || display === "" ) { display = "block"; } - + // Store the correct default display elemdisplay[ nodeName ] = display; diff --git a/src/event.js b/src/event.js index 758c8f56..daafe54a 100644 --- a/src/event.js +++ b/src/event.js @@ -33,7 +33,7 @@ jQuery.event = { handler = returnFalse; } else if ( !handler ) { // Fixes bug #7229. Fix recommended by jdalton - return; + return; } var handleObjIn, handleObj; diff --git a/src/offset.js b/src/offset.js index a10d30a0..1003c400 100644 --- a/src/offset.js +++ b/src/offset.js @@ -275,7 +275,7 @@ jQuery.each( ["Left", "Top"], function( i, name ) { if ( win ) { win.scrollTo( !i ? val : jQuery(win).scrollLeft(), - i ? val : jQuery(win).scrollTop() + i ? val : jQuery(win).scrollTop() ); } else { diff --git a/src/traversing.js b/src/traversing.js index 90601df5..fe2e33d8 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -204,11 +204,11 @@ jQuery.each({ }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var ret = jQuery.map( this, fn, until ), - // The variable 'args' was introduced in - // https://github.com/jquery/jquery/commit/52a0238 - // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. - // http://code.google.com/p/v8/issues/detail?id=1050 - args = slice.call(arguments); + // The variable 'args' was introduced in + // https://github.com/jquery/jquery/commit/52a0238 + // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. + // http://code.google.com/p/v8/issues/detail?id=1050 + args = slice.call(arguments); if ( !runtil.test( name ) ) { selector = until; diff --git a/test/unit/event.js b/test/unit/event.js index 6b78a249..b7b26046 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -615,18 +615,18 @@ test("unbind(type)", function() { message = "unbind many with function"; $elem.bind('error1 error2',error) - .unbind('error1 error2', error ) - .trigger('error1').triggerHandler('error2'); + .unbind('error1 error2', error ) + .trigger('error1').triggerHandler('error2'); message = "unbind many"; // #3538 $elem.bind('error1 error2',error) - .unbind('error1 error2') - .trigger('error1').triggerHandler('error2'); + .unbind('error1 error2') + .trigger('error1').triggerHandler('error2'); message = "unbind without a type or handler"; $elem.bind("error1 error2.test",error) - .unbind() - .trigger("error1").triggerHandler("error2"); + .unbind() + .trigger("error1").triggerHandler("error2"); }); test("unbind(eventObject)", function() { From faa6fe32f72900d7b31000caead2794a8346f6d8 Mon Sep 17 00:00:00 2001 From: Anton M Date: Tue, 15 Feb 2011 22:30:34 +0100 Subject: [PATCH 104/123] Revert "Merge branch '8099' of https://github.com/rwldrn/jquery into rwldrn-8099" This reverts commit bb9408516aa0fc8892f4e07a99b1a47bce06081b, reversing changes made to 3ad8dd242acec1066f43a9349f4c1a352680d37b. Conflicts: src/effects.js --- src/effects.js | 29 ++--------------------------- test/data/testsuite.css | 3 --- test/unit/effects.js | 12 ------------ 3 files changed, 2 insertions(+), 42 deletions(-) diff --git a/src/effects.js b/src/effects.js index 58a15139..fd832ce4 100644 --- a/src/effects.js +++ b/src/effects.js @@ -505,42 +505,17 @@ if ( jQuery.expr && jQuery.expr.filters ) { } function defaultDisplay( nodeName ) { - var stylesheets = document.styleSheets, - disabled = [], - elem, display, style, idx; - if ( !elemdisplay[ nodeName ] ) { + var elem = jQuery("<" + nodeName + ">").appendTo("body"), + display = elem.css("display"); - // #8099 - If the end-dev has globally changed a default - // display, we can temporarily disable their styles to check - // for the correct default value - for ( idx = 0; idx < stylesheets.length; ++idx ) { - style = stylesheets[ idx ]; - disabled[ idx ] = style.disabled; - style.disabled = true; - } - - // To accurately check an element's default display value, - // create a temp element and check it's default display, this - // will ensure that the value returned is not a user-tampered - // value. - elem = jQuery("<" + nodeName + ">").appendTo("body"); - display = elem.css("display"); - - // Remove temp element elem.remove(); if ( display === "none" || display === "" ) { display = "block"; } - // Store the correct default display elemdisplay[ nodeName ] = display; - - // Restore stylesheets - for ( idx = 0; idx < stylesheets.length; ++idx ) { - stylesheets[ idx ].disabled = disabled[ idx ]; - } } return elemdisplay[ nodeName ]; diff --git a/test/data/testsuite.css b/test/data/testsuite.css index 9ca2cd74..cffaaa46 100644 --- a/test/data/testsuite.css +++ b/test/data/testsuite.css @@ -109,6 +109,3 @@ div#show-tests * { display: none; } #nothiddendiv { font-size: 16px; } #nothiddendivchild.em { font-size: 2em; } #nothiddendivchild.prct { font-size: 150%; } - -/* 8099 changes to default styles are read correctly */ -tt { display: none; } diff --git a/test/unit/effects.js b/test/unit/effects.js index 7da81434..a07c076d 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -162,18 +162,6 @@ test("Persist correct display value", function() { }); }); -test("show() resolves correct default display #8099", function() { - expect(3); - var bug8099 = jQuery("").appendTo("#main"); - - equals( bug8099.css("display"), "none", "default display override for all tt" ); - equals( bug8099.show().css("display"), "inline", "Correctly resolves display:inline" ); - - bug8099.remove(); - - equals( jQuery("#foo").hide().show().css("display"), "block", "Correctly resolves display:block after hide/show" ); -}); - test("animate(Hash, Object, Function)", function() { expect(1); stop(); From 5b38439011799ae53156d137305d9440e0cddb0a Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 17 Feb 2011 17:03:09 +0100 Subject: [PATCH 105/123] Fixes #8297. Makes sure response headers with empty values are handled properly and do not prevent proper parsing of the entire response headers string. Unit test amended. --- src/ajax.js | 4 ++-- test/data/headers.php | 2 ++ test/unit/ajax.js | 12 +++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 76a2dc81..6414e8c2 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -4,7 +4,7 @@ var r20 = /%20/g, rbracket = /\[\]$/, rCRLF = /\r?\n/g, rhash = /#.*$/, - rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /(?:^file|^widget|\-extension):$/, @@ -439,7 +439,7 @@ jQuery.extend({ } match = responseHeaders[ key.toLowerCase() ]; } - return match || null; + return match === undefined ? null : match; }, // Overrides response content-type header diff --git a/test/data/headers.php b/test/data/headers.php index d500b16f..968f13f1 100644 --- a/test/data/headers.php +++ b/test/data/headers.php @@ -1,6 +1,8 @@ Date: Tue, 15 Feb 2011 22:41:08 -0500 Subject: [PATCH 106/123] Only perpetrate the .toJSON hack on data caches when they are attached to a plain Javascript object. Part of the continuing saga of #8108. --- src/data.js | 11 ++++++++++- test/unit/data.js | 6 ------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/data.js b/src/data.js index 6efe7b01..2d53a710 100644 --- a/src/data.js +++ b/src/data.js @@ -68,7 +68,9 @@ jQuery.extend({ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery // metadata on plain JS objects when the object is serialized using // JSON.stringify - cache[ id ].toJSON = jQuery.noop; + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } } // An object can be passed to jQuery.data instead of a key/value pair; this gets @@ -168,6 +170,13 @@ jQuery.extend({ // data if it existed if ( internalCache ) { cache[ id ] = {}; + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + cache[ id ][ internalKey ] = internalCache; // Otherwise, we need to eliminate the expando on the node to avoid diff --git a/test/unit/data.js b/test/unit/data.js index c6ef843a..8fb7f35a 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -338,18 +338,12 @@ test("data-* attributes", function() { num++; } - // TODO: Remove this hack which was introduced for 1.5.1 - num--; - equals( num, check.length, "Make sure that the right number of properties came through." ); for ( var prop in obj2 ) { num2++; } - // TODO: Remove this hack which was introduced for 1.5.1 - num2--; - equals( num2, check.length, "Make sure that the right number of properties came through." ); child.attr("data-other", "newvalue"); From 85d9343271da85fc945bf37a604873eaf247a3a7 Mon Sep 17 00:00:00 2001 From: louisremi Date: Thu, 17 Feb 2011 17:26:23 +0100 Subject: [PATCH 107/123] Fixes #7912. Make sure .cur() only returns 0 as fallback value when it needs to ("", auto, undefined, null). This change makes .cur() more .cssHooks friendly. .cur() now returns the unmodified value by .css() if it isn't a number, number-alike or a value that needs a fallback to 0. This way fx.start doesn't need to be recalculated for complex values. --- src/effects.js | 10 ++++++--- test/unit/effects.js | 49 ++++++++++++++++++++++++++++++++------------ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/effects.js b/src/effects.js index fd832ce4..d9e9a8b3 100644 --- a/src/effects.js +++ b/src/effects.js @@ -185,7 +185,7 @@ jQuery.fn.extend({ } else { var parts = rfxnum.exec(val), - start = e.cur() || 0; + start = e.cur(); if ( parts ) { var end = parseFloat( parts[2] ), @@ -336,8 +336,12 @@ jQuery.fx.prototype = { return this.elem[ this.prop ]; } - var r = parseFloat( jQuery.css( this.elem, this.prop ) ); - return r || 0; + var parsed, + r = jQuery.css( this.elem, this.prop ); + // Empty strings, null, undefined and "auto" are converted to 0, + // complex values such as "rotate(1rad)" are returned as is, + // simple values such as "10px" are parsed to Float. + return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; }, // Start an animation from one number to another diff --git a/test/unit/effects.js b/test/unit/effects.js index a07c076d..4bb92fc0 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -558,21 +558,44 @@ jQuery.checkOverflowDisplay = function(){ start(); } -test("support negative values < -10000 (bug #7193)", function () { - expect(1); - stop(); +test("jQuery.fx.prototype.cur()", function() { + expect(5); + var nothiddendiv = jQuery('#nothiddendiv').css({ + color: '#ABC', + border: '5px solid black', + left: 'auto', + marginBottom: '11000px' + })[0]; - jQuery.extend(jQuery.fx.step, { - "marginBottom": function(fx) { - equals( fx.cur(), -11000, "Element has margin-bottom of -11000" ); - delete jQuery.fx.step.marginBottom; - } - }); + equals( + (new jQuery.fx( nothiddendiv, {}, 'color' )).cur(), + jQuery.css( nothiddendiv,'color' ), + "Return the same value as jQuery.css for complex properties (bug #7912)" + ); - jQuery("#main").css("marginBottom", "-11000px").animate({ marginBottom: "-11001px" }, { - duration: 1, - complete: start - }); + strictEqual( + (new jQuery.fx( nothiddendiv, {}, 'borderLeftWidth' )).cur(), + 5, + "Return simple values parsed as Float" + ); + + strictEqual( + (new jQuery.fx( nothiddendiv, {}, 'backgroundPosition' )).cur(), + 0, + 'Return 0 when jQuery.css returns an empty string' + ); + + strictEqual( + (new jQuery.fx( nothiddendiv, {}, 'left' )).cur(), + 0, + 'Return 0 when jQuery.css returns "auto"' + ); + + equals( + (new jQuery.fx( nothiddendiv, {}, 'marginBottom' )).cur(), + 11000, + "support negative values < -10000 (bug #7193)" + ); }); test("JS Overflow and Display", function() { From 4b91b918a360d056a6e4a63ee306e97f839dac59 Mon Sep 17 00:00:00 2001 From: Anton M Date: Thu, 17 Feb 2011 19:12:57 +0100 Subject: [PATCH 108/123] Fix a some inaccuracies in the original test case for #7912. - Use fresh div instead of one outside the test-fixture - make sure the empty string test tests actually that (not 0% 0%) - actually test for < -10000 (#7193) - fixed some whitespace issues --- test/unit/effects.js | 48 ++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/test/unit/effects.js b/test/unit/effects.js index 4bb92fc0..c0a812f4 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -558,42 +558,52 @@ jQuery.checkOverflowDisplay = function(){ start(); } -test("jQuery.fx.prototype.cur()", function() { - expect(5); - var nothiddendiv = jQuery('#nothiddendiv').css({ - color: '#ABC', - border: '5px solid black', - left: 'auto', - marginBottom: '11000px' +test( "jQuery.fx.prototype.cur()", 6, function() { + var div = jQuery( "
    " ).appendTo( "#main" ).css({ + color: "#ABC", + border: "5px solid black", + left: "auto", + marginBottom: "-11000px" })[0]; equals( - (new jQuery.fx( nothiddendiv, {}, 'color' )).cur(), - jQuery.css( nothiddendiv,'color' ), + ( new jQuery.fx( div, {}, "color" ) ).cur(), + jQuery.css( div, "color" ), "Return the same value as jQuery.css for complex properties (bug #7912)" ); strictEqual( - (new jQuery.fx( nothiddendiv, {}, 'borderLeftWidth' )).cur(), + ( new jQuery.fx( div, {}, "borderLeftWidth" ) ).cur(), 5, "Return simple values parsed as Float" ); - strictEqual( - (new jQuery.fx( nothiddendiv, {}, 'backgroundPosition' )).cur(), - 0, - 'Return 0 when jQuery.css returns an empty string' - ); + // backgroundPosition actually returns 0% 0% in most browser + // this fakes a "" return + jQuery.cssHooks.backgroundPosition = { + get: function() { + ok( true, "hook used" ); + return ""; + } + }; strictEqual( - (new jQuery.fx( nothiddendiv, {}, 'left' )).cur(), + ( new jQuery.fx( div, {}, "backgroundPosition" ) ).cur(), 0, - 'Return 0 when jQuery.css returns "auto"' + "Return 0 when jQuery.css returns an empty string" + ); + + delete jQuery.cssHooks.backgroundPosition; + + strictEqual( + ( new jQuery.fx( div, {}, "left" ) ).cur(), + 0, + "Return 0 when jQuery.css returns 'auto'" ); equals( - (new jQuery.fx( nothiddendiv, {}, 'marginBottom' )).cur(), - 11000, + ( new jQuery.fx( div, {}, "marginBottom" ) ).cur(), + -11000, "support negative values < -10000 (bug #7193)" ); }); From 752db8fffeffa796f5cdb5553331436c0a4cc44e Mon Sep 17 00:00:00 2001 From: Alex Sexton Date: Thu, 17 Feb 2011 18:01:30 -0600 Subject: [PATCH 109/123] A temporary workaround for #8018 that avoids any chance of compatibility-breaking changes until a proper fix can be landed in 1.6. --- src/event.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/event.js b/src/event.js index daafe54a..1bfb4bbc 100644 --- a/src/event.js +++ b/src/event.js @@ -23,11 +23,16 @@ jQuery.event = { return; } - // For whatever reason, IE has trouble passing the window object - // around, causing it to be cloned in the process - if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { - elem = window; + // TODO :: Use a try/catch until it's safe to pull this out (likely 1.6) + // Minor release fix for bug #8018 + try { + // For whatever reason, IE has trouble passing the window object + // around, causing it to be cloned in the process + if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { + elem = window; + } } + catch ( e ) {} if ( handler === false ) { handler = returnFalse; From a43a5ca9cf79afcd662df5b9110d7ccba45c0b53 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Fri, 18 Feb 2011 18:06:26 +0100 Subject: [PATCH 110/123] Revert "Adds an invert method to promises that returns a "inverted" promise that is resolved when the underlying deferred is rejected and rejected when the underlying deferred is resolved." This reverts commit 4e975430510f443ef76a90d077bc8956fb8b8cc0. --- src/core.js | 42 ++++++++------------------------------- test/unit/core.js | 50 +++++++++-------------------------------------- 2 files changed, 17 insertions(+), 75 deletions(-) diff --git a/src/core.js b/src/core.js index 586e372d..e7efb655 100644 --- a/src/core.js +++ b/src/core.js @@ -56,16 +56,8 @@ var jQuery = function( selector, context ) { // The deferred used on DOM ready readyList, - // Promise methods (with equivalent for invert) - promiseMethods = { - then: 0, // will be overwritten for invert - done: "fail", - fail: "done", - isResolved: "isRejected", - isRejected: "isResolved", - promise: "invert", - invert: "promise" - }, + // Promise methods + promiseMethods = "then done fail isResolved isRejected promise".split( " " ), // The ready event handler DOMContentLoaded, @@ -885,9 +877,8 @@ jQuery.extend({ Deferred: function( func ) { var deferred = jQuery._Deferred(), failDeferred = jQuery._Deferred(), - promise, - invert; - // Add errorDeferred methods, then, promise and invert + promise; + // Add errorDeferred methods, then and promise jQuery.extend( deferred, { then: function( doneCallbacks, failCallbacks ) { deferred.done( doneCallbacks ).fail( failCallbacks ); @@ -899,35 +890,18 @@ jQuery.extend({ isRejected: failDeferred.isResolved, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { + promise: function( obj , i /* internal */ ) { if ( obj == null ) { if ( promise ) { return promise; } promise = obj = {}; } - for( var methodName in promiseMethods ) { - obj[ methodName ] = deferred[ methodName ]; + i = promiseMethods.length; + while( i-- ) { + obj[ promiseMethods[ i ] ] = deferred[ promiseMethods[ i ] ]; } return obj; - }, - // Get the invert promise for this deferred - // If obj is provided, the invert promise aspect is added to the object - invert: function( obj ) { - if ( obj == null ) { - if ( invert ) { - return invert; - } - invert = obj = {}; - } - for( var methodName in promiseMethods ) { - obj[ methodName ] = promiseMethods[ methodName ] && deferred[ promiseMethods[methodName] ]; - } - obj.then = invert.then || function( doneCallbacks, failCallbacks ) { - deferred.done( failCallbacks ).fail( doneCallbacks ); - return this; - }; - return obj; } } ); // Make sure only one callback list will be used diff --git a/test/unit/core.js b/test/unit/core.js index 16700e4d..bce0de0f 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -554,8 +554,8 @@ test("toArray()", function() { expect(1); same( jQuery("#main p").toArray(), q("firstp","ap","sndp","en","sap","first"), - "Convert jQuery object to an Array" ); -}); + "Convert jQuery object to an Array" ) +}) test("get(Number)", function() { expect(2); @@ -567,7 +567,7 @@ test("get(-Number)",function() { expect(2); equals( jQuery("p").get(-1), document.getElementById("first"), "Get a single element with negative index" ); strictEqual( jQuery("#firstp").get(-2), undefined, "Try get with index negative index larger then elements count" ); -}); +}) test("each(Function)", function() { expect(1); @@ -1009,7 +1009,7 @@ test("jQuery._Deferred()", function() { test("jQuery.Deferred()", function() { - expect( 20 ); + expect( 10 ); jQuery.Deferred( function( defer ) { strictEqual( this , defer , "Defer passed as this & first argument" ); @@ -1049,26 +1049,10 @@ test("jQuery.Deferred()", function() { ok( true , "Error on reject (new)" ); }); - strictEqual( jQuery.Deferred().resolve( "test" ).invert().then(null,function(value) { - strictEqual( value, "test", "Resolved deferred => then fail callback called" ); - }).fail(function( value ) { - strictEqual( value, "test", "Resolved deferred => fail callback called" ); - }).isRejected(), true, "Invert promise is rejected when deferred is resolved" ); - - strictEqual( jQuery.Deferred().reject( "test" ).invert().then(function(value) { - strictEqual( value, "test", "Rejected deferred => then done callback called" ); - }).done(function( value ) { - strictEqual( value, "test", "Rejected deferred => done callback called" ); - }).isResolved(), true, "Invert promise is resolved when deferred is rejected" ); - var tmp = jQuery.Deferred(); strictEqual( tmp.promise() , tmp.promise() , "Test deferred always return same promise" ); - strictEqual( tmp.invert() , tmp.invert() , "Test deferred always return same invert" ); strictEqual( tmp.promise() , tmp.promise().promise() , "Test deferred's promise always return same promise as deferred" ); - strictEqual( tmp.promise() , tmp.invert().invert() , "Test deferred's promise is the same as double invert" ); - strictEqual( tmp.invert() , tmp.invert().promise() , "Test deferred's invert always return same invert as deferred as a promise" ); - strictEqual( tmp.invert() , tmp.promise().invert() , "Test deferred's promise always return same invert as deferred" ); }); test("jQuery.when()", function() { @@ -1116,7 +1100,7 @@ test("jQuery.when()", function() { test("jQuery.when() - joined", function() { - expect(14); + expect(8); jQuery.when( 1, 2, 3 ).done( function( a, b, c ) { strictEqual( a , 1 , "Test first param is first resolved value - non-observables" ); @@ -1137,28 +1121,12 @@ test("jQuery.when() - joined", function() { ok( false , "Test the created deferred was resolved - resolved observable"); }); - jQuery.when( 1 , successDeferred.invert() , 3 ).fail( function( a, b, c ) { - strictEqual( a , 1 , "Test first param is first rejected value - resolved observable inverted" ); - same( b , 2 , "Test second param is second rejected value - resolved observable inverted" ); - strictEqual( c , 3 , "Test third param is third rejected value - resolved observable inverted" ); - }).done( function() { - ok( false , "Test the inverted deferred was rejected - resolved observable inverted"); - }); - jQuery.when( 1 , errorDeferred , 3 ).done( function() { ok( false , "Test the created deferred was rejected - rejected observable"); }).fail( function( error , errorParam ) { strictEqual( error , "error" , "Test first param is first rejected value - rejected observable" ); strictEqual( errorParam , "errorParam" , "Test second param is second rejected value - rejected observable" ); }); - - jQuery.when( 1 , errorDeferred.invert() , 3 ).fail( function() { - ok( false , "Test the inverted deferred was resolved - rejected observable inverted"); - }).done( function( a , b , c ) { - strictEqual( a , 1 , "Test first param is first resolved value - rejected observable inverted" ); - same( b , [ "error", "errorParam" ] , "Test second param is second resolved value - rejected observable inverted" ); - strictEqual( c , 3 , "Test third param is third resolved value - rejected observable inverted" ); - }); }); test("jQuery.sub() - Static Methods", function(){ @@ -1175,16 +1143,16 @@ test("jQuery.sub() - Static Methods", function(){ } }); Subclass.fn.extend({subClassMethod: function() { return this;}}); - + //Test Simple Subclass ok(Subclass.topLevelMethod() === false, 'Subclass.topLevelMethod thought debug was true'); ok(Subclass.config.locale == 'en_US', Subclass.config.locale + ' is wrong!'); same(Subclass.config.test, undefined, 'Subclass.config.test is set incorrectly'); equal(jQuery.ajax, Subclass.ajax, 'The subclass failed to get all top level methods'); - + //Create a SubSubclass var SubSubclass = Subclass.sub(); - + //Make Sure the SubSubclass inherited properly ok(SubSubclass.topLevelMethod() === false, 'SubSubclass.topLevelMethod thought debug was true'); ok(SubSubclass.config.locale == 'en_US', SubSubclass.config.locale + ' is wrong!'); @@ -1201,7 +1169,7 @@ test("jQuery.sub() - Static Methods", function(){ ok(SubSubclass.config.locale == 'es_MX', SubSubclass.config.locale + ' is wrong!'); ok(SubSubclass.config.test == 'worked', 'SubSubclass.config.test is set incorrectly'); notEqual(jQuery.ajax, SubSubclass.ajax, 'The subsubclass failed to get all top level methods'); - + //This shows that the modifications to the SubSubClass did not bubble back up to it's superclass ok(Subclass.topLevelMethod() === false, 'Subclass.topLevelMethod thought debug was true'); ok(Subclass.config.locale == 'en_US', Subclass.config.locale + ' is wrong!'); From 47abe5e1da5bcb5a268aefea9817b8747b051b18 Mon Sep 17 00:00:00 2001 From: Dan Heberden Date: Fri, 18 Feb 2011 10:09:07 -0800 Subject: [PATCH 111/123] Bug #6911 - Prevent action on disabled elements, both triggering and bound via .live() --- src/event.js | 2 +- test/delegatetest.html | 155 +++++++++++++++++++++++++---------------- 2 files changed, 95 insertions(+), 62 deletions(-) diff --git a/src/event.js b/src/event.js index 1bfb4bbc..f7e0a08c 100644 --- a/src/event.js +++ b/src/event.js @@ -1099,7 +1099,7 @@ function liveHandler( event ) { for ( j = 0; j < live.length; j++ ) { handleObj = live[j]; - if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) { + if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { elem = close.elem; related = null; diff --git a/test/delegatetest.html b/test/delegatetest.html index 6479d26e..c4f33aae 100644 --- a/test/delegatetest.html +++ b/test/delegatetest.html @@ -11,63 +11,71 @@

    Change Tests

    - - - - - - - - - - - - + + + + + + + + + + + + + @@ -79,6 +87,7 @@ + @@ -89,6 +98,7 @@ + @@ -100,6 +110,7 @@ + @@ -111,6 +122,7 @@ + @@ -121,11 +133,24 @@ + + + + + + + + + + + + +
    - Change each: - - - - - - - -
    - - - - -
    - -
    - - - - -
    - - - - - - - $(document).bind('change')
    + Change each: + + + + + + + +
    + +
    + + +
    +
    +
    +
    +
    +
    + +
    + +
    + + +
    + + + + + + + $(document).bind('change')
    + $(document).bind('click') +
    Live: SELECT MULTI CHECKBOXBUTTON RADIO FILE TEXTSELECT MULTI CHECKBOXBUTTON RADIO FILE TEXTSELECT MULTI CHECKBOXBUTTON RADIO FILE TEXTSELECT MULTI CHECKBOXBUTTON RADIO FILE TEXTSELECT MULTI CHECKBOXBUTTON RADIO FILE TEXTSELECT MULTI CHECKBOXBUTTON RADIO FILE TEXT TEXTAREA
    Live Click:SELECTMULTICHECKBOXBUTTONRADIOFILETEXTTEXTAREADOCUMENT

    Submit Tests

    @@ -162,7 +187,7 @@