diff options
Diffstat (limited to 'dom')
-rw-r--r-- | dom/base/nsGkAtomList.h | 1 | ||||
-rw-r--r-- | dom/base/nsScriptLoader.cpp | 15 | ||||
-rw-r--r-- | dom/html/HTMLScriptElement.cpp | 12 | ||||
-rw-r--r-- | dom/html/HTMLScriptElement.h | 2 | ||||
-rw-r--r-- | dom/html/test/file_script_module.html | 42 | ||||
-rw-r--r-- | dom/html/test/file_script_nomodule.html | 32 | ||||
-rw-r--r-- | dom/html/test/mochitest.ini | 4 | ||||
-rw-r--r-- | dom/html/test/test_script_module.html | 56 | ||||
-rw-r--r-- | dom/webidl/HTMLScriptElement.webidl | 2 |
9 files changed, 164 insertions, 2 deletions
diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index 8fefa0e02..73a3a02b1 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -665,6 +665,7 @@ GK_ATOM(noembed, "noembed") GK_ATOM(noframes, "noframes") GK_ATOM(nohref, "nohref") GK_ATOM(noisolation, "noisolation") +GK_ATOM(nomodule, "nomodule") GK_ATOM(nonce, "nonce") GK_ATOM(none, "none") GK_ATOM(noresize, "noresize") diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp index 6f8251fc3..61d122386 100644 --- a/dom/base/nsScriptLoader.cpp +++ b/dom/base/nsScriptLoader.cpp @@ -1452,7 +1452,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) nsCOMPtr<nsIContent> scriptContent = do_QueryInterface(aElement); - // Step 12. Check that the script is not an eventhandler + // Step 13. Check that the script is not an eventhandler if (IsScriptEventHandler(scriptContent)) { return false; } @@ -1486,7 +1486,18 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) } } - // Step 14. in the HTML5 spec + // "In modern user agents that support module scripts, the script element with + // the nomodule attribute will be ignored". + // "The nomodule attribute must not be specified on module scripts (and will + // be ignored if it is)." + if (ModuleScriptsEnabled() && + scriptKind == nsScriptKind::Classic && + scriptContent->IsHTMLElement() && + scriptContent->HasAttr(kNameSpaceID_None, nsGkAtoms::nomodule)) { + return false; + } + + // Step 15. and later in the HTML5 spec nsresult rv = NS_OK; RefPtr<nsScriptLoadRequest> request; if (aElement->GetScriptExternal()) { diff --git a/dom/html/HTMLScriptElement.cpp b/dom/html/HTMLScriptElement.cpp index 94d09c12c..095b9b77d 100644 --- a/dom/html/HTMLScriptElement.cpp +++ b/dom/html/HTMLScriptElement.cpp @@ -218,6 +218,18 @@ HTMLScriptElement::SetAsync(bool aValue, ErrorResult& rv) SetHTMLBoolAttr(nsGkAtoms::async, aValue, rv); } +bool +HTMLScriptElement::NoModule() +{ + return GetBoolAttr(nsGkAtoms::nomodule); +} + +void +HTMLScriptElement::SetNoModule(bool aValue, ErrorResult& aRv) +{ + SetHTMLBoolAttr(nsGkAtoms::nomodule, aValue, aRv); +} + nsresult HTMLScriptElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) diff --git a/dom/html/HTMLScriptElement.h b/dom/html/HTMLScriptElement.h index 00628bd6d..19ceb414f 100644 --- a/dom/html/HTMLScriptElement.h +++ b/dom/html/HTMLScriptElement.h @@ -89,6 +89,8 @@ public: } bool Async(); void SetAsync(bool aValue, ErrorResult& rv); + bool NoModule(); + void SetNoModule(bool aValue, ErrorResult& rv); protected: virtual ~HTMLScriptElement(); diff --git a/dom/html/test/file_script_module.html b/dom/html/test/file_script_module.html new file mode 100644 index 000000000..78c499265 --- /dev/null +++ b/dom/html/test/file_script_module.html @@ -0,0 +1,42 @@ +<html> +<body> + <script> +// Helper methods. +function ok(a, msg) { + parent.postMessage({ check: !!a, msg }, "*") +} + +function is(a, b, msg) { + ok(a === b, msg); +} + +function finish() { + parent.postMessage({ done: true }, "*"); +} + </script> + + <script id="a" nomodule>42</script> + <script id="b">42</script> + <script> +// Let's test the behavior of nomodule attribute and noModule getter/setter. +var a = document.getElementById("a"); +is(a.noModule, true, "HTMLScriptElement with nomodule attribute has noModule set to true"); +a.removeAttribute("nomodule"); +is(a.noModule, false, "HTMLScriptElement without nomodule attribute has noModule set to false"); +a.noModule = true; +ok(a.hasAttribute('nomodule'), "HTMLScriptElement.noModule = true add the nomodule attribute"); + +var b = document.getElementById("b"); +is(b.noModule, false, "HTMLScriptElement without nomodule attribute has noModule set to false"); +b.noModule = true; +ok(b.hasAttribute('nomodule'), "HTMLScriptElement.noModule = true add the nomodule attribute"); + </script> + + <script>var foo = 42;</script> + <script nomodule>foo = 43;</script> + <script> +is(foo, 42, "nomodule HTMLScriptElements should not be executed in modern browsers"); +finish(); + </script> +</body> +</html> diff --git a/dom/html/test/file_script_nomodule.html b/dom/html/test/file_script_nomodule.html new file mode 100644 index 000000000..303edb90b --- /dev/null +++ b/dom/html/test/file_script_nomodule.html @@ -0,0 +1,32 @@ +<html> +<body> + <script> +// Helper methods. +function ok(a, msg) { + parent.postMessage({ check: !!a, msg }, "*") +} + +function is(a, b, msg) { + ok(a === b, msg); +} + +function finish() { + parent.postMessage({ done: true }, "*"); +} + </script> + + <script id="a" nomodule>42</script> + <script> +// Let's test the behavior of nomodule attribute and noModule getter/setter. +var a = document.getElementById("a"); +ok(!("noModule" in a), "When modules are disabled HTMLScriptElement.noModule is not defined"); + </script> + + <script>var foo = 42;</script> + <script nomodule>foo = 43;</script> + <script> +is(foo, 43, "nomodule attribute is ignored when modules are disabled"); +finish(); + </script> +</body> +</html> diff --git a/dom/html/test/mochitest.ini b/dom/html/test/mochitest.ini index 99b425df8..0c0ba847c 100644 --- a/dom/html/test/mochitest.ini +++ b/dom/html/test/mochitest.ini @@ -606,3 +606,7 @@ skip-if = os == "android" # up/down arrow keys not supported on android [test_bug1295719_event_sequence_for_number_keys.html] [test_bug1310865.html] [test_bug1315146.html] ++[test_script_module.html] ++support-files = ++ file_script_module.html ++ file_script_nomodule.html
\ No newline at end of file diff --git a/dom/html/test/test_script_module.html b/dom/html/test/test_script_module.html new file mode 100644 index 000000000..4878bb379 --- /dev/null +++ b/dom/html/test/test_script_module.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for HTMLScriptElement with nomodule attribute</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> + <script> +onmessage = (e) => { + if ("done" in e.data) { + next(); + } else if ("check" in e.data) { + ok(e.data.check, e.data.msg); + } else { + ok(false, "Unknown message"); + } +} + +var tests = [ + function() { + SpecialPowers.pushPrefEnv({"set":[["dom.moduleScripts.enabled", true]]}) + .then(() => { + var ifr = document.createElement('iframe'); + ifr.src = "file_script_module.html"; + document.body.appendChild(ifr); + }); + }, + + function() { + SpecialPowers.pushPrefEnv({"set":[["dom.moduleScripts.enabled", false]]}) + .then(() => { + var ifr = document.createElement('iframe'); + ifr.src = "file_script_nomodule.html"; + document.body.appendChild(ifr); + }); + }, +]; + +SimpleTest.waitForExplicitFinish(); +next(); + +function next() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + </script> + +</body> +</html> diff --git a/dom/webidl/HTMLScriptElement.webidl b/dom/webidl/HTMLScriptElement.webidl index 377056366..5b64c42d7 100644 --- a/dom/webidl/HTMLScriptElement.webidl +++ b/dom/webidl/HTMLScriptElement.webidl @@ -13,6 +13,8 @@ interface HTMLScriptElement : HTMLElement { attribute DOMString src; [SetterThrows] attribute DOMString type; + [SetterThrows, Pref="dom.moduleScripts.enabled"] + attribute boolean noModule; [SetterThrows] attribute DOMString charset; [SetterThrows] |