⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 replaceselectioncommand.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        if (!isNodeRendered(node) && !isTableStructureNode(node))            unrendered.append(node);    size_t n = unrendered.size();    for (size_t i = 0; i < n; ++i)        removeNode(unrendered[i]);}void ReplacementFragment::removeInterchangeNodes(Node* container){    // Interchange newlines at the "start" of the incoming fragment must be    // either the first node in the fragment or the first leaf in the fragment.    Node* node = container->firstChild();    while (node) {        if (isInterchangeNewlineNode(node)) {            m_hasInterchangeNewlineAtStart = true;            removeNode(node);            break;        }        node = node->firstChild();    }    if (!container->hasChildNodes())        return;    // Interchange newlines at the "end" of the incoming fragment must be    // either the last node in the fragment or the last leaf in the fragment.    node = container->lastChild();    while (node) {        if (isInterchangeNewlineNode(node)) {            m_hasInterchangeNewlineAtEnd = true;            removeNode(node);            break;        }        node = node->lastChild();    }        node = container->firstChild();    while (node) {        Node *next = node->traverseNextNode();        if (isInterchangeConvertedSpaceSpan(node)) {            RefPtr<Node> n = 0;            while ((n = node->firstChild())) {                removeNode(n);                insertNodeBefore(n, node);            }            removeNode(node);            if (n)                next = n->traverseNextNode();        }        node = next;    }}ReplaceSelectionCommand::ReplaceSelectionCommand(Document* document, PassRefPtr<DocumentFragment> fragment,        bool selectReplacement, bool smartReplace, bool matchStyle, bool preventNesting, bool movingParagraph,        EditAction editAction)     : CompositeEditCommand(document),      m_selectReplacement(selectReplacement),       m_smartReplace(smartReplace),      m_matchStyle(matchStyle),      m_documentFragment(fragment),      m_preventNesting(preventNesting),      m_movingParagraph(movingParagraph),      m_editAction(editAction),      m_shouldMergeEnd(false){}static bool hasMatchingQuoteLevel(VisiblePosition endOfExistingContent, VisiblePosition endOfInsertedContent){    Position existing = endOfExistingContent.deepEquivalent();    Position inserted = endOfInsertedContent.deepEquivalent();    bool isInsideMailBlockquote = nearestMailBlockquote(inserted.node());    return isInsideMailBlockquote && (numEnclosingMailBlockquotes(existing) == numEnclosingMailBlockquotes(inserted));}bool ReplaceSelectionCommand::shouldMergeStart(bool selectionStartWasStartOfParagraph, bool fragmentHasInterchangeNewlineAtStart){    VisiblePosition startOfInsertedContent(positionAtStartOfInsertedContent());    VisiblePosition prev = startOfInsertedContent.previous(true);    if (prev.isNull())        return false;        if (!m_movingParagraph && hasMatchingQuoteLevel(prev, positionAtEndOfInsertedContent()))        return true;    return !selectionStartWasStartOfParagraph &&            !fragmentHasInterchangeNewlineAtStart &&           isStartOfParagraph(startOfInsertedContent) &&            !startOfInsertedContent.deepEquivalent().node()->hasTagName(brTag) &&           shouldMerge(startOfInsertedContent, prev);}bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph){    VisiblePosition endOfInsertedContent(positionAtEndOfInsertedContent());    VisiblePosition next = endOfInsertedContent.next(true);    if (next.isNull())        return false;    return !selectionEndWasEndOfParagraph &&           isEndOfParagraph(endOfInsertedContent) &&            !endOfInsertedContent.deepEquivalent().node()->hasTagName(brTag) &&           shouldMerge(endOfInsertedContent, next);}static bool isMailPasteAsQuotationNode(const Node* node){    return node && node->hasTagName(blockquoteTag) && node->isElementNode() && static_cast<const Element*>(node)->getAttribute(classAttr) == ApplePasteAsQuotation;}// Wrap CompositeEditCommand::removeNodePreservingChildren() so we can update the nodes we trackvoid ReplaceSelectionCommand::removeNodePreservingChildren(Node* node){    if (m_firstNodeInserted == node)        m_firstNodeInserted = node->traverseNextNode();    if (m_lastLeafInserted == node)        m_lastLeafInserted = node->lastChild() ? node->lastChild() : node->traverseNextSibling();    CompositeEditCommand::removeNodePreservingChildren(node);}// Wrap CompositeEditCommand::removeNodeAndPruneAncestors() so we can update the nodes we trackvoid ReplaceSelectionCommand::removeNodeAndPruneAncestors(Node* node){    // prepare in case m_firstNodeInserted and/or m_lastLeafInserted get removed    // FIXME: shouldn't m_lastLeafInserted be adjusted using traversePreviousNode()?    Node* afterFirst = m_firstNodeInserted ? m_firstNodeInserted->traverseNextSibling() : 0;    Node* afterLast = m_lastLeafInserted ? m_lastLeafInserted->traverseNextSibling() : 0;        CompositeEditCommand::removeNodeAndPruneAncestors(node);        // adjust m_firstNodeInserted and m_lastLeafInserted since either or both may have been removed    if (m_lastLeafInserted && !m_lastLeafInserted->inDocument())        m_lastLeafInserted = afterLast;    if (m_firstNodeInserted && !m_firstNodeInserted->inDocument())        m_firstNodeInserted = m_lastLeafInserted && m_lastLeafInserted->inDocument() ? afterFirst : 0;}static bool isHeaderElement(Node* a){    if (!a)        return false;            return a->hasTagName(h1Tag) ||           a->hasTagName(h2Tag) ||           a->hasTagName(h3Tag) ||           a->hasTagName(h4Tag) ||           a->hasTagName(h5Tag);}static bool haveSameTagName(Node* a, Node* b){    return a && b && a->isElementNode() && b->isElementNode() && static_cast<Element*>(a)->tagName() == static_cast<Element*>(b)->tagName();}bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const VisiblePosition& destination){    if (source.isNull() || destination.isNull())        return false;            Node* sourceNode = source.deepEquivalent().node();    Node* destinationNode = destination.deepEquivalent().node();    Node* sourceBlock = enclosingBlock(sourceNode);    Node* destinationBlock = enclosingBlock(destinationNode);    return !enclosingNodeOfType(source.deepEquivalent(), &isMailPasteAsQuotationNode) &&           sourceBlock && (!sourceBlock->hasTagName(blockquoteTag) || isMailBlockquote(sourceBlock))  &&           enclosingListChild(sourceBlock) == enclosingListChild(destinationNode) &&           enclosingTableCell(source.deepEquivalent()) == enclosingTableCell(destination.deepEquivalent()) &&           (!isHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, destinationBlock)) &&           // Don't merge to or from a position before or after a block because it would           // be a no-op and cause infinite recursion.           !isBlock(sourceNode) && !isBlock(destinationNode);}// Style rules that match just inserted elements could change their appearance, like// a div inserted into a document with div { display:inline; }.void ReplaceSelectionCommand::negateStyleRulesThatAffectAppearance(){    for (RefPtr<Node> node = m_firstNodeInserted.get(); node; node = node->traverseNextNode()) {        // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance        if (isStyleSpan(node.get())) {            HTMLElement* e = static_cast<HTMLElement*>(node.get());            // There are other styles that style rules can give to style spans,            // but these are the two important ones because they'll prevent            // inserted content from appearing in the right paragraph.            // FIXME: Hyatt is concerned that selectively using display:inline will give inconsistent            // results. We already know one issue because td elements ignore their display property            // in quirks mode (which Mail.app is always in). We should look for an alternative.            if (isBlock(e))                e->getInlineStyleDecl()->setProperty(CSSPropertyDisplay, CSSValueInline);            if (e->renderer() && e->renderer()->style()->floating() != FNONE)                e->getInlineStyleDecl()->setProperty(CSSPropertyFloat, CSSValueNone);        }        if (node == m_lastLeafInserted)            break;    }}void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(){    document()->updateLayoutIgnorePendingStylesheets();    if (!m_lastLeafInserted->renderer() &&         m_lastLeafInserted->isTextNode() &&         !enclosingNodeWithTag(Position(m_lastLeafInserted.get(), 0), selectTag) &&         !enclosingNodeWithTag(Position(m_lastLeafInserted.get(), 0), scriptTag)) {        if (m_firstNodeInserted == m_lastLeafInserted) {            removeNode(m_lastLeafInserted.get());            m_lastLeafInserted = 0;            m_firstNodeInserted = 0;            return;        }        RefPtr<Node> previous = m_lastLeafInserted->traversePreviousNode();        removeNode(m_lastLeafInserted.get());        m_lastLeafInserted = previous;    }        // We don't have to make sure that m_firstNodeInserted isn't inside a select or script element, because    // it is a top level node in the fragment and the user can't insert into those elements.    if (!m_firstNodeInserted->renderer() &&         m_firstNodeInserted->isTextNode()) {        if (m_firstNodeInserted == m_lastLeafInserted) {            removeNode(m_firstNodeInserted.get());            m_firstNodeInserted = 0;            m_lastLeafInserted = 0;            return;        }        RefPtr<Node> next = m_firstNodeInserted->traverseNextSibling();        removeNode(m_firstNodeInserted.get());        m_firstNodeInserted = next;    }}void ReplaceSelectionCommand::handlePasteAsQuotationNode(){    Node* node = m_firstNodeInserted.get();    if (isMailPasteAsQuotationNode(node))        removeNodeAttribute(static_cast<Element*>(node), classAttr);}VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent(){    Node* lastNode = m_lastLeafInserted.get();    Node* enclosingSelect = enclosingNodeWithTag(Position(lastNode, 0), selectTag);    if (enclosingSelect)        lastNode = enclosingSelect;    return VisiblePosition(Position(lastNode, maxDeepOffset(lastNode)));}VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent(){    // Return the inserted content's first VisiblePosition.    return VisiblePosition(nextCandidate(positionBeforeNode(m_firstNodeInserted.get())));}// Remove style spans before insertion if they are unnecessary.  It's faster because we'll // avoid doing a layout.static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const Position& insertionPos){    Node* topNode = fragment.firstChild();        // Handling this case is more complicated (see handleStyleSpans) and doesn't receive the optimization.    if (isMailPasteAsQuotationNode(topNode))        return false;        // Either there are no style spans in the fragment or a WebKit client has added content to the fragment    // before inserting it.  Look for and handle style spans after insertion.    if (!isStyleSpan(topNode))        return false;        Node* sourceDocumentStyleSpan = topNode;    RefPtr<Node> copiedRangeStyleSpan = sourceDocumentStyleSpan->firstChild();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -