mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 1406325 - Part 5: Implement try to upgrade. f=echen, r=smaug
This commit is contained in:
parent
d1400ac8b1
commit
a710f595fa
@ -324,6 +324,24 @@ CustomElementRegistry::RegisterUnresolvedElement(Element* aElement, nsAtom* aTyp
|
||||
aElement->AddStates(NS_EVENT_STATE_UNRESOLVED);
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementRegistry::UnregisterUnresolvedElement(Element* aElement,
|
||||
nsAtom* aTypeName)
|
||||
{
|
||||
nsTArray<nsWeakPtr>* candidates;
|
||||
if (mCandidatesMap.Get(aTypeName, &candidates)) {
|
||||
MOZ_ASSERT(candidates);
|
||||
// We don't need to iterate the candidates array and remove the element from
|
||||
// the array for performance reason. It'll be handled by bug 1396620.
|
||||
for (size_t i = 0; i < candidates->Length(); ++i) {
|
||||
nsCOMPtr<Element> elem = do_QueryReferent(candidates->ElementAt(i));
|
||||
if (elem && elem.get() == aElement) {
|
||||
candidates->RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ UniquePtr<CustomElementCallback>
|
||||
CustomElementRegistry::CreateCustomElementCallback(
|
||||
nsIDocument::ElementCallbackType aType, Element* aCustomElement,
|
||||
|
@ -396,15 +396,6 @@ public:
|
||||
*/
|
||||
static void Upgrade(Element* aElement, CustomElementDefinition* aDefinition, ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
~CustomElementRegistry();
|
||||
|
||||
static UniquePtr<CustomElementCallback> CreateCustomElementCallback(
|
||||
nsIDocument::ElementCallbackType aType, Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
/**
|
||||
* Registers an unresolved custom element that is a candidate for
|
||||
* upgrade when the definition is registered via registerElement.
|
||||
@ -416,6 +407,21 @@ private:
|
||||
void RegisterUnresolvedElement(Element* aElement,
|
||||
nsAtom* aTypeName = nullptr);
|
||||
|
||||
/**
|
||||
* Unregister an unresolved custom element that is a candidate for
|
||||
* upgrade when a custom element is removed from tree.
|
||||
*/
|
||||
void UnregisterUnresolvedElement(Element* aElement,
|
||||
nsAtom* aTypeName = nullptr);
|
||||
private:
|
||||
~CustomElementRegistry();
|
||||
|
||||
static UniquePtr<CustomElementCallback> CreateCustomElementCallback(
|
||||
nsIDocument::ElementCallbackType aType, Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
void UpgradeCandidates(nsAtom* aKey,
|
||||
CustomElementDefinition* aDefinition,
|
||||
ErrorResult& aRv);
|
||||
|
@ -1759,8 +1759,13 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
// Connected callback must be enqueued whenever a custom element becomes
|
||||
// connected.
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
if (data && data->mState == CustomElementData::State::eCustom) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eConnected, this);
|
||||
if (data) {
|
||||
if (data->mState == CustomElementData::State::eCustom) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eConnected, this);
|
||||
} else {
|
||||
// Step 7.7.2.2 https://dom.spec.whatwg.org/#concept-node-insert
|
||||
nsContentUtils::TryToUpgradeElement(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2088,9 +2093,16 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
// disconnected.
|
||||
if (CustomElementRegistry::IsCustomElementEnabled()) {
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
if (data && data->mState == CustomElementData::State::eCustom) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDisconnected,
|
||||
this);
|
||||
if (data) {
|
||||
if (data->mState == CustomElementData::State::eCustom) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDisconnected,
|
||||
this);
|
||||
} else {
|
||||
// Remove an unresolved custom element that is a candidate for
|
||||
// upgrade when a custom element is disconnected.
|
||||
// We will make sure it's shadow-including tree order in bug 1326028.
|
||||
nsContentUtils::UnregisterUnresolvedElement(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -240,6 +240,7 @@ extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end,
|
||||
int ns_aware, const char** colon);
|
||||
|
||||
class imgLoader;
|
||||
class nsAtom;
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::ipc;
|
||||
@ -10119,6 +10120,27 @@ nsContentUtils::HttpsStateIsModern(nsIDocument* aDocument)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::TryToUpgradeElement(Element* aElement)
|
||||
{
|
||||
NodeInfo* nodeInfo = aElement->NodeInfo();
|
||||
RefPtr<nsAtom> typeAtom =
|
||||
aElement->GetCustomElementData()->GetCustomElementType();
|
||||
CustomElementDefinition* definition =
|
||||
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
|
||||
nodeInfo->LocalName(),
|
||||
nodeInfo->NamespaceID(),
|
||||
typeAtom);
|
||||
if (definition) {
|
||||
nsContentUtils::EnqueueUpgradeReaction(aElement, definition);
|
||||
} else {
|
||||
// Add an unresolved custom element that is a candidate for
|
||||
// upgrade when a custom element is connected to the document.
|
||||
// We will make sure it's shadow-including tree order in bug 1326028.
|
||||
nsContentUtils::RegisterUnresolvedElement(aElement, typeAtom);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ CustomElementDefinition*
|
||||
nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
const nsAString& aLocalName,
|
||||
@ -10145,6 +10167,46 @@ nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
return registry->LookupCustomElementDefinition(aLocalName, aTypeAtom);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::RegisterUnresolvedElement(Element* aElement, nsAtom* aTypeName)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
nsPIDOMWindowInner* window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
return;
|
||||
}
|
||||
|
||||
registry->RegisterUnresolvedElement(aElement, aTypeName);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::UnregisterUnresolvedElement(Element* aElement)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
RefPtr<nsAtom> typeAtom =
|
||||
aElement->GetCustomElementData()->GetCustomElementType();
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
nsPIDOMWindowInner* window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
return;
|
||||
}
|
||||
|
||||
registry->UnregisterUnresolvedElement(aElement, typeAtom);
|
||||
}
|
||||
|
||||
/* static */ CustomElementDefinition*
|
||||
nsContentUtils::GetElementDefinitionIfObservingAttr(Element* aCustomElement,
|
||||
nsAtom* aExtensionType,
|
||||
|
@ -3029,6 +3029,12 @@ public:
|
||||
*/
|
||||
static bool HttpsStateIsModern(nsIDocument* aDocument);
|
||||
|
||||
/**
|
||||
* Try to upgrade an element.
|
||||
* https://html.spec.whatwg.org/multipage/custom-elements.html#concept-try-upgrade
|
||||
*/
|
||||
static void TryToUpgradeElement(Element* aElement);
|
||||
|
||||
/**
|
||||
* Looking up a custom element definition.
|
||||
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
||||
@ -3039,6 +3045,8 @@ public:
|
||||
uint32_t aNameSpaceID,
|
||||
nsAtom* aTypeAtom);
|
||||
|
||||
static void RegisterUnresolvedElement(Element* aElement, nsAtom* aTypeName);
|
||||
static void UnregisterUnresolvedElement(Element* aElement);
|
||||
|
||||
static mozilla::dom::CustomElementDefinition*
|
||||
GetElementDefinitionIfObservingAttr(Element* aCustomElement,
|
||||
|
@ -8,6 +8,7 @@ function test_upgrade(f, msg) {
|
||||
// Run upgrading test on an element created by document.createElement.
|
||||
test_with_new_window(function(testWindow, testMsg) {
|
||||
let element = testWindow.document.createElement('unresolved-element');
|
||||
testWindow.document.documentElement.appendChild(element);
|
||||
f(testWindow, element, testMsg);
|
||||
}, msg + ' (document.createElement)');
|
||||
}
|
||||
@ -21,6 +22,14 @@ test_upgrade(function(testWindow, testElement, msg) {
|
||||
MyCustomElement.prototype, msg);
|
||||
}, 'Custom element must be upgraded if there is a matching definition');
|
||||
|
||||
test_upgrade(function(testWindow, testElement, msg) {
|
||||
testElement.remove();
|
||||
class MyCustomElement extends testWindow.HTMLElement {};
|
||||
testWindow.customElements.define('unresolved-element', MyCustomElement);
|
||||
SimpleTest.is(Object.getPrototypeOf(testElement),
|
||||
testWindow.HTMLElement.prototype, msg);
|
||||
}, 'Custom element must not be upgraded if it has been removed from tree');
|
||||
|
||||
test_upgrade(function(testWindow, testElement, msg) {
|
||||
let exceptionToThrow = {name: 'exception thrown by a custom constructor'};
|
||||
class ThrowCustomElement extends testWindow.HTMLElement {
|
||||
|
@ -1,5 +0,0 @@
|
||||
[HTMLOptionElement.html]
|
||||
type: testharness
|
||||
[text on HTMLOptionElement must enqueue disconnectedCallback when removing a custom element]
|
||||
expected: FAIL
|
||||
|
@ -1,20 +0,0 @@
|
||||
[upgrading.html]
|
||||
type: testharness
|
||||
[Creating an element in the document of the template elements and adopting back to a document with browsing context must enqueue a custom element upgrade reaction]
|
||||
expected: FAIL
|
||||
|
||||
[Creating an element in a cloned document and adopting back to a document with browsing context must enqueue a custom element upgrade reaction]
|
||||
expected: FAIL
|
||||
|
||||
[Creating an element in a document created by createHTMLDocument and adopting back to a document with browsing context must enqueue a custom element upgrade reaction]
|
||||
expected: FAIL
|
||||
|
||||
[Creating an element in an HTML document created by createDocument and adopting back to a document with browsing context must enqueue a custom element upgrade reaction]
|
||||
expected: FAIL
|
||||
|
||||
["define" in the document of an iframe must not enqueue a custom element upgrade reaction on a disconnected unresolved custom element]
|
||||
expected: FAIL
|
||||
|
||||
[Adopting and inserting an unresolved custom element into the document of an iframe must enqueue a custom element upgrade reaction]
|
||||
expected: FAIL
|
||||
|
Loading…
Reference in New Issue
Block a user