зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1505875 - Clear out the ShadowRoot host pointer when unattaching it. r=smaug
As expected, this is specific to the UA widget stuff. What's going on here is that given we don't clear out the host when unattaching the shadow tree, mutating that shadow tree still notifies all the way up to the document, and that gets all the other code confused, thinking that the node is connected. Indeed, the first assertion that fails when loading that test-case in a debug build is: https://searchfox.org/mozilla-central/rev/17f55aee76b7c4610a974cffd3453454e0c8de7b/dom/base/nsNodeUtils.cpp#93 This seems the best fix to avoid confusion. Also clear the mutation observer, to completely forget about the host. Chrome code dealing with UA widgets needs to be careful, but I think this is safe. All the code that assumes that GetHost() doesn't return null is in code dealing with connected shadow trees only (style system / layout), or in mutation observer notifications from the host. Differential Revision: https://phabricator.services.mozilla.com/D11369 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
25ac4aee06
Коммит
80bd2cd013
|
@ -1329,25 +1329,24 @@ Element::AttachShadowWithoutNameChecks(ShadowRootMode aMode)
|
|||
void
|
||||
Element::UnattachShadow()
|
||||
{
|
||||
RefPtr<ShadowRoot> shadowRoot = GetShadowRoot();
|
||||
ShadowRoot* shadowRoot = GetShadowRoot();
|
||||
if (!shadowRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
if (doc) {
|
||||
if (nsIDocument* doc = GetComposedDoc()) {
|
||||
if (nsIPresShell* shell = doc->GetShell()) {
|
||||
shell->DestroyFramesForAndRestyle(this);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(!GetPrimaryFrame());
|
||||
|
||||
// Simply unhook the shadow root from the element.
|
||||
MOZ_ASSERT(!shadowRoot->HasSlots(), "Won't work when shadow root has slots!");
|
||||
shadowRoot->Unbind();
|
||||
shadowRoot->Unattach();
|
||||
SetShadowRoot(nullptr);
|
||||
|
||||
// Beware shadowRoot could be dead after this call.
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -178,6 +178,17 @@ ShadowRoot::Unbind()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::Unattach()
|
||||
{
|
||||
MOZ_ASSERT(!HasSlots(), "Won't work!");
|
||||
MOZ_ASSERT(IsUAWidget());
|
||||
MOZ_ASSERT(GetHost());
|
||||
Unbind();
|
||||
GetHost()->RemoveMutationObserver(this);
|
||||
SetHost(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::InvalidateStyleAndLayoutOnSubtree(Element* aElement)
|
||||
{
|
||||
|
|
|
@ -98,6 +98,10 @@ public:
|
|||
// being connected.
|
||||
void Unbind();
|
||||
|
||||
// Only intended for UA widgets. Forget our shadow host and unbinds all our
|
||||
// kids.
|
||||
void Unattach();
|
||||
|
||||
// Calls BindToTree on each of our kids, and also maybe flags us as being
|
||||
// connected.
|
||||
nsresult Bind();
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<script>
|
||||
function go() {
|
||||
var r = document.getSelection().getRangeAt(0).cloneRange();
|
||||
a.type = "";
|
||||
r.insertNode(b);
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<input id="a" autofocus type="date">
|
||||
<summary id="b">x</summary>
|
|
@ -245,3 +245,4 @@ load 1445670.html
|
|||
load 1458016.html
|
||||
pref(dom.webcomponents.shadowdom.enabled,true) load 1459688.html
|
||||
load 1460794.html
|
||||
pref(dom.webcomponents.shadowdom.enabled,true) load 1505875.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче