diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2020-01-20 20:14:59 -0500 |
---|---|---|
committer | Gaming4JC <g4jc@hyperbola.info> | 2020-01-26 15:50:48 -0500 |
commit | 8d456c7508882933502dd435a4ae91ee0b5c82c1 (patch) | |
tree | dd1ef38691c25a80787dfcdca06038a7fac18c7e | |
parent | c99209cfd7d2ae15e2579910a45242958d8ca5ed (diff) | |
download | uxp-8d456c7508882933502dd435a4ae91ee0b5c82c1.tar.gz |
Bug 1415761 - Catch the exception and rethrow it after invoking custom elements reactions;
The spec was unclear on how CEReactions interact with thrown exceptions; see https://github.com/whatwg/html/issues/3217. The spec is now being clarified in https://github.com/whatwg/html/pull/3235.
Tag UXP Issue mcp-graveyard/UXP#1344
-rw-r--r-- | dom/base/CustomElementRegistry.h | 13 | ||||
-rw-r--r-- | dom/base/nsDocument.cpp | 3 | ||||
-rw-r--r-- | dom/bindings/Codegen.py | 2 | ||||
-rw-r--r-- | js/xpconnect/tests/mochitest/test_bug1094930.html | 6 | ||||
-rw-r--r-- | parser/html/nsHtml5TreeOperation.cpp | 3 | ||||
-rw-r--r-- | testing/web-platform/tests/custom-elements/reactions/with-exceptions.html | 31 |
6 files changed, 50 insertions, 8 deletions
diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index c180a10af3..51c97fd5e2 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -472,15 +472,24 @@ public: class MOZ_RAII AutoCEReaction final { public: - explicit AutoCEReaction(CustomElementReactionsStack* aReactionsStack) - : mReactionsStack(aReactionsStack) { + // JSContext is allowed to be a nullptr if we are guaranteeing that we're + // not doing something that might throw but not finish reporting a JS + // exception during the lifetime of the AutoCEReaction. + AutoCEReaction(CustomElementReactionsStack* aReactionsStack, JSContext* aCx) + : mReactionsStack(aReactionsStack) + , mCx(aCx) { mReactionsStack->CreateAndPushElementQueue(); } ~AutoCEReaction() { + Maybe<JS::AutoSaveExceptionState> ases; + if (mCx) { + ases.emplace(mCx); + } mReactionsStack->PopAndInvokeElementQueue(); } private: RefPtr<CustomElementReactionsStack> mReactionsStack; + JSContext* mCx; }; } // namespace dom diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 9043e409ae..f3e4925893 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -5809,7 +5809,8 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType, return; } - AutoCEReaction ceReaction(this->GetDocGroup()->CustomElementReactionsStack()); + AutoCEReaction ceReaction(this->GetDocGroup()->CustomElementReactionsStack(), + aCx); // Unconditionally convert TYPE to lowercase. nsAutoString lcType; nsContentUtils::ASCIIToLower(aType, lcType); diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 730465fee7..8ee732cca3 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -7679,7 +7679,7 @@ class CGPerSignatureCall(CGThing): CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(${obj}); Maybe<AutoCEReaction> ceReaction; if (reactionsStack) { - ceReaction.emplace(reactionsStack); + ceReaction.emplace(reactionsStack, cx); } """, obj=objectName))) diff --git a/js/xpconnect/tests/mochitest/test_bug1094930.html b/js/xpconnect/tests/mochitest/test_bug1094930.html index 4349493607..674edfe475 100644 --- a/js/xpconnect/tests/mochitest/test_bug1094930.html +++ b/js/xpconnect/tests/mochitest/test_bug1094930.html @@ -16,14 +16,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1094930 <script type="application/javascript"> SimpleTest.waitForExplicitFinish(); var proto = { - createdCallback: function() { - ok(true, "createdCallback was called"); + connectedCallback: function() { + ok(true, "connectedCallback was called"); SimpleTest.finish() } }; var f = document.registerElement.call(frames[0].document, "x-foo", { prototype: proto }); - var inst = new f(); + frames[0].document.firstChild.appendChild(new f()); </script> </body> </html> diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp index d530cbba3a..d747f80a8a 100644 --- a/parser/html/nsHtml5TreeOperation.cpp +++ b/parser/html/nsHtml5TreeOperation.cpp @@ -450,7 +450,8 @@ nsHtml5TreeOperation::CreateHTMLElement( nsAutoMicroTask mt; } dom::AutoCEReaction - autoCEReaction(document->GetDocGroup()->CustomElementReactionsStack()); + autoCEReaction(document->GetDocGroup()->CustomElementReactionsStack(), + nullptr); nsCOMPtr<dom::Element> newElement; NS_NewHTMLElement(getter_AddRefs(newElement), nodeInfo.forget(), diff --git a/testing/web-platform/tests/custom-elements/reactions/with-exceptions.html b/testing/web-platform/tests/custom-elements/reactions/with-exceptions.html new file mode 100644 index 0000000000..82e0f59c93 --- /dev/null +++ b/testing/web-platform/tests/custom-elements/reactions/with-exceptions.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Custom Elements: CEReactions interaction with exceptions</title> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<meta name="help" content="https://html.spec.whatwg.org/multipage/#cereactions"> +<meta name="help" content="https://github.com/whatwg/html/pull/3235"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../resources/custom-elements-helpers.js"></script> + +<div id="log"></div> + +<script> +"use strict"; +// Basically from https://github.com/whatwg/html/issues/3217#issuecomment-343633273 +test_with_window((contentWindow, contentDocument) => { + let reactionRan = false; + contentWindow.customElements.define("custom-element", class extends contentWindow.HTMLElement { + disconnectedCallback() { + reactionRan = true; + } + }); + const text = contentDocument.createTextNode(""); + contentDocument.documentElement.appendChild(text); + const element = contentDocument.createElement("custom-element"); + contentDocument.documentElement.appendChild(element); + assert_throws("HierarchyRequestError", () => text.before("", contentDocument.documentElement)); + assert_true(reactionRan); +}, "Reaction must run even after the exception is thrown"); +</script> |