Esempio n. 1
0
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;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
void
HTMLMetaElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
  nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
  CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMMetaRemoved"));
  nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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();
}
Esempio n. 6
0
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);
  }
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
  }
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
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);
    }
  }
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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();
}
Esempio n. 15
0
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;
}