Example #1
0
void
CharacterData::UnbindFromTree(bool aDeep, bool aNullParent)
{
  // Unset frame flags; if we need them again later, they'll get set again.
  UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
             NS_REFRAME_IF_WHITESPACE);

  nsIDocument* document = GetComposedDoc();

  if (aNullParent) {
    if (this->IsRootOfNativeAnonymousSubtree()) {
      nsNodeUtils::NativeAnonymousChildListChange(this, true);
    }
    if (GetParent()) {
      NS_RELEASE(mParent);
    } else {
      mParent = nullptr;
    }
    SetParentIsContent(false);
  }
  ClearInDocument();

  if (aNullParent || !mParent->IsInShadowTree()) {
    UnsetFlags(NODE_IS_IN_SHADOW_TREE);

    // Begin keeping track of our subtree root.
    SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
  }

  if (document && !GetContainingShadow()) {
    // Notify XBL- & nsIAnonymousContentCreator-generated
    // anonymous content that the document is changing.
    // Unlike XBL, bindings for web components shadow DOM
    // do not get uninstalled.
    if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
      nsContentUtils::AddScriptRunner(
        new RemoveFromBindingManagerRunnable(document->BindingManager(), this,
                                             document));
    }
  }

  nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
  if (slots) {
    slots->mBindingParent = nullptr;
    if (aNullParent || !mParent->IsInShadowTree()) {
      slots->mContainingShadow = nullptr;
    }
  }

  nsNodeUtils::ParentChainChanged(this);
}
Example #2
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;
}