📄 editor.cpp
字号:
ExceptionCode ec = 0; RefPtr<Event> evt = ClipboardEvent::create(eventType, true, true, clipboard); target->dispatchEvent(evt, ec); bool noDefaultProcessing = evt->defaultPrevented(); // invalidate clipboard here for security clipboard->setAccessPolicy(ClipboardNumb); return !noDefaultProcessing;}void Editor::applyStyle(CSSStyleDeclaration* style, EditAction editingAction){ switch (m_frame->selection()->selectionType()) { case VisibleSelection::NoSelection: // do nothing break; case VisibleSelection::CaretSelection: m_frame->computeAndSetTypingStyle(style, editingAction); break; case VisibleSelection::RangeSelection: if (style) applyCommand(ApplyStyleCommand::create(m_frame->document(), style, editingAction)); break; }} bool Editor::shouldApplyStyle(CSSStyleDeclaration* style, Range* range){ return client()->shouldApplyStyle(style, range);} void Editor::applyParagraphStyle(CSSStyleDeclaration* style, EditAction editingAction){ switch (m_frame->selection()->selectionType()) { case VisibleSelection::NoSelection: // do nothing break; case VisibleSelection::CaretSelection: case VisibleSelection::RangeSelection: if (style) applyCommand(ApplyStyleCommand::create(m_frame->document(), style, editingAction, ApplyStyleCommand::ForceBlockProperties)); break; }}void Editor::applyStyleToSelection(CSSStyleDeclaration* style, EditAction editingAction){ if (!style || style->length() == 0 || !canEditRichly()) return; if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toNormalizedRange().get())) applyStyle(style, editingAction);}void Editor::applyParagraphStyleToSelection(CSSStyleDeclaration* style, EditAction editingAction){ if (!style || style->length() == 0 || !canEditRichly()) return; if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toNormalizedRange().get())) applyParagraphStyle(style, editingAction);}bool Editor::clientIsEditable() const{ return client() && client()->isEditable();}bool Editor::selectionStartHasStyle(CSSStyleDeclaration* style) const{ Node* nodeToRemove; RefPtr<CSSComputedStyleDeclaration> selectionStyle = m_frame->selectionComputedStyle(nodeToRemove); if (!selectionStyle) return false; RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable(); bool match = true; CSSMutableStyleDeclaration::const_iterator end = mutableStyle->end(); for (CSSMutableStyleDeclaration::const_iterator it = mutableStyle->begin(); it != end; ++it) { int propertyID = (*it).id(); if (!equalIgnoringCase(mutableStyle->getPropertyValue(propertyID), selectionStyle->getPropertyValue(propertyID))) { match = false; break; } } if (nodeToRemove) { ExceptionCode ec = 0; nodeToRemove->remove(ec); ASSERT(ec == 0); } return match;}static void updateState(CSSMutableStyleDeclaration* desiredStyle, CSSComputedStyleDeclaration* computedStyle, bool& atStart, TriState& state){ CSSMutableStyleDeclaration::const_iterator end = desiredStyle->end(); for (CSSMutableStyleDeclaration::const_iterator it = desiredStyle->begin(); it != end; ++it) { int propertyID = (*it).id(); String desiredProperty = desiredStyle->getPropertyValue(propertyID); String computedProperty = computedStyle->getPropertyValue(propertyID); TriState propertyState = equalIgnoringCase(desiredProperty, computedProperty) ? TrueTriState : FalseTriState; if (atStart) { state = propertyState; atStart = false; } else if (state != propertyState) { state = MixedTriState; break; } }}TriState Editor::selectionHasStyle(CSSStyleDeclaration* style) const{ bool atStart = true; TriState state = FalseTriState; RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable(); if (!m_frame->selection()->isRange()) { Node* nodeToRemove; RefPtr<CSSComputedStyleDeclaration> selectionStyle = m_frame->selectionComputedStyle(nodeToRemove); if (!selectionStyle) return FalseTriState; updateState(mutableStyle.get(), selectionStyle.get(), atStart, state); if (nodeToRemove) { ExceptionCode ec = 0; nodeToRemove->remove(ec); ASSERT(ec == 0); } } else { for (Node* node = m_frame->selection()->start().node(); node; node = node->traverseNextNode()) { RefPtr<CSSComputedStyleDeclaration> nodeStyle = computedStyle(node); if (nodeStyle) updateState(mutableStyle.get(), nodeStyle.get(), atStart, state); if (state == MixedTriState) break; if (node == m_frame->selection()->end().node()) break; } } return state;}void Editor::indent(){ applyCommand(IndentOutdentCommand::create(m_frame->document(), IndentOutdentCommand::Indent));}void Editor::outdent(){ applyCommand(IndentOutdentCommand::create(m_frame->document(), IndentOutdentCommand::Outdent));}static void dispatchEditableContentChangedEvents(const EditCommand& command){ Element* startRoot = command.startingRootEditableElement(); Element* endRoot = command.endingRootEditableElement(); ExceptionCode ec; if (startRoot) startRoot->dispatchEvent(Event::create(eventNames().webkitEditableContentChangedEvent, false, false), ec); if (endRoot && endRoot != startRoot) endRoot->dispatchEvent(Event::create(eventNames().webkitEditableContentChangedEvent, false, false), ec);}void Editor::appliedEditing(PassRefPtr<EditCommand> cmd){ dispatchEditableContentChangedEvents(*cmd); VisibleSelection newSelection(cmd->endingSelection()); // Don't clear the typing style with this selection change. We do those things elsewhere if necessary. changeSelectionAfterCommand(newSelection, false, false, cmd.get()); if (!cmd->preservesTypingStyle()) m_frame->setTypingStyle(0); // Command will be equal to last edit command only in the case of typing if (m_lastEditCommand.get() == cmd) ASSERT(cmd->isTypingCommand()); else { // Only register a new undo command if the command passed in is // different from the last command m_lastEditCommand = cmd; if (client()) client()->registerCommandForUndo(m_lastEditCommand); } respondToChangedContents(newSelection); }void Editor::unappliedEditing(PassRefPtr<EditCommand> cmd){ dispatchEditableContentChangedEvents(*cmd); VisibleSelection newSelection(cmd->startingSelection()); changeSelectionAfterCommand(newSelection, true, true, cmd.get()); m_lastEditCommand = 0; if (client()) client()->registerCommandForRedo(cmd); respondToChangedContents(newSelection); }void Editor::reappliedEditing(PassRefPtr<EditCommand> cmd){ dispatchEditableContentChangedEvents(*cmd); VisibleSelection newSelection(cmd->endingSelection()); changeSelectionAfterCommand(newSelection, true, true, cmd.get()); m_lastEditCommand = 0; if (client()) client()->registerCommandForUndo(cmd); respondToChangedContents(newSelection); }Editor::Editor(Frame* frame) : m_frame(frame) , m_deleteButtonController(new DeleteButtonController(frame)) , m_ignoreCompositionSelectionChange(false) , m_shouldStartNewKillRingSequence(false) // This is off by default, since most editors want this behavior (this matches IE but not FF). , m_shouldStyleWithCSS(false){ }Editor::~Editor(){}void Editor::clear(){ m_compositionNode = 0; m_customCompositionUnderlines.clear(); m_shouldStyleWithCSS = false;}bool Editor::insertText(const String& text, Event* triggeringEvent){ return m_frame->eventHandler()->handleTextInputEvent(text, triggeringEvent);}bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectInsertedText, Event* triggeringEvent){ if (text.isEmpty()) return false; VisibleSelection selection = selectionForCommand(triggeringEvent); if (!selection.isContentEditable()) return false; RefPtr<Range> range = selection.toNormalizedRange(); if (!shouldInsertText(text, range.get(), EditorInsertActionTyped)) return true; // Get the selection to use for the event that triggered this insertText. // If the event handler changed the selection, we may want to use a different selection // that is contained in the event target. selection = selectionForCommand(triggeringEvent); if (selection.isContentEditable()) { if (Node* selectionStart = selection.start().node()) { RefPtr<Document> document = selectionStart->document(); // Insert the text TypingCommand::insertText(document.get(), text, selection, selectInsertedText); // Reveal the current selection if (Frame* editedFrame = document->frame()) if (Page* page = editedFrame->page()) page->focusController()->focusedOrMainFrame()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); } } return true;}bool Editor::insertLineBreak(){ if (!canEdit()) return false; if (!shouldInsertText("\n", m_frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped)) return true; TypingCommand::insertLineBreak(m_frame->document()); revealSelectionAfterEditingOperation(); return true;}bool Editor::insertParagraphSeparator(){ if (!canEdit()) return false; if (!canEditRichly()) return insertLineBreak(); if (!shouldInsertText("\n", m_frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped)) return true; TypingCommand::insertParagraphSeparator(m_frame->document()); revealSelectionAfterEditingOperation(); return true;}void Editor::cut(){ if (tryDHTMLCut()) return; // DHTML did the whole operation if (!canCut()) { systemBeep(); return; } RefPtr<Range> selection = selectedRange(); if (shouldDeleteRange(selection.get())) { Pasteboard::generalPasteboard()->writeSelection(selection.get(), canSmartCopyOrDelete(), m_frame); didWriteSelectionToPasteboard(); deleteSelectionWithSmartDelete(canSmartCopyOrDelete()); }}void Editor::copy(){ if (tryDHTMLCopy()) return; // DHTML did the whole operation if (!canCopy()) { systemBeep(); return; } Document* document = m_frame->document(); if (HTMLImageElement* imageElement = imageElementFromImageDocument(document)) Pasteboard::generalPasteboard()->writeImage(imageElement, document->url(), document->title()); else Pasteboard::generalPasteboard()->writeSelection(selectedRange().get(), canSmartCopyOrDelete(), m_frame); didWriteSelectionToPasteboard();}#if !PLATFORM(MAC)void Editor::paste(){ ASSERT(m_frame->document()); if (tryDHTMLPaste())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -