Changeset 222956 in webkit


Ignore:
Timestamp:
Oct 5, 2017 8:51:35 PM (6 years ago)
Author:
rniwa@webkit.org
Message:

DataTransfer shouldn't contain text/html when performing Paste and Match Style
https://bugs.webkit.org/show_bug.cgi?id=174165
<rdar://problem/33138027>

Reviewed by Wenson Hsieh.

Source/WebCore:

When performing Paste and Match Style, only expose the plain text by creating a StaticPasteboard with plain text content.

This patch introduces ClipboardEventKind enum class to differentiate regular paste and paste and match style (internally
called as pasteAsPlainText) since both operations use "paste" event.

Tests: editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text-when-custom-pasteboard-data-disabled.html

editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text.html

  • dom/DataTransfer.cpp:

(WebCore::DataTransfer::createForCopyAndPaste): Made this function take Pasteboard as an argument.

  • dom/DataTransfer.h:
  • editing/Editor.cpp:

(WebCore::ClipboardEventKind): Added.
(WebCore::eventNameForClipboardEvent): Added.
(WebCore::createDataTransferForClipboardEvent): Added.
(WebCore::dispatchClipboardEvent):
(WebCore::Editor::canDHTMLCut):
(WebCore::Editor::canDHTMLCopy):
(WebCore::Editor::canDHTMLPaste):
(WebCore::Editor::tryDHTMLCopy):
(WebCore::Editor::tryDHTMLCut):
(WebCore::Editor::tryDHTMLPaste): Deleted.
(WebCore::Editor::paste):
(WebCore::Editor::pasteAsPlainText):

  • platform/ios/PasteboardIOS.mm:

(WebCore::Pasteboard::addHTMLClipboardTypesForCocoaType): Add "text/html" when public.html UTI is in the pasteboard
even when the custom pasteboard data is disabled. We continue to add public.html in the case some app dependent on
seeing "public.html" in dataTransfer.types.

LayoutTests:

Added regression tests for pasting as plain text.

  • editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text-expected.txt: Added.
  • editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text-when-custom-pasteboard-data-disabled-expected.txt: Added.
  • editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text-when-custom-pasteboard-data-disabled.html: Added.
  • editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text.html: Added.
Location:
trunk
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r222949 r222956  
     12017-10-05  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        DataTransfer shouldn't contain text/html when performing Paste and Match Style
     4        https://bugs.webkit.org/show_bug.cgi?id=174165
     5        <rdar://problem/33138027>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Added regression tests for pasting as plain text.
     10
     11        * editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text-expected.txt: Added.
     12        * editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text-when-custom-pasteboard-data-disabled-expected.txt: Added.
     13        * editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text-when-custom-pasteboard-data-disabled.html: Added.
     14        * editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text.html: Added.
     15
    1162017-10-05  Myles C. Maxfield  <mmaxfield@apple.com>
    217
  • trunk/Source/WebCore/ChangeLog

    r222953 r222956  
     12017-10-05  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        DataTransfer shouldn't contain text/html when performing Paste and Match Style
     4        https://bugs.webkit.org/show_bug.cgi?id=174165
     5        <rdar://problem/33138027>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        When performing Paste and Match Style, only expose the plain text by creating a StaticPasteboard with plain text content.
     10
     11        This patch introduces ClipboardEventKind enum class to differentiate regular paste and paste and match style (internally
     12        called as pasteAsPlainText) since both operations use "paste" event.
     13
     14        Tests: editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text-when-custom-pasteboard-data-disabled.html
     15               editing/pasteboard/data-transfer-get-data-on-paste-as-plain-text.html
     16
     17        * dom/DataTransfer.cpp:
     18        (WebCore::DataTransfer::createForCopyAndPaste): Made this function take Pasteboard as an argument.
     19        * dom/DataTransfer.h:
     20        * editing/Editor.cpp:
     21        (WebCore::ClipboardEventKind): Added.
     22        (WebCore::eventNameForClipboardEvent): Added.
     23        (WebCore::createDataTransferForClipboardEvent): Added.
     24        (WebCore::dispatchClipboardEvent):
     25        (WebCore::Editor::canDHTMLCut):
     26        (WebCore::Editor::canDHTMLCopy):
     27        (WebCore::Editor::canDHTMLPaste):
     28        (WebCore::Editor::tryDHTMLCopy):
     29        (WebCore::Editor::tryDHTMLCut):
     30        (WebCore::Editor::tryDHTMLPaste): Deleted.
     31        (WebCore::Editor::paste):
     32        (WebCore::Editor::pasteAsPlainText):
     33        * platform/ios/PasteboardIOS.mm:
     34        (WebCore::Pasteboard::addHTMLClipboardTypesForCocoaType): Add "text/html" when public.html UTI is in the pasteboard
     35        even when the custom pasteboard data is disabled. We continue to add public.html in the case some app dependent on
     36        seeing "public.html" in dataTransfer.types.
     37
    1382017-10-05  Zalan Bujtas  <zalan@apple.com>
    239
  • trunk/Source/WebCore/dom/DataTransfer.cpp

    r222904 r222956  
    7777}
    7878
    79 Ref<DataTransfer> DataTransfer::createForCopyAndPaste(StoreMode mode)
    80 {
    81     return adoptRef(*new DataTransfer(mode, mode == StoreMode::ReadWrite ? std::make_unique<StaticPasteboard>() : Pasteboard::createForCopyAndPaste()));
     79Ref<DataTransfer> DataTransfer::createForCopyAndPaste(StoreMode storeMode, std::unique_ptr<Pasteboard>&& pasteboard)
     80{
     81    return adoptRef(*new DataTransfer(storeMode, WTFMove(pasteboard)));
    8282}
    8383
  • trunk/Source/WebCore/dom/DataTransfer.h

    r222885 r222956  
    4545    enum class StoreMode { Invalid, ReadWrite, Readonly, Protected };
    4646
    47     static Ref<DataTransfer> createForCopyAndPaste(StoreMode);
     47    static Ref<DataTransfer> createForCopyAndPaste(StoreMode, std::unique_ptr<Pasteboard>&&);
    4848    static Ref<DataTransfer> createForInputEvent(const String& plainText, const String& htmlText);
    4949
  • trunk/Source/WebCore/editing/Editor.cpp

    r222642 r222956  
    315315}
    316316
     317enum class ClipboardEventKind {
     318    Copy,
     319    Cut,
     320    Paste,
     321    PasteAsPlainText,
     322    BeforeCopy,
     323    BeforeCut,
     324    BeforePaste,
     325};
     326
     327static AtomicString eventNameForClipboardEvent(ClipboardEventKind kind)
     328{
     329    switch (kind) {
     330    case ClipboardEventKind::Copy:
     331        return eventNames().copyEvent;
     332    case ClipboardEventKind::Cut:
     333        return eventNames().cutEvent;
     334    case ClipboardEventKind::Paste:
     335    case ClipboardEventKind::PasteAsPlainText:
     336        return eventNames().pasteEvent;
     337    case ClipboardEventKind::BeforeCopy:
     338        return eventNames().beforecopyEvent;
     339    case ClipboardEventKind::BeforeCut:
     340        return eventNames().beforecutEvent;
     341    case ClipboardEventKind::BeforePaste:
     342        return eventNames().beforepasteEvent;
     343    }
     344    ASSERT_NOT_REACHED();
     345    return { };
     346}
     347
     348static Ref<DataTransfer> createDataTransferForClipboardEvent(ClipboardEventKind kind)
     349{
     350    switch (kind) {
     351    case ClipboardEventKind::Copy:
     352    case ClipboardEventKind::Cut:
     353        return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::ReadWrite, std::make_unique<StaticPasteboard>());
     354    case ClipboardEventKind::PasteAsPlainText:
     355        if (Settings::customPasteboardDataEnabled()) {
     356            auto plainTextType = ASCIILiteral("text/plain");
     357            auto plainText = Pasteboard::createForCopyAndPaste()->readString(plainTextType);
     358            auto pasteboard = std::make_unique<StaticPasteboard>();
     359            pasteboard->writeString(plainTextType, plainText);
     360            return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::Readonly, WTFMove(pasteboard));
     361        }
     362        FALLTHROUGH;
     363    case ClipboardEventKind::Paste:
     364        return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::Readonly, Pasteboard::createForCopyAndPaste());
     365    case ClipboardEventKind::BeforeCopy:
     366    case ClipboardEventKind::BeforeCut:
     367    case ClipboardEventKind::BeforePaste:
     368        return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::Invalid, std::make_unique<StaticPasteboard>());
     369    }
     370    ASSERT_NOT_REACHED();
     371    return DataTransfer::createForCopyAndPaste(DataTransfer::StoreMode::Invalid, std::make_unique<StaticPasteboard>());
     372}
     373
    317374// Returns whether caller should continue with "the default processing", which is the same as
    318375// the event handler NOT setting the return value to false
    319376// https://w3c.github.io/clipboard-apis/#fire-a-clipboard-event
    320 static bool dispatchClipboardEvent(RefPtr<Element>&& target, const AtomicString& eventType)
     377static bool dispatchClipboardEvent(RefPtr<Element>&& target, ClipboardEventKind kind)
    321378{
    322379    // FIXME: Move the target selection code here.
     
    324381        return true;
    325382
    326     DataTransfer::StoreMode storeMode;
    327     if (eventType == eventNames().pasteEvent)
    328         storeMode = DataTransfer::StoreMode::Readonly;
    329     else if (eventType == eventNames().copyEvent || eventType == eventNames().cutEvent)
    330         storeMode = DataTransfer::StoreMode::ReadWrite;
    331     else {
    332         ASSERT(eventType == eventNames().beforecutEvent || eventType == eventNames().beforecopyEvent || eventType == eventNames().beforepasteEvent);
    333         storeMode = DataTransfer::StoreMode::Invalid;
    334     }
    335 
    336     auto dataTransfer = DataTransfer::createForCopyAndPaste(storeMode);
     383    auto dataTransfer = createDataTransferForClipboardEvent(kind);
    337384
    338385    ClipboardEvent::Init init;
     
    340387    init.cancelable = true;
    341388    init.clipboardData = dataTransfer.ptr();
    342     auto event = ClipboardEvent::create(eventType, init, Event::IsTrusted::Yes);
     389    auto event = ClipboardEvent::create(eventNameForClipboardEvent(kind), init, Event::IsTrusted::Yes);
    343390
    344391    target->dispatchEvent(event);
    345392    bool noDefaultProcessing = event->defaultPrevented();
    346     if (noDefaultProcessing && storeMode == DataTransfer::StoreMode::ReadWrite) {
     393    if (noDefaultProcessing && (kind == ClipboardEventKind::Copy || kind == ClipboardEventKind::Cut)) {
    347394        auto pasteboard = Pasteboard::createForCopyAndPaste();
    348395        pasteboard->clear();
     
    365412        return false;
    366413
    367     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().beforecutEvent);
     414    return !dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::BeforeCut);
    368415}
    369416
     
    372419    if (m_frame.selection().selection().isInPasswordField())
    373420        return false;
    374     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().beforecopyEvent);
     421    return !dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::BeforeCopy);
    375422}
    376423
    377424bool Editor::canDHTMLPaste()
    378425{
    379     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().beforepasteEvent);
     426    return !dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::BeforePaste);
    380427}
    381428
     
    645692        return false;
    646693
    647     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().copyEvent);
     694    return !dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::Copy);
    648695}
    649696
     
    653700        return false;
    654701   
    655     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().cutEvent);
    656 }
    657 
    658 bool Editor::tryDHTMLPaste()
    659 {
    660     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().pasteEvent);
     702    return !dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::Cut);
    661703}
    662704
     
    13371379void Editor::paste(Pasteboard& pasteboard)
    13381380{
    1339     if (tryDHTMLPaste())
     1381    if (!dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::Paste))
    13401382        return; // DHTML did the whole operation
    13411383    if (!canPaste())
     
    13511393void Editor::pasteAsPlainText()
    13521394{
    1353     if (tryDHTMLPaste())
     1395    if (!dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::PasteAsPlainText))
    13541396        return;
    13551397    if (!canPaste())
  • trunk/Source/WebCore/editing/Editor.h

    r222642 r222956  
    147147    bool tryDHTMLCopy();
    148148    bool tryDHTMLCut();
    149     WEBCORE_EXPORT bool tryDHTMLPaste();
    150149
    151150    WEBCORE_EXPORT bool canCut() const;
  • trunk/Source/WebCore/platform/ios/PasteboardIOS.mm

    r222702 r222956  
    359359        return;
    360360    }
     361    if ([cocoaType isEqualToString:(NSString *)kUTTypeHTML]) {
     362        resultTypes.add(ASCIILiteral("text/html"));
     363        // We don't return here for App compatibility.
     364    }
    361365    if (Pasteboard::shouldTreatCocoaTypeAsFile(cocoaType))
    362366        return;
Note: See TracChangeset for help on using the changeset viewer.