📄 htmlediting.cpp
字号:
return 0;}static HTMLElement* embeddedSublist(Node* listItem){ // Check the DOM so that we'll find collapsed sublists without renderers. for (Node* n = listItem->firstChild(); n; n = n->nextSibling()) { if (isListElement(n)) return static_cast<HTMLElement*>(n); } return 0;}static Node* appendedSublist(Node* listItem){ // Check the DOM so that we'll find collapsed sublists without renderers. for (Node* n = listItem->nextSibling(); n; n = n->nextSibling()) { if (isListElement(n)) return static_cast<HTMLElement*>(n); if (n->renderer() && n->renderer()->isListItem()) return 0; } return 0;}Node* enclosingEmptyListItem(const VisiblePosition& visiblePos){ // Check that position is on a line by itself inside a list item Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().node()); if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(visiblePos)) return 0; VisiblePosition firstInListChild(Position(listChildNode, 0)); VisiblePosition lastInListChild(Position(listChildNode, maxDeepOffset(listChildNode))); if (firstInListChild != visiblePos || lastInListChild != visiblePos) return 0; if (embeddedSublist(listChildNode) || appendedSublist(listChildNode)) return 0; return listChildNode;}HTMLElement* outermostEnclosingList(Node* node){ HTMLElement* list = enclosingList(node); if (!list) return 0; while (HTMLElement* nextList = enclosingList(list)) list = nextList; return list;}Node* highestAncestor(Node* node){ ASSERT(node); Node* parent = node; while ((node = node->parentNode())) parent = node; return parent;}// FIXME: do not require renderer, so that this can be used within fragments, or rename to isRenderedTable()bool isTableElement(Node* n){ if (!n || !n->isElementNode()) return false; RenderObject* renderer = n->renderer(); return (renderer && (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE));}bool isTableCell(const Node* node){ RenderObject* r = node->renderer(); if (!r) return node->hasTagName(tdTag) || node->hasTagName(thTag); return r->isTableCell();}PassRefPtr<HTMLElement> createDefaultParagraphElement(Document* document){ return new HTMLDivElement(divTag, document);}PassRefPtr<HTMLElement> createBreakElement(Document* document){ return new HTMLBRElement(brTag, document);}PassRefPtr<HTMLElement> createOrderedListElement(Document* document){ return new HTMLOListElement(olTag, document);}PassRefPtr<HTMLElement> createUnorderedListElement(Document* document){ return new HTMLUListElement(ulTag, document);}PassRefPtr<HTMLElement> createListItemElement(Document* document){ return new HTMLLIElement(liTag, document);}PassRefPtr<HTMLElement> createHTMLElement(Document* document, const QualifiedName& name){ return HTMLElementFactory::createHTMLElement(name, document, 0, false);}PassRefPtr<HTMLElement> createHTMLElement(Document* document, const AtomicString& tagName){ return createHTMLElement(document, QualifiedName(nullAtom, tagName, xhtmlNamespaceURI));}bool isTabSpanNode(const Node *node){ return node && node->hasTagName(spanTag) && node->isElementNode() && static_cast<const Element *>(node)->getAttribute(classAttr) == AppleTabSpanClass;}bool isTabSpanTextNode(const Node *node){ return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode());}Node *tabSpanNode(const Node *node){ return isTabSpanTextNode(node) ? node->parentNode() : 0;}Position positionBeforeTabSpan(const Position& pos){ Node *node = pos.node(); if (isTabSpanTextNode(node)) node = tabSpanNode(node); else if (!isTabSpanNode(node)) return pos; return positionBeforeNode(node);}PassRefPtr<Element> createTabSpanElement(Document* document, PassRefPtr<Node> tabTextNode){ // Make the span to hold the tab. RefPtr<Element> spanElement = document->createElement(spanTag, false); spanElement->setAttribute(classAttr, AppleTabSpanClass); spanElement->setAttribute(styleAttr, "white-space:pre"); // Add tab text to that span. if (!tabTextNode) tabTextNode = document->createEditingTextNode("\t"); ExceptionCode ec = 0; spanElement->appendChild(tabTextNode, ec); ASSERT(ec == 0); return spanElement.release();}PassRefPtr<Element> createTabSpanElement(Document* document, const String& tabText){ return createTabSpanElement(document, document->createTextNode(tabText));}PassRefPtr<Element> createTabSpanElement(Document* document){ return createTabSpanElement(document, PassRefPtr<Node>());}bool isNodeRendered(const Node *node){ if (!node) return false; RenderObject *renderer = node->renderer(); if (!renderer) return false; return renderer->style()->visibility() == VISIBLE;}Node *nearestMailBlockquote(const Node *node){ for (Node *n = const_cast<Node *>(node); n; n = n->parentNode()) { if (isMailBlockquote(n)) return n; } return 0;}unsigned numEnclosingMailBlockquotes(const Position& p){ unsigned num = 0; for (Node* n = p.node(); n; n = n->parentNode()) if (isMailBlockquote(n)) num++; return num;}bool isMailBlockquote(const Node *node){ if (!node || !node->isElementNode() && !node->hasTagName(blockquoteTag)) return false; return static_cast<const Element *>(node)->getAttribute("type") == "cite";}int caretMinOffset(const Node* n){ RenderObject* r = n->renderer(); ASSERT(!n->isCharacterDataNode() || !r || r->isText()); // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now. return r ? r->caretMinOffset() : 0;}// If a node can contain candidates for VisiblePositions, return the offset of the last candidate, otherwise // return the number of children for container nodes and the length for unrendered text nodes.int caretMaxOffset(const Node* n){ // For rendered text nodes, return the last position that a caret could occupy. if (n->isTextNode() && n->renderer()) return n->renderer()->caretMaxOffset(); // For containers return the number of children. For others do the same as above. return maxDeepOffset(n);}bool lineBreakExistsAtPosition(const VisiblePosition& visiblePosition){ if (visiblePosition.isNull()) return false; Position downstream(visiblePosition.deepEquivalent().downstream()); return downstream.node()->hasTagName(brTag) || downstream.node()->isTextNode() && downstream.node()->renderer()->style()->preserveNewline() && visiblePosition.characterAfter() == '\n';}// Modifies selections that have an end point at the edge of a table// that contains the other endpoint so that they don't confuse// code that iterates over selected paragraphs.VisibleSelection selectionForParagraphIteration(const VisibleSelection& original){ VisibleSelection newSelection(original); VisiblePosition startOfSelection(newSelection.visibleStart()); VisiblePosition endOfSelection(newSelection.visibleEnd()); // If the end of the selection to modify is just after a table, and // if the start of the selection is inside that table, then the last paragraph // that we'll want modify is the last one inside the table, not the table itself // (a table is itself a paragraph). if (Node* table = isFirstPositionAfterTable(endOfSelection)) if (startOfSelection.deepEquivalent().node()->isDescendantOf(table)) newSelection = VisibleSelection(startOfSelection, endOfSelection.previous(true)); // If the start of the selection to modify is just before a table, // and if the end of the selection is inside that table, then the first paragraph // we'll want to modify is the first one inside the table, not the paragraph // containing the table itself. if (Node* table = isLastPositionBeforeTable(startOfSelection)) if (endOfSelection.deepEquivalent().node()->isDescendantOf(table)) newSelection = VisibleSelection(startOfSelection.next(true), endOfSelection); return newSelection;}int indexForVisiblePosition(VisiblePosition& visiblePosition){ if (visiblePosition.isNull()) return 0; Position p(visiblePosition.deepEquivalent()); RefPtr<Range> range = Range::create(p.node()->document(), Position(p.node()->document(), 0), rangeCompliantEquivalent(p)); return TextIterator::rangeLength(range.get(), true);}PassRefPtr<Range> avoidIntersectionWithNode(const Range* range, Node* node){ if (!range) return 0; Document* document = range->ownerDocument(); Node* startContainer = range->startContainer(); int startOffset = range->startOffset(); Node* endContainer = range->endContainer(); int endOffset = range->endOffset(); if (!startContainer) return 0; ASSERT(endContainer); if (startContainer == node || startContainer->isDescendantOf(node)) { ASSERT(node->parentNode()); startContainer = node->parentNode(); startOffset = node->nodeIndex(); } if (endContainer == node || endContainer->isDescendantOf(node)) { ASSERT(node->parentNode()); endContainer = node->parentNode(); endOffset = node->nodeIndex(); } return Range::create(document, startContainer, startOffset, endContainer, endOffset);}VisibleSelection avoidIntersectionWithNode(const VisibleSelection& selection, Node* node){ if (selection.isNone()) return VisibleSelection(selection); VisibleSelection updatedSelection(selection); Node* base = selection.base().node(); Node* extent = selection.extent().node(); ASSERT(base); ASSERT(extent); if (base == node || base->isDescendantOf(node)) { ASSERT(node->parentNode()); updatedSelection.setBase(Position(node->parentNode(), node->nodeIndex())); } if (extent == node || extent->isDescendantOf(node)) { ASSERT(node->parentNode()); updatedSelection.setExtent(Position(node->parentNode(), node->nodeIndex())); } return updatedSelection;}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -