本文整理汇总了C++中ContainerNode::firstChild方法的典型用法代码示例。如果您正苦于以下问题:C++ ContainerNode::firstChild方法的具体用法?C++ ContainerNode::firstChild怎么用?C++ ContainerNode::firstChild使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ContainerNode
的用法示例。
在下文中一共展示了ContainerNode::firstChild方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: patchNode
Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionState& exceptionState)
{
// Don't parse <html> as a fragment.
if (node->isDocumentNode() || (node->parentNode() && node->parentNode()->isDocumentNode())) {
patchDocument(markup);
return 0;
}
Node* previousSibling = node->previousSibling();
RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
Node* targetNode = node->parentElementOrShadowRoot() ? node->parentElementOrShadowRoot() : m_document.documentElement();
// Use the document BODY as the context element when editing immediate shadow root children,
// as it provides an equivalent parsing context.
if (targetNode->isShadowRoot())
targetNode = m_document.body();
Element* targetElement = toElement(targetNode);
// FIXME: This code should use one of createFragment* in markup.h
if (m_document.isHTMLDocument())
fragment->parseHTML(markup, targetElement);
else
fragment->parseXML(markup, targetElement);
// Compose the old list.
ContainerNode* parentNode = node->parentNode();
Vector<OwnPtr<Digest> > oldList;
for (Node* child = parentNode->firstChild(); child; child = child->nextSibling())
oldList.append(createDigest(child, 0));
// Compose the new list.
String markupCopy = markup.lower();
Vector<OwnPtr<Digest> > newList;
for (Node* child = parentNode->firstChild(); child != node; child = child->nextSibling())
newList.append(createDigest(child, 0));
for (Node* child = fragment->firstChild(); child; child = child->nextSibling()) {
if (isHTMLHeadElement(*child) && !child->firstChild() && markupCopy.find("</head>") == kNotFound)
continue; // HTML5 parser inserts empty <head> tag whenever it parses <body>
if (isHTMLBodyElement(*child) && !child->firstChild() && markupCopy.find("</body>") == kNotFound)
continue; // HTML5 parser inserts empty <body> tag whenever it parses </head>
newList.append(createDigest(child, &m_unusedNodesMap));
}
for (Node* child = node->nextSibling(); child; child = child->nextSibling())
newList.append(createDigest(child, 0));
if (!innerPatchChildren(parentNode, oldList, newList, exceptionState)) {
// Fall back to total replace.
if (!m_domEditor->replaceChild(parentNode, fragment.release(), node, exceptionState))
return 0;
}
return previousSibling ? previousSibling->nextSibling() : parentNode->firstChild();
}
示例2: patchNode
Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionCode& ec)
{
// Don't parse <html> as a fragment.
if (node->isDocumentNode() || (node->parentNode() && node->parentNode()->isDocumentNode())) {
patchDocument(markup);
return 0;
}
Node* previousSibling = node->previousSibling();
// FIXME: This code should use one of createFragment* in markup.h
RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
if (m_document->isHTMLDocument())
fragment->parseHTML(markup, node->parentElement() ? node->parentElement() : m_document->documentElement());
else
fragment->parseXML(markup, node->parentElement() ? node->parentElement() : m_document->documentElement());
// Compose the old list.
ContainerNode* parentNode = node->parentNode();
Vector<OwnPtr<Digest> > oldList;
for (Node* child = parentNode->firstChild(); child; child = child->nextSibling())
oldList.append(createDigest(child, 0));
// Compose the new list.
String markupCopy = markup;
markupCopy.makeLower();
Vector<OwnPtr<Digest> > newList;
for (Node* child = parentNode->firstChild(); child != node; child = child->nextSibling())
newList.append(createDigest(child, 0));
for (Node* child = fragment->firstChild(); child; child = child->nextSibling()) {
if (child->hasTagName(headTag) && !child->firstChild() && markupCopy.find("</head>") == notFound)
continue; // HTML5 parser inserts empty <head> tag whenever it parses <body>
if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.find("</body>") == notFound)
continue; // HTML5 parser inserts empty <body> tag whenever it parses </head>
newList.append(createDigest(child, &m_unusedNodesMap));
}
for (Node* child = node->nextSibling(); child; child = child->nextSibling())
newList.append(createDigest(child, 0));
if (!innerPatchChildren(parentNode, oldList, newList, ec)) {
// Fall back to total replace.
ec = 0;
if (!m_domEditor->replaceChild(parentNode, fragment.release(), node, ec))
return 0;
}
return previousSibling ? previousSibling->nextSibling() : parentNode->firstChild();
}
示例3: doApply
void SimplifyMarkupCommand::doApply()
{
ContainerNode* rootNode = m_firstNode->parentNode();
WillBeHeapVector<RefPtrWillBeMember<ContainerNode>> nodesToRemove;
// Walk through the inserted nodes, to see if there are elements that could be removed
// without affecting the style. The goal is to produce leaner markup even when starting
// from a verbose fragment.
// We look at inline elements as well as non top level divs that don't have attributes.
for (Node* node = m_firstNode.get(); node && node != m_nodeAfterLast; node = NodeTraversal::next(*node)) {
if (node->hasChildren() || (node->isTextNode() && node->nextSibling()))
continue;
ContainerNode* startingNode = node->parentNode();
if (!startingNode)
continue;
RenderStyle* startingStyle = startingNode->renderStyle();
if (!startingStyle)
continue;
ContainerNode* currentNode = startingNode;
ContainerNode* topNodeWithStartingStyle = nullptr;
while (currentNode != rootNode) {
if (currentNode->parentNode() != rootNode && isRemovableBlock(currentNode))
nodesToRemove.append(currentNode);
currentNode = currentNode->parentNode();
if (!currentNode)
break;
if (!currentNode->renderer() || !currentNode->renderer()->isRenderInline() || toRenderInline(currentNode->renderer())->alwaysCreateLineBoxes())
continue;
if (currentNode->firstChild() != currentNode->lastChild()) {
topNodeWithStartingStyle = 0;
break;
}
if (!currentNode->renderStyle()->visualInvalidationDiff(*startingStyle).hasDifference())
topNodeWithStartingStyle = currentNode;
}
if (topNodeWithStartingStyle) {
for (ContainerNode* node = startingNode; node != topNodeWithStartingStyle; node = node->parentNode())
nodesToRemove.append(node);
}
}
// we perform all the DOM mutations at once.
for (size_t i = 0; i < nodesToRemove.size(); ++i) {
// FIXME: We can do better by directly moving children from nodesToRemove[i].
int numPrunedAncestors = pruneSubsequentAncestorsToRemove(nodesToRemove, i);
if (numPrunedAncestors < 0)
continue;
removeNodePreservingChildren(nodesToRemove[i], AssumeContentIsAlwaysEditable);
i += numPrunedAncestors;
}
}
示例4: notifyDescendantInsertedIntoTree
static void notifyDescendantInsertedIntoTree(ContainerNode& insertionPoint, ContainerNode& node, NodeVector& postInsertionNotificationTargets)
{
for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
if (is<ContainerNode>(*child))
notifyNodeInsertedIntoTree(insertionPoint, downcast<ContainerNode>(*child), postInsertionNotificationTargets);
}
if (ShadowRoot* root = node.shadowRoot())
notifyNodeInsertedIntoTree(insertionPoint, *root, postInsertionNotificationTargets);
}
示例5: detachChildren
static void detachChildren(ContainerNode& current, DetachType detachType)
{
for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
if (child->isTextNode()) {
Style::detachTextRenderer(*toText(child));
continue;
}
if (child->isElementNode())
detachRenderTree(*toElement(child), detachType);
}
current.clearChildNeedsStyleRecalc();
}
示例6: attachChildren
static void attachChildren(ContainerNode& current)
{
for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
ASSERT(!child->attached() || childAttachedAllowedWhenAttachingChildren(current));
if (child->attached())
continue;
if (child->isTextNode()) {
attachTextRenderer(*toText(child));
continue;
}
if (child->isElementNode())
attachRenderTree(*toElement(child), nullptr);
}
}
示例7: rowIndex
int HTMLTableRowElement::rowIndex() const
{
ContainerNode* table = parentNode();
if (!table)
return -1;
table = table->parentNode();
if (!table || !table->hasTagName(tableTag))
return -1;
// To match Firefox, the row indices work like this:
// Rows from the first <thead> are numbered before all <tbody> rows.
// Rows from the first <tfoot> are numbered after all <tbody> rows.
// Rows from other <thead> and <tfoot> elements don't get row indices at all.
int rIndex = 0;
if (HTMLTableSectionElement* head = static_cast<HTMLTableElement*>(table)->tHead()) {
for (Node *row = head->firstChild(); row; row = row->nextSibling()) {
if (row == this)
return rIndex;
if (row->hasTagName(trTag))
++rIndex;
}
}
for (Node *node = table->firstChild(); node; node = node->nextSibling()) {
if (node->hasTagName(tbodyTag)) {
HTMLTableSectionElement* section = static_cast<HTMLTableSectionElement*>(node);
for (Node* row = section->firstChild(); row; row = row->nextSibling()) {
if (row == this)
return rIndex;
if (row->hasTagName(trTag))
++rIndex;
}
}
}
if (HTMLTableSectionElement* foot = static_cast<HTMLTableElement*>(table)->tFoot()) {
for (Node *row = foot->firstChild(); row; row = row->nextSibling()) {
if (row == this)
return rIndex;
if (row->hasTagName(trTag))
++rIndex;
}
}
// We get here for rows that are in <thead> or <tfoot> sections other than the main header and footer.
return -1;
}
示例8: item
// FIXME: It is silly that these functions are in HTMLCollection.cpp.
Node* LiveNodeListBase::item(unsigned offset) const
{
if (isItemCacheValid() && cachedItemOffset() == offset)
return cachedItem();
if (isLengthCacheValid() && cachedLength() <= offset)
return 0;
#if ENABLE(MICRODATA)
if (type() == ItemProperties)
static_cast<const HTMLPropertiesCollection*>(this)->updateRefElements();
else if (type() == PropertyNodeListType)
static_cast<const PropertyNodeList*>(this)->updateRefElements();
#endif
ContainerNode* root = rootContainerNode();
if (!root) {
// FIMXE: In someTextNode.childNodes case the root is Text. We shouldn't even make a LiveNodeList for that.
setLengthCache(0);
return 0;
}
if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLastOrCachedItem(offset)) {
Node* lastItem = itemBefore(0);
ASSERT(lastItem);
setItemCache(lastItem, cachedLength() - 1, 0);
} else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedItemOffset())) {
unsigned offsetInArray = 0;
Node* firstItem;
if (type() == ChildNodeListType)
firstItem = root->firstChild();
else if (isNodeList(type()))
firstItem = traverseLiveNodeListFirstElement(root);
else
firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstElement(offsetInArray, root);
if (!firstItem) {
setLengthCache(0);
return 0;
}
setItemCache(firstItem, 0, offsetInArray);
ASSERT(!cachedItemOffset());
}
if (cachedItemOffset() == offset)
return cachedItem();
return itemBeforeOrAfterCachedItem(offset, root);
}
示例9: populateChildren
inline void DistributionPool::populateChildren(const ContainerNode& parent)
{
clear();
for (Node* child = parent.firstChild(); child; child = child->nextSibling()) {
if (isActiveInsertionPoint(*child)) {
InsertionPoint* insertionPoint = toInsertionPoint(child);
for (size_t i = 0; i < insertionPoint->size(); ++i)
m_nodes.append(insertionPoint->at(i));
} else {
m_nodes.append(child);
}
}
m_distributed.resize(m_nodes.size());
m_distributed.fill(false);
}
示例10: populateChildren
inline void DistributionPool::populateChildren(const ContainerNode& parent) {
clear();
for (Node* child = parent.firstChild(); child; child = child->nextSibling()) {
if (isHTMLSlotElement(child)) {
// TODO(hayato): Support re-distribution across v0 and v1 shadow trees
continue;
}
if (isActiveInsertionPoint(*child)) {
InsertionPoint* insertionPoint = toInsertionPoint(child);
for (size_t i = 0; i < insertionPoint->distributedNodesSize(); ++i)
m_nodes.append(insertionPoint->distributedNodeAt(i));
} else {
m_nodes.append(child);
}
}
m_distributed.resize(m_nodes.size());
m_distributed.fill(false);
}
示例11: notifyNodeRemovedFromTree
void notifyNodeRemovedFromTree(ContainerNode& insertionPoint, ContainerNode& node)
{
NoEventDispatchAssertion assertNoEventDispatch;
ASSERT(!insertionPoint.inDocument());
node.removedFrom(insertionPoint);
for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
if (is<ContainerNode>(*child))
notifyNodeRemovedFromTree(insertionPoint, downcast<ContainerNode>(*child));
}
if (!is<Element>(node))
return;
if (RefPtr<ShadowRoot> root = downcast<Element>(node).shadowRoot())
notifyNodeRemovedFromTree(insertionPoint, *root.get());
}
示例12: addChildNodesToDeletionQueue
void addChildNodesToDeletionQueue(Node*& head, Node*& tail, ContainerNode& container)
{
// We have to tell all children that their parent has died.
Node* next = nullptr;
for (auto* node = container.firstChild(); node; node = next) {
ASSERT(!node->m_deletionHasBegun);
next = node->nextSibling();
node->setNextSibling(nullptr);
node->setParentNode(nullptr);
container.setFirstChild(next);
if (next)
next->setPreviousSibling(nullptr);
if (!node->refCount()) {
#ifndef NDEBUG
node->m_deletionHasBegun = true;
#endif
// Add the node to the list of nodes to be deleted.
// Reuse the nextSibling pointer for this purpose.
if (tail)
tail->setNextSibling(node);
else
head = node;
tail = node;
} else {
Ref<Node> protect(*node); // removedFromDocument may remove remove all references to this node.
if (Document* containerDocument = container.ownerDocument())
containerDocument->adoptIfNeeded(*node);
if (node->isInTreeScope())
notifyChildNodeRemoved(container, *node);
}
}
container.setLastChild(nullptr);
}
示例13: hasOneChild
static inline bool hasOneTextChild(ContainerNode& node)
{
return hasOneChild(node) && node.firstChild()->isTextNode();
}