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
Manipulation: Add support script type module #3869
Conversation
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.
Thanks for the pull request. Can you also reference a relevant issue, creating one if necessary?
src/manipulation/var/rscriptType.js
Outdated
@@ -1,5 +1,5 @@ | |||
define( function() { | |||
"use strict"; | |||
|
|||
return ( /^$|\/(?:java|ecma)script/i ); | |||
return ( /^$|module|\/(?:java|ecma)script/i ); |
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.
^module$
src/manipulation.js
Outdated
@@ -193,14 +193,19 @@ function domManip( collection, args, callback, ignored ) { | |||
!dataPriv.access( node, "globalEval" ) && | |||
jQuery.contains( doc, node ) ) { | |||
|
|||
if ( node.src ) { | |||
if ( node.src && node.type !== "module" ) { |
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.
It's very convenient that module execution is inherently asynchronous with respect to parsing. But I suppose we'll also need awareness of nomodule
now.
src/core/DOMEval.js
Outdated
@@ -3,12 +3,19 @@ define( [ | |||
], function( document ) { | |||
"use strict"; | |||
|
|||
function DOMEval( code, doc ) { | |||
function DOMEval( code, doc, type, src ) { |
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.
See #3766. I think this is sufficient cause to pass around the node object itself, instead of adding parameter after parameter.
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.
function globalEval
depends from DOMEval
, probably we should write another function something like DOMScript
, that function can receive node object. also this function can include all checks like
if ( rscriptType.test( node.type || "" ) &&
!dataPriv.access( node, "globalEval" ) &&
jQuery.contains( doc, node ) ) {
if ( node.src && node.type !== "module" ) {
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.
DOMEval
is already an internal function, and only invoked at two preexisting sites. We don't need to introduce another function, we just need to update the signature to e.g. function DOMEval( code, doc, node )
and copy over whitelisted attributes (src
, type
, crossorigin
, integrity
, etc.) in the body.
src/core/DOMEval.js
Outdated
if ( code ) { | ||
script.text = code; | ||
} | ||
if ( type === "module" ) { |
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.
The HTML Standard specifies a case-insensitive match for "module", which we need to respect.
src/core/DOMEval.js
Outdated
doc = doc || document; | ||
|
||
var script = doc.createElement( "script" ); | ||
|
||
script.text = code; | ||
if ( code ) { |
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 don't think we need this condition.
src/core/DOMEval.js
Outdated
} | ||
jQuery.each( [ | ||
"type", | ||
"nomodule", |
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.
jQuery.each
is almost certainly overkill for what should be for ( property in scriptProperties )
iteration when node
is provided, and "nomodule" doesn't belong in the list because it is ignored on module scripts (which are the only cases where we have a node here).
src/manipulation.js
Outdated
@@ -193,14 +193,14 @@ function domManip( collection, args, callback, ignored ) { | |||
!dataPriv.access( node, "globalEval" ) && | |||
jQuery.contains( doc, node ) ) { | |||
|
|||
if ( node.src ) { | |||
if ( node.src && !/^module$/i.test( node.type ) ) { |
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.
We don't like inlining regex definitions; this should be node.type.toLowerCase() === "module"
unless a supported browser has non-string type properties, in which case the regex should be defined outside the function.
test/unit/manipulation.js
Outdated
"<script>ok( true, 'evaluated: no type' );</script>", | ||
"<div>", | ||
"<script type='something/else'>ok( false, 'evaluated: inner non-script' );</script>", | ||
"<script type='text/javascript'>ok( true, 'evaluated: inner text/javascript' );</script>", | ||
"<script type='text/ecmascript'>ok( true, 'evaluated: inner text/ecmascript' );</script>", | ||
"<script type='module'>ok( true, 'evaluated: inner module' );</script>", |
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.
We should also have a test for a module script with src
.
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.
This won't work in browsers not supporting modules, will it? A separate iframe test might be better, especially that these tests are already too big.
I think we would like to separate the module tests from other tests and only run them if modules are supported. |
src/core/DOMEval.js
Outdated
script.text = code; | ||
if ( node ) { | ||
for ( i in { type: true, src: true } ) { |
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.
This object should be a preservedScriptAttributes
variable, not a literal buried in the function body.
Browser is skipping scripts by default in case type is unsuported. this means tests wont run in case modules arent supported. |
@tbepdb still, we'd like to separate all module-related tests from the others. |
Fixes: #3871
Summary
For method
$('selector').html()
append support native ECMAScript modules, like that
<script type="module" scr="PATH/file.js"></script>
and like that
Checklist