Bug 1596445 - Add some supporting code to nsINode to deal with NAC and shadow DOM separately. r=bzbarsky

We'll use these to remove GetBindingParent.

Differential Revision: https://phabricator.services.mozilla.com/D53029

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-11-15 15:10:45 +00:00
parent 6ed954d4c7
commit f36874d798
6 changed files with 69 additions and 37 deletions

View File

@ -1056,13 +1056,6 @@ bool FragmentOrElement::IsLink(nsIURI** aURI) const {
return false;
}
nsIContent* nsIContent::GetContainingShadowHost() const {
if (mozilla::dom::ShadowRoot* shadow = GetContainingShadow()) {
return shadow->GetHost();
}
return nullptr;
}
void nsIContent::SetAssignedSlot(HTMLSlotElement* aSlot) {
MOZ_ASSERT(aSlot || GetExistingExtendedContentSlots());
ExtendedContentSlots()->mAssignedSlot = aSlot;

View File

@ -395,8 +395,6 @@ class nsIContent : public nsINode {
/**
* Gets the root of the node tree for this content if it is in a shadow tree.
* This method is called |GetContainingShadow| instead of |GetRootShadowRoot|
* to avoid confusion with |GetShadowRoot|.
*
* @return The ShadowRoot that is the root of the node tree.
*/
@ -405,14 +403,6 @@ class nsIContent : public nsINode {
return slots ? slots->mContainingShadow.get() : nullptr;
}
/**
* Gets the shadow host if this content is in a shadow tree. That is, the host
* of |GetContainingShadow|, if its not null.
*
* @return The shadow host, if this is in shadow tree, or null.
*/
nsIContent* GetContainingShadowHost() const;
/**
* Gets the assigned slot associated with this content.
*

View File

@ -580,9 +580,23 @@ std::ostream& operator<<(std::ostream& aStream, const nsINode& aNode) {
return aStream << str.get();
}
ShadowRoot* nsINode::GetContainingShadow() const {
if (!IsInShadowTree()) {
return nullptr;
}
return AsContent()->GetContainingShadow();
}
nsIContent* nsINode::GetContainingShadowHost() const {
if (ShadowRoot* shadow = GetContainingShadow()) {
return shadow->GetHost();
}
return nullptr;
}
SVGUseElement* nsINode::DoGetContainingSVGUseShadowHost() const {
MOZ_ASSERT(IsInShadowTree());
return SVGUseElement::FromNodeOrNull(AsContent()->GetContainingShadowHost());
return SVGUseElement::FromNodeOrNull(GetContainingShadowHost());
}
void nsINode::GetNodeValueInternal(nsAString& aNodeValue) {

View File

@ -91,6 +91,7 @@ class Optional;
class OwningNodeOrString;
template <typename>
class Sequence;
class ShadowRoot;
class SVGUseElement;
class Text;
class TextOrElementOrDocument;
@ -1260,10 +1261,58 @@ class nsINode : public mozilla::dom::EventTarget {
* TODO(emilio):: Remove this function, and use just
* IsInNativeAnonymousSubtree, or something?
*/
bool IsInAnonymousSubtree() const {
return IsInNativeAnonymousSubtree();
bool IsInAnonymousSubtree() const { return IsInNativeAnonymousSubtree(); }
/**
* If |this| or any ancestor is native anonymous, return the root of the
* native anonymous subtree. Note that in case of nested native anonymous
* content, this returns the innermost root, not the outermost.
*/
nsIContent* GetClosestNativeAnonymousSubtreeRoot() const {
if (!IsInNativeAnonymousSubtree()) {
return nullptr;
}
MOZ_ASSERT(IsContent(), "How did non-content end up in NAC?");
for (const nsINode* node = this; node; node = node->GetParentNode()) {
if (node->IsRootOfNativeAnonymousSubtree()) {
return const_cast<nsINode*>(node)->AsContent();
}
}
// FIXME(emilio): This should not happen, usually, but editor removes nodes
// in native anonymous subtrees, and we don't clean nodes from the current
// event content stack from ContentRemoved, so it can actually happen, see
// bug 1510208.
NS_WARNING("GetClosestNativeAnonymousSubtreeRoot on disconnected NAC!");
return nullptr;
}
/**
* If |this| or any ancestor is native anonymous, return the parent of the
* native anonymous subtree. Note that in case of nested native anonymous
* content, this returns the parent of the innermost root, not the outermost.
*/
nsIContent* GetClosestNativeAnonymousSubtreeRootParent() const {
const nsIContent* root = GetClosestNativeAnonymousSubtreeRoot();
if (!root) {
return nullptr;
}
// We could put this in nsIContentInlines.h or such to avoid this
// reinterpret_cast, but it doesn't seem worth it.
return reinterpret_cast<const nsINode*>(root)->GetParent();
}
/**
* Gets the root of the node tree for this content if it is in a shadow tree.
*/
mozilla::dom::ShadowRoot* GetContainingShadow() const;
/**
* Gets the shadow host if this content is in a shadow tree. That is, the host
* of |GetContainingShadow|, if its not null.
*
* @return The shadow host, if this is in shadow tree, or null.
*/
nsIContent* GetContainingShadowHost() const;
bool IsInSVGUseShadowTree() const {
return !!GetContainingSVGUseShadowHost();
}

View File

@ -2007,18 +2007,10 @@ void PresShell::FireResizeEvent() {
}
static nsIContent* GetNativeAnonymousSubtreeRoot(nsIContent* aContent) {
if (!aContent || !aContent->IsInNativeAnonymousSubtree()) {
if (!aContent) {
return nullptr;
}
auto* current = aContent;
// FIXME(emilio): This should not need to worry about current being null, but
// editor removes nodes in native anonymous subtrees, and we don't clean nodes
// from the current event content stack from ContentRemoved, so it can
// actually happen, see bug 1510208.
while (current && !current->IsRootOfNativeAnonymousSubtree()) {
current = current->GetFlattenedTreeParent();
}
return current;
return aContent->GetClosestNativeAnonymousSubtreeRoot();
}
void PresShell::NativeAnonymousContentRemoved(nsIContent* aAnonContent) {

View File

@ -73,13 +73,7 @@ nsFind::~nsFind() = default;
static nsIContent& AnonymousSubtreeRootParent(const nsINode& aNode) {
MOZ_ASSERT(aNode.IsInNativeAnonymousSubtree());
nsIContent* current = aNode.GetParent();
while (current->IsInNativeAnonymousSubtree()) {
current = current->GetParent();
MOZ_ASSERT(current, "huh?");
}
return *current;
return *aNode.GetClosestNativeAnonymousSubtreeRootParent();
}
static void DumpNode(const nsINode* aNode) {