mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-29 10:37:33 +09:00
Bug 1299363 - Part 5-1: Make the constructor created by document.registerElement() also works with construction stack.
So that the old upgrade can also work with new upgrade steps which will be implemented in part 5-2. Tag UXP Issue #1344
This commit is contained in:
parent
3dce7ee1bb
commit
b2e0ae6983
2 changed files with 54 additions and 43 deletions
|
|
@ -799,40 +799,6 @@ CustomElementRegistry::Upgrade(Element* aElement,
|
||||||
|
|
||||||
MOZ_ASSERT(aElement->IsHTMLElement(aDefinition->mLocalName));
|
MOZ_ASSERT(aElement->IsHTMLElement(aDefinition->mLocalName));
|
||||||
|
|
||||||
AutoJSAPI jsapi;
|
|
||||||
if (NS_WARN_IF(!jsapi.Init(mWindow))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSContext* cx = jsapi.cx();
|
|
||||||
|
|
||||||
JS::Rooted<JSObject*> reflector(cx, aElement->GetWrapper());
|
|
||||||
if (reflector) {
|
|
||||||
Maybe<JSAutoCompartment> ac;
|
|
||||||
JS::Rooted<JSObject*> prototype(cx, aDefinition->mPrototype);
|
|
||||||
if (aElement->NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(prototype))) {
|
|
||||||
ac.emplace(cx, reflector);
|
|
||||||
if (!JS_WrapObject(cx, &prototype) ||
|
|
||||||
!JS_SetPrototype(cx, reflector, prototype)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// We want to set the custom prototype in the compartment where it was
|
|
||||||
// registered. We store the prototype from define() without unwrapped,
|
|
||||||
// hence the prototype's compartment is the compartment where it was
|
|
||||||
// registered.
|
|
||||||
// In the case that |reflector| and |prototype| are in different
|
|
||||||
// compartments, this will set the prototype on the |reflector|'s wrapper
|
|
||||||
// and thus only visible in the wrapper's compartment, since we know
|
|
||||||
// reflector's principal does not subsume prototype's in this case.
|
|
||||||
ac.emplace(cx, prototype);
|
|
||||||
if (!JS_WrapObject(cx, &reflector) ||
|
|
||||||
!JS_SetPrototype(cx, reflector, prototype)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EnqueueLifecycleCallback(nsIDocument::eCreated, aElement, nullptr, aDefinition);
|
EnqueueLifecycleCallback(nsIDocument::eCreated, aElement, nullptr, aDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5670,19 +5670,64 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDependentAtomString localName(definition->mLocalName);
|
RefPtr<Element> element;
|
||||||
|
|
||||||
nsCOMPtr<Element> element =
|
// We integrate with construction stack and do prototype swizzling here, so
|
||||||
document->CreateElem(localName, nullptr, kNameSpaceID_XHTML);
|
// that old upgrade behavior could also share the new upgrade steps.
|
||||||
NS_ENSURE_TRUE(element, true);
|
// And this old upgrade will be remove at some point (when everything is
|
||||||
|
// switched to latest custom element spec).
|
||||||
|
nsTArray<RefPtr<nsGenericHTMLElement>>& constructionStack =
|
||||||
|
definition->mConstructionStack;
|
||||||
|
if (constructionStack.Length()) {
|
||||||
|
element = constructionStack.LastElement();
|
||||||
|
NS_ENSURE_TRUE(element != ALEADY_CONSTRUCTED_MARKER, false);
|
||||||
|
|
||||||
if (definition->mLocalName != typeAtom) {
|
// Do prototype swizzling if dom reflector exists.
|
||||||
// This element is a custom element by extension, thus we need to
|
JS::Rooted<JSObject*> reflector(aCx, element->GetWrapper());
|
||||||
// do some special setup. For non-extended custom elements, this happens
|
if (reflector) {
|
||||||
// when the element is created.
|
Maybe<JSAutoCompartment> ac;
|
||||||
nsContentUtils::SetupCustomElement(element, &elemName);
|
JS::Rooted<JSObject*> prototype(aCx, definition->mPrototype);
|
||||||
|
if (element->NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(prototype))) {
|
||||||
|
ac.emplace(aCx, reflector);
|
||||||
|
if (!JS_WrapObject(aCx, &prototype) ||
|
||||||
|
!JS_SetPrototype(aCx, reflector, prototype)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We want to set the custom prototype in the compartment where it was
|
||||||
|
// registered. We store the prototype from define() without unwrapped,
|
||||||
|
// hence the prototype's compartment is the compartment where it was
|
||||||
|
// registered.
|
||||||
|
// In the case that |reflector| and |prototype| are in different
|
||||||
|
// compartments, this will set the prototype on the |reflector|'s wrapper
|
||||||
|
// and thus only visible in the wrapper's compartment, since we know
|
||||||
|
// reflector's principal does not subsume prototype's in this case.
|
||||||
|
ac.emplace(aCx, prototype);
|
||||||
|
if (!JS_WrapObject(aCx, &reflector) ||
|
||||||
|
!JS_SetPrototype(aCx, reflector, prototype)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap into current context.
|
||||||
|
if (!JS_WrapObject(aCx, &reflector)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.rval().setObject(*reflector);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nsDependentAtomString localName(definition->mLocalName);
|
||||||
|
element =
|
||||||
|
document->CreateElem(localName, nullptr, kNameSpaceID_XHTML,
|
||||||
|
(definition->mLocalName != typeAtom) ? &elemName
|
||||||
|
: nullptr);
|
||||||
|
NS_ENSURE_TRUE(element, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The prototype setup happens in Element::WrapObject().
|
||||||
|
|
||||||
nsresult rv = nsContentUtils::WrapNative(aCx, element, element, args.rval());
|
nsresult rv = nsContentUtils::WrapNative(aCx, element, element, args.rval());
|
||||||
NS_ENSURE_SUCCESS(rv, true);
|
NS_ENSURE_SUCCESS(rv, true);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue