Skip to content

Commit 6a2c60c

Browse files
committed
Selector: Re-expose jQuery.find.tokenize
`Sizzle.tokenize` is an internal Sizzle API, but exposed. As a result, it has historically been available in jQuery via `jQuery.find.tokenize`. That got dropped during Sizzle removal; this change restores the API. In addition to that, Sizzle tests have been backported for the following APIs: * `jQuery.find.matchesSelector` * `jQuery.find.matches` * `jQuery.find.compile` * `jQuery.find.select` * `jQuery.find.tokenize` Fixes jquerygh-5259 Ref jquery/sizzle#242 Ref jquerygh-5113 Ref jquerygh-4395 Ref jquerygh-4406
1 parent 7287894 commit 6a2c60c

File tree

2 files changed

+224
-3
lines changed

2 files changed

+224
-3
lines changed

src/selector.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,12 +2091,12 @@ jQuery.find = find;
20912091
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
20922092
jQuery.unique = jQuery.uniqueSort;
20932093

2094-
// These have always been private, but they used to be documented
2095-
// as part of Sizzle so let's maintain them in the 3.x line
2096-
// for backwards compatibility purposes.
2094+
// These have always been private, but they used to be documented as part of
2095+
// Sizzle so let's maintain them for now for backwards compatibility purposes.
20972096
find.compile = compile;
20982097
find.select = select;
20992098
find.setDocument = setDocument;
2099+
find.tokenize = tokenize;
21002100

21012101
find.escape = jQuery.escapeSelector;
21022102
find.getText = jQuery.text;

test/unit/selector.js

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,3 +2448,224 @@ QUnit[ QUnit.jQuerySelectors ? "test" : "skip" ]( "Ensure no 'undefined' handler
24482448
assert.ok( !jQuery.expr.attrHandle.hasOwnProperty( "undefined" ),
24492449
"Extra attr handlers are not added to Expr.attrHandle (https://github.com/jquery/sizzle/issues/353)" );
24502450
} );
2451+
2452+
QUnit.test( "jQuery.find.matchesSelector", function( assert ) {
2453+
assert.expect( 15 );
2454+
2455+
var link = document.getElementById( "simon1" ),
2456+
input = document.getElementById( "text1" ),
2457+
option = document.getElementById( "option1a" ),
2458+
disconnected = document.createElement( "div" );
2459+
2460+
link.title = "Don't click me";
2461+
assert.ok( jQuery.find.matchesSelector( link, "[rel='bookmark']" ), "attribute-equals string" );
2462+
assert.ok( jQuery.find.matchesSelector( link, "[rel=bookmark]" ), "attribute-equals identifier" );
2463+
assert.ok( jQuery.find.matchesSelector( link, "[\nrel = bookmark\t]" ),
2464+
"attribute-equals identifier (whitespace ignored)" );
2465+
assert.ok( jQuery.find.matchesSelector( link, "a[title=\"Don't click me\"]" ),
2466+
"attribute-equals string containing single quote" );
2467+
2468+
// jQuery #12303
2469+
input.setAttribute( "data-pos", ":first" );
2470+
assert.ok( jQuery.find.matchesSelector( input, "input[data-pos=\\:first]" ),
2471+
"attribute-equals POS in identifier" );
2472+
assert.ok( jQuery.find.matchesSelector( input, "input[data-pos=':first']" ),
2473+
"attribute-equals POS in string" );
2474+
assert.ok( jQuery.find.matchesSelector( input, ":input[data-pos=':first']" ),
2475+
"attribute-equals POS in string after pseudo" );
2476+
2477+
option.setAttribute( "test", "" );
2478+
assert.ok( jQuery.find.matchesSelector( option, "[id=option1a]" ),
2479+
"id attribute-equals identifier" );
2480+
assert.ok( jQuery.find.matchesSelector( option, "[id*=option1][type!=checkbox]" ),
2481+
"attribute-not-equals identifier" );
2482+
assert.ok( jQuery.find.matchesSelector( option, "[id*=option1]" ), "attribute-contains identifier" );
2483+
assert.ok( !jQuery.find.matchesSelector( option, "[test^='']" ),
2484+
"attribute-starts-with empty string (negative)" );
2485+
2486+
option.className = "=]";
2487+
assert.ok( jQuery.find.matchesSelector( option, ".\\=\\]" ),
2488+
"class selector with attribute-equals confusable" );
2489+
2490+
assert.ok( jQuery.find.matchesSelector( disconnected, "div" ), "disconnected element" );
2491+
assert.ok( jQuery.find.matchesSelector( link, "* > *" ), "child combinator matches in document" );
2492+
assert.ok( !jQuery.find.matchesSelector( disconnected, "* > *" ), "child combinator fails in fragment" );
2493+
} );
2494+
2495+
QUnit.test( "jQuery.find.matches", function( assert ) {
2496+
assert.expect( 4 );
2497+
2498+
var iframeChild,
2499+
input = document.getElementById( "text1" ),
2500+
div = document.createElement( "div" ),
2501+
iframe = document.getElementById( "iframe" ),
2502+
iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
2503+
2504+
assert.deepEqual( jQuery.find.matches( "input", [ input ] ), [ input ],
2505+
"jQuery.find.matches with seed of input element" );
2506+
assert.deepEqual( jQuery.find.matches( "div", [ div ] ), [ div ],
2507+
"jQuery.find.matches with disconnected element" );
2508+
2509+
iframeDoc.open();
2510+
iframeDoc.write( "<body><div id='foo'><div id='bar'></div></div></body>" );
2511+
iframeDoc.close();
2512+
2513+
iframeChild = iframeDoc.getElementById( "bar" );
2514+
2515+
assert.deepEqual(
2516+
jQuery.find.matches( ":root > body > #foo > #bar", [ iframeChild ] ),
2517+
[ iframeChild ],
2518+
"jQuery.find.matches infers context from element"
2519+
);
2520+
2521+
assert.deepEqual(
2522+
jQuery.find.matches( ":root *", [ div, iframeChild, input ] ),
2523+
[ iframeChild, input ],
2524+
"jQuery.find.matches infers context from each seed element"
2525+
);
2526+
} );
2527+
2528+
QUnit.test( "jQuery.find.select with pre-compiled function", function( assert ) {
2529+
assert.expect( 6 );
2530+
2531+
supportjQuery.each( [
2532+
"#qunit-fixture #first",
2533+
"ol#listWithTabIndex > li[tabindex]",
2534+
"#liveSpan1"
2535+
], function( i, selector ) {
2536+
var compiled = jQuery.find.compile( selector );
2537+
assert.equal( jQuery.find.select( compiled, document ).length,
2538+
1, "Should match using a compiled selector function" );
2539+
assert.equal(
2540+
jQuery.find.select( compiled, jQuery( "#first" )[ 0 ] ).length,
2541+
0, "Should not match with different context" );
2542+
} );
2543+
} );
2544+
2545+
// Internal, but we test it for backwards compatibility for edge cases
2546+
QUnit.test( "jQuery.find.tokenize", function( assert ) {
2547+
assert.expect( 1 );
2548+
2549+
var selector = "#id .class > div[prop=\"value\"] + input:nth-child(1):button, span:contains(\"Text\") ~ div:has(div:has(span)):not(.not-this.not-that > div)",
2550+
tokens = [
2551+
[
2552+
{
2553+
"value": "#id",
2554+
"type": "ID",
2555+
"matches": [
2556+
"id"
2557+
]
2558+
},
2559+
{
2560+
"value": " ",
2561+
"type": " "
2562+
},
2563+
{
2564+
"value": ".class",
2565+
"type": "CLASS",
2566+
"matches": [
2567+
"class"
2568+
]
2569+
},
2570+
{
2571+
"value": " > ",
2572+
"type": ">"
2573+
},
2574+
{
2575+
"value": "div",
2576+
"type": "TAG",
2577+
"matches": [
2578+
"div"
2579+
]
2580+
},
2581+
{
2582+
"value": "[prop=\"value\"]",
2583+
"type": "ATTR",
2584+
"matches": [
2585+
"prop",
2586+
"=",
2587+
"value"
2588+
]
2589+
},
2590+
{
2591+
"value": " + ",
2592+
"type": "+"
2593+
},
2594+
{
2595+
"value": "input",
2596+
"type": "TAG",
2597+
"matches": [
2598+
"input"
2599+
]
2600+
},
2601+
{
2602+
"value": ":nth-child(1)",
2603+
"type": "CHILD",
2604+
"matches": [
2605+
"nth",
2606+
"child",
2607+
"1",
2608+
0,
2609+
1,
2610+
undefined,
2611+
"",
2612+
"1"
2613+
]
2614+
},
2615+
{
2616+
"value": ":button",
2617+
"type": "PSEUDO",
2618+
"matches": [
2619+
"button",
2620+
undefined
2621+
]
2622+
}
2623+
],
2624+
[
2625+
{
2626+
"value": "span",
2627+
"type": "TAG",
2628+
"matches": [
2629+
"span"
2630+
]
2631+
},
2632+
{
2633+
"value": ":contains(\"Text\")",
2634+
"type": "PSEUDO",
2635+
"matches": [
2636+
"contains",
2637+
"Text"
2638+
]
2639+
},
2640+
{
2641+
"value": " ~ ",
2642+
"type": "~"
2643+
},
2644+
{
2645+
"value": "div",
2646+
"type": "TAG",
2647+
"matches": [
2648+
"div"
2649+
]
2650+
},
2651+
{
2652+
"value": ":has(div:has(span))",
2653+
"type": "PSEUDO",
2654+
"matches": [
2655+
"has",
2656+
"div:has(span)"
2657+
]
2658+
},
2659+
{
2660+
"value": ":not(.not-this.not-that > div)",
2661+
"type": "PSEUDO",
2662+
"matches": [
2663+
"not",
2664+
".not-this.not-that > div"
2665+
]
2666+
}
2667+
]
2668+
];
2669+
2670+
assert.deepEqual( jQuery.find.tokenize( selector ), tokens, "Tokenization successful" );
2671+
} );

0 commit comments

Comments
 (0)