Offset: allow offset setter to throw for disconnected elements
[jquery.git] / src / selector-native.js
blob1b2dd185baa5f7a8efa10acccc8fbf7df4a8d003
1 define([
2         "./core",
3         "./var/document",
4         "./var/documentElement"
5 ], function( jQuery, document, documentElement ) {
7 /*
8  * Optional (non-Sizzle) selector module for custom builds.
9  *
10  * Note that this DOES NOT SUPPORT many documented jQuery
11  * features in exchange for its smaller size:
12  *
13  * Attribute not equal selector
14  * Positional selectors (:first; :eq(n); :odd; etc.)
15  * Type selectors (:input; :checkbox; :button; etc.)
16  * State-based selectors (:animated; :visible; :hidden; etc.)
17  * :has(selector)
18  * :not(complex selector)
19  * custom selectors via Sizzle extensions
20  * Leading combinators (e.g., $collection.find("> *"))
21  * Reliable functionality on XML fragments
22  * Requiring all parts of a selector to match elements under context
23  *   (e.g., $div.find("div > *") now matches children of $div)
24  * Matching against non-elements
25  * Reliable sorting of disconnected nodes
26  * querySelectorAll bug fixes (e.g., unreliable :focus on WebKit)
27  *
28  * If any of these are unacceptable tradeoffs, either use Sizzle or
29  * customize this stub for the project's specific needs.
30  */
32 var hasDuplicate,
33         matches = documentElement.matches ||
34                 documentElement.webkitMatchesSelector ||
35                 documentElement.mozMatchesSelector ||
36                 documentElement.oMatchesSelector ||
37                 documentElement.msMatchesSelector,
38         sortOrder = function( a, b ) {
39                 // Flag for duplicate removal
40                 if ( a === b ) {
41                         hasDuplicate = true;
42                         return 0;
43                 }
45                 var compare = b.compareDocumentPosition &&
46                         a.compareDocumentPosition &&
47                         a.compareDocumentPosition( b );
49                 if ( compare ) {
50                         // Disconnected nodes
51                         if ( compare & 1 ) {
53                                 // Choose the first element that is related to our document
54                                 if ( a === document || jQuery.contains(document, a) ) {
55                                         return -1;
56                                 }
57                                 if ( b === document || jQuery.contains(document, b) ) {
58                                         return 1;
59                                 }
61                                 // Maintain original order
62                                 return 0;
63                         }
65                         return compare & 4 ? -1 : 1;
66                 }
68                 // Not directly comparable, sort on existence of method
69                 return a.compareDocumentPosition ? -1 : 1;
70         };
72 jQuery.extend({
73         find: function( selector, context, results, seed ) {
74                 var elem, nodeType,
75                         i = 0;
77                 results = results || [];
78                 context = context || document;
80                 // Same basic safeguard as Sizzle
81                 if ( !selector || typeof selector !== "string" ) {
82                         return results;
83                 }
85                 // Early return if context is not an element or document
86                 if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
87                         return [];
88                 }
90                 if ( seed ) {
91                         while ( (elem = seed[i++]) ) {
92                                 if ( jQuery.find.matchesSelector(elem, selector) ) {
93                                         results.push( elem );
94                                 }
95                         }
96                 } else {
97                         jQuery.merge( results, context.querySelectorAll(selector) );
98                 }
100                 return results;
101         },
102         unique: function( results ) {
103                 var elem,
104                         duplicates = [],
105                         i = 0,
106                         j = 0;
108                 hasDuplicate = false;
109                 results.sort( sortOrder );
111                 if ( hasDuplicate ) {
112                         while ( (elem = results[i++]) ) {
113                                 if ( elem === results[ i ] ) {
114                                         j = duplicates.push( i );
115                                 }
116                         }
117                         while ( j-- ) {
118                                 results.splice( duplicates[ j ], 1 );
119                         }
120                 }
122                 return results;
123         },
124         text: function( elem ) {
125                 var node,
126                         ret = "",
127                         i = 0,
128                         nodeType = elem.nodeType;
130                 if ( !nodeType ) {
131                         // If no nodeType, this is expected to be an array
132                         while ( (node = elem[i++]) ) {
133                                 // Do not traverse comment nodes
134                                 ret += jQuery.text( node );
135                         }
136                 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
137                         // Use textContent for elements
138                         return elem.textContent;
139                 } else if ( nodeType === 3 || nodeType === 4 ) {
140                         return elem.nodeValue;
141                 }
142                 // Do not include comment or processing instruction nodes
144                 return ret;
145         },
146         contains: function( a, b ) {
147                 var adown = a.nodeType === 9 ? a.documentElement : a,
148                         bup = b && b.parentNode;
149                 return a === bup || !!( bup && bup.nodeType === 1 && adown.contains(bup) );
150         },
151         isXMLDoc: function( elem ) {
152                 return (elem.ownerDocument || elem).documentElement.nodeName !== "HTML";
153         },
154         expr: {
155                 attrHandle: {},
156                 match: {
157                         bool: /^(?:checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped)$/i,
158                         needsContext: /^[\x20\t\r\n\f]*[>+~]/
159                 }
160         }
163 jQuery.extend( jQuery.find, {
164         matches: function( expr, elements ) {
165                 return jQuery.find( expr, null, null, elements );
166         },
167         matchesSelector: function( elem, expr ) {
168                 return matches.call( elem, expr );
169         },
170         attr: function( elem, name ) {
171                 return elem.getAttribute( name );
172         }