nsresult HTMLSharedElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix, const nsAString& aValue, bool aNotify) { nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue, aNotify); NS_ENSURE_SUCCESS(rv, rv); // If the href attribute of a <base> tag is changing, we may need to update // the document's base URI, which will cause all the links on the page to be // re-resolved given the new base. If the target attribute is changing, we // similarly need to change the base target. if (mNodeInfo->Equals(nsGkAtoms::base) && aNameSpaceID == kNameSpaceID_None && IsInDoc()) { if (aName == nsGkAtoms::href) { SetBaseURIUsingFirstBaseWithHref(GetUncomposedDoc(), this); } else if (aName == nsGkAtoms::target) { SetBaseTargetUsingFirstBaseWithTarget(GetUncomposedDoc(), this); } } return NS_OK; }
nsresult HTMLSharedElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName, const nsAttrValue* aValue, const nsAttrValue* aOldValue, nsIPrincipal* aSubjectPrincipal, bool aNotify) { if (aNamespaceID == kNameSpaceID_None) { if (aName == nsGkAtoms::href) { // If the href attribute of a <base> tag is changing, we may need to // update the document's base URI, which will cause all the links on the // page to be re-resolved given the new base. // If the href is being unset (aValue is null), we will need to find a new // <base>. if (mNodeInfo->Equals(nsGkAtoms::base) && IsInUncomposedDoc()) { SetBaseURIUsingFirstBaseWithHref(GetUncomposedDoc(), aValue ? this : nullptr); } } else if (aName == nsGkAtoms::target) { // The target attribute is in pretty much the same situation as the href // attribute, above. if (mNodeInfo->Equals(nsGkAtoms::base) && IsInUncomposedDoc()) { SetBaseTargetUsingFirstBaseWithTarget(GetUncomposedDoc(), aValue ? this : nullptr); } } } return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify); }
void HTMLMetaElement::UnbindFromTree(bool aDeep, bool aNullParent) { nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc(); CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMMetaRemoved")); nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); }
void HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent) { // Cancel any DNS prefetches // Note: Must come before ResetLinkState. If called after, it will recreate // mCachedURI based on data that is invalid - due to a call to GetHostname. CancelDNSPrefetch(HTML_LINK_DNS_PREFETCH_DEFERRED, HTML_LINK_DNS_PREFETCH_REQUESTED); CancelPrefetchOrPreload(); // Without removing the link state we risk a dangling pointer // in the mStyledLinks hashtable Link::ResetLinkState(false, Link::ElementHasHref()); // If this is reinserted back into the document it will not be // from the parser. Document* oldDoc = GetUncomposedDoc(); ShadowRoot* oldShadowRoot = GetContainingShadow(); // We want to update the localization but only if the // link is removed from a DOM change, and not // because the document is going away. bool ignore; if (oldDoc && oldDoc->GetScriptHandlingObject(ignore) && this->AttrValueIs(kNameSpaceID_None, nsGkAtoms::rel, nsGkAtoms::localization, eIgnoreCase)) { oldDoc->LocalizationLinkRemoved(this); } CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved")); nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); Unused << UpdateStyleSheetInternal(oldDoc, oldShadowRoot); }
void HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent) { // Cancel any DNS prefetches // Note: Must come before ResetLinkState. If called after, it will recreate // mCachedURI based on data that is invalid - due to a call to GetHostname. CancelDNSPrefetch(HTML_LINK_DNS_PREFETCH_DEFERRED, HTML_LINK_DNS_PREFETCH_REQUESTED); // If this link is ever reinserted into a document, it might // be under a different xml:base, so forget the cached state now. Link::ResetLinkState(false, Link::ElementHasHref()); // If this is reinserted back into the document it will not be // from the parser. nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc(); // Check for a ShadowRoot because link elements are inert in a // ShadowRoot. ShadowRoot* oldShadowRoot = GetBindingParent() ? GetBindingParent()->GetShadowRoot() : nullptr; OwnerDoc()->UnregisterPendingLinkUpdate(this); CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved")); nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); UpdateStyleSheetInternal(oldDoc, oldShadowRoot); UpdateImport(); }
nsGenericHTMLElement* HTMLLabelElement::GetLabeledElement() const { nsAutoString elementId; if (!GetAttr(kNameSpaceID_None, nsGkAtoms::_for, elementId)) { // No @for, so we are a label for our first form control element. // Do a depth-first traversal to look for the first form control element. return GetFirstLabelableDescendant(); } // We have a @for. The id has to be linked to an element in the same document // and this element should be a labelable form control. //XXXsmaug It is unclear how this should work in case the element is in // Shadow DOM. // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=26365. nsIDocument* doc = GetUncomposedDoc(); if (!doc) { return nullptr; } Element* element = doc->GetElementById(elementId); if (element && element->IsLabelable()) { return static_cast<nsGenericHTMLElement*>(element); } return nullptr; }
void SVGTitleElement::SendTitleChangeEvent(bool aBound) { nsIDocument* doc = GetUncomposedDoc(); if (doc) { doc->NotifyPossibleTitleChange(aBound); } }
nsresult HTMLSharedElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, bool aNotify) { nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aName, aNotify); NS_ENSURE_SUCCESS(rv, rv); // If we're the first <base> with an href and our href attribute is being // unset, then we're no longer the first <base> with an href, and we need to // find the new one. Similar for target. if (mNodeInfo->Equals(nsGkAtoms::base) && aNameSpaceID == kNameSpaceID_None && IsInDoc()) { if (aName == nsGkAtoms::href) { SetBaseURIUsingFirstBaseWithHref(GetUncomposedDoc(), nullptr); } else if (aName == nsGkAtoms::target) { SetBaseTargetUsingFirstBaseWithTarget(GetUncomposedDoc(), nullptr); } } return NS_OK; }
nsresult HTMLMetaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None) { if (aName == nsGkAtoms::content) { nsIDocument *document = GetUncomposedDoc(); CreateAndDispatchEvent(document, NS_LITERAL_STRING("DOMMetaChanged")); } } return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, aNotify); }
void HTMLLinkElement::UpdateImport() { // 1. link node should be attached to the document. nsCOMPtr<nsIDocument> doc = GetUncomposedDoc(); if (!doc) { // We might have been just removed from the document, so // let's remove ourself from the list of link nodes of // the import and reset mImportLoader. if (mImportLoader) { mImportLoader->RemoveLinkElement(this); mImportLoader = nullptr; } return; } // 2. rel type should be import. nsAutoString rel; GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel); uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal()); if (!(linkTypes & eHTMLIMPORT)) { mImportLoader = nullptr; return; } nsCOMPtr<nsIURI> uri = GetHrefURI(); if (!uri) { mImportLoader = nullptr; return; } if (!nsStyleLinkElement::IsImportEnabled()) { // For now imports are hidden behind a pref... return; } nsRefPtr<ImportManager> manager = doc->ImportManager(); MOZ_ASSERT(manager, "ImportManager should be created lazily when needed"); { // The load even might fire sooner than we could set mImportLoader so // we must use async event and a scriptBlocker here. nsAutoScriptBlocker scriptBlocker; // CORS check will happen at the start of the load. mImportLoader = manager->Get(uri, this, doc); } }
void HTMLStyleElement::UnbindFromTree(bool aDeep, bool aNullParent) { nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc(); ShadowRoot* oldShadow = GetContainingShadow(); nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); if (oldShadow && GetContainingShadow()) { // The style is in a shadow tree and is still in the // shadow tree. Thus the sheets in the shadow DOM // do not need to be updated. return; } UpdateStyleSheetInternal(oldDoc, oldShadow); }
void HTMLSharedElement::UnbindFromTree(bool aDeep, bool aNullParent) { nsIDocument* doc = GetUncomposedDoc(); nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); // If we're removing a <base> from a document, we may need to update the // document's base URI and base target if (doc && mNodeInfo->Equals(nsGkAtoms::base)) { if (HasAttr(kNameSpaceID_None, nsGkAtoms::href)) { SetBaseURIUsingFirstBaseWithHref(doc, nullptr); } if (HasAttr(kNameSpaceID_None, nsGkAtoms::target)) { SetBaseTargetUsingFirstBaseWithTarget(doc, nullptr); } } }
void HTMLStyleElement::UnbindFromTree(bool aDeep, bool aNullParent) { nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc(); nsCOMPtr<nsIDocument> oldComposedDoc = GetComposedDoc(); ShadowRoot* oldShadow = GetContainingShadow(); nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); if (GetContainingShadow() && !oldComposedDoc) { // The style is in a shadow tree and was already not // in the composed document. Thus the sheet does not // need to be updated. return; } UpdateStyleSheetInternal(oldDoc, oldShadow); }
void HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent) { // If this link is ever reinserted into a document, it might // be under a different xml:base, so forget the cached state now. Link::ResetLinkState(false, Link::ElementHasHref()); nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc(); // Check for a ShadowRoot because link elements are inert in a // ShadowRoot. ShadowRoot* oldShadowRoot = GetBindingParent() ? GetBindingParent()->GetShadowRoot() : nullptr; OwnerDoc()->UnregisterPendingLinkUpdate(this); CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved")); nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); UpdateStyleSheetInternal(oldDoc, oldShadowRoot); UpdateImport(); }
nsresult CharacterData::BindToTree(Document* aDocument, nsIContent* aParent, nsIContent* aBindingParent) { MOZ_ASSERT(aParent || aDocument, "Must have document if no parent!"); MOZ_ASSERT(NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc(), "Must have the same owner document"); MOZ_ASSERT(!aParent || aDocument == aParent->GetUncomposedDoc(), "aDocument must be current doc of aParent"); MOZ_ASSERT(!GetUncomposedDoc() && !IsInUncomposedDoc(), "Already have a document. Unbind first!"); MOZ_ASSERT(!IsInComposedDoc(), "Already have a document. Unbind first!"); // Note that as we recurse into the kids, they'll have a non-null parent. So // only assert if our parent is _changing_ while we have a parent. MOZ_ASSERT(!GetParent() || aParent == GetParent(), "Already have a parent. Unbind first!"); MOZ_ASSERT(!GetBindingParent() || aBindingParent == GetBindingParent() || (!aBindingParent && aParent && aParent->GetBindingParent() == GetBindingParent()), "Already have a binding parent. Unbind first!"); MOZ_ASSERT(aBindingParent != this, "Content must not be its own binding parent"); MOZ_ASSERT(!IsRootOfNativeAnonymousSubtree() || aBindingParent == aParent, "Native anonymous content must have its parent as its " "own binding parent"); if (!aBindingParent && aParent) { aBindingParent = aParent->GetBindingParent(); } // First set the binding parent if (aBindingParent) { NS_ASSERTION(IsRootOfNativeAnonymousSubtree() || !HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE) || (aParent && aParent->IsInNativeAnonymousSubtree()), "Trying to re-bind content from native anonymous subtree to " "non-native anonymous parent!"); ExtendedContentSlots()->mBindingParent = aBindingParent; // Weak, so no addref happens. if (aParent->IsInNativeAnonymousSubtree()) { SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE); } if (aParent->HasFlag(NODE_HAS_BEEN_IN_UA_WIDGET)) { SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET); } if (HasFlag(NODE_IS_ANONYMOUS_ROOT)) { aParent->SetMayHaveAnonymousChildren(); } } if (aParent && aParent->IsInShadowTree()) { ClearSubtreeRootPointer(); SetFlags(NODE_IS_IN_SHADOW_TREE); SetIsConnected(aParent->IsInComposedDoc()); MOZ_ASSERT(aParent->GetContainingShadow()); ExtendedContentSlots()->mContainingShadow = aParent->GetContainingShadow(); } bool hadParent = !!GetParentNode(); // Set parent if (aParent) { if (!GetParent()) { NS_ADDREF(aParent); } mParent = aParent; } else { mParent = aDocument; } SetParentIsContent(aParent); // XXXbz sXBL/XBL2 issue! // Set document if (aDocument) { // We no longer need to track the subtree pointer (and in fact we'll assert // if we do this any later). ClearSubtreeRootPointer(); // XXX See the comment in Element::BindToTree SetIsInDocument(); SetIsConnected(true); if (mText.IsBidi()) { aDocument->SetBidiEnabled(); } // Clear the lazy frame construction bits. UnsetFlags(NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES); } else if (!IsInShadowTree()) { // If we're not in the doc and not in a shadow tree, // update our subtree pointer. SetSubtreeRootPointer(aParent->SubtreeRoot()); } nsNodeUtils::ParentChainChanged(this); if (!hadParent && IsRootOfNativeAnonymousSubtree()) { nsNodeUtils::NativeAnonymousChildListChange(this, false); } UpdateEditableState(false); MOZ_ASSERT(aDocument == GetUncomposedDoc(), "Bound to wrong document"); MOZ_ASSERT(aParent == GetParent(), "Bound to wrong parent"); MOZ_ASSERT(aBindingParent == GetBindingParent(), "Bound to wrong binding parent"); return NS_OK; }