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 #1344
This commit is contained in:
Gaming4JC 2020-01-20 20:14:59 -05:00 • committed by Roy Tam
commit 5db13d0f4b
6 changed files with 50 additions and 8 deletions

View file

@ -472,15 +472,24 @@ public:
class MOZ_RAII AutoCEReaction final { class MOZ_RAII AutoCEReaction final {
public: public:
explicit AutoCEReaction(CustomElementReactionsStack* aReactionsStack) // JSContext is allowed to be a nullptr if we are guaranteeing that we're
: mReactionsStack(aReactionsStack) { // 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(); mReactionsStack->CreateAndPushElementQueue();
} }
~AutoCEReaction() { ~AutoCEReaction() {
Maybe<JS::AutoSaveExceptionState> ases;
if (mCx) {
ases.emplace(mCx);
}
mReactionsStack->PopAndInvokeElementQueue(); mReactionsStack->PopAndInvokeElementQueue();
} }
private: private:
RefPtr<CustomElementReactionsStack> mReactionsStack; RefPtr<CustomElementReactionsStack> mReactionsStack;
JSContext* mCx;
}; };
} // namespace dom } // namespace dom

View file

@ -5809,7 +5809,8 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
return; return;
} }
AutoCEReaction ceReaction(this->GetDocGroup()->CustomElementReactionsStack()); AutoCEReaction ceReaction(this->GetDocGroup()->CustomElementReactionsStack(),
aCx);
// Unconditionally convert TYPE to lowercase. // Unconditionally convert TYPE to lowercase.
nsAutoString lcType; nsAutoString lcType;
nsContentUtils::ASCIIToLower(aType, lcType); nsContentUtils::ASCIIToLower(aType, lcType);

View file

@ -7679,7 +7679,7 @@ class CGPerSignatureCall(CGThing):
CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(${obj}); CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(${obj});
Maybe<AutoCEReaction> ceReaction; Maybe<AutoCEReaction> ceReaction;
if (reactionsStack) { if (reactionsStack) {
ceReaction.emplace(reactionsStack); ceReaction.emplace(reactionsStack, cx);
} }
""", obj=objectName))) """, obj=objectName)))

View file

@ -16,14 +16,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1094930
<script type="application/javascript"> <script type="application/javascript">
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
var proto = { var proto = {
createdCallback: function() { connectedCallback: function() {
ok(true, "createdCallback was called"); ok(true, "connectedCallback was called");
SimpleTest.finish() SimpleTest.finish()
} }
}; };
var f = document.registerElement.call(frames[0].document, "x-foo", { prototype: proto }); var f = document.registerElement.call(frames[0].document, "x-foo", { prototype: proto });
var inst = new f(); frames[0].document.firstChild.appendChild(new f());
</script> </script>
</body> </body>
</html> </html>

View file

@ -450,7 +450,8 @@ nsHtml5TreeOperation::CreateHTMLElement(
nsAutoMicroTask mt; nsAutoMicroTask mt;
} }
dom::AutoCEReaction dom::AutoCEReaction
autoCEReaction(document->GetDocGroup()->CustomElementReactionsStack()); autoCEReaction(document->GetDocGroup()->CustomElementReactionsStack(),
nullptr);
nsCOMPtr<dom::Element> newElement; nsCOMPtr<dom::Element> newElement;
NS_NewHTMLElement(getter_AddRefs(newElement), nodeInfo.forget(), NS_NewHTMLElement(getter_AddRefs(newElement), nodeInfo.forget(),

View file

@ -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>