-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Scripts: Use HTML API to build SCRIPT tags #10639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
4a8ca98
4a28ef2
0bef687
cdba027
ba54ae4
a697e9e
2b3d0d0
8246439
1b6b4fd
b3e88e8
27c6371
deebd54
d78cd35
c29c3d9
abeebd6
aaacd6f
3f7f227
1362451
8d30680
3b5ef4e
f8cfdf9
501d201
253b971
bcc02ae
ea03441
c7d1827
a134e82
d4bd4b3
edae8d5
02ca3c0
d058a78
dfb63af
11f51c9
a3e0e27
288b952
a7495dd
614916d
5828382
d8c320c
016a29f
369eefc
d67749d
2869880
d6bfdca
b7099e4
010a2a2
ab53486
3ba2267
64a23b7
c920821
dbd9f55
7bef55a
4333300
504a928
55d4e47
1c84037
2ef0bf0
cb6b990
da28eec
e399bf6
83c1fab
1872681
83ff62f
5979782
d469ae4
402ae9f
6b2c9ba
eef0ccb
71d2686
d4693a2
eb4e091
4c3b0b2
40015c9
bfa60cf
3252160
0b9b2bd
b2533e1
ddeb301
b36fc32
1249af0
645cb45
f23b35b
31cefb7
25279e3
6660196
b436e71
95259d2
91c019d
09e3aa2
30d7747
c1c6067
292614d
6a6e1cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2872,7 +2872,14 @@ function wp_get_script_tag( $attributes ) { | |
| */ | ||
| $attributes = apply_filters( 'wp_script_attributes', $attributes ); | ||
|
|
||
| return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) ); | ||
| $processor = new WP_HTML_Tag_Processor( '<script></script>' ); | ||
| $processor->next_tag(); | ||
| foreach ( $attributes as $name => $value ) { | ||
| if ( is_string( $value ) || true === $value ) { | ||
| $processor->set_attribute( $name, $value ); | ||
| } | ||
| } | ||
| return "{$processor->get_updated_html()}\n"; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -2916,7 +2923,15 @@ function wp_get_inline_script_tag( $data, $attributes = array() ) { | |
| */ | ||
| $attributes = apply_filters( 'wp_inline_script_attributes', $attributes, $data ); | ||
|
|
||
| return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $data ); | ||
| $processor = new WP_HTML_Tag_Processor( '<script></script>' ); | ||
| $processor->next_tag(); | ||
| foreach ( $attributes as $name => $value ) { | ||
| if ( is_string( $value ) || true === $value ) { | ||
| $processor->set_attribute( $name, $value ); | ||
| } | ||
| } | ||
| $processor->set_modifiable_text( $data ); | ||
| return "{$processor->get_updated_html()}\n"; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same question as above |
||
| } | ||
|
|
||
| /** | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious why you chose DOT as opposed to Mermaid? I know that GitHub supports Mermaid. In any case, I'm very impressed that you went to the effort of making a diagram to document this. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| digraph { | ||
| rankdir=TB; | ||
|
|
||
| // Entry point | ||
| entry [shape=plaintext label="Open script"]; | ||
| entry -> script_data; | ||
|
|
||
| // Double-circle states arranged more compactly | ||
| data [shape=doublecircle label="Close script"]; | ||
| script_data [shape=doublecircle color=blue label="script\ndata"]; | ||
| script_data_escaped [shape=circle color=orange label="escaped"]; | ||
| script_data_double_escaped [shape=circle color=red label="double\nescaped"]; | ||
|
|
||
| // Group related nodes on same ranks where possible | ||
| {rank=same; script_data script_data_escaped script_data_double_escaped} | ||
|
|
||
| script_data -> script_data [label="<!--(…)>\n(all dashes)"]; | ||
| script_data -> script_data_escaped [label="<!--"]; | ||
| script_data -> data [label="</script†"]; | ||
|
|
||
| script_data_escaped -> script_data [label="-->"]; | ||
| script_data_escaped -> script_data_double_escaped [label="<script†"]; | ||
| script_data_escaped -> data [label="</script†"]; | ||
|
|
||
| script_data_double_escaped -> script_data [label="-->"]; | ||
| script_data_double_escaped -> script_data_escaped [label="</script†"]; | ||
|
|
||
| label="† = Case insensitive 'script' followed by one of ' \\t\\f\\r\\n/>'"; | ||
| labelloc=b; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <?php | ||
|
|
||
| /** | ||
| * This is the original Graphviz source for the SCRIPT tag | ||
| * parsing behavior, used in the documentation for the HTML API. | ||
| * | ||
| * @see WP_HTML_Tag_Processor::escape_javascript_script_contents() | ||
| * | ||
| * @return string | ||
| */ | ||
| function wp_html_api_script_element_escaping_diagram_source() { | ||
| return file_get_contents( __DIR__ . '/script-element-escaping-diagram.dot' ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -333,8 +333,8 @@ public function test_delayed_dependent_with_blocking_dependency_not_enqueued( $s | |
| // This dependent is registered but not enqueued, so it should not factor into the eligible loading strategy. | ||
| wp_register_script( 'dependent-script-a4', '/dependent-script-a4.js', array( 'main-script-a4' ), null ); | ||
| $output = get_echo( 'wp_print_scripts' ); | ||
| $expected = str_replace( "'", '"', "<script src='/main-script-a4.js' id='main-script-a4-js' {$strategy} data-wp-strategy='{$strategy}'></script>" ); | ||
| $this->assertStringContainsString( $expected, $output, 'Only enqueued dependents should affect the eligible strategy.' ); | ||
| $expected = "<script src='/main-script-a4.js' id='main-script-a4-js' {$strategy} data-wp-strategy='{$strategy}'></script>"; | ||
| $this->assertEqualHTMLScriptTagById( $expected, $output, 'Only enqueued dependents should affect the eligible strategy.' ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I missed this in #10649! but this is big
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These test changes should be extracted to their own PR. |
||
| } | ||
|
|
||
| /** | ||
|
|
@@ -1076,8 +1076,8 @@ public function test_various_strategy_dependency_chains( $set_up, $expected_mark | |
| public function test_loading_strategy_with_defer_having_no_dependents_nor_dependencies() { | ||
| wp_enqueue_script( 'main-script-d1', 'http://example.com/main-script-d1.js', array(), null, array( 'strategy' => 'defer' ) ); | ||
| $output = get_echo( 'wp_print_scripts' ); | ||
| $expected = str_replace( "'", '"', "<script src='http://example.com/main-script-d1.js' id='main-script-d1-js' defer data-wp-strategy='defer'></script>\n" ); | ||
| $this->assertStringContainsString( $expected, $output, 'Expected defer, as there is no dependent or dependency' ); | ||
| $expected = "<script src='http://example.com/main-script-d1.js' id='main-script-d1-js' defer data-wp-strategy='defer'></script>\n"; | ||
| $this->assertEqualHTMLScriptTagById( $expected, $output, 'Expected defer, as there is no dependent or dependency' ); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -1096,7 +1096,7 @@ public function test_loading_strategy_with_defer_dependent_and_varied_dependenci | |
| wp_enqueue_script( 'main-script-d2', 'http://example.com/main-script-d2.js', array( 'dependency-script-d2-1', 'dependency-script-d2-3' ), null, array( 'strategy' => 'defer' ) ); | ||
| $output = get_echo( 'wp_print_scripts' ); | ||
| $expected = '<script src="http://example.com/main-script-d2.js" id="main-script-d2-js" defer data-wp-strategy="defer"></script>'; | ||
| $this->assertStringContainsString( $expected, $output, 'Expected defer, as all dependencies are either deferred or blocking' ); | ||
| $this->assertEqualHTMLScriptTagById( $expected, $output, 'Expected defer, as all dependencies are either deferred or blocking' ); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -1115,7 +1115,7 @@ public function test_loading_strategy_with_all_defer_dependencies() { | |
| wp_enqueue_script( 'dependent-script-d3-3', 'http://example.com/dependent-script-d3-3.js', array( 'dependent-script-d3-2' ), null, array( 'strategy' => 'defer' ) ); | ||
| $output = get_echo( 'wp_print_scripts' ); | ||
| $expected = '<script src="http://example.com/main-script-d3.js" id="main-script-d3-js" defer data-wp-strategy="defer"></script>'; | ||
| $this->assertStringContainsString( $expected, $output, 'Expected defer, as all dependents have defer loading strategy' ); | ||
| $this->assertEqualHTMLScriptTagById( $expected, $output, 'Expected defer, as all dependents have defer loading strategy' ); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -1495,9 +1495,10 @@ public function test_loading_strategy_with_invalid_defer_registration() { | |
| wp_enqueue_script( 'dependent-script-d4-1', '/dependent-script-d4-1.js', array( 'main-script-d4' ), null, array( 'strategy' => 'defer' ) ); | ||
| wp_enqueue_script( 'dependent-script-d4-2', '/dependent-script-d4-2.js', array( 'dependent-script-d4-1' ), null ); | ||
| wp_enqueue_script( 'dependent-script-d4-3', '/dependent-script-d4-3.js', array( 'dependent-script-d4-2' ), null, array( 'strategy' => 'defer' ) ); | ||
|
|
||
| $output = get_echo( 'wp_print_scripts' ); | ||
| $expected = str_replace( "'", '"', "<script src='/main-script-d4.js' id='main-script-d4-js' data-wp-strategy='defer'></script>\n" ); | ||
| $this->assertStringContainsString( $expected, $output, 'Scripts registered as defer but that have all dependents with no strategy, should become blocking (no strategy).' ); | ||
| $expected = "<script src='/main-script-d4.js' id='main-script-d4-js' data-wp-strategy='defer'></script>\n"; | ||
| $this->assertEqualHTMLScriptTagById( $expected, $output, 'Scripts registered as defer but that have all dependents with no strategy, should become blocking (no strategy).' ); | ||
| } | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate this type guarding, but it feels a bit redundant. are we attempting to type-check the filter results or are we trying to guard against sending invalid types to
set_attribute()?it doesn’t currently type-check against a string, but we could add
_doing_it_wrong()if we want to incur the runtime cost of type-checking there, which would seem okay.I just want to question the intent here and the fact that this hides type errors and mistakes in the calling code by skipping over attributes which presumably were supposed to be set.