Bug 1555944 - Make nsIContent::GetBindingParent return an element. r=bzbarsky

Differential Revision: https://phabricator.services.mozilla.com/D33308
This commit is contained in:
Emilio Cobos Álvarez 2019-05-31 18:13:49 +02:00
Родитель 6ada67c323
Коммит 80e62fe4db
6 изменённых файлов: 40 добавлений и 35 удалений

Просмотреть файл

@ -33,15 +33,11 @@ struct MOZ_STACK_CLASS BindContext final {
Element* GetBindingParent() const { return mBindingParent; } Element* GetBindingParent() const { return mBindingParent; }
// This constructor should be used for regular appends to content. // This constructor should be used for regular appends to content.
//
// FIXME(emilio, bug 1555944): nsIContent::GetBindingParent() should return an
// Element*.
explicit BindContext(nsINode& aParentNode) explicit BindContext(nsINode& aParentNode)
: mDoc(*aParentNode.OwnerDoc()), : mDoc(*aParentNode.OwnerDoc()),
mSubtreeRootChanges(true), mSubtreeRootChanges(true),
mBindingParent(aParentNode.IsContent() mBindingParent(aParentNode.IsContent()
? static_cast<Element*>( ? aParentNode.AsContent()->GetBindingParent()
aParentNode.AsContent()->GetBindingParent())
: nullptr) {} : nullptr) {}
// When re-binding a shadow host into a tree, we re-bind all the shadow tree // When re-binding a shadow host into a tree, we re-bind all the shadow tree

Просмотреть файл

@ -1123,6 +1123,28 @@ void nsIContent::SetXBLInsertionPoint(nsIContent* aContent) {
} }
} }
#ifdef DEBUG
void nsIContent::AssertAnonymousSubtreeRelatedInvariants() const {
NS_ASSERTION(!IsRootOfNativeAnonymousSubtree() ||
(GetParent() && GetBindingParent() == GetParent()),
"root of native anonymous subtree must have parent equal "
"to binding parent");
NS_ASSERTION(!GetParent() ||
((GetBindingParent() == GetParent()) ==
HasFlag(NODE_IS_ANONYMOUS_ROOT)) ||
// Unfortunately default content for XBL insertion points
// is anonymous content that is bound with the parent of
// the insertion point as the parent but the bound element
// for the binding as the binding parent. So we have to
// complicate the assert a bit here.
(GetBindingParent() &&
(GetBindingParent() == GetParent()->GetBindingParent()) ==
HasFlag(NODE_IS_ANONYMOUS_ROOT)),
"For nodes with parent, flag and GetBindingParent() check "
"should match");
}
#endif
void FragmentOrElement::GetTextContentInternal(nsAString& aTextContent, void FragmentOrElement::GetTextContentInternal(nsAString& aTextContent,
OOMReporter& aError) { OOMReporter& aError) {
if (!nsContentUtils::GetNodeTextContent(this, true, aTextContent, fallible)) { if (!nsContentUtils::GetNodeTextContent(this, true, aTextContent, fallible)) {

Просмотреть файл

@ -186,28 +186,18 @@ class nsIContent : public nsINode {
*/ */
nsIContent* FindFirstNonChromeOnlyAccessContent() const; nsIContent* FindFirstNonChromeOnlyAccessContent() const;
#ifdef DEBUG
void AssertAnonymousSubtreeRelatedInvariants() const;
#endif
/** /**
* Returns true if and only if this node has a parent, but is not in * Returns true if and only if this node has a parent, but is not in
* its parent's child list. * its parent's child list.
*/ */
bool IsRootOfAnonymousSubtree() const { bool IsRootOfAnonymousSubtree() const {
NS_ASSERTION(!IsRootOfNativeAnonymousSubtree() || #ifdef DEBUG
(GetParent() && GetBindingParent() == GetParent()), AssertAnonymousSubtreeRelatedInvariants();
"root of native anonymous subtree must have parent equal " #endif
"to binding parent");
NS_ASSERTION(!GetParent() ||
((GetBindingParent() == GetParent()) ==
HasFlag(NODE_IS_ANONYMOUS_ROOT)) ||
// Unfortunately default content for XBL insertion points
// is anonymous content that is bound with the parent of
// the insertion point as the parent but the bound element
// for the binding as the binding parent. So we have to
// complicate the assert a bit here.
(GetBindingParent() &&
(GetBindingParent() == GetParent()->GetBindingParent()) ==
HasFlag(NODE_IS_ANONYMOUS_ROOT)),
"For nodes with parent, flag and GetBindingParent() check "
"should match");
return HasFlag(NODE_IS_ANONYMOUS_ROOT); return HasFlag(NODE_IS_ANONYMOUS_ROOT);
} }
@ -401,7 +391,7 @@ class nsIContent : public nsINode {
* *
* @return the binding parent * @return the binding parent
*/ */
virtual nsIContent* GetBindingParent() const { virtual mozilla::dom::Element* GetBindingParent() const {
const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots(); const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
return slots ? slots->mBindingParent.get() : nullptr; return slots ? slots->mBindingParent.get() : nullptr;
} }
@ -735,11 +725,10 @@ class nsIContent : public nsINode {
/** /**
* The nearest enclosing content node with a binding that created us. * The nearest enclosing content node with a binding that created us.
* TODO(emilio): This should be an Element*.
* *
* @see nsIContent::GetBindingParent * @see nsIContent::GetBindingParent
*/ */
nsCOMPtr<nsIContent> mBindingParent; RefPtr<mozilla::dom::Element> mBindingParent;
/** /**
* @see nsIContent::GetXBLInsertionPoint * @see nsIContent::GetXBLInsertionPoint

Просмотреть файл

@ -349,7 +349,7 @@ class nsXULElement : public nsStyledElement {
bool aIsTrustedEvent) override; bool aIsTrustedEvent) override;
void ClickWithInputSource(uint16_t aInputSource, bool aIsTrustedEvent); void ClickWithInputSource(uint16_t aInputSource, bool aIsTrustedEvent);
nsIContent* GetBindingParent() const final { return mBindingParent; } Element* GetBindingParent() const final { return mBindingParent; }
virtual bool IsNodeOfType(uint32_t aFlags) const override; virtual bool IsNodeOfType(uint32_t aFlags) const override;
virtual bool IsFocusableInternal(int32_t* aTabIndex, virtual bool IsFocusableInternal(int32_t* aTabIndex,
@ -368,7 +368,7 @@ class nsXULElement : public nsStyledElement {
// This function should ONLY be used by BindToTree implementations. // This function should ONLY be used by BindToTree implementations.
// The function exists solely because XUL elements store the binding // The function exists solely because XUL elements store the binding
// parent as a member instead of in the slots, as Element does. // parent as a member instead of in the slots, as Element does.
void SetXULBindingParent(nsIContent* aBindingParent) { void SetXULBindingParent(Element* aBindingParent) {
mBindingParent = aBindingParent; mBindingParent = aBindingParent;
} }
@ -541,7 +541,7 @@ class nsXULElement : public nsStyledElement {
* The nearest enclosing content node with a binding * The nearest enclosing content node with a binding
* that created us. * that created us.
*/ */
nsCOMPtr<nsIContent> mBindingParent; RefPtr<Element> mBindingParent;
/** /**
* Abandon our prototype linkage, and copy all attributes locally * Abandon our prototype linkage, and copy all attributes locally

Просмотреть файл

@ -1722,8 +1722,7 @@ FontSizePrefs Gecko_GetBaseSize(nsAtom* aLanguage) {
} }
const Element* Gecko_GetBindingParent(const Element* aElement) { const Element* Gecko_GetBindingParent(const Element* aElement) {
nsIContent* parent = aElement->GetBindingParent(); return aElement->GetBindingParent();
return parent ? parent->AsElement() : nullptr;
} }
static StaticRefPtr<UACacheReporter> gUACacheReporter; static StaticRefPtr<UACacheReporter> gUACacheReporter;

Просмотреть файл

@ -704,9 +704,8 @@ impl<'le> GeckoElement<'le> {
.map(GeckoElement) .map(GeckoElement)
} }
} else { } else {
let binding_parent = unsafe { self.non_xul_xbl_binding_parent_raw_content().as_ref() } let binding_parent = unsafe { self.non_xul_xbl_binding_parent().as_ref() }
.map(GeckoNode::from_content) .map(GeckoElement);
.and_then(|n| n.as_element());
debug_assert!( debug_assert!(
binding_parent == binding_parent ==
@ -721,10 +720,10 @@ impl<'le> GeckoElement<'le> {
} }
#[inline] #[inline]
fn non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent { fn non_xul_xbl_binding_parent(&self) -> *mut RawGeckoElement {
debug_assert!(!self.is_xul_element()); debug_assert!(!self.is_xul_element());
self.extended_slots().map_or(ptr::null_mut(), |slots| { self.extended_slots().map_or(ptr::null_mut(), |slots| {
slots._base.mBindingParent.raw::<nsIContent>() slots._base.mBindingParent.mRawPtr
}) })
} }