From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- dom/base/nsIContentInlines.h | 254 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 dom/base/nsIContentInlines.h (limited to 'dom/base/nsIContentInlines.h') diff --git a/dom/base/nsIContentInlines.h b/dom/base/nsIContentInlines.h new file mode 100644 index 0000000000..89cc7b9c30 --- /dev/null +++ b/dom/base/nsIContentInlines.h @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsIContentInlines_h +#define nsIContentInlines_h + +#include "nsIContent.h" +#include "mozilla/dom/Document.h" +#include "nsContentUtils.h" +#include "nsAtom.h" +#include "nsIFrame.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/HTMLSlotElement.h" +#include "mozilla/dom/ShadowRoot.h" + +inline bool nsIContent::IsInHTMLDocument() const { + return OwnerDoc()->IsHTMLDocument(); +} + +inline bool nsIContent::IsInChromeDocument() const { + return nsContentUtils::IsChromeDoc(OwnerDoc()); +} + +inline void nsIContent::SetPrimaryFrame(nsIFrame* aFrame) { + MOZ_ASSERT(IsInUncomposedDoc() || IsInShadowTree(), "This will end badly!"); + + // is known to trigger this, see bug 749326 and bug 135040. + MOZ_ASSERT(IsHTMLElement(nsGkAtoms::area) || !aFrame || !mPrimaryFrame || + aFrame == mPrimaryFrame, + "Losing track of existing primary frame"); + + if (aFrame) { + MOZ_ASSERT(!aFrame->IsPlaceholderFrame()); + if (MOZ_LIKELY(!IsHTMLElement(nsGkAtoms::area)) || + aFrame->GetContent() == this) { + aFrame->SetIsPrimaryFrame(true); + } + } else if (nsIFrame* currentPrimaryFrame = GetPrimaryFrame()) { + if (MOZ_LIKELY(!IsHTMLElement(nsGkAtoms::area)) || + currentPrimaryFrame->GetContent() == this) { + currentPrimaryFrame->SetIsPrimaryFrame(false); + } + } + + mPrimaryFrame = aFrame; +} + +inline mozilla::dom::ShadowRoot* nsIContent::GetShadowRoot() const { + if (!IsElement()) { + return nullptr; + } + + return AsElement()->GetShadowRoot(); +} + +template +static inline nsINode* GetFlattenedTreeParentNode(const nsINode* aNode) { + if (!aNode->IsContent()) { + return nullptr; + } + + nsINode* parent = aNode->GetParentNode(); + if (!parent || !parent->IsContent()) { + return parent; + } + + const nsIContent* content = aNode->AsContent(); + nsIContent* parentAsContent = parent->AsContent(); + + if (aType == nsINode::eForStyle && + content->IsRootOfNativeAnonymousSubtree() && + parentAsContent == content->OwnerDoc()->GetRootElement()) { + const bool docLevel = + content->GetProperty(nsGkAtoms::docLevelNativeAnonymousContent); + return docLevel ? content->OwnerDocAsNode() : parent; + } + + if (content->IsRootOfNativeAnonymousSubtree()) { + return parent; + } + + if (parentAsContent->GetShadowRoot()) { + // If it's not assigned to any slot it's not part of the flat tree, and thus + // we return null. + return content->GetAssignedSlot(); + } + + if (parentAsContent->IsInShadowTree()) { + if (auto* slot = mozilla::dom::HTMLSlotElement::FromNode(parentAsContent)) { + // If the assigned nodes list is empty, we're fallback content which is + // active, otherwise we are not part of the flat tree. + return slot->AssignedNodes().IsEmpty() ? parent : nullptr; + } + + if (auto* shadowRoot = + mozilla::dom::ShadowRoot::FromNode(parentAsContent)) { + return shadowRoot->GetHost(); + } + } + + // Common case. + return parent; +} + +inline nsINode* nsINode::GetFlattenedTreeParentNode() const { + return ::GetFlattenedTreeParentNode(this); +} + +inline nsIContent* nsIContent::GetFlattenedTreeParent() const { + nsINode* parent = GetFlattenedTreeParentNode(); + return (parent && parent->IsContent()) ? parent->AsContent() : nullptr; +} + +inline bool nsIContent::IsEventAttributeName(nsAtom* aName) { + const char16_t* name = aName->GetUTF16String(); + if (name[0] != 'o' || name[1] != 'n') { + return false; + } + + return IsEventAttributeNameInternal(aName); +} + +inline nsINode* nsINode::GetFlattenedTreeParentNodeForStyle() const { + return ::GetFlattenedTreeParentNode(this); +} + +inline bool nsINode::NodeOrAncestorHasDirAuto() const { + return AncestorHasDirAuto() || (IsElement() && AsElement()->HasDirAuto()); +} + +inline bool nsINode::IsEditable() const { + if (HasFlag(NODE_IS_EDITABLE)) { + // The node is in an editable contentEditable subtree. + return true; + } + + // All editable anonymous content should be made explicitly editable via the + // NODE_IS_EDITABLE flag. + if (IsInNativeAnonymousSubtree()) { + return false; + } + + // Check if the node is in a document and the document is in designMode. + return IsInDesignMode(); +} + +inline bool nsINode::IsEditingHost() const { + if (!IsInComposedDoc() || IsInDesignMode() || !IsEditable() || + IsInNativeAnonymousSubtree()) { + return false; + } + nsIContent* const parent = GetParent(); + return !parent || // The root element (IsInComposedDoc() is checked above) + !parent->IsEditable(); // or an editable node in a non-editable one +} + +inline bool nsINode::IsInDesignMode() const { + if (!OwnerDoc()->HasFlag(NODE_IS_EDITABLE)) { + return false; + } + + if (IsDocument()) { + return HasFlag(NODE_IS_EDITABLE); + } + + // NOTE(emilio): If you change this to be the composed doc you also need to + // change NotifyEditableStateChange() in Document.cpp. + // NOTE(masayuki): Perhaps, we should keep this behavior because of + // web-compat. + if (IsInUncomposedDoc() && GetUncomposedDoc()->HasFlag(NODE_IS_EDITABLE)) { + return true; + } + + // FYI: In design mode, form controls don't work as usual. For example, + // isn't focusable but can be deleted and replaced + // with typed text.