mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-22 23:27:30 +09:00
Bug 1466991 - Part 2: Reparent nodes when they start being in the XBL scope.
This commit is contained in:
parent
34f16bf61c
commit
2f2751e46c
1 changed files with 49 additions and 0 deletions
|
|
@ -27,6 +27,7 @@
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/Event.h"
|
#include "mozilla/dom/Event.h"
|
||||||
#include "mozilla/dom/ShadowRoot.h"
|
#include "mozilla/dom/ShadowRoot.h"
|
||||||
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
#include "nsAttrValueOrString.h"
|
#include "nsAttrValueOrString.h"
|
||||||
#include "nsBindingManager.h"
|
#include "nsBindingManager.h"
|
||||||
#include "nsCCUncollectableMarker.h"
|
#include "nsCCUncollectableMarker.h"
|
||||||
|
|
@ -1569,6 +1570,48 @@ CheckForOutdatedParent(nsINode* aParent, nsINode* aNode)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
ReparentWrappersInSubtree(nsIContent* aRoot)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(ShouldUseXBLScope(aRoot));
|
||||||
|
// Start off with no global so we don't fire any error events on failure.
|
||||||
|
AutoJSAPI jsapi;
|
||||||
|
jsapi.Init();
|
||||||
|
|
||||||
|
JSContext* cx = jsapi.cx();
|
||||||
|
|
||||||
|
nsIGlobalObject* docGlobal = aRoot->OwnerDoc()->GetScopeObject();
|
||||||
|
if (NS_WARN_IF(!docGlobal)) {
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::Rooted<JSObject*> rootedGlobal(cx, docGlobal->GetGlobalJSObject());
|
||||||
|
if (NS_WARN_IF(!rootedGlobal)) {
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
rootedGlobal = xpc::GetXBLScope(cx, rootedGlobal);
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
JS::Rooted<JSObject*> reflector(cx);
|
||||||
|
for (nsIContent* cur = aRoot; cur; cur = cur->GetNextNode(aRoot)) {
|
||||||
|
if ((reflector = cur->GetWrapper())) {
|
||||||
|
JSAutoCompartment ac(cx, reflector);
|
||||||
|
rv = ReparentWrapper(cx, reflector);
|
||||||
|
if NS_FAILED(rv) {
|
||||||
|
// We _could_ consider BlastSubtreeToPieces here, but it's not really
|
||||||
|
// needed. Having some nodes in here accessible to content while others
|
||||||
|
// are not is probably OK. We just need to fail out of the actual
|
||||||
|
// insertion, so they're not in the DOM. Returning a failure here will
|
||||||
|
// do that.
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
|
nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
|
||||||
bool aNotify, nsAttrAndChildArray& aChildArray)
|
bool aNotify, nsAttrAndChildArray& aChildArray)
|
||||||
|
|
@ -1606,9 +1649,15 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
|
||||||
nsIContent* parent =
|
nsIContent* parent =
|
||||||
IsNodeOfType(eDOCUMENT) ? nullptr : static_cast<nsIContent*>(this);
|
IsNodeOfType(eDOCUMENT) ? nullptr : static_cast<nsIContent*>(this);
|
||||||
|
|
||||||
|
bool wasInXBLScope = ShouldUseXBLScope(aKid);
|
||||||
rv = aKid->BindToTree(doc, parent,
|
rv = aKid->BindToTree(doc, parent,
|
||||||
parent ? parent->GetBindingParent() : nullptr,
|
parent ? parent->GetBindingParent() : nullptr,
|
||||||
true);
|
true);
|
||||||
|
if (NS_SUCCEEDED(rv) && !wasInXBLScope && ShouldUseXBLScope(aKid)) {
|
||||||
|
MOZ_ASSERT(ShouldUseXBLScope(this),
|
||||||
|
"Why does the kid need to use an XBL scope?");
|
||||||
|
rv = ReparentWrappersInSubtree(aKid);
|
||||||
|
}
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
if (GetFirstChild() == aKid) {
|
if (GetFirstChild() == aKid) {
|
||||||
mFirstChild = aKid->GetNextSibling();
|
mFirstChild = aKid->GetNextSibling();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue