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

📄 editor.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * 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 "Editor.h"#include "AXObjectCache.h"#include "ApplyStyleCommand.h"#include "CSSComputedStyleDeclaration.h"#include "CSSProperty.h"#include "CSSPropertyNames.h"#include "CSSValueKeywords.h"#include "ClipboardEvent.h"#include "DeleteButtonController.h"#include "DeleteSelectionCommand.h"#include "DocLoader.h"#include "DocumentFragment.h"#include "EditorClient.h"#include "EventHandler.h"#include "EventNames.h"#include "FocusController.h"#include "Frame.h"#include "FrameTree.h"#include "FrameView.h"#include "HTMLInputElement.h"#include "HTMLTextAreaElement.h"#include "HitTestResult.h"#include "IndentOutdentCommand.h"#include "InsertListCommand.h"#include "KeyboardEvent.h"#include "ModifySelectionListLevel.h"#include "Page.h"#include "Pasteboard.h"#include "RemoveFormatCommand.h"#include "RenderBlock.h"#include "RenderPart.h"#include "ReplaceSelectionCommand.h"#include "Sound.h"#include "Text.h"#include "TextIterator.h"#include "TypingCommand.h"#include "htmlediting.h"#include "markup.h"#include "visible_units.h"#include <wtf/UnusedParam.h>namespace WebCore {using namespace std;using namespace HTMLNames;// When an event handler has moved the selection outside of a text control// we should use the target control's selection for this editing operation.VisibleSelection Editor::selectionForCommand(Event* event){    VisibleSelection selection = m_frame->selection()->selection();    if (!event)        return selection;    // If the target is a text control, and the current selection is outside of its shadow tree,    // then use the saved selection for that text control.    Node* target = event->target()->toNode();    Node* selectionStart = selection.start().node();    if (target && (!selectionStart || target->shadowAncestorNode() != selectionStart->shadowAncestorNode())) {        if (target->hasTagName(inputTag) && static_cast<HTMLInputElement*>(target)->isTextField())            return static_cast<HTMLInputElement*>(target)->selection();        if (target->hasTagName(textareaTag))            return static_cast<HTMLTextAreaElement*>(target)->selection();    }    return selection;}EditorClient* Editor::client() const{    if (Page* page = m_frame->page())        return page->editorClient();    return 0;}void Editor::handleKeyboardEvent(KeyboardEvent* event){    if (EditorClient* c = client())        c->handleKeyboardEvent(event);}void Editor::handleInputMethodKeydown(KeyboardEvent* event){    if (EditorClient* c = client())        c->handleInputMethodKeydown(event);}bool Editor::canEdit() const{    return m_frame->selection()->isContentEditable();}bool Editor::canEditRichly() const{    return m_frame->selection()->isContentRichlyEditable();}// WinIE uses onbeforecut and onbeforepaste to enables the cut and paste menu items.  They// also send onbeforecopy, apparently for symmetry, but it doesn't affect the menu items.// We need to use onbeforecopy as a real menu enabler because we allow elements that are not// normally selectable to implement copy/paste (like divs, or a document body).bool Editor::canDHTMLCut(){    return !m_frame->selection()->isInPasswordField() && !dispatchCPPEvent(eventNames().beforecutEvent, ClipboardNumb);}bool Editor::canDHTMLCopy(){    return !m_frame->selection()->isInPasswordField() && !dispatchCPPEvent(eventNames().beforecopyEvent, ClipboardNumb);}bool Editor::canDHTMLPaste(){    return !dispatchCPPEvent(eventNames().beforepasteEvent, ClipboardNumb);}bool Editor::canCut() const{    return canCopy() && canDelete();}static HTMLImageElement* imageElementFromImageDocument(Document* document){    if (!document)        return 0;    if (!document->isImageDocument())        return 0;        HTMLElement* body = document->body();    if (!body)        return 0;        Node* node = body->firstChild();    if (!node)        return 0;        if (!node->hasTagName(imgTag))        return 0;    return static_cast<HTMLImageElement*>(node);}bool Editor::canCopy() const{    if (imageElementFromImageDocument(m_frame->document()))        return true;    SelectionController* selection = m_frame->selection();    return selection->isRange() && !selection->isInPasswordField();}bool Editor::canPaste() const{    return canEdit();}bool Editor::canDelete() const{    SelectionController* selection = m_frame->selection();    return selection->isRange() && selection->isContentEditable();}bool Editor::canDeleteRange(Range* range) const{    ExceptionCode ec = 0;    Node* startContainer = range->startContainer(ec);    Node* endContainer = range->endContainer(ec);    if (!startContainer || !endContainer)        return false;        if (!startContainer->isContentEditable() || !endContainer->isContentEditable())        return false;        if (range->collapsed(ec)) {        VisiblePosition start(startContainer, range->startOffset(ec), DOWNSTREAM);        VisiblePosition previous = start.previous();        // FIXME: We sometimes allow deletions at the start of editable roots, like when the caret is in an empty list item.        if (previous.isNull() || previous.deepEquivalent().node()->rootEditableElement() != startContainer->rootEditableElement())            return false;    }    return true;}bool Editor::smartInsertDeleteEnabled(){       return client() && client()->smartInsertDeleteEnabled();}    bool Editor::canSmartCopyOrDelete(){    return client() && client()->smartInsertDeleteEnabled() && m_frame->selectionGranularity() == WordGranularity;}bool Editor::isSelectTrailingWhitespaceEnabled(){    return client() && client()->isSelectTrailingWhitespaceEnabled();}bool Editor::deleteWithDirection(SelectionController::EDirection direction, TextGranularity granularity, bool killRing, bool isTypingAction){    if (!canEdit())        return false;    if (m_frame->selection()->isRange()) {        if (isTypingAction) {            TypingCommand::deleteKeyPressed(m_frame->document(), canSmartCopyOrDelete(), granularity);            revealSelectionAfterEditingOperation();        } else {            if (killRing)                addToKillRing(selectedRange().get(), false);            deleteSelectionWithSmartDelete(canSmartCopyOrDelete());            // Implicitly calls revealSelectionAfterEditingOperation().        }    } else {                switch (direction) {            case SelectionController::FORWARD:            case SelectionController::RIGHT:                TypingCommand::forwardDeleteKeyPressed(m_frame->document(), canSmartCopyOrDelete(), granularity, killRing);                break;            case SelectionController::BACKWARD:            case SelectionController::LEFT:                TypingCommand::deleteKeyPressed(m_frame->document(), canSmartCopyOrDelete(), granularity, killRing);                break;        }        revealSelectionAfterEditingOperation();    }    // FIXME: We should to move this down into deleteKeyPressed.    // clear the "start new kill ring sequence" setting, because it was set to true    // when the selection was updated by deleting the range    if (killRing)        setStartNewKillRingSequence(false);    return true;}void Editor::deleteSelectionWithSmartDelete(bool smartDelete){    if (m_frame->selection()->isNone())        return;        applyCommand(DeleteSelectionCommand::create(m_frame->document(), smartDelete));}void Editor::pasteAsPlainTextWithPasteboard(Pasteboard* pasteboard){    String text = pasteboard->plainText(m_frame);    if (client() && client()->shouldInsertText(text, selectedRange().get(), EditorInsertActionPasted))        replaceSelectionWithText(text, false, canSmartReplaceWithPasteboard(pasteboard));}void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText){    RefPtr<Range> range = selectedRange();    bool chosePlainText;    RefPtr<DocumentFragment> fragment = pasteboard->documentFragment(m_frame, range, allowPlainText, chosePlainText);    if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted))        replaceSelectionWithFragment(fragment, false, canSmartReplaceWithPasteboard(pasteboard), chosePlainText);}bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard){    return client() && client()->smartInsertDeleteEnabled() && pasteboard->canSmartReplace();}bool Editor::shouldInsertFragment(PassRefPtr<DocumentFragment> fragment, PassRefPtr<Range> replacingDOMRange, EditorInsertAction givenAction){    if (!client())        return false;            Node* child = fragment->firstChild();    if (child && fragment->lastChild() == child && child->isCharacterDataNode())        return client()->shouldInsertText(static_cast<CharacterData*>(child)->data(), replacingDOMRange.get(), givenAction);    return client()->shouldInsertNode(fragment.get(), replacingDOMRange.get(), givenAction);}void Editor::replaceSelectionWithFragment(PassRefPtr<DocumentFragment> fragment, bool selectReplacement, bool smartReplace, bool matchStyle){    if (m_frame->selection()->isNone() || !fragment)        return;        applyCommand(ReplaceSelectionCommand::create(m_frame->document(), fragment, selectReplacement, smartReplace, matchStyle));    revealSelectionAfterEditingOperation();}void Editor::replaceSelectionWithText(const String& text, bool selectReplacement, bool smartReplace){    replaceSelectionWithFragment(createFragmentFromText(selectedRange().get(), text), selectReplacement, smartReplace, true); }PassRefPtr<Range> Editor::selectedRange(){    if (!m_frame)        return 0;    return m_frame->selection()->toNormalizedRange();}bool Editor::shouldDeleteRange(Range* range) const{    ExceptionCode ec;    if (!range || range->collapsed(ec))        return false;        if (!canDeleteRange(range))        return false;    return client() && client()->shouldDeleteRange(range);}bool Editor::tryDHTMLCopy(){       if (m_frame->selection()->isInPasswordField())        return false;    // Must be done before oncopy adds types and data to the pboard,    // also done for security, as it erases data from the last copy/paste.    Pasteboard::generalPasteboard()->clear();    return !dispatchCPPEvent(eventNames().copyEvent, ClipboardWritable);}bool Editor::tryDHTMLCut(){    if (m_frame->selection()->isInPasswordField())

⌨️ 快捷键说明

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