Skip to content
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

Closed
wants to merge 7 commits into from
Closed

Manipulation: Add support script type module #3869

wants to merge 7 commits into from

Conversation

tbepdb
Copy link
Contributor

@tbepdb tbepdb commented Dec 3, 2017

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

<script type="module">
  import * as myModule from "PATH/myModule.js";
</script>

Checklist

Copy link
Member

@gibson042 gibson042 left a 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?

@@ -1,5 +1,5 @@
define( function() {
"use strict";

return ( /^$|\/(?:java|ecma)script/i );
return ( /^$|module|\/(?:java|ecma)script/i );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^module$

@@ -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" ) {
Copy link
Member

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.

@@ -3,12 +3,19 @@ define( [
], function( document ) {
"use strict";

function DOMEval( code, doc ) {
function DOMEval( code, doc, type, src ) {
Copy link
Member

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.

Copy link
Contributor Author

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" ) {

Copy link
Member

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.

if ( code ) {
script.text = code;
}
if ( type === "module" ) {
Copy link
Member

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.

doc = doc || document;

var script = doc.createElement( "script" );

script.text = code;
if ( code ) {
Copy link
Member

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.

}
jQuery.each( [
"type",
"nomodule",
Copy link
Member

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).

@@ -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 ) ) {
Copy link
Member

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.

"<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>",
Copy link
Member

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.

Copy link
Member

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.

@timmywil
Copy link
Member

I think we would like to separate the module tests from other tests and only run them if modules are supported.

script.text = code;
if ( node ) {
for ( i in { type: true, src: true } ) {
Copy link
Member

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.

@tbepdb
Copy link
Contributor Author

tbepdb commented Dec 11, 2017

Browser is skipping scripts by default in case type is unsuported. this means tests wont run in case modules arent supported.

@timmywil
Copy link
Member

@tbepdb still, we'd like to separate all module-related tests from the others.

@timmywil timmywil closed this in 5d3a968 Jan 16, 2018
@lock lock bot locked as resolved and limited conversation to collaborators Jul 15, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

DOM inserted scripts should support script type module
4 participants