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

📄 compositeeditcommand.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#include "CompositeEditCommand.h"#include "AppendNodeCommand.h"#include "ApplyStyleCommand.h"#include "CSSComputedStyleDeclaration.h"#include "CSSMutableStyleDeclaration.h"#include "CharacterNames.h"#include "DeleteFromTextNodeCommand.h"#include "DeleteSelectionCommand.h"#include "Document.h"#include "DocumentFragment.h"#include "EditorInsertAction.h"#include "Element.h"#include "HTMLNames.h"#include "InlineTextBox.h"#include "InsertIntoTextNodeCommand.h"#include "InsertLineBreakCommand.h"#include "InsertNodeBeforeCommand.h"#include "InsertParagraphSeparatorCommand.h"#include "InsertTextCommand.h"#include "JoinTextNodesCommand.h"#include "MergeIdenticalElementsCommand.h"#include "Range.h"#include "RemoveCSSPropertyCommand.h"#include "RemoveNodeCommand.h"#include "RemoveNodePreservingChildrenCommand.h"#include "ReplaceSelectionCommand.h"#include "RenderBlock.h"#include "RenderText.h"#include "SetNodeAttributeCommand.h"#include "SplitElementCommand.h"#include "SplitTextNodeCommand.h"#include "SplitTextNodeContainingElementCommand.h"#include "Text.h"#include "TextIterator.h"#include "WrapContentsInDummySpanCommand.h"#include "htmlediting.h"#include "markup.h"#include "visible_units.h"using namespace std;namespace WebCore {using namespace HTMLNames;CompositeEditCommand::CompositeEditCommand(Document *document)     : EditCommand(document){}void CompositeEditCommand::doUnapply(){    size_t size = m_commands.size();    for (size_t i = size; i != 0; --i)        m_commands[i - 1]->unapply();}void CompositeEditCommand::doReapply(){    size_t size = m_commands.size();    for (size_t i = 0; i != size; ++i)        m_commands[i]->reapply();}//// sugary-sweet convenience functions to help create and apply edit commands in composite commands//void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> cmd){    cmd->setParent(this);    cmd->apply();    m_commands.append(cmd);}void CompositeEditCommand::applyStyle(CSSStyleDeclaration* style, EditAction editingAction){    applyCommandToComposite(ApplyStyleCommand::create(document(), style, editingAction));}void CompositeEditCommand::applyStyle(CSSStyleDeclaration* style, const Position& start, const Position& end, EditAction editingAction){    applyCommandToComposite(ApplyStyleCommand::create(document(), style, start, end, editingAction));}void CompositeEditCommand::applyStyledElement(PassRefPtr<Element> element){    applyCommandToComposite(ApplyStyleCommand::create(element, false));}void CompositeEditCommand::removeStyledElement(PassRefPtr<Element> element){    applyCommandToComposite(ApplyStyleCommand::create(element, true));}void CompositeEditCommand::insertParagraphSeparator(bool useDefaultParagraphElement){    applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(), useDefaultParagraphElement));}void CompositeEditCommand::insertLineBreak(){    applyCommandToComposite(InsertLineBreakCommand::create(document()));}void CompositeEditCommand::insertNodeBefore(PassRefPtr<Node> insertChild, PassRefPtr<Node> refChild){    ASSERT(!refChild->hasTagName(bodyTag));    applyCommandToComposite(InsertNodeBeforeCommand::create(insertChild, refChild));}void CompositeEditCommand::insertNodeAfter(PassRefPtr<Node> insertChild, PassRefPtr<Node> refChild){    ASSERT(insertChild);    ASSERT(refChild);    ASSERT(!refChild->hasTagName(bodyTag));    Element* parent = refChild->parentElement();    ASSERT(parent);    if (parent->lastChild() == refChild)        appendNode(insertChild, parent);    else {        ASSERT(refChild->nextSibling());        insertNodeBefore(insertChild, refChild->nextSibling());    }}void CompositeEditCommand::insertNodeAt(PassRefPtr<Node> insertChild, const Position& editingPosition){    ASSERT(isEditablePosition(editingPosition));    // For editing positions like [table, 0], insert before the table,    // likewise for replaced elements, brs, etc.    Position p = rangeCompliantEquivalent(editingPosition);    Node* refChild = p.node();    int offset = p.offset();        if (canHaveChildrenForEditing(refChild)) {        Node* child = refChild->firstChild();        for (int i = 0; child && i < offset; i++)            child = child->nextSibling();        if (child)            insertNodeBefore(insertChild, child);        else            appendNode(insertChild, static_cast<Element*>(refChild));    } else if (caretMinOffset(refChild) >= offset)        insertNodeBefore(insertChild, refChild);    else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) {        splitTextNode(static_cast<Text *>(refChild), offset);        insertNodeBefore(insertChild, refChild);    } else        insertNodeAfter(insertChild, refChild);}void CompositeEditCommand::appendNode(PassRefPtr<Node> node, PassRefPtr<Element> parent){    ASSERT(canHaveChildrenForEditing(parent.get()));    applyCommandToComposite(AppendNodeCommand::create(parent, node));}void CompositeEditCommand::removeChildrenInRange(PassRefPtr<Node> node, unsigned from, unsigned to){    Vector<RefPtr<Node> > children;    Node* child = node->childNode(from);    for (unsigned i = from; child && i < to; i++, child = child->nextSibling())        children.append(child);    size_t size = children.size();    for (size_t i = 0; i < size; ++i)        removeNode(children[i].release());}void CompositeEditCommand::removeNode(PassRefPtr<Node> node){    applyCommandToComposite(RemoveNodeCommand::create(node));}void CompositeEditCommand::removeNodePreservingChildren(PassRefPtr<Node> node){    applyCommandToComposite(RemoveNodePreservingChildrenCommand::create(node));}void CompositeEditCommand::removeNodeAndPruneAncestors(PassRefPtr<Node> node){    RefPtr<Node> parent = node->parentNode();    removeNode(node);    prune(parent.release());}static bool hasARenderedDescendant(Node* node){    Node* n = node->firstChild();    while (n) {        if (n->renderer())            return true;        n = n->traverseNextNode(node);    }    return false;}void CompositeEditCommand::prune(PassRefPtr<Node> node){    while (node) {        // If you change this rule you may have to add an updateLayout() here.        RenderObject* renderer = node->renderer();        if (renderer && (!renderer->canHaveChildren() || hasARenderedDescendant(node.get()) || node->rootEditableElement() == node))            return;                    RefPtr<Node> next = node->parentNode();        removeNode(node);        node = next;    }}void CompositeEditCommand::splitTextNode(PassRefPtr<Text> node, unsigned offset){    applyCommandToComposite(SplitTextNodeCommand::create(node, offset));}void CompositeEditCommand::splitElement(PassRefPtr<Element> element, PassRefPtr<Node> atChild){    applyCommandToComposite(SplitElementCommand::create(element, atChild));}void CompositeEditCommand::mergeIdenticalElements(PassRefPtr<Element> prpFirst, PassRefPtr<Element> prpSecond){    RefPtr<Element> first = prpFirst;    RefPtr<Element> second = prpSecond;    ASSERT(!first->isDescendantOf(second.get()) && second != first);    if (first->nextSibling() != second) {        removeNode(second);        insertNodeAfter(second, first);    }    applyCommandToComposite(MergeIdenticalElementsCommand::create(first, second));}void CompositeEditCommand::wrapContentsInDummySpan(PassRefPtr<Element> element){    applyCommandToComposite(WrapContentsInDummySpanCommand::create(element));}void CompositeEditCommand::splitTextNodeContainingElement(PassRefPtr<Text> text, unsigned offset){    applyCommandToComposite(SplitTextNodeContainingElementCommand::create(text, offset));}void CompositeEditCommand::joinTextNodes(PassRefPtr<Text> text1, PassRefPtr<Text> text2){    applyCommandToComposite(JoinTextNodesCommand::create(text1, text2));}void CompositeEditCommand::inputText(const String& text, bool selectInsertedText){    int offset = 0;    int length = text.length();    RefPtr<Range> startRange = Range::create(document(), Position(document()->documentElement(), 0), endingSelection().start());    int startIndex = TextIterator::rangeLength(startRange.get());    int newline;    do {        newline = text.find('\n', offset);        if (newline != offset) {            RefPtr<InsertTextCommand> command = InsertTextCommand::create(document());            applyCommandToComposite(command);            int substringLength = newline == -1 ? length - offset : newline - offset;            command->input(text.substring(offset, substringLength), false);        }        if (newline != -1)            insertLineBreak();                    offset = newline + 1;    } while (newline != -1 && offset != length);        if (selectInsertedText) {        RefPtr<Range> selectedRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), startIndex, length);        setEndingSelection(VisibleSelection(selectedRange.get()));    }}void CompositeEditCommand::insertTextIntoNode(PassRefPtr<Text> node, unsigned offset, const String& text){    applyCommandToComposite(InsertIntoTextNodeCommand::create(node, offset, text));}void CompositeEditCommand::deleteTextFromNode(PassRefPtr<Text> node, unsigned offset, unsigned count){    applyCommandToComposite(DeleteFromTextNodeCommand::create(node, offset, count));}void CompositeEditCommand::replaceTextInNode(PassRefPtr<Text> node, unsigned offset, unsigned count, const String& replacementText){    applyCommandToComposite(DeleteFromTextNodeCommand::create(node.get(), offset, count));    applyCommandToComposite(InsertIntoTextNodeCommand::create(node, offset, replacementText));}Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos){    if (!isTabSpanTextNode(pos.node()))        return pos;        Node* tabSpan = tabSpanNode(pos.node());        if (pos.offset() <= caretMinOffset(pos.node()))        return positionBeforeNode(tabSpan);            if (pos.offset() >= caretMaxOffset(pos.node()))        return positionAfterNode(tabSpan);    splitTextNodeContainingElement(static_cast<Text *>(pos.node()), pos.offset());    return positionBeforeNode(tabSpan);}void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtr<Node> node, const Position& pos){    // insert node before, after, or at split of tab span    insertNodeAt(node, positionOutsideTabSpan(pos));}void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements){    if (endingSelection().isRange())        applyCommandToComposite(DeleteSelectionCommand::create(document(), smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements));}

⌨️ 快捷键说明

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