📄 typingcommand.cpp
字号:
/* * 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 "TypingCommand.h"#include "BeforeTextInsertedEvent.h"#include "BreakBlockquoteCommand.h"#include "DeleteSelectionCommand.h"#include "Document.h"#include "Editor.h"#include "Element.h"#include "Frame.h"#include "InsertLineBreakCommand.h"#include "InsertParagraphSeparatorCommand.h"#include "InsertTextCommand.h"#include "RenderObject.h"#include "SelectionController.h"#include "VisiblePosition.h"#include "htmlediting.h"#include "visible_units.h"namespace WebCore {TypingCommand::TypingCommand(Document *document, ETypingCommand commandType, const String &textToInsert, bool selectInsertedText, TextGranularity granularity, bool killRing) : CompositeEditCommand(document), m_commandType(commandType), m_textToInsert(textToInsert), m_openForMoreTyping(true), m_selectInsertedText(selectInsertedText), m_smartDelete(false), m_granularity(granularity), m_killRing(killRing), m_openedByBackwardDelete(false){}void TypingCommand::deleteSelection(Document* document, bool smartDelete){ ASSERT(document); Frame* frame = document->frame(); ASSERT(frame); if (!frame->selection()->isRange()) return; EditCommand* lastEditCommand = frame->editor()->lastEditCommand(); if (isOpenForMoreTypingCommand(lastEditCommand)) { static_cast<TypingCommand*>(lastEditCommand)->deleteSelection(smartDelete); return; } RefPtr<TypingCommand> typingCommand = TypingCommand::create(document, DeleteSelection, "", false); typingCommand->setSmartDelete(smartDelete); typingCommand->apply();}void TypingCommand::deleteKeyPressed(Document *document, bool smartDelete, TextGranularity granularity, bool killRing){ ASSERT(document); Frame *frame = document->frame(); ASSERT(frame); EditCommand* lastEditCommand = frame->editor()->lastEditCommand(); if (isOpenForMoreTypingCommand(lastEditCommand)) { static_cast<TypingCommand*>(lastEditCommand)->deleteKeyPressed(granularity, killRing); return; } RefPtr<TypingCommand> typingCommand = TypingCommand::create(document, DeleteKey, "", false, granularity, killRing); typingCommand->setSmartDelete(smartDelete); typingCommand->apply();}void TypingCommand::forwardDeleteKeyPressed(Document *document, bool smartDelete, TextGranularity granularity, bool killRing){ // FIXME: Forward delete in TextEdit appears to open and close a new typing command. ASSERT(document); Frame *frame = document->frame(); ASSERT(frame); EditCommand* lastEditCommand = frame->editor()->lastEditCommand(); if (isOpenForMoreTypingCommand(lastEditCommand)) { static_cast<TypingCommand*>(lastEditCommand)->forwardDeleteKeyPressed(granularity, killRing); return; } RefPtr<TypingCommand> typingCommand = TypingCommand::create(document, ForwardDeleteKey, "", false, granularity, killRing); typingCommand->setSmartDelete(smartDelete); typingCommand->apply();}void TypingCommand::insertText(Document* document, const String& text, bool selectInsertedText, bool insertedTextIsComposition){ ASSERT(document); Frame* frame = document->frame(); ASSERT(frame); insertText(document, text, frame->selection()->selection(), selectInsertedText, insertedTextIsComposition);}void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition){ ASSERT(document); RefPtr<Frame> frame = document->frame(); ASSERT(frame); VisibleSelection currentSelection = frame->selection()->selection(); bool changeSelection = currentSelection != selectionForInsertion; String newText = text; Node* startNode = selectionForInsertion.start().node(); if (startNode && startNode->rootEditableElement() && !insertedTextIsComposition) { // Send BeforeTextInsertedEvent. The event handler will update text if necessary. ExceptionCode ec = 0; RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text); startNode->rootEditableElement()->dispatchEvent(evt, ec); newText = evt->text(); } if (newText.isEmpty()) return; // Set the starting and ending selection appropriately if we are using a selection // that is different from the current selection. In the future, we should change EditCommand // to deal with custom selections in a general way that can be used by all of the commands. RefPtr<EditCommand> lastEditCommand = frame->editor()->lastEditCommand(); if (isOpenForMoreTypingCommand(lastEditCommand.get())) { TypingCommand* lastTypingCommand = static_cast<TypingCommand*>(lastEditCommand.get()); if (changeSelection) { lastTypingCommand->setStartingSelection(selectionForInsertion); lastTypingCommand->setEndingSelection(selectionForInsertion); } lastTypingCommand->insertText(newText, selectInsertedText); if (changeSelection) { lastTypingCommand->setEndingSelection(currentSelection); frame->selection()->setSelection(currentSelection); } return; } RefPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, selectInsertedText); if (changeSelection) { cmd->setStartingSelection(selectionForInsertion); cmd->setEndingSelection(selectionForInsertion); } applyCommand(cmd); if (changeSelection) { cmd->setEndingSelection(currentSelection); frame->selection()->setSelection(currentSelection); }}void TypingCommand::insertLineBreak(Document *document){ ASSERT(document); Frame *frame = document->frame(); ASSERT(frame); EditCommand* lastEditCommand = frame->editor()->lastEditCommand(); if (isOpenForMoreTypingCommand(lastEditCommand)) { static_cast<TypingCommand*>(lastEditCommand)->insertLineBreak(); return; } applyCommand(TypingCommand::create(document, InsertLineBreak));}void TypingCommand::insertParagraphSeparatorInQuotedContent(Document *document){ ASSERT(document); Frame *frame = document->frame(); ASSERT(frame); EditCommand* lastEditCommand = frame->editor()->lastEditCommand(); if (isOpenForMoreTypingCommand(lastEditCommand)) { static_cast<TypingCommand*>(lastEditCommand)->insertParagraphSeparatorInQuotedContent(); return; } applyCommand(TypingCommand::create(document, InsertParagraphSeparatorInQuotedContent));}void TypingCommand::insertParagraphSeparator(Document *document){ ASSERT(document); Frame *frame = document->frame(); ASSERT(frame); EditCommand* lastEditCommand = frame->editor()->lastEditCommand(); if (isOpenForMoreTypingCommand(lastEditCommand)) { static_cast<TypingCommand*>(lastEditCommand)->insertParagraphSeparator(); return; } applyCommand(TypingCommand::create(document, InsertParagraphSeparator));}bool TypingCommand::isOpenForMoreTypingCommand(const EditCommand* cmd){ return cmd && cmd->isTypingCommand() && static_cast<const TypingCommand*>(cmd)->isOpenForMoreTyping();}void TypingCommand::closeTyping(EditCommand* cmd){ if (isOpenForMoreTypingCommand(cmd)) static_cast<TypingCommand*>(cmd)->closeTyping();}void TypingCommand::doApply(){ if (endingSelection().isNone()) return; if (m_commandType == DeleteKey) if (m_commands.isEmpty()) m_openedByBackwardDelete = true; switch (m_commandType) { case DeleteSelection: deleteSelection(m_smartDelete); return; case DeleteKey: deleteKeyPressed(m_granularity, m_killRing); return; case ForwardDeleteKey: forwardDeleteKeyPressed(m_granularity, m_killRing); return; case InsertLineBreak: insertLineBreak(); return; case InsertParagraphSeparator: insertParagraphSeparator(); return; case InsertParagraphSeparatorInQuotedContent: insertParagraphSeparatorInQuotedContent(); return; case InsertText: insertText(m_textToInsert, m_selectInsertedText); return; } ASSERT_NOT_REACHED();}EditAction TypingCommand::editingAction() const{ return EditActionTyping;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -