From 2875460f6321e17e06be94f01d727fe8ddfe5465 Mon Sep 17 00:00:00 2001 From: John Resig Date: Fri, 19 Dec 2008 04:37:10 +0000 Subject: [PATCH] Added selector path logging (creates a trail that plugins can use). --- src/core.js | 29 ++++++++++++++++++------ test/unit/core.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/core.js b/src/core.js index d6577e605..94122a1d5 100644 --- a/src/core.js +++ b/src/core.js @@ -38,6 +38,7 @@ jQuery.fn = jQuery.prototype = { if ( selector.nodeType ) { this[0] = selector; this.length = 1; + this.context = selector; return this; } // Handle HTML strings @@ -64,7 +65,10 @@ jQuery.fn = jQuery.prototype = { return jQuery().find( selector ); // Otherwise, we inject the element directly into the jQuery object - return jQuery( elem ); + var ret = jQuery( elem ); + ret.context = document; + ret.selector = selector; + return ret; } selector = []; } @@ -82,6 +86,9 @@ jQuery.fn = jQuery.prototype = { return this.setArray(jQuery.makeArray(selector)); }, + // Start with an empty selector + selector: "", + // The current version of jQuery being used jquery: "@VERSION", @@ -104,13 +111,20 @@ jQuery.fn = jQuery.prototype = { // Take an array of elements and push it onto the stack // (returning the new matched element set) - pushStack: function( elems ) { + pushStack: function( elems, name, selector ) { // Build a new jQuery matched element set var ret = jQuery( elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; + ret.context = this.context; + + if ( name === "find" ) + ret.selector = this.selector + (this.selector ? " " : "") + selector; + else if ( name ) + ret.selector = this.selector + "." + name + "(" + selector + ")"; + // Return the newly-formed element set return ret; }, @@ -265,7 +279,7 @@ jQuery.fn = jQuery.prototype = { return this.pushStack( /[^+>] [^+>]/.test( selector ) ? jQuery.unique( elems ) : - elems ); + elems, "find", selector ); }, clone: function( events ) { @@ -319,14 +333,14 @@ jQuery.fn = jQuery.prototype = { return selector.call( elem, i ); }) || - jQuery.multiFilter( selector, this ) ); + jQuery.multiFilter( selector, this ), "filter", selector ); }, not: function( selector ) { if ( typeof selector === "string" ) // test special case where just one selector is passed in if ( isSimple.test( selector ) ) - return this.pushStack( jQuery.multiFilter( selector, this, true ) ); + return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); else selector = jQuery.multiFilter( selector, this ); @@ -444,7 +458,8 @@ jQuery.fn = jQuery.prototype = { }, slice: function() { - return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); + return this.pushStack( Array.prototype.slice.apply( this, arguments ), + "slice", Array.prototype.slice.call(arguments).join(",") ); }, map: function( callback ) { @@ -1272,7 +1287,7 @@ jQuery.each({ if ( selector && typeof selector == "string" ) ret = jQuery.multiFilter( selector, ret ); - return this.pushStack( jQuery.unique( ret ) ); + return this.pushStack( jQuery.unique( ret ), name, selector ); }; }); diff --git a/test/unit/core.js b/test/unit/core.js index 45003e888..6c670af7b 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -50,6 +50,64 @@ test("jQuery()", function() { equals( jQuery([1,2,3]).get(1), 2, "Test passing an array to the factory" ); equals( jQuery(document.body).get(0), jQuery('body').get(0), "Test passing an html node to the factory" ); +}); + +test("selector state", function() { + expect(26); + + var test; + + test = jQuery(); + equals( test.selector, "", "Empty jQuery Selector" ); + equals( test.context, document, "Empty jQuery Context" ); + + test = jQuery(document); + equals( test.selector, "", "Document Selector" ); + equals( test.context, document, "Document Context" ); + + test = jQuery(document.body); + equals( test.selector, "", "Body Selector" ); + equals( test.context, document.body, "Body Context" ); + + test = jQuery("#main"); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document, "#main Context" ); + + test = jQuery("#main", document); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document, "#main Context" ); + + test = jQuery("#main", document.body); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document.body, "#main Context" ); + + test = jQuery(document.body).find("#main"); + equals( test.selector, "#main", "#main find Selector" ); + equals( test.context, document.body, "#main find Context" ); + + test = jQuery("#main").filter("div"); + equals( test.selector, "#main.filter(div)", "#main filter Selector" ); + equals( test.context, document, "#main filter Context" ); + + test = jQuery("#main").not("div"); + equals( test.selector, "#main.not(div)", "#main not Selector" ); + equals( test.context, document, "#main not Context" ); + + test = jQuery("#main").filter("div").not("div"); + equals( test.selector, "#main.filter(div).not(div)", "#main filter, not Selector" ); + equals( test.context, document, "#main filter, not Context" ); + + test = jQuery("#main").filter("div").not("div").end(); + equals( test.selector, "#main.filter(div)", "#main filter, not, end Selector" ); + equals( test.context, document, "#main filter, not, end Context" ); + + test = jQuery("#main").parent("body"); + equals( test.selector, "#main.parent(body)", "#main parent Selector" ); + equals( test.context, document, "#main parent Context" ); + + test = jQuery("#main").eq(0); + equals( test.selector, "#main.slice(0,1)", "#main eq Selector" ); + equals( test.context, document, "#main eq Context" ); }); test("browser", function() {