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

📄 dragcontroller.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2007, 2009 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 "DragController.h"#include "CSSStyleDeclaration.h"#include "Clipboard.h"#include "ClipboardAccessPolicy.h"#include "DocLoader.h"#include "Document.h"#include "DocumentFragment.h"#include "DragActions.h"#include "DragClient.h"#include "DragData.h"#include "Editor.h"#include "EditorClient.h"#include "Element.h"#include "EventHandler.h"#include "FloatRect.h"#include "Frame.h"#include "FrameLoader.h"#include "FrameView.h"#include "HTMLAnchorElement.h"#include "HTMLInputElement.h"#include "HTMLNames.h"#include "HitTestResult.h"#include "Image.h"#include "MoveSelectionCommand.h"#include "Node.h"#include "Page.h"#include "RenderFileUploadControl.h"#include "RenderImage.h"#include "ReplaceSelectionCommand.h"#include "ResourceRequest.h"#include "SelectionController.h"#include "Settings.h"#include "Text.h"#include "htmlediting.h"#include "markup.h"#include <wtf/CurrentTime.h>#include <wtf/RefPtr.h>namespace WebCore {static PlatformMouseEvent createMouseEvent(DragData* dragData){    // FIXME: We should fake modifier keys here.    return PlatformMouseEvent(dragData->clientPosition(), dragData->globalPosition(),                              LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime());}    DragController::DragController(Page* page, DragClient* client)    : m_page(page)    , m_client(client)    , m_document(0)    , m_dragInitiator(0)    , m_dragDestinationAction(DragDestinationActionNone)    , m_dragSourceAction(DragSourceActionNone)    , m_didInitiateDrag(false)    , m_isHandlingDrag(false)    , m_dragOperation(DragOperationNone){}    DragController::~DragController(){       m_client->dragControllerDestroyed();}    static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragData, RefPtr<Range> context,                                          bool allowPlainText, bool& chosePlainText){    ASSERT(dragData);    chosePlainText = false;    Document* document = context->ownerDocument();    ASSERT(document);    if (document && dragData->containsCompatibleContent()) {        if (PassRefPtr<DocumentFragment> fragment = dragData->asFragment(document))            return fragment;        if (dragData->containsURL()) {            String title;            String url = dragData->asURL(&title);            if (!url.isEmpty()) {                RefPtr<HTMLAnchorElement> anchor = new HTMLAnchorElement(document);                anchor->setHref(url);                ExceptionCode ec;                RefPtr<Node> anchorText = document->createTextNode(title);                anchor->appendChild(anchorText, ec);                RefPtr<DocumentFragment> fragment = document->createDocumentFragment();                fragment->appendChild(anchor, ec);                return fragment.get();            }        }    }    if (allowPlainText && dragData->containsPlainText()) {        chosePlainText = true;        return createFragmentFromText(context.get(), dragData->asPlainText()).get();    }        return 0;}bool DragController::dragIsMove(SelectionController* selection){    return m_document == m_dragInitiator && selection->isContentEditable() && !isCopyKeyDown();}void DragController::cancelDrag(){    m_page->dragCaretController()->clear();}void DragController::dragEnded(){    m_dragInitiator = 0;    m_didInitiateDrag = false;     m_page->dragCaretController()->clear(); }    DragOperation DragController::dragEntered(DragData* dragData) {    return dragEnteredOrUpdated(dragData);}    void DragController::dragExited(DragData* dragData) {       ASSERT(dragData);    Frame* mainFrame = m_page->mainFrame();        if (RefPtr<FrameView> v = mainFrame->view()) {        ClipboardAccessPolicy policy = mainFrame->loader()->baseURL().isLocalFile() ? ClipboardReadable : ClipboardTypesReadable;        RefPtr<Clipboard> clipboard = dragData->createClipboard(policy);        clipboard->setSourceOperation(dragData->draggingSourceOperationMask());        mainFrame->eventHandler()->cancelDragAndDrop(createMouseEvent(dragData), clipboard.get());        clipboard->setAccessPolicy(ClipboardNumb);    // invalidate clipboard here for security    }    cancelDrag();    m_document = 0;}    DragOperation DragController::dragUpdated(DragData* dragData) {    return dragEnteredOrUpdated(dragData);}    bool DragController::performDrag(DragData* dragData){       ASSERT(dragData);    m_document = m_page->mainFrame()->documentAtPoint(dragData->clientPosition());    if (m_isHandlingDrag) {        ASSERT(m_dragDestinationAction & DragDestinationActionDHTML);        m_client->willPerformDragDestinationAction(DragDestinationActionDHTML, dragData);        RefPtr<Frame> mainFrame = m_page->mainFrame();        if (mainFrame->view()) {            // Sending an event can result in the destruction of the view and part.            RefPtr<Clipboard> clipboard = dragData->createClipboard(ClipboardReadable);            clipboard->setSourceOperation(dragData->draggingSourceOperationMask());            mainFrame->eventHandler()->performDragAndDrop(createMouseEvent(dragData), clipboard.get());            clipboard->setAccessPolicy(ClipboardNumb);    // invalidate clipboard here for security        }        m_document = 0;        return true;    }         if ((m_dragDestinationAction & DragDestinationActionEdit) && concludeEditDrag(dragData)) {        m_document = 0;        return true;    }        m_document = 0;    if (operationForLoad(dragData) == DragOperationNone)        return false;    m_client->willPerformDragDestinationAction(DragDestinationActionLoad, dragData);    m_page->mainFrame()->loader()->load(ResourceRequest(dragData->asURL()), false);    return true;}    DragOperation DragController::dragEnteredOrUpdated(DragData* dragData){    ASSERT(dragData);    IntPoint windowPoint = dragData->clientPosition();        Document* newDraggingDoc = 0;    if (Frame* frame = m_page->mainFrame())        newDraggingDoc = frame->documentAtPoint(windowPoint);    if (m_document != newDraggingDoc) {        if (m_document)            cancelDrag();        m_document = newDraggingDoc;    }        m_dragDestinationAction = m_client->actionMaskForDrag(dragData);        DragOperation operation = DragOperationNone;        if (m_dragDestinationAction == DragDestinationActionNone)        cancelDrag();    else {        operation = tryDocumentDrag(dragData, m_dragDestinationAction);        if (operation == DragOperationNone && (m_dragDestinationAction & DragDestinationActionLoad))            return operationForLoad(dragData);    }        return operation;}static HTMLInputElement* asFileInput(Node* node){    ASSERT(node);        // The button for a FILE input is a sub element with no set input type    // In order to get around this problem we assume any non-FILE input element    // is this internal button, and try querying the shadow parent node.    if (node->hasTagName(HTMLNames::inputTag) && node->isShadowNode() && static_cast<HTMLInputElement*>(node)->inputType() != HTMLInputElement::FILE)      node = node->shadowParentNode();        if (!node || !node->hasTagName(HTMLNames::inputTag))        return 0;        HTMLInputElement* inputElem = static_cast<HTMLInputElement*>(node);    if (inputElem->inputType() == HTMLInputElement::FILE)        return inputElem;        return 0;}    DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask){    ASSERT(dragData);        if (!m_document)        return DragOperationNone;        DragOperation operation = DragOperationNone;    if (actionMask & DragDestinationActionDHTML)        operation = tryDHTMLDrag(dragData);    m_isHandlingDrag = operation != DragOperationNone;     RefPtr<FrameView> frameView = m_document->view();    if (!frameView)        return operation;        if ((actionMask & DragDestinationActionEdit) && !m_isHandlingDrag && canProcessDrag(dragData)) {        if (dragData->containsColor())             return DragOperationGeneric;                IntPoint dragPos = dragData->clientPosition();        IntPoint point = frameView->windowToContents(dragPos);        Element* element = m_document->elementFromPoint(point.x(), point.y());        ASSERT(element);        Frame* innerFrame = element->document()->frame();        ASSERT(innerFrame);        if (!asFileInput(element)) {            VisibleSelection dragCaret;            if (Frame* frame = m_document->frame())                dragCaret = frame->visiblePositionForPoint(point);            m_page->dragCaretController()->setSelection(dragCaret);        }                return dragIsMove(innerFrame->selection()) ? DragOperationMove : DragOperationCopy;    }         m_page->dragCaretController()->clear();    return operation;}DragSourceAction DragController::delegateDragSourceAction(const IntPoint& windowPoint){      m_dragSourceAction = m_client->dragSourceActionMaskForPoint(windowPoint);    return m_dragSourceAction;}    DragOperation DragController::operationForLoad(DragData* dragData){    ASSERT(dragData);    Document* doc = 0;    doc = m_page->mainFrame()->documentAtPoint(dragData->clientPosition());    if (doc && (m_didInitiateDrag || doc->isPluginDocument() || (doc->frame() && doc->frame()->editor()->clientIsEditable())))        return DragOperationNone;    return dragOperation(dragData);}static bool setSelectionToDragCaret(Frame* frame, VisibleSelection& dragCaret, RefPtr<Range>& range, const IntPoint& point){    frame->selection()->setSelection(dragCaret);    if (frame->selection()->isNone()) {        dragCaret = frame->visiblePositionForPoint(point);        frame->selection()->setSelection(dragCaret);        range = dragCaret.toNormalizedRange();    }    return !frame->selection()->isNone() && frame->selection()->isContentEditable();}bool DragController::concludeEditDrag(DragData* dragData){    ASSERT(dragData);    ASSERT(!m_isHandlingDrag);        if (!m_document)        return false;        IntPoint point = m_document->view()->windowToContents(dragData->clientPosition());    Element* element =  m_document->elementFromPoint(point.x(), point.y());    ASSERT(element);    Frame* innerFrame = element->ownerDocument()->frame();    ASSERT(innerFrame);        if (dragData->containsColor()) {        Color color = dragData->asColor();        if (!color.isValid())            return false;        if (!innerFrame)            return false;        RefPtr<Range> innerRange = innerFrame->selection()->toNormalizedRange();        RefPtr<CSSStyleDeclaration> style = m_document->createCSSStyleDeclaration();        ExceptionCode ec;        style->setProperty("color", color.name(), ec);        if (!innerFrame->editor()->shouldApplyStyle(style.get(), innerRange.get()))            return false;        m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData);        innerFrame->editor()->applyStyle(style.get(), EditActionSetColor);        return true;    }        if (!m_page->dragController()->canProcessDrag(dragData)) {        m_page->dragCaretController()->clear();        return false;    }        if (HTMLInputElement* fileInput = asFileInput(element)) {                if (!fileInput->isEnabled())            return false;                if (!dragData->containsFiles())            return false;                Vector<String> filenames;        dragData->asFilenames(filenames);        if (filenames.isEmpty())            return false;                // Ugly.  For security none of the API's available to us to set the input value         // on file inputs.  Even forcing a change in HTMLInputElement doesn't work as        // RenderFileUploadControl clears the file when doing updateFromElement()        RenderFileUploadControl* renderer = static_cast<RenderFileUploadControl*>(fileInput->renderer());                if (!renderer)            return false;                renderer->receiveDroppedFiles(filenames);        return true;    }    VisibleSelection dragCaret(m_page->dragCaretController()->selection());    m_page->dragCaretController()->clear();    RefPtr<Range> range = dragCaret.toNormalizedRange();        // For range to be null a WebKit client must have done something bad while    // manually controlling drag behaviour    if (!range)  

⌨️ 快捷键说明

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