/* -*- 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/. */
/** * class used to implement attr() generated content
*/ class nsAttributeTextNode final : public nsTextNode, public nsStubMutationObserver { public:
NS_DECL_ISUPPORTS_INHERITED
already_AddRefed<CharacterData> CloneDataNode(
mozilla::dom::NodeInfo* aNodeInfo, bool aCloneText) const override {
RefPtr<nsAttributeTextNode> it = new (aNodeInfo->NodeInfoManager()) nsAttributeTextNode(
do_AddRef(aNodeInfo), mNameSpaceID, mAttrName, mFallback); if (aCloneText) {
it->mText = mText;
}
return it.forget();
}
// Public method for the event to run void UpdateText() { UpdateText(true); }
private: virtual ~nsAttributeTextNode() {
NS_ASSERTION(!mGrandparent, "We were not unbound!");
}
// Update our text to our parent's current attr value void UpdateText(bool aNotify);
// This doesn't need to be a strong pointer because it's only non-null // while we're bound to the document tree, and it points to an ancestor // so the ancestor must be bound to the document tree the whole time // and can't be deleted.
Element* mGrandparent; // What attribute we're showing
int32_t mNameSpaceID;
RefPtr<nsAtom> mAttrName;
RefPtr<nsAtom> mFallback;
};
nsTextNode::~nsTextNode() = default;
// Use the CC variant of this, even though this class does not define // a new CC participant, to make QIing to the CC interfaces faster.
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(nsTextNode, CharacterData)
nsresult nsAttributeTextNode::BindToTree(BindContext& aContext,
nsINode& aParent) {
MOZ_ASSERT(aParent.IsContent() && aParent.GetParent(), "This node can't be a child of the document or of " "the document root");
NS_ASSERTION(!mGrandparent, "We were already bound!");
mGrandparent = aParent.GetParent()->AsElement();
mGrandparent->AddMutationObserver(this);
// Note that there is no need to notify here, since we have no // frame yet at this point.
UpdateText(false);
return NS_OK;
}
void nsAttributeTextNode::UnbindFromTree(UnbindContext& aContext) { // UnbindFromTree can be called anytime so we have to be safe. if (mGrandparent) { // aContext might not be true here, but we want to remove the // mutation observer anyway since we only need it while we're // in the document.
mGrandparent->RemoveMutationObserver(this);
mGrandparent = nullptr;
}
nsTextNode::UnbindFromTree(aContext);
}
void nsAttributeTextNode::AttributeChanged(Element* aElement,
int32_t aNameSpaceID,
nsAtom* aAttribute, int32_t aModType, const nsAttrValue* aOldValue) { if (aNameSpaceID == mNameSpaceID && aAttribute == mAttrName &&
aElement == mGrandparent) { // Since UpdateText notifies, do it when it's safe to run script. Note // that if we get unbound while the event is up that's ok -- we'll just // have no grandparent when it fires, and will do nothing. void (nsAttributeTextNode::*update)() = &nsAttributeTextNode::UpdateText;
nsContentUtils::AddScriptRunner(NewRunnableMethod( "nsAttributeTextNode::AttributeChanged", this, update));
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.