/*
 * Copyright (C) 2007-2022 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 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 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 "HTMLAnchorElement.h"
#include "SVGAElement.h"
#include "SVGElementTypeHelpers.h"


#if ENABLE(DRAG_SUPPORT)
#include "CachedImage.h"
#include "CachedResourceLoader.h"
#include "ColorSerialization.h"
#include "DataTransfer.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DragActions.h"
#include "DragClient.h"
#include "DragData.h"
#include "DragImage.h"
#include "DragState.h"
#include "Editing.h"
#include "Editor.h"
#include "EditorClient.h"
#include "ElementAncestorIterator.h"
#include "EventHandler.h"
#include "EventLoop.h"
#include "File.h"
#include "FloatRect.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameLoadRequest.h"
#include "FrameLoader.h"
#include "FrameSelection.h"
#include "FrameView.h"
#include "HTMLAttachmentElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLModelElement.h"
#include "HTMLParserIdioms.h"
#include "HTMLPlugInElement.h"
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "Image.h"
#include "ImageOrientation.h"
#include "ImageOverlay.h"
#include "Model.h"
#include "MoveSelectionCommand.h"
#include "Page.h"
#include "Pasteboard.h"
#include "PlatformKeyboardEvent.h"
#include "PluginDocument.h"
#include "PluginViewBase.h"
#include "Position.h"
#include "PromisedAttachmentInfo.h"
#include "Range.h"
#include "RenderAttachment.h"
#include "RenderFileUploadControl.h"
#include "RenderImage.h"
#include "RenderView.h"
#include "ReplaceSelectionCommand.h"
#include "ResourceRequest.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include "ShadowRoot.h"
#include "SimpleRange.h"
#include "StyleProperties.h"
#include "Text.h"
#include "TextEvent.h"
#include "VisiblePosition.h"
#include "WebContentReader.h"
#include "markup.h"
#include <wtf/SetForScope.h>
#endif

#if ENABLE(DATA_DETECTION)
#include "DataDetection.h"
#endif

#if PLATFORM(IOS_FAMILY)
#include "SelectionGeometry.h"
#endif

namespace WebCore {

bool isDraggableLink(const Element& element)
{
    if (is<HTMLAnchorElement>(element)) {
        auto& anchorElement = downcast<HTMLAnchorElement>(element);
        if (!anchorElement.isLiveLink())
            return false;
#if ENABLE(DATA_DETECTION)
        return !DataDetection::isDataDetectorURL(anchorElement.href());
#else
        return true;
#endif
    }
    if (is<SVGAElement>(element))
        return element.isLink();
    return false;
}

#if ENABLE(DRAG_SUPPORT)
    
static PlatformMouseEvent createMouseEvent(const DragData& dragData)
{
    bool shiftKey = false;
    bool ctrlKey = false;
    bool altKey = false;
    bool metaKey = false;

    PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);

    return PlatformMouseEvent(dragData.clientPosition(), dragData.globalPosition(),
                              LeftButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey,
                              metaKey, WallTime::now(), ForceAtClick, NoTap);
}

DragController::DragController(Page& page, std::unique_ptr<DragClient>&& client)
    : m_page(page)
    , m_client(WTFMove(client))
{
}

DragController::~DragController() = default;

static RefPtr<DocumentFragment> documentFragmentFromDragData(const DragData& dragData, Frame& frame, const SimpleRange& context, bool allowPlainText, bool& chosePlainText)
{
    chosePlainText = false;

    if (dragData.containsCompatibleContent()) {
        if (auto fragment = frame.editor().webContentFromPasteboard(*Pasteboard::create(dragData), context, allowPlainText, chosePlainText))
            return fragment;

        if (dragData.containsURL(DragData::DoNotConvertFilenames)) {
            String title;
            String url = dragData.asURL(DragData::DoNotConvertFilenames, &title);
            if (!url.isEmpty()) {
                auto& document = context.start.document();
                auto anchor = HTMLAnchorElement::create(document);
                anchor->setHref(AtomString { url });
                if (title.isEmpty()) {
                    // Try the plain text first because the URL might be normalized or escaped.
                    if (dragData.containsPlainText())
                        title = dragData.asPlainText();
                    if (title.isEmpty())
                        title = url;
                }
                anchor->appendChild(document.createTextNode(WTFMove(title)));
                auto fragment = document.createDocumentFragment();
                fragment->appendChild(anchor);
                return fragment;
            }
        }
    }
    if (allowPlainText && dragData.containsPlainText()) {
        chosePlainText = true;
        return createFragmentFromText(context, dragData.asPlainText()).ptr();
    }

    return nullptr;
}

#if !PLATFORM(IOS_FAMILY)

DragOperation DragController::platformGenericDragOperation()
{
    return DragOperation::Move;
}

#endif

bool DragController::dragIsMove(FrameSelection& selection, const DragData& dragData)
{
    const VisibleSelection& visibleSelection = selection.selection();
    return m_documentUnderMouse == m_dragInitiator && visibleSelection.isContentEditable() && visibleSelection.isRange() && !isCopyKeyDown(dragData);
}

void DragController::clearDragCaret()
{
    m_page.dragCaretController().clear();
}

void DragController::dragEnded()
{
    m_dragInitiator = nullptr;
    m_didInitiateDrag = false;
    m_documentUnderMouse = nullptr;
    clearDragCaret();
    removeAllDroppedImagePlaceholders();
    
    client().dragEnded();
}

std::optional<DragOperation> DragController::dragEntered(const DragData& dragData)
{
    return dragEnteredOrUpdated(dragData);
}

void DragController::dragExited(const DragData& dragData)
{
    auto& mainFrame = m_page.mainFrame();
    if (mainFrame.view())
        mainFrame.eventHandler().cancelDragAndDrop(createMouseEvent(dragData), Pasteboard::create(dragData), dragData.draggingSourceOperationMask(), dragData.containsFiles());
    mouseMovedIntoDocument(nullptr);
    if (m_fileInputElementUnderMouse)
        m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
    m_fileInputElementUnderMouse = nullptr;
}

std::optional<DragOperation> DragController::dragUpdated(const DragData& dragData)
{
    return dragEnteredOrUpdated(dragData);
}

inline static bool dragIsHandledByDocument(DragHandlingMethod dragHandlingMethod)
{
    return dragHandlingMethod != DragHandlingMethod::None && dragHandlingMethod != DragHandlingMethod::PageLoad;
}

bool DragController::performDragOperation(const DragData& dragData)
{
    if (!m_droppedImagePlaceholders.isEmpty() && m_droppedImagePlaceholderRange && tryToUpdateDroppedImagePlaceholders(dragData)) {
        m_droppedImagePlaceholders.clear();
        m_droppedImagePlaceholderRange = std::nullopt;
        m_documentUnderMouse = nullptr;
        clearDragCaret();
        return true;
    }

    removeAllDroppedImagePlaceholders();

    SetForScope isPerformingDrop(m_isPerformingDrop, true);
    IgnoreSelectionChangeForScope ignoreSelectionChanges { m_page.focusController().focusedOrMainFrame() };

    m_documentUnderMouse = m_page.mainFrame().documentAtPoint(dragData.clientPosition());

    ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow;
    if (m_documentUnderMouse)
        shouldOpenExternalURLsPolicy = m_documentUnderMouse->shouldOpenExternalURLsPolicyToPropagate();

    if ((m_dragDestinationActionMask.contains(DragDestinationAction::DHTML)) && dragIsHandledByDocument(m_dragHandlingMethod)) {
        client().willPerformDragDestinationAction(DragDestinationAction::DHTML, dragData);
        Ref<Frame> mainFrame(m_page.mainFrame());
        bool preventedDefault = false;
        if (mainFrame->view())
            preventedDefault = mainFrame->eventHandler().performDragAndDrop(createMouseEvent(dragData), Pasteboard::create(dragData), dragData.draggingSourceOperationMask(), dragData.containsFiles());
        if (preventedDefault) {
            clearDragCaret();
            m_documentUnderMouse = nullptr;
            return true;
        }
    }

    if ((m_dragDestinationActionMask.contains(DragDestinationAction::Edit)) && concludeEditDrag(dragData)) {
        client().didConcludeEditDrag();
        m_documentUnderMouse = nullptr;
        clearDragCaret();
        return true;
    }

    m_documentUnderMouse = nullptr;
    clearDragCaret();

    if (!operationForLoad(dragData))
        return false;

    auto urlString = dragData.asURL();
    if (urlString.isEmpty())
        return false;

    client().willPerformDragDestinationAction(DragDestinationAction::Load, dragData);
    ResourceRequest resourceRequest { urlString };
    resourceRequest.setIsAppInitiated(false);
    FrameLoadRequest frameLoadRequest { m_page.mainFrame(), resourceRequest };
    frameLoadRequest.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicy);
    frameLoadRequest.setIsRequestFromClientOrUserInput();
    m_page.mainFrame().loader().load(WTFMove(frameLoadRequest));
    return true;
}

void DragController::mouseMovedIntoDocument(Document* newDocument)
{
    if (m_documentUnderMouse == newDocument)
        return;

    // If we were over another document clear the selection
    if (m_documentUnderMouse)
        clearDragCaret();
    m_documentUnderMouse = newDocument;
}

std::optional<DragOperation> DragController::dragEnteredOrUpdated(const DragData& dragData)
{
    mouseMovedIntoDocument(m_page.mainFrame().documentAtPoint(dragData.clientPosition()));

    m_dragDestinationActionMask = dragData.dragDestinationActionMask();
    if (m_dragDestinationActionMask.isEmpty()) {
        clearDragCaret(); // FIXME: Why not call mouseMovedIntoDocument(nullptr)?
        return std::nullopt;
    }

    std::optional<DragOperation> dragOperation;
    m_dragHandlingMethod = tryDocumentDrag(dragData, m_dragDestinationActionMask, dragOperation);
    if (m_dragHandlingMethod == DragHandlingMethod::None && (m_dragDestinationActionMask.contains(DragDestinationAction::Load))) {
        dragOperation = operationForLoad(dragData);
        if (dragOperation)
            m_dragHandlingMethod = DragHandlingMethod::PageLoad;
    } else if (m_dragHandlingMethod == DragHandlingMethod::SetColor)
        dragOperation = DragOperation::Copy;

    updateSupportedTypeIdentifiersForDragHandlingMethod(m_dragHandlingMethod, dragData);
    return dragOperation;
}

static HTMLInputElement* asFileInput(Node& node)
{
    if (!is<HTMLInputElement>(node))
        return nullptr;

    auto* inputElement = &downcast<HTMLInputElement>(node);

    // If this is a button inside of the a file input, move up to the file input.
    if (inputElement->isTextButton())
        inputElement = dynamicDowncast<HTMLInputElement>(inputElement->shadowHost());

    return inputElement && inputElement->isFileUpload() ? inputElement : nullptr;
}

#if ENABLE(INPUT_TYPE_COLOR)

static bool isEnabledColorInput(Node& node)
{
    if (!is<HTMLInputElement>(node))
        return false;
    auto& input = downcast<HTMLInputElement>(node);
    return input.isColorControl() && !input.isDisabledFormControl();
}

static bool isInShadowTreeOfEnabledColorInput(Node& node)
{
    auto* host = node.shadowHost();
    return host && isEnabledColorInput(*host);
}

#endif

// This can return null if an empty document is loaded.
static Element* elementUnderMouse(Document* documentUnderMouse, const IntPoint& p)
{
    Frame* frame = documentUnderMouse->frame();
    float zoomFactor = frame ? frame->pageZoomFactor() : 1;
    LayoutPoint point(p.x() * zoomFactor, p.y() * zoomFactor);

    HitTestResult result(point);
    documentUnderMouse->hitTest(HitTestRequest(), result);

    auto* node = result.innerNode();
    if (!node)
        return nullptr;
    // FIXME: Use parentElementInComposedTree here.
    auto* element = is<Element>(*node) ? &downcast<Element>(*node) : node->parentElement();
    auto* host = element->shadowHost();
    return host ? host : element;
}

#if !PLATFORM(IOS_FAMILY)

void DragController::updateSupportedTypeIdentifiersForDragHandlingMethod(DragHandlingMethod, const DragData&) const
{
}

#endif

DragHandlingMethod DragController::tryDocumentDrag(const DragData& dragData, OptionSet<DragDestinationAction> destinationActionMask, std::optional<DragOperation>& dragOperation)
{
    if (!m_documentUnderMouse)
        return DragHandlingMethod::None;

    if (m_dragInitiator && !m_documentUnderMouse->securityOrigin().canReceiveDragData(m_dragInitiator->securityOrigin()))
        return DragHandlingMethod::None;

    bool isHandlingDrag = false;
    if (destinationActionMask.contains(DragDestinationAction::DHTML)) {
        isHandlingDrag = tryDHTMLDrag(dragData, dragOperation);
        // Do not continue if m_documentUnderMouse has been reset by tryDHTMLDrag.
        // tryDHTMLDrag fires dragenter event. The event listener that listens
        // to this event may create a nested message loop (open a modal dialog),
        // which could process dragleave event and reset m_documentUnderMouse in
        // dragExited.
        if (!m_documentUnderMouse)
            return DragHandlingMethod::None;
    }

    // It's unclear why this check is after tryDHTMLDrag.
    // We send drag events in tryDHTMLDrag and that may be the reason.
    RefPtr<FrameView> frameView = m_documentUnderMouse->view();
    if (!frameView)
        return DragHandlingMethod::None;

    if (isHandlingDrag) {
        clearDragCaret();
        m_numberOfItemsToBeAccepted = dragData.numberOfFiles();
        return DragHandlingMethod::NonDefault;
    }

    if (destinationActionMask.contains(DragDestinationAction::Edit) && canProcessDrag(dragData)) {
        if (dragData.containsColor()) {
            dragOperation = DragOperation::Generic;
            return DragHandlingMethod::SetColor;
        }

        IntPoint point = frameView->windowToContents(dragData.clientPosition());
        Element* element = elementUnderMouse(m_documentUnderMouse.get(), point);
        if (!element)
            return DragHandlingMethod::None;
        
        HTMLInputElement* elementAsFileInput = asFileInput(*element);
        if (m_fileInputElementUnderMouse != elementAsFileInput) {
            if (m_fileInputElementUnderMouse)
                m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
            m_fileInputElementUnderMouse = elementAsFileInput;
        }
        
        if (!m_fileInputElementUnderMouse)
            m_page.dragCaretController().setCaretPosition(m_documentUnderMouse->frame()->visiblePositionForPoint(point));
        else
            clearDragCaret();

        Frame* innerFrame = element->document().frame();
        dragOperation = dragIsMove(innerFrame->selection(), dragData) ? DragOperation::Move : DragOperation::Copy;

        unsigned numberOfFiles = dragData.numberOfFiles();
        if (m_fileInputElementUnderMouse) {
            if (m_fileInputElementUnderMouse->isDisabledFormControl())
                m_numberOfItemsToBeAccepted = 0;
            else if (m_fileInputElementUnderMouse->multiple())
                m_numberOfItemsToBeAccepted = numberOfFiles;
            else if (numberOfFiles > 1)
                m_numberOfItemsToBeAccepted = 0;
            else
                m_numberOfItemsToBeAccepted = 1;
            
            if (!m_numberOfItemsToBeAccepted)
                dragOperation = std::nullopt;
            m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(m_numberOfItemsToBeAccepted);
        } else {
            // We are not over a file input element. The dragged item(s) will loaded into the view,
            // dropped as text paths on other input elements, or handled by script on the page.
            m_numberOfItemsToBeAccepted = numberOfFiles;
        }

        if (m_fileInputElementUnderMouse)
            return DragHandlingMethod::UploadFile;

        if (m_page.dragCaretController().isContentRichlyEditable())
            return DragHandlingMethod::EditRichText;

        return DragHandlingMethod::EditPlainText;
    }
    
    // We are not over an editable region. Make sure we're clearing any prior drag cursor.
    clearDragCaret();
    if (m_fileInputElementUnderMouse)
        m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
    m_fileInputElementUnderMouse = nullptr;
    return DragHandlingMethod::None;
}

OptionSet<DragSourceAction> DragController::delegateDragSourceAction(const IntPoint& rootViewPoint)
{
    m_dragSourceAction = client().dragSourceActionMaskForPoint(rootViewPoint);
    return m_dragSourceAction;
}

std::optional<DragOperation> DragController::operationForLoad(const DragData& dragData)
{
    Document* document = m_page.mainFrame().documentAtPoint(dragData.clientPosition());

    bool pluginDocumentAcceptsDrags = false;
    if (auto* pluginDocument = dynamicDowncast<PluginDocument>(document)) {
        if (auto* pluginView = pluginDocument->pluginWidget())
            pluginDocumentAcceptsDrags = pluginView->shouldAllowNavigationFromDrags();
    }

    if (document && (m_didInitiateDrag || (is<PluginDocument>(*document) && !pluginDocumentAcceptsDrags) || document->hasEditableStyle()))
        return std::nullopt;
    return dragOperation(dragData);
}

static bool setSelectionToDragCaret(Frame* frame, VisibleSelection& dragCaret, const IntPoint& point)
{
    Ref<Frame> protector(*frame);
    frame->selection().setSelection(dragCaret);
    if (frame->selection().selection().isNone()) {
        dragCaret = frame->visiblePositionForPoint(point);
        frame->selection().setSelection(dragCaret);
    }
    return !frame->selection().isNone() && frame->selection().selection().isContentEditable();
}

bool DragController::dispatchTextInputEventFor(Frame* innerFrame, const DragData& dragData)
{
    ASSERT(m_page.dragCaretController().hasCaret());
    String text = m_page.dragCaretController().isContentRichlyEditable() ? emptyString() : dragData.asPlainText();
    auto target = innerFrame->editor().findEventTargetFrom(m_page.dragCaretController().caretPosition());
    // FIXME: What guarantees target is not null?
    auto event = TextEvent::createForDrop(&innerFrame->windowProxy(), text);
    target->dispatchEvent(event);
    return !event->defaultPrevented();
}

bool DragController::concludeEditDrag(const DragData& dragData)
{
    RefPtr<HTMLInputElement> fileInput = m_fileInputElementUnderMouse;
    if (m_fileInputElementUnderMouse) {
        m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
        m_fileInputElementUnderMouse = nullptr;
    }

    if (!m_documentUnderMouse)
        return false;

    IntPoint point = m_documentUnderMouse->view()->windowToContents(dragData.clientPosition());
    Element* element = elementUnderMouse(m_documentUnderMouse.get(), point);
    if (!element)
        return false;
    RefPtr<Frame> innerFrame = element->document().frame();
    ASSERT(innerFrame);

    if (m_page.dragCaretController().hasCaret() && !dispatchTextInputEventFor(innerFrame.get(), dragData))
        return true;

    if (dragData.containsColor()) {
        Color color = dragData.asColor();
        if (!color.isValid())
            return false;
#if ENABLE(INPUT_TYPE_COLOR)
        if (isEnabledColorInput(*element)) {
            auto& input = downcast<HTMLInputElement>(*element);
            input.setValue(serializationForHTML(color), DispatchInputAndChangeEvent);
            return true;
        }
#endif
        auto innerRange = innerFrame->selection().selection().toNormalizedRange();
        if (!innerRange)
            return false;
        auto style = MutableStyleProperties::create();
        style->setProperty(CSSPropertyColor, serializationForHTML(color), false);
        if (!innerFrame->editor().shouldApplyStyle(style, *innerRange))
            return false;
        client().willPerformDragDestinationAction(DragDestinationAction::Edit, dragData);
        innerFrame->editor().applyStyle(style.ptr(), EditAction::SetColor);
        return true;
    }

    if (dragData.containsFiles() && fileInput) {
        // fileInput should be the element we hit tested for, unless it was made
        // display:none in a drop event handler.
        ASSERT(fileInput == element || !fileInput->renderer());
        if (fileInput->isDisabledFormControl())
            return false;

        return fileInput->receiveDroppedFiles(dragData);
    }

    if (!m_page.dragController().canProcessDrag(dragData))
        return false;

    VisibleSelection dragCaret = m_page.dragCaretController().caretPosition();
    auto range = dragCaret.toNormalizedRange();
    RefPtr<Element> rootEditableElement = innerFrame->selection().selection().rootEditableElement();

    // For range to be null a WebKit client must have done something bad while
    // manually controlling drag behaviour
    if (!range)
        return false;

    ResourceCacheValidationSuppressor validationSuppressor(range->start.document().cachedResourceLoader());
    auto& editor = innerFrame->editor();
    bool isMove = dragIsMove(innerFrame->selection(), dragData);
    if (isMove || dragCaret.isContentRichlyEditable()) {
        bool chosePlainText = false;
        auto fragment = documentFragmentFromDragData(dragData, *innerFrame, *range, true, chosePlainText);
        if (!fragment || !editor.shouldInsertFragment(*fragment, range, EditorInsertAction::Dropped))
            return false;

        client().willPerformDragDestinationAction(DragDestinationAction::Edit, dragData);

        if (editor.client() && editor.client()->performTwoStepDrop(*fragment, *range, isMove))
            return true;

        if (isMove) {
            // NSTextView behavior is to always smart delete on moving a selection,
            // but only to smart insert if the selection granularity is word granularity.
            bool smartDelete = editor.smartInsertDeleteEnabled();
            bool smartInsert = smartDelete && innerFrame->selection().granularity() == TextGranularity::WordGranularity && dragData.canSmartReplace();
            MoveSelectionCommand::create(fragment.releaseNonNull(), dragCaret.base(), smartInsert, smartDelete)->apply();
        } else {
            if (setSelectionToDragCaret(innerFrame.get(), dragCaret, point)) {
                OptionSet<ReplaceSelectionCommand::CommandOption> options { ReplaceSelectionCommand::SelectReplacement, ReplaceSelectionCommand::PreventNesting };
                if (dragData.canSmartReplace())
                    options.add(ReplaceSelectionCommand::SmartReplace);
                if (chosePlainText)
                    options.add(ReplaceSelectionCommand::MatchStyle);
                ReplaceSelectionCommand::create(*m_documentUnderMouse, fragment.releaseNonNull(), options, EditAction::InsertFromDrop)->apply();
            }
        }
    } else {
        String text = dragData.asPlainText();
        if (text.isEmpty() || !editor.shouldInsertText(text, *range, EditorInsertAction::Dropped))
            return false;

        client().willPerformDragDestinationAction(DragDestinationAction::Edit, dragData);
        auto fragment = createFragmentFromText(*range, text);
        if (editor.client() && editor.client()->performTwoStepDrop(fragment.get(), *range, isMove))
            return true;

        if (setSelectionToDragCaret(innerFrame.get(), dragCaret, point))
            ReplaceSelectionCommand::create(*m_documentUnderMouse, WTFMove(fragment), { ReplaceSelectionCommand::SelectReplacement, ReplaceSelectionCommand::MatchStyle, ReplaceSelectionCommand::PreventNesting }, EditAction::InsertFromDrop)->apply();
    }

    if (rootEditableElement) {
        if (Frame* frame = rootEditableElement->document().frame())
            frame->eventHandler().updateDragStateAfterEditDragIfNeeded(*rootEditableElement);
    }

    return true;
}

bool DragController::canProcessDrag(const DragData& dragData)
{
    IntPoint point = m_page.mainFrame().view()->windowToContents(dragData.clientPosition());
    HitTestResult result = HitTestResult(point);
    if (!m_page.mainFrame().contentRenderer())
        return false;

    constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::AllowChildFrameContent };
    result = m_page.mainFrame().eventHandler().hitTestResultAtPoint(point, hitType);

    auto* dragNode = result.innerNonSharedNode();
    if (!dragNode)
        return false;

    DragData::DraggingPurpose dragPurpose = DragData::DraggingPurpose::ForEditing;
    if (asFileInput(*dragNode))
        dragPurpose = DragData::DraggingPurpose::ForFileUpload;
#if ENABLE(INPUT_TYPE_COLOR)
    else if (isEnabledColorInput(*dragNode) || isInShadowTreeOfEnabledColorInput(*dragNode))
        dragPurpose = DragData::DraggingPurpose::ForColorControl;
#endif

    if (!dragData.containsCompatibleContent(dragPurpose))
        return false;

    if (dragPurpose == DragData::DraggingPurpose::ForFileUpload)
        return true;

#if ENABLE(INPUT_TYPE_COLOR)
    if (dragPurpose == DragData::DraggingPurpose::ForColorControl)
        return true;
#endif

    if (!dragNode->hasEditableStyle())
        return false;

    if (m_didInitiateDrag && m_documentUnderMouse == m_dragInitiator && result.isSelected())
        return false;

    return true;
}

static std::optional<DragOperation> defaultOperationForDrag(OptionSet<DragOperation> sourceOperationMask)
{
    // This is designed to match IE's operation fallback for the case where
    // the page calls preventDefault() in a drag event but doesn't set dropEffect.
    if (sourceOperationMask.containsAll({ DragOperation::Copy, DragOperation::Link, DragOperation::Generic, DragOperation::Private, DragOperation::Move, DragOperation::Delete }))
        return DragOperation::Copy;
    if (sourceOperationMask.isEmpty())
        return std::nullopt;
    if (sourceOperationMask.contains(DragOperation::Move))
        return DragOperation::Move;
    if (sourceOperationMask.contains(DragOperation::Generic))
        return DragController::platformGenericDragOperation();
    if (sourceOperationMask.contains(DragOperation::Copy))
        return DragOperation::Copy;
    if (sourceOperationMask.contains(DragOperation::Link))
        return DragOperation::Link;
    
    // FIXME: Does IE really return "generic" even if no operations were allowed by the source?
    return DragOperation::Generic;
}

bool DragController::tryDHTMLDrag(const DragData& dragData, std::optional<DragOperation>& operation)
{
    ASSERT(m_documentUnderMouse);
    Ref<Frame> mainFrame(m_page.mainFrame());
    RefPtr<FrameView> viewProtector = mainFrame->view();
    if (!viewProtector)
        return false;

    auto sourceOperationMask = dragData.draggingSourceOperationMask();
    auto targetResponse = mainFrame->eventHandler().updateDragAndDrop(createMouseEvent(dragData), [&dragData]() {
        return Pasteboard::create(dragData);
    }, sourceOperationMask, dragData.containsFiles());
    if (!targetResponse.accept)
        return false;

    if (!targetResponse.operationMask)
        operation = defaultOperationForDrag(sourceOperationMask);
    else if (!sourceOperationMask.containsAny(targetResponse.operationMask.value())) // The element picked an operation which is not supported by the source.
        operation = std::nullopt;
    else
        operation = defaultOperationForDrag(targetResponse.operationMask.value());

    return true;
}

static bool imageElementIsDraggable(const HTMLImageElement& image, const Frame& sourceFrame)
{
    if (sourceFrame.settings().loadsImagesAutomatically())
        return true;

    auto* renderer = image.renderer();
    if (!is<RenderImage>(renderer))
        return false;

    auto* cachedImage = downcast<RenderImage>(*renderer).cachedImage();
    return cachedImage && !cachedImage->errorOccurred() && cachedImage->imageForRenderer(renderer);
}

#if ENABLE(MODEL_ELEMENT)

static bool modelElementIsDraggable(const HTMLModelElement& modelElement)
{
    return modelElement.supportsDragging() && !!modelElement.model();
}

#endif

#if ENABLE(ATTACHMENT_ELEMENT)

static RefPtr<HTMLAttachmentElement> enclosingAttachmentElement(Element& element)
{
    if (is<HTMLAttachmentElement>(element))
        return downcast<HTMLAttachmentElement>(&element);

    if (is<HTMLAttachmentElement>(element.parentOrShadowHostElement()))
        return downcast<HTMLAttachmentElement>(element.parentOrShadowHostElement());

    return { };
}

#endif

Element* DragController::draggableElement(const Frame* sourceFrame, Element* startElement, const IntPoint& dragOrigin, DragState& state) const
{
    state.type = sourceFrame->selection().contains(dragOrigin) ? DragSourceAction::Selection : OptionSet<DragSourceAction>({ });
    if (!startElement)
        return nullptr;

#if ENABLE(ATTACHMENT_ELEMENT)
    if (auto attachment = enclosingAttachmentElement(*startElement)) {
        auto& selection = sourceFrame->selection().selection();
        bool isSingleAttachmentSelection = selection.start() == Position(attachment.get(), Position::PositionIsBeforeAnchor) && selection.end() == Position(attachment.get(), Position::PositionIsAfterAnchor);
        auto* renderer = attachment->renderer();
        if (!renderer || renderer->style().userDrag() == UserDrag::None)
            return nullptr;

        auto selectedRange = selection.firstRange();
        if (isSingleAttachmentSelection || !selectedRange || !contains<ComposedTree>(*selectedRange, *attachment)) {
            state.type = DragSourceAction::Attachment;
            return attachment.get();
        }
    }
#endif // ENABLE(ATTACHMENT_ELEMENT)

    auto selectionDragElement = state.type.contains(DragSourceAction::Selection) && m_dragSourceAction.contains(DragSourceAction::Selection) ? startElement : nullptr;
    if (ImageOverlay::isOverlayText(startElement))
        return selectionDragElement;

    for (auto* element = startElement; element; element = element->parentOrShadowHostElement()) {
        auto* renderer = element->renderer();
        if (!renderer)
            continue;

        UserDrag dragMode = renderer->style().userDrag();
        if (m_dragSourceAction.contains(DragSourceAction::DHTML) && dragMode == UserDrag::Element) {
            state.type = DragSourceAction::DHTML;
            return element;
        }
        if (dragMode == UserDrag::Auto) {
            if ((m_dragSourceAction.contains(DragSourceAction::Image))
                && is<HTMLImageElement>(*element)
                && imageElementIsDraggable(downcast<HTMLImageElement>(*element), *sourceFrame)) {
                state.type.add(DragSourceAction::Image);
                return element;
            }
            if (m_dragSourceAction.contains(DragSourceAction::Link) && isDraggableLink(*element)) {
                state.type.add(DragSourceAction::Link);
                return element;
            }
#if ENABLE(ATTACHMENT_ELEMENT)
            if (m_dragSourceAction.contains(DragSourceAction::Attachment)
                && is<HTMLAttachmentElement>(*element)
                && downcast<HTMLAttachmentElement>(*element).file()) {
                state.type.add(DragSourceAction::Attachment);
                return element;
            }
#endif
#if ENABLE(INPUT_TYPE_COLOR)
            if (m_dragSourceAction.contains(DragSourceAction::Color) && isEnabledColorInput(*element)) {
                state.type.add(DragSourceAction::Color);
                return element;
            }
#endif
#if ENABLE(MODEL_ELEMENT)
            if (m_dragSourceAction.contains(DragSourceAction::Model) && is<HTMLModelElement>(*element) && modelElementIsDraggable(downcast<HTMLModelElement>(*element))) {
                state.type.add(DragSourceAction::Model);
                return element;
            }
#endif
        }
    }

    // We either have nothing to drag or we have a selection and we're not over a draggable element.
    return selectionDragElement;
}

static CachedImage* getCachedImage(Element& element)
{
    RenderObject* renderer = element.renderer();
    if (!is<RenderImage>(renderer))
        return nullptr;
    auto& image = downcast<RenderImage>(*renderer);
    return image.cachedImage();
}

static Image* getImage(Element& element)
{
    CachedImage* cachedImage = getCachedImage(element);
    // Don't use cachedImage->imageForRenderer() here as that may return BitmapImages for cached SVG Images.
    // Users of getImage() want access to the SVGImage, in order to figure out the filename extensions,
    // which would be empty when asking the cached BitmapImages.
    return (cachedImage && !cachedImage->errorOccurred()) ?
        cachedImage->image() : nullptr;
}

static void selectElement(Element& element)
{
    if (auto frame = element.document().frame()) {
        if (auto range = makeRangeSelectingNode(element))
            frame->selection().setSelection(*range);
    }
}

static IntPoint dragLocForDHTMLDrag(const IntPoint& mouseDraggedPoint, const IntPoint& dragOrigin, const IntPoint& dragImageOffset, bool isLinkImage)
{
    // dragImageOffset is the cursor position relative to the lower-left corner of the image.
#if PLATFORM(MAC)
    // We add in the Y dimension because we are a flipped view, so adding moves the image down.
    const int yOffset = dragImageOffset.y();
#else
    const int yOffset = -dragImageOffset.y();
#endif

    if (isLinkImage)
        return IntPoint(mouseDraggedPoint.x() - dragImageOffset.x(), mouseDraggedPoint.y() + yOffset);

    return IntPoint(dragOrigin.x() - dragImageOffset.x(), dragOrigin.y() + yOffset);
}

static FloatPoint dragImageAnchorPointForSelectionDrag(Frame& frame, const IntPoint& mouseDraggedPoint)
{
    IntRect draggingRect = enclosingIntRect(frame.selection().selectionBounds());

    float x = (mouseDraggedPoint.x() - draggingRect.x()) / (float)draggingRect.width();
    float y = (mouseDraggedPoint.y() - draggingRect.y()) / (float)draggingRect.height();

    return FloatPoint { x, y };
}

static IntPoint dragLocForSelectionDrag(Frame& src)
{
    IntRect draggingRect = enclosingIntRect(src.selection().selectionBounds());
    int xpos = draggingRect.maxX();
    xpos = draggingRect.x() < xpos ? draggingRect.x() : xpos;
    int ypos = draggingRect.maxY();
#if PLATFORM(COCOA)
    // Deal with flipped coordinates on Mac
    ypos = draggingRect.y() > ypos ? draggingRect.y() : ypos;
#else
    ypos = draggingRect.y() < ypos ? draggingRect.y() : ypos;
#endif
    return IntPoint(xpos, ypos);
}

void DragController::prepareForDragStart(Frame& source, OptionSet<DragSourceAction> actionMask, Element& element, DataTransfer& dataTransfer, const IntPoint& dragOrigin) const
{
#if !PLATFORM(WIN)
    Ref<Frame> protector(source);
    auto hitTestResult = hitTestResultForDragStart(source, element, dragOrigin);
    if (!hitTestResult)
        return;

    auto& pasteboard = dataTransfer.pasteboard();
    auto& editor = source.editor();
    if (actionMask == DragSourceAction::Selection) {
        if (enclosingTextFormControl(source.selection().selection().start()))
            pasteboard.writePlainText(editor.selectedTextForDataTransfer(), Pasteboard::CannotSmartReplace);
        else
            editor.writeSelectionToPasteboard(pasteboard);
        return;
    }

    auto* image = getImage(element);
    auto imageURL = hitTestResult->absoluteImageURL();
    if (actionMask.contains(DragSourceAction::Image) && !imageURL.isEmpty() && image && !image->isNull()) {
        editor.writeImageToPasteboard(pasteboard, element, imageURL, { });
        return;
    }

    auto linkURL = hitTestResult->absoluteLinkURL();
    if (actionMask.contains(DragSourceAction::Link) && !linkURL.isEmpty() && source.document()->securityOrigin().canDisplay(linkURL))
        editor.copyURL(linkURL, hitTestResult->textContent().simplifyWhiteSpace(), pasteboard);
#else
    // FIXME: Make this work on Windows by implementing Editor::writeSelectionToPasteboard and Editor::writeImageToPasteboard.
    UNUSED_PARAM(source);
    UNUSED_PARAM(actionMask);
    UNUSED_PARAM(element);
    UNUSED_PARAM(dataTransfer);
    UNUSED_PARAM(dragOrigin);
#endif
}

std::optional<HitTestResult> DragController::hitTestResultForDragStart(Frame& source, Element& element, const IntPoint& location) const
{
    if (!source.view() || !source.contentRenderer())
        return std::nullopt;

    constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::AllowChildFrameContent };
    auto hitTestResult = source.eventHandler().hitTestResultAtPoint(location, hitType);

    bool sourceContainsHitNode = element.containsIncludingShadowDOM(hitTestResult.innerNode());
    if (!sourceContainsHitNode) {
        // The original node being dragged isn't under the drag origin anymore... maybe it was
        // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
        // something that's not actually under the drag origin.
        return std::nullopt;
    }

    return { hitTestResult };
}

bool DragController::startDrag(Frame& src, const DragState& state, OptionSet<DragOperation> sourceOperationMask, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, HasNonDefaultPasteboardData hasData)
{
    if (!state.source)
        return false;

#if PLATFORM(GTK)
    if (dragEvent.isTouchEvent())
        return false;
#endif

    Ref<Frame> protector(src);
    auto hitTestResult = hitTestResultForDragStart(src, *state.source, dragOrigin);
    if (!hitTestResult)
        return false;

    auto linkURL = hitTestResult->absoluteLinkURL();
    auto imageURL = hitTestResult->absoluteImageURL();

    IntPoint mouseDraggedPoint = src.view()->windowToContents(dragEvent.position());

    m_draggingImageURL = URL();
    m_sourceDragOperationMask = sourceOperationMask;

    DragImage dragImage;
    IntPoint dragLoc(0, 0);
    IntPoint dragImageOffset(0, 0);

    ASSERT(state.dataTransfer);

    DataTransfer& dataTransfer = *state.dataTransfer;
    if (state.type == DragSourceAction::DHTML) {
        dragImage = DragImage { dataTransfer.createDragImage(dragImageOffset) };
        // We allow DHTML/JS to set the drag image, even if its a link, image or text we're dragging.
        // This is in the spirit of the IE API, which allows overriding of pasteboard data and DragOp.
        if (dragImage) {
            dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, !linkURL.isEmpty());
            m_dragOffset = dragImageOffset;
        }
    }

    if (state.type == DragSourceAction::Selection || !imageURL.isEmpty() || !linkURL.isEmpty()) {
        // Selection, image, and link drags receive a default set of allowed drag operations that
        // follows from:
        // http://trac.webkit.org/browser/trunk/WebKit/mac/WebView/WebHTMLView.mm?rev=48526#L3430
        m_sourceDragOperationMask.add({ DragOperation::Generic, DragOperation::Copy });
    }

    ASSERT(state.source);
    Element& element = *state.source;

    bool mustUseLegacyDragClient = hasData == HasNonDefaultPasteboardData::Yes || client().useLegacyDragClient();

    IntRect dragImageBounds;
    Image* image = getImage(element);
    if (state.type == DragSourceAction::Selection) {
        PasteboardWriterData pasteboardWriterData;

        if (hasData == HasNonDefaultPasteboardData::No) {
            if (src.selection().selection().isNone()) {
                // The page may have cleared out the selection in the dragstart handler, in which case we should bail
                // out of the drag, since there is no content to write to the pasteboard.
                return false;
            }

            // FIXME: This entire block is almost identical to the code in Editor::copy, and the code should be shared.
            auto selectionRange = src.selection().selection().toNormalizedRange();
            ASSERT(selectionRange);

            src.editor().willWriteSelectionToPasteboard(*selectionRange);
            auto selection = src.selection().selection();
            bool shouldDragAsPlainText = enclosingTextFormControl(selection.start());
            if (auto range = selection.range(); range && ImageOverlay::isInsideOverlay(*range))
                shouldDragAsPlainText = true;

            if (shouldDragAsPlainText) {
                if (mustUseLegacyDragClient)
                    dataTransfer.pasteboard().writePlainText(src.editor().selectedTextForDataTransfer(), Pasteboard::CannotSmartReplace);
                else {
                    PasteboardWriterData::PlainText plainText;
                    plainText.canSmartCopyOrDelete = false;
                    plainText.text = src.editor().selectedTextForDataTransfer();
                    pasteboardWriterData.setPlainText(WTFMove(plainText));
                }
            } else {
                if (mustUseLegacyDragClient) {
#if !PLATFORM(WIN)
                    src.editor().writeSelectionToPasteboard(dataTransfer.pasteboard());
#else
                    // FIXME: Convert Windows to match the other platforms and delete this.
                    dataTransfer.pasteboard().writeSelection(*selectionRange, src.editor().canSmartCopyOrDelete(), src, IncludeImageAltTextForDataTransfer);
#endif
                } else {
#if PLATFORM(COCOA)
                    src.editor().writeSelection(pasteboardWriterData);
#endif
                }
            }

            src.editor().didWriteSelectionToPasteboard();
        }
        client().willPerformDragSourceAction(DragSourceAction::Selection, dragOrigin, dataTransfer);
        if (!dragImage) {
            TextIndicatorData textIndicator;
            dragImage = DragImage { dissolveDragImageToFraction(createDragImageForSelection(src, textIndicator), DragImageAlpha) };
            if (textIndicator.contentImage)
                dragImage.setIndicatorData(textIndicator);
            dragLoc = dragLocForSelectionDrag(src);
            m_dragOffset = IntPoint(dragOrigin.x() - dragLoc.x(), dragOrigin.y() - dragLoc.y());
        }

        if (!dragImage)
            return false;

        if (mustUseLegacyDragClient) {
            doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { });
            return true;
        }

        DragItem dragItem;
        dragItem.imageAnchorPoint = dragImageAnchorPointForSelectionDrag(src, mouseDraggedPoint);
        dragItem.image = WTFMove(dragImage);
        dragItem.data = WTFMove(pasteboardWriterData);
        dragItem.containsSelection = true;

        beginDrag(WTFMove(dragItem), src, dragOrigin, mouseDraggedPoint, dataTransfer, DragSourceAction::Selection);

        return true;
    }

    if (!src.document()->securityOrigin().canDisplay(linkURL)) {
        src.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to drag local resource: " + linkURL.stringCenterEllipsizedToLength());
        return false;
    }

    if (!imageURL.isEmpty() && image && !image->isNull() && m_dragSourceAction.contains(DragSourceAction::Image)) {
        // We shouldn't be starting a drag for an image that can't provide an extension.
        // This is an early detection for problems encountered later upon drop.
        ASSERT(!image->filenameExtension().isEmpty());

#if ENABLE(ATTACHMENT_ELEMENT)
        auto attachmentInfo = src.editor().promisedAttachmentInfo(element);
#else
        PromisedAttachmentInfo attachmentInfo;
#endif

        if (hasData == HasNonDefaultPasteboardData::No) {
            m_draggingImageURL = imageURL;
            if (element.isContentRichlyEditable())
                selectElement(element);
            if (!attachmentInfo)
                declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult->altDisplayString());
        }

        client().willPerformDragSourceAction(DragSourceAction::Image, dragOrigin, dataTransfer);

        if (!dragImage)
            doImageDrag(element, dragOrigin, hitTestResult->imageRect(), src, m_dragOffset, state, WTFMove(attachmentInfo));
        else {
            // DHTML defined drag image
            doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, WTFMove(attachmentInfo));
        }

        return true;
    }

    if (!linkURL.isEmpty() && m_dragSourceAction.contains(DragSourceAction::Link)) {
        PasteboardWriterData pasteboardWriterData;

        String textContentWithSimplifiedWhiteSpace = hitTestResult->textContent().simplifyWhiteSpace();

        if (hasData == HasNonDefaultPasteboardData::No) {
            // Simplify whitespace so the title put on the dataTransfer resembles what the user sees
            // on the web page. This includes replacing newlines with spaces.
            if (mustUseLegacyDragClient)
                src.editor().copyURL(linkURL, textContentWithSimplifiedWhiteSpace, dataTransfer.pasteboard());
            else
                pasteboardWriterData.setURLData(src.editor().pasteboardWriterURL(linkURL, textContentWithSimplifiedWhiteSpace));
        } else if (dataTransfer.pasteboard().canWriteTrustworthyWebURLsPboardType()) {
            // Make sure the pasteboard also contains trustworthy link data
            // but don't overwrite more general pasteboard types.
            PasteboardURL pasteboardURL;
            pasteboardURL.url = linkURL;
            pasteboardURL.title = hitTestResult->textContent();
            dataTransfer.pasteboard().writeTrustworthyWebURLsPboardType(pasteboardURL);
        }

        const VisibleSelection& sourceSelection = src.selection().selection();
        if (sourceSelection.isCaret() && sourceSelection.isContentEditable()) {
            // a user can initiate a drag on a link without having any text
            // selected.  In this case, we should expand the selection to
            // the enclosing anchor element
            Position pos = sourceSelection.base();
            Node* node = enclosingAnchorElement(pos);
            if (node)
                src.selection().setSelection(VisibleSelection::selectionFromContentsOfNode(node));
        }

        client().willPerformDragSourceAction(DragSourceAction::Link, dragOrigin, dataTransfer);
        if (!dragImage) {
            TextIndicatorData textIndicator;
            dragImage = DragImage { createDragImageForLink(element, linkURL, textContentWithSimplifiedWhiteSpace, textIndicator, src.settings().fontRenderingMode(), m_page.deviceScaleFactor()) };
            if (dragImage) {
                m_dragOffset = dragOffsetForLinkDragImage(dragImage.get());
                dragLoc = IntPoint(dragOrigin.x() + m_dragOffset.x(), dragOrigin.y() + m_dragOffset.y());
                dragImage = DragImage { platformAdjustDragImageForDeviceScaleFactor(dragImage.get(), m_page.deviceScaleFactor()) };
                if (textIndicator.contentImage)
                    dragImage.setIndicatorData(textIndicator);
            }
        }

        if (mustUseLegacyDragClient) {
            doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { });
            return true;
        }

        DragItem dragItem;
        dragItem.imageAnchorPoint = dragImage ? anchorPointForLinkDragImage(dragImage.get()) : FloatPoint();
        dragItem.image = WTFMove(dragImage);
        dragItem.data = WTFMove(pasteboardWriterData);
        dragItem.containsSelection = true;

        beginDrag(WTFMove(dragItem), src, dragOrigin, mouseDraggedPoint, dataTransfer, DragSourceAction::Selection);

        return true;
    }

#if ENABLE(ATTACHMENT_ELEMENT)
    if (is<HTMLAttachmentElement>(element) && m_dragSourceAction.contains(DragSourceAction::Attachment)) {
        auto& attachment = downcast<HTMLAttachmentElement>(element);
        auto* attachmentRenderer = attachment.renderer();

        src.editor().setIgnoreSelectionChanges(true);
        auto previousSelection = src.selection().selection();
        selectElement(element);

        PromisedAttachmentInfo promisedAttachment;
        if (hasData == HasNonDefaultPasteboardData::No) {
            auto& editor = src.editor();
            promisedAttachment = editor.promisedAttachmentInfo(attachment);
#if PLATFORM(COCOA)
            if (!promisedAttachment && editor.client()) {
                // Otherwise, if no file URL is specified, call out to the injected bundle to populate the pasteboard with data.
                editor.willWriteSelectionToPasteboard(src.selection().selection().toNormalizedRange());
                editor.writeSelectionToPasteboard(dataTransfer.pasteboard());
                editor.didWriteSelectionToPasteboard();
            }
#endif
        }
        
        client().willPerformDragSourceAction(DragSourceAction::Attachment, dragOrigin, dataTransfer);
        
        if (!dragImage) {
            TextIndicatorData textIndicator;
            if (attachmentRenderer)
                attachmentRenderer->setShouldDrawBorder(false);
            dragImage = DragImage { dissolveDragImageToFraction(createDragImageForSelection(src, textIndicator), DragImageAlpha) };
            if (attachmentRenderer)
                attachmentRenderer->setShouldDrawBorder(true);
            if (textIndicator.contentImage)
                dragImage.setIndicatorData(textIndicator);
            dragLoc = dragLocForSelectionDrag(src);
            m_dragOffset = IntPoint(dragOrigin.x() - dragLoc.x(), dragOrigin.y() - dragLoc.y());
        }
        doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, WTFMove(promisedAttachment));
        if (!element.isContentRichlyEditable())
            src.selection().setSelection(previousSelection);
        src.editor().setIgnoreSelectionChanges(false);
        return true;
    }
#endif

#if ENABLE(INPUT_TYPE_COLOR)
    bool isColorControl = is<HTMLInputElement>(state.source) && downcast<HTMLInputElement>(*state.source).isColorControl();
    if (isColorControl && m_dragSourceAction.contains(DragSourceAction::Color)) {
        auto& input = downcast<HTMLInputElement>(*state.source);
        auto color = input.valueAsColor();

        Path visiblePath;
        dragImage = DragImage { createDragImageForColor(color, input.boundsInRootViewSpace(), input.document().page()->pageScaleFactor(), visiblePath) };
        dragImage.setVisiblePath(visiblePath);
        dataTransfer.pasteboard().write(color);
        dragImageOffset = IntPoint { dragImageSize(dragImage.get()) };
        dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, false);

        client().willPerformDragSourceAction(DragSourceAction::Color, dragOrigin, dataTransfer);
        doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { });
        return true;
    }
#endif

#if ENABLE(MODEL_ELEMENT)
    bool isModel = is<HTMLModelElement>(state.source);
    if (isModel && m_dragSourceAction.contains(DragSourceAction::Model)) {
        auto& modelElement = downcast<HTMLModelElement>(*state.source);
        dragImage = DragImage { createDragImageForNode(src, modelElement) };

        PasteboardImage pasteboardImage;
        pasteboardImage.suggestedName = modelElement.currentSrc().lastPathComponent().toString();
        pasteboardImage.resourceMIMEType = modelElement.model()->mimeType();
        pasteboardImage.resourceData = modelElement.model()->data();
        dataTransfer.pasteboard().write(pasteboardImage);

        dragImageOffset = IntPoint { dragImageSize(dragImage.get()) };
        dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, false);

        client().willPerformDragSourceAction(DragSourceAction::Model, dragOrigin, dataTransfer);
        doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { });
        return true;
    }
#endif

    if (state.type == DragSourceAction::DHTML && dragImage) {
        ASSERT(m_dragSourceAction.contains(DragSourceAction::DHTML));
        client().willPerformDragSourceAction(DragSourceAction::DHTML, dragOrigin, dataTransfer);
        doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, { });
        return true;
    }

    return false;
}

void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, const IntRect& layoutRect, Frame& frame, IntPoint& dragImageOffset, const DragState& state, PromisedAttachmentInfo&& attachmentInfo)
{
    IntPoint mouseDownPoint = dragOrigin;
    DragImage dragImage;
    IntPoint scaledOrigin;

    if (!element.renderer())
        return;

    ImageOrientation orientation = element.renderer()->imageOrientation();

    Image* image = getImage(element);
    if (image && !layoutRect.isEmpty() && shouldUseCachedImageForDragImage(*image) && (dragImage = DragImage { createDragImageFromImage(image, orientation) })) {
        dragImage = DragImage { fitDragImageToMaxSize(dragImage.get(), layoutRect.size(), maxDragImageSize()) };
        IntSize fittedSize = dragImageSize(dragImage.get());

        dragImage = DragImage { platformAdjustDragImageForDeviceScaleFactor(dragImage.get(), m_page.deviceScaleFactor()) };
        dragImage = DragImage { dissolveDragImageToFraction(dragImage.get(), DragImageAlpha) };

        // Properly orient the drag image and orient it differently if it's smaller than the original.
        float scale = fittedSize.width() / (float)layoutRect.width();
        float dx = scale * (layoutRect.x() - mouseDownPoint.x());
        float originY = layoutRect.y();
#if PLATFORM(COCOA)
        // Compensate for accursed flipped coordinates in Cocoa.
        originY += layoutRect.height();
#endif
        float dy = scale * (originY - mouseDownPoint.y());
        scaledOrigin = IntPoint((int)(dx + 0.5), (int)(dy + 0.5));
    } else {
        if (CachedImage* cachedImage = getCachedImage(element)) {
            dragImage = DragImage { createDragImageIconForCachedImageFilename(cachedImage->response().suggestedFilename()) };
            if (dragImage) {
                dragImage = DragImage { platformAdjustDragImageForDeviceScaleFactor(dragImage.get(), m_page.deviceScaleFactor()) };
                scaledOrigin = IntPoint(DragIconRightInset - dragImageSize(dragImage.get()).width(), DragIconBottomInset);
            }
        }
    }

    if (!dragImage)
        return;

    dragImageOffset = mouseDownPoint + scaledOrigin;
    doSystemDrag(WTFMove(dragImage), dragImageOffset, dragOrigin, frame, state, WTFMove(attachmentInfo));
}

void DragController::beginDrag(DragItem dragItem, Frame& frame, const IntPoint& mouseDownPoint, const IntPoint& mouseDraggedPoint, DataTransfer& dataTransfer, DragSourceAction dragSourceAction)
{
    ASSERT(!client().useLegacyDragClient());

    m_didInitiateDrag = true;
    m_dragInitiator = frame.document();

    // Protect this frame and view, as a load may occur mid drag and attempt to unload this frame
    Ref<Frame> mainFrameProtector(m_page.mainFrame());
    RefPtr<FrameView> viewProtector = mainFrameProtector->view();

    auto mouseDownPointInRootViewCoordinates = viewProtector->rootViewToContents(frame.view()->contentsToRootView(mouseDownPoint));
    auto mouseDraggedPointInRootViewCoordinates = viewProtector->rootViewToContents(frame.view()->contentsToRootView(mouseDraggedPoint));

    client().beginDrag(WTFMove(dragItem), frame, mouseDownPointInRootViewCoordinates, mouseDraggedPointInRootViewCoordinates, dataTransfer, dragSourceAction);
}

static RefPtr<Element> containingLinkElement(Element& element)
{
    for (auto& currentElement : lineageOfType<Element>(element)) {
        if (currentElement.isLink())
            return &currentElement;
    }
    return nullptr;
}

void DragController::doSystemDrag(DragImage image, const IntPoint& dragLoc, const IntPoint& eventPos, Frame& frame, const DragState& state, PromisedAttachmentInfo&& promisedAttachmentInfo)
{
    m_didInitiateDrag = true;
    m_dragInitiator = frame.document();
    // Protect this frame and view, as a load may occur mid drag and attempt to unload this frame
    Ref<Frame> frameProtector(m_page.mainFrame());
    RefPtr<FrameView> viewProtector = frameProtector->view();

    DragItem item;
    item.image = WTFMove(image);
    ASSERT(state.type.hasExactlyOneBitSet());
    item.sourceAction = state.type.toSingleValue();
    item.promisedAttachmentInfo = WTFMove(promisedAttachmentInfo);
    item.containsSelection = frame.selection().contains(eventPos);

    auto eventPositionInRootViewCoordinates = frame.view()->contentsToRootView(eventPos);
    auto dragLocationInRootViewCoordinates = frame.view()->contentsToRootView(dragLoc);
    item.eventPositionInContentCoordinates = viewProtector->rootViewToContents(eventPositionInRootViewCoordinates);
    item.dragLocationInContentCoordinates = viewProtector->rootViewToContents(dragLocationInRootViewCoordinates);
    item.dragLocationInWindowCoordinates = viewProtector->contentsToWindow(item.dragLocationInContentCoordinates);
    if (auto element = state.source) {
        auto dataTransferImageElement = state.dataTransfer->dragImageElement();
        if (state.type == DragSourceAction::DHTML) {
            // If the drag image has been customized, fall back to positioning the preview relative to the drag event location.
            IntSize dragPreviewSize;
            if (dataTransferImageElement)
                dragPreviewSize = dataTransferImageElement->boundsInRootViewSpace().size();
            else {
                dragPreviewSize = dragImageSize(item.image.get());
                if (auto* page = frame.page())
                    dragPreviewSize.scale(1 / page->deviceScaleFactor());
            }
            item.dragPreviewFrameInRootViewCoordinates = { dragLocationInRootViewCoordinates, WTFMove(dragPreviewSize) };
        } else {
            // We can position the preview using the bounds of the drag source element.
            item.dragPreviewFrameInRootViewCoordinates = element->boundsInRootViewSpace();
        }

        if (auto link = containingLinkElement(*element)) {
            auto titleAttribute = link->attributeWithoutSynchronization(HTMLNames::titleAttr);
            item.title = titleAttribute.isEmpty() ? link->innerText() : titleAttribute.string();
            item.url = frame.document()->completeURL(stripLeadingAndTrailingHTMLSpaces(link->getAttribute(HTMLNames::hrefAttr)));
        }
    }
    client().startDrag(WTFMove(item), *state.dataTransfer, frameProtector.get());
    // DragClient::startDrag can cause our Page to dispear, deallocating |this|.
    if (!frameProtector->page())
        return;

    cleanupAfterSystemDrag();
}

void DragController::removeAllDroppedImagePlaceholders()
{
    m_droppedImagePlaceholderRange = std::nullopt;
    for (auto& placeholder : std::exchange(m_droppedImagePlaceholders, { })) {
        if (placeholder->isConnected())
            placeholder->remove();
    }
}

bool DragController::tryToUpdateDroppedImagePlaceholders(const DragData& dragData)
{
    ASSERT(!m_droppedImagePlaceholders.isEmpty());
    ASSERT(m_droppedImagePlaceholderRange);

    Ref document = m_droppedImagePlaceholders[0]->document();
    RefPtr frame = document->frame();
    if (!frame)
        return false;

    WebContentReader reader(*frame, *m_droppedImagePlaceholderRange, true);
    auto pasteboard = Pasteboard::create(dragData);
    pasteboard->read(reader);

    if (!reader.fragment)
        return false;

    Vector<Ref<HTMLImageElement>> imageElements;
    for (auto& imageElement : descendantsOfType<HTMLImageElement>(*reader.fragment))
        imageElements.append(imageElement);

    if (imageElements.size() != m_droppedImagePlaceholders.size()) {
        ASSERT_NOT_REACHED();
        return false;
    }

    for (size_t i = 0; i < imageElements.size(); ++i) {
        auto& imageElement = imageElements[i];
        auto& placeholder = m_droppedImagePlaceholders[i];
        placeholder->setAttributeWithoutSynchronization(HTMLNames::srcAttr, imageElement->attributeWithoutSynchronization(HTMLNames::srcAttr));
#if ENABLE(ATTACHMENT_ELEMENT)
        if (auto attachment = imageElement->attachmentElement())
            placeholder->setAttachmentElement(attachment.releaseNonNull());
#endif
    }
    return true;
}

void DragController::insertDroppedImagePlaceholdersAtCaret(const Vector<IntSize>& imageSizes)
{
    auto& caretController = m_page.dragCaretController();
    if (!caretController.isContentRichlyEditable())
        return;

    auto dropCaret = caretController.caretPosition();
    if (dropCaret.isNull())
        return;

    RefPtr document = dropCaret.deepEquivalent().document();
    if (!document)
        return;

    RefPtr frame = document->frame();
    if (!frame)
        return;

    IgnoreSelectionChangeForScope selectionChange { *frame };

    auto fragment = DocumentFragment::create(*document);
    for (auto& size : imageSizes) {
        ASSERT(!size.isEmpty());
        auto image = HTMLImageElement::create(*document);
        image->setAttributeWithoutSynchronization(HTMLNames::widthAttr, AtomString::number(size.width()));
        image->setAttributeWithoutSynchronization(HTMLNames::heightAttr, AtomString::number(size.height()));
        image->setInlineStyleProperty(CSSPropertyMaxWidth, 100, CSSUnitType::CSS_PERCENTAGE);
        image->setInlineStyleProperty(CSSPropertyBackgroundColor, serializationForCSS(Color::black.colorWithAlphaByte(13)));
        image->setIsDroppedImagePlaceholder();
        fragment->appendChild(WTFMove(image));
    }

    frame->selection().setSelection(dropCaret);

    auto command = ReplaceSelectionCommand::create(*document, WTFMove(fragment), { ReplaceSelectionCommand::PreventNesting, ReplaceSelectionCommand::SmartReplace }, EditAction::InsertFromDrop);
    command->apply();

    auto insertedContentRange = command->insertedContentRange();
    if (!insertedContentRange) {
        ASSERT_NOT_REACHED();
        return;
    }

    auto container = commonInclusiveAncestor<ComposedTree>(*insertedContentRange);
    if (!is<ContainerNode>(container)) {
        ASSERT_NOT_REACHED();
        return;
    }

    Vector<Ref<HTMLImageElement>> placeholders;
    for (auto& placeholder : descendantsOfType<HTMLImageElement>(downcast<ContainerNode>(*container))) {
        if (intersects<ComposedTree>(*insertedContentRange, placeholder))
            placeholders.append(placeholder);
    }

    if (placeholders.size() != imageSizes.size()) {
        ASSERT_NOT_REACHED();
        return;
    }

    for (size_t i = 0; i < placeholders.size(); ++i) {
        auto& placeholder = placeholders[i];
        auto imageSize = imageSizes[i];
        double clientWidth = placeholder->clientWidth();
        double heightRespectingAspectRatio = (imageSize.height() * clientWidth) / imageSize.width();
        placeholder->setAttributeWithoutSynchronization(HTMLNames::heightAttr, AtomString::number(heightRespectingAspectRatio));
    }

    document->updateLayout();

    m_droppedImagePlaceholders = WTFMove(placeholders);
    m_droppedImagePlaceholderRange = WTFMove(insertedContentRange);

    frame->selection().clear();
    caretController.setCaretPosition(makeDeprecatedLegacyPosition(m_droppedImagePlaceholderRange->start));
}

void DragController::finalizeDroppedImagePlaceholder(HTMLImageElement& placeholder, CompletionHandler<void()>&& completion)
{
    placeholder.document().eventLoop().queueTask(TaskSource::InternalAsyncTask, [completion = WTFMove(completion), placeholder = Ref { placeholder }] () mutable {
        if (placeholder->isDroppedImagePlaceholder()) {
            placeholder->removeAttribute(HTMLNames::heightAttr);
            placeholder->removeInlineStyleProperty(CSSPropertyBackgroundColor);
        }
        completion();
    });
}

// Manual drag caret manipulation
void DragController::placeDragCaret(const IntPoint& windowPoint)
{
    mouseMovedIntoDocument(m_page.mainFrame().documentAtPoint(windowPoint));
    if (!m_documentUnderMouse)
        return;
    Frame* frame = m_documentUnderMouse->frame();
    FrameView* frameView = frame->view();
    if (!frameView)
        return;
    IntPoint framePoint = frameView->windowToContents(windowPoint);

    m_page.dragCaretController().setCaretPosition(frame->visiblePositionForPoint(framePoint));
}

bool DragController::shouldUseCachedImageForDragImage(const Image& image) const
{
#if PLATFORM(IOS_FAMILY)
    UNUSED_PARAM(image);
    return true;
#else
    return image.size().height() * image.size().width() <= MaxOriginalImageArea;
#endif
}

#endif // ENABLE(DRAG_SUPPORT)

} // namespace WebCore
