Docs: Update remaining HTTP URLs to HTTPS
[jquery.git] / src / selector-native.js
blobb245e33506e7e025e0d11e73303adae669a605d6
1 /*
2  * Optional limited selector module for custom builds.
3  *
4  * Note that this DOES NOT SUPPORT many documented jQuery
5  * features in exchange for its smaller size:
6  *
7  * * Attribute not equal selector (!=)
8  * * Positional selectors (:first; :eq(n); :odd; etc.)
9  * * Type selectors (:input; :checkbox; :button; etc.)
10  * * State-based selectors (:animated; :visible; :hidden; etc.)
11  * * :has(selector) in browsers without native support
12  * * :not(complex selector) in IE
13  * * custom selectors via jQuery extensions
14  * * Reliable functionality on XML fragments
15  * * Matching against non-elements
16  * * Reliable sorting of disconnected nodes
17  * * querySelectorAll bug fixes (e.g., unreliable :focus on WebKit)
18  *
19  * If any of these are unacceptable tradeoffs, either use the full
20  * selector engine or  customize this stub for the project's specific
21  * needs.
22  */
24 import { jQuery } from "./core.js";
25 import { document } from "./var/document.js";
26 import { whitespace } from "./var/whitespace.js";
27 import { isIE } from "./var/isIE.js";
28 import { rleadingCombinator } from "./selector/var/rleadingCombinator.js";
29 import { rdescend } from "./selector/var/rdescend.js";
30 import { rsibling } from "./selector/var/rsibling.js";
31 import { matches } from "./selector/var/matches.js";
32 import { testContext } from "./selector/testContext.js";
33 import { filterMatchExpr } from "./selector/filterMatchExpr.js";
34 import { preFilter } from "./selector/preFilter.js";
35 import { tokenize } from "./selector/tokenize.js";
36 import { toSelector } from "./selector/toSelector.js";
38 // The following utils are attached directly to the jQuery object.
39 import "./selector/escapeSelector.js";
40 import "./selector/uniqueSort.js";
42 var matchExpr = jQuery.extend( {
43         needsContext: new RegExp( "^" + whitespace + "*[>+~]" )
44 }, filterMatchExpr );
46 jQuery.extend( {
47         find: function( selector, context, results, seed ) {
48                 var elem, nid, groups, newSelector,
49                         newContext = context && context.ownerDocument,
51                         // nodeType defaults to 9, since context defaults to document
52                         nodeType = context ? context.nodeType : 9,
53                         i = 0;
55                 results = results || [];
56                 context = context || document;
58                 // Same basic safeguard as in the full selector module
59                 if ( !selector || typeof selector !== "string" ) {
60                         return results;
61                 }
63                 // Early return if context is not an element, document or document fragment
64                 if ( nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
65                         return [];
66                 }
68                 if ( seed ) {
69                         while ( ( elem = seed[ i++ ] ) ) {
70                                 if ( jQuery.find.matchesSelector( elem, selector ) ) {
71                                         results.push( elem );
72                                 }
73                         }
74                 } else {
76                         newSelector = selector;
77                         newContext = context;
79                         // qSA considers elements outside a scoping root when evaluating child or
80                         // descendant combinators, which is not what we want.
81                         // In such cases, we work around the behavior by prefixing every selector in the
82                         // list with an ID selector referencing the scope context.
83                         // The technique has to be used as well when a leading combinator is used
84                         // as such selectors are not recognized by querySelectorAll.
85                         // Thanks to Andrew Dupont for this technique.
86                         if ( nodeType === 1 &&
87                                 ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) {
89                                 // Expand context for sibling selectors
90                                 newContext = rsibling.test( selector ) &&
91                                         testContext( context.parentNode ) ||
92                                         context;
94                                 // Outside of IE, if we're not changing the context we can
95                                 // use :scope instead of an ID.
96                                 if ( newContext !== context || isIE ) {
98                                         // Capture the context ID, setting it first if necessary
99                                         if ( ( nid = context.getAttribute( "id" ) ) ) {
100                                                 nid = jQuery.escapeSelector( nid );
101                                         } else {
102                                                 context.setAttribute( "id", ( nid = jQuery.expando ) );
103                                         }
104                                 }
106                                 // Prefix every selector in the list
107                                 groups = tokenize( selector );
108                                 i = groups.length;
109                                 while ( i-- ) {
110                                         groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
111                                                 toSelector( groups[ i ] );
112                                 }
113                                 newSelector = groups.join( "," );
114                         }
116                         try {
117                                 jQuery.merge( results, newContext.querySelectorAll( newSelector ) );
118                         } finally {
119                                 if ( nid === jQuery.expando ) {
120                                         context.removeAttribute( "id" );
121                                 }
122                         }
123                 }
125                 return results;
126         },
127         expr: {
129                 // Can be adjusted by the user
130                 cacheLength: 50,
132                 match: matchExpr,
133                 preFilter: preFilter
134         }
135 } );
137 jQuery.extend( jQuery.find, {
138         matches: function( expr, elements ) {
139                 return jQuery.find( expr, null, null, elements );
140         },
141         matchesSelector: function( elem, expr ) {
142                 return matches.call( elem, expr );
143         },
144         tokenize: tokenize
145 } );
147 export { jQuery, jQuery as $ };