Title: [272111] branches/safari-611-branch
Revision
272111
Author
[email protected]
Date
2021-01-29 21:41:34 -0800 (Fri, 29 Jan 2021)

Log Message

Cherry-pick r271507. rdar://problem/73473467

    [Cocoa] Strip DataDetectors links when copying content to the pasteboard
    https://bugs.webkit.org/show_bug.cgi?id=220526
    <rdar://problem/71045590>

    Reviewed by Ryosuke Niwa.

    Source/WebCore:

    Currently, when DataDetectors links are written to the pasteboard when
    copied. This is problematic, since clicking on a DataDetector link
    outside of a valid context results in an attempt to open an invalid
    URL. Instead, DataDetectors links should be stripped when copied.

    To remove the link, while preserving any custom styles, the <a> element
    created by Data Detection is replaced with a <span> element. Any
    attributes and styles added by WebKit are removed as a part of this
    transformation.

    Tests: editing/pasteboard/copy-paste-data-detected-links.html
           CopyRTF.StripsDataDetectedLinks
           PasteWebArchive.StripsDataDetectedLinks

    * editing/cocoa/DataDetection.h:
    * editing/cocoa/DataDetection.mm:
    (WebCore::DataDetection::isDataDetectorElement):

    Add a helper to check if an element was created through Data Detection.

    * editing/cocoa/HTMLConverter.mm:
    (HTMLConverter::_addLinkForElement):

    Do not add NSLinkAttributeName for DataDetectors links.

    (HTMLConverter::_exitElement):

    Factor out link creation logic.

    * editing/markup.cpp:
    (WebCore::StyledMarkupAccumulator::spanReplacementForElement):

    Centralize the logic that determines whether or not an element should
    be replaced by a <span>. Previously, this only applied to <slot>
    elements. Now, it applies to <slot> and DataDetectors links.

    (WebCore::StyledMarkupAccumulator::appendStartTag):

    If the element was created through DataDetection, append a <span>
    rather than an <a>, to drop the link. The DataDetectors and href
    attributes are also dropped from the markup string. Finally, remove
    the text decoration style that was added by WebKit to style the
    DataDetectors link.

    (WebCore::StyledMarkupAccumulator::appendEndTag):

    Consult shouldReplaceElementWithSpan when appending the end tag.

    Tools:

    Added API tests to verify DataDetectors links are not preserved when
    copying/pasting WebArchives and rich text.

    * TestWebKitAPI/Tests/WebKitCocoa/CopyRTF.mm:
    (StripsDataDetectorsLinks):
    * TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm:
    (StripsDataDetectorsLinks):

    LayoutTests:

    Added a test which copies content containing two data detected links
    and verifies that the links are removed.

    * editing/pasteboard/copy-paste-data-detected-links-expected.txt: Added.
    * editing/pasteboard/copy-paste-data-detected-links.html: Added.

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271507 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-611-branch/LayoutTests/ChangeLog (272110 => 272111)


--- branches/safari-611-branch/LayoutTests/ChangeLog	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/LayoutTests/ChangeLog	2021-01-30 05:41:34 UTC (rev 272111)
@@ -1,5 +1,100 @@
 2021-01-29  Alan Coon  <[email protected]>
 
+        Cherry-pick r271507. rdar://problem/73473467
+
+    [Cocoa] Strip DataDetectors links when copying content to the pasteboard
+    https://bugs.webkit.org/show_bug.cgi?id=220526
+    <rdar://problem/71045590>
+    
+    Reviewed by Ryosuke Niwa.
+    
+    Source/WebCore:
+    
+    Currently, when DataDetectors links are written to the pasteboard when
+    copied. This is problematic, since clicking on a DataDetector link
+    outside of a valid context results in an attempt to open an invalid
+    URL. Instead, DataDetectors links should be stripped when copied.
+    
+    To remove the link, while preserving any custom styles, the <a> element
+    created by Data Detection is replaced with a <span> element. Any
+    attributes and styles added by WebKit are removed as a part of this
+    transformation.
+    
+    Tests: editing/pasteboard/copy-paste-data-detected-links.html
+           CopyRTF.StripsDataDetectedLinks
+           PasteWebArchive.StripsDataDetectedLinks
+    
+    * editing/cocoa/DataDetection.h:
+    * editing/cocoa/DataDetection.mm:
+    (WebCore::DataDetection::isDataDetectorElement):
+    
+    Add a helper to check if an element was created through Data Detection.
+    
+    * editing/cocoa/HTMLConverter.mm:
+    (HTMLConverter::_addLinkForElement):
+    
+    Do not add NSLinkAttributeName for DataDetectors links.
+    
+    (HTMLConverter::_exitElement):
+    
+    Factor out link creation logic.
+    
+    * editing/markup.cpp:
+    (WebCore::StyledMarkupAccumulator::spanReplacementForElement):
+    
+    Centralize the logic that determines whether or not an element should
+    be replaced by a <span>. Previously, this only applied to <slot>
+    elements. Now, it applies to <slot> and DataDetectors links.
+    
+    (WebCore::StyledMarkupAccumulator::appendStartTag):
+    
+    If the element was created through DataDetection, append a <span>
+    rather than an <a>, to drop the link. The DataDetectors and href
+    attributes are also dropped from the markup string. Finally, remove
+    the text decoration style that was added by WebKit to style the
+    DataDetectors link.
+    
+    (WebCore::StyledMarkupAccumulator::appendEndTag):
+    
+    Consult shouldReplaceElementWithSpan when appending the end tag.
+    
+    Tools:
+    
+    Added API tests to verify DataDetectors links are not preserved when
+    copying/pasting WebArchives and rich text.
+    
+    * TestWebKitAPI/Tests/WebKitCocoa/CopyRTF.mm:
+    (StripsDataDetectorsLinks):
+    * TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm:
+    (StripsDataDetectorsLinks):
+    
+    LayoutTests:
+    
+    Added a test which copies content containing two data detected links
+    and verifies that the links are removed.
+    
+    * editing/pasteboard/copy-paste-data-detected-links-expected.txt: Added.
+    * editing/pasteboard/copy-paste-data-detected-links.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-01-14  Aditya Keerthi  <[email protected]>
+
+            [Cocoa] Strip DataDetectors links when copying content to the pasteboard
+            https://bugs.webkit.org/show_bug.cgi?id=220526
+            <rdar://problem/71045590>
+
+            Reviewed by Ryosuke Niwa.
+
+            Added a test which copies content containing two data detected links
+            and verifies that the links are removed.
+
+            * editing/pasteboard/copy-paste-data-detected-links-expected.txt: Added.
+            * editing/pasteboard/copy-paste-data-detected-links.html: Added.
+
+2021-01-29  Alan Coon  <[email protected]>
+
         Cherry-pick r271459. rdar://problem/73473665
 
     [macOS] "Correct Spelling Automatically" menu items are inconsistent when autocorrect="off"

Added: branches/safari-611-branch/LayoutTests/editing/pasteboard/copy-paste-data-detected-links-expected.txt (0 => 272111)


--- branches/safari-611-branch/LayoutTests/editing/pasteboard/copy-paste-data-detected-links-expected.txt	                        (rev 0)
+++ branches/safari-611-branch/LayoutTests/editing/pasteboard/copy-paste-data-detected-links-expected.txt	2021-01-30 05:41:34 UTC (rev 272111)
@@ -0,0 +1,12 @@
+This tests copy/paste of content containing data-detected links.
+| "Meeting "
+| <span>
+|   dir="ltr"
+|   style="font-weight: bold;"
+|   "on Friday 11/6 at 4pm"
+| " "
+| "at"
+| " "
+| <span>
+|   dir="ltr"
+|   "1 Apple Park Way, Cupertino CA<#selection-caret>"

Added: branches/safari-611-branch/LayoutTests/editing/pasteboard/copy-paste-data-detected-links.html (0 => 272111)


--- branches/safari-611-branch/LayoutTests/editing/pasteboard/copy-paste-data-detected-links.html	                        (rev 0)
+++ branches/safari-611-branch/LayoutTests/editing/pasteboard/copy-paste-data-detected-links.html	2021-01-30 05:41:34 UTC (rev 272111)
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests copy/paste of content containing data-detected links.</p>
+<div id="copy" contenteditable="true">
+    <span>Meeting <a href="" dir="ltr" x-apple-data-detectors="true" x-apple-data-detectors-type="calendar-event" x-apple-data-detectors-result="0" style="color: currentcolor; text-decoration-color: rgba(128, 128, 128, 0.38); font-weight: bold;">on Friday 11/6 at 4pm</a> at <a href="" dir="ltr" x-apple-data-detectors="true" x-apple-data-detectors-type="address" x-apple-data-detectors-result="1" style="color: currentcolor; text-decoration-color: rgba(128, 128, 128, 0.38);">1 Apple Park Way, Cupertino CA</a>
+    </span>
+</div>
+<div id="paste" contenteditable="true"></div>
+<script src=""
+<script>
+var copy = document.getElementById("copy");
+copy.focus();
+document.execCommand("SelectAll");
+document.execCommand("Copy");
+
+var paste = document.getElementById("paste");
+paste.focus();
+document.execCommand("Paste");
+
+Markup.description(document.getElementsByTagName('p')[0].textContent);
+Markup.dump('paste');
+</script>
+</body>
+</html>

Modified: branches/safari-611-branch/Source/WebCore/ChangeLog (272110 => 272111)


--- branches/safari-611-branch/Source/WebCore/ChangeLog	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/Source/WebCore/ChangeLog	2021-01-30 05:41:34 UTC (rev 272111)
@@ -1,5 +1,142 @@
 2021-01-29  Alan Coon  <[email protected]>
 
+        Cherry-pick r271507. rdar://problem/73473467
+
+    [Cocoa] Strip DataDetectors links when copying content to the pasteboard
+    https://bugs.webkit.org/show_bug.cgi?id=220526
+    <rdar://problem/71045590>
+    
+    Reviewed by Ryosuke Niwa.
+    
+    Source/WebCore:
+    
+    Currently, when DataDetectors links are written to the pasteboard when
+    copied. This is problematic, since clicking on a DataDetector link
+    outside of a valid context results in an attempt to open an invalid
+    URL. Instead, DataDetectors links should be stripped when copied.
+    
+    To remove the link, while preserving any custom styles, the <a> element
+    created by Data Detection is replaced with a <span> element. Any
+    attributes and styles added by WebKit are removed as a part of this
+    transformation.
+    
+    Tests: editing/pasteboard/copy-paste-data-detected-links.html
+           CopyRTF.StripsDataDetectedLinks
+           PasteWebArchive.StripsDataDetectedLinks
+    
+    * editing/cocoa/DataDetection.h:
+    * editing/cocoa/DataDetection.mm:
+    (WebCore::DataDetection::isDataDetectorElement):
+    
+    Add a helper to check if an element was created through Data Detection.
+    
+    * editing/cocoa/HTMLConverter.mm:
+    (HTMLConverter::_addLinkForElement):
+    
+    Do not add NSLinkAttributeName for DataDetectors links.
+    
+    (HTMLConverter::_exitElement):
+    
+    Factor out link creation logic.
+    
+    * editing/markup.cpp:
+    (WebCore::StyledMarkupAccumulator::spanReplacementForElement):
+    
+    Centralize the logic that determines whether or not an element should
+    be replaced by a <span>. Previously, this only applied to <slot>
+    elements. Now, it applies to <slot> and DataDetectors links.
+    
+    (WebCore::StyledMarkupAccumulator::appendStartTag):
+    
+    If the element was created through DataDetection, append a <span>
+    rather than an <a>, to drop the link. The DataDetectors and href
+    attributes are also dropped from the markup string. Finally, remove
+    the text decoration style that was added by WebKit to style the
+    DataDetectors link.
+    
+    (WebCore::StyledMarkupAccumulator::appendEndTag):
+    
+    Consult shouldReplaceElementWithSpan when appending the end tag.
+    
+    Tools:
+    
+    Added API tests to verify DataDetectors links are not preserved when
+    copying/pasting WebArchives and rich text.
+    
+    * TestWebKitAPI/Tests/WebKitCocoa/CopyRTF.mm:
+    (StripsDataDetectorsLinks):
+    * TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm:
+    (StripsDataDetectorsLinks):
+    
+    LayoutTests:
+    
+    Added a test which copies content containing two data detected links
+    and verifies that the links are removed.
+    
+    * editing/pasteboard/copy-paste-data-detected-links-expected.txt: Added.
+    * editing/pasteboard/copy-paste-data-detected-links.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-01-14  Aditya Keerthi  <[email protected]>
+
+            [Cocoa] Strip DataDetectors links when copying content to the pasteboard
+            https://bugs.webkit.org/show_bug.cgi?id=220526
+            <rdar://problem/71045590>
+
+            Reviewed by Ryosuke Niwa.
+
+            Currently, when DataDetectors links are written to the pasteboard when
+            copied. This is problematic, since clicking on a DataDetector link
+            outside of a valid context results in an attempt to open an invalid
+            URL. Instead, DataDetectors links should be stripped when copied.
+
+            To remove the link, while preserving any custom styles, the <a> element
+            created by Data Detection is replaced with a <span> element. Any
+            attributes and styles added by WebKit are removed as a part of this
+            transformation.
+
+            Tests: editing/pasteboard/copy-paste-data-detected-links.html
+                   CopyRTF.StripsDataDetectedLinks
+                   PasteWebArchive.StripsDataDetectedLinks
+
+            * editing/cocoa/DataDetection.h:
+            * editing/cocoa/DataDetection.mm:
+            (WebCore::DataDetection::isDataDetectorElement):
+
+            Add a helper to check if an element was created through Data Detection.
+
+            * editing/cocoa/HTMLConverter.mm:
+            (HTMLConverter::_addLinkForElement):
+
+            Do not add NSLinkAttributeName for DataDetectors links.
+
+            (HTMLConverter::_exitElement):
+
+            Factor out link creation logic.
+
+            * editing/markup.cpp:
+            (WebCore::StyledMarkupAccumulator::spanReplacementForElement):
+
+            Centralize the logic that determines whether or not an element should
+            be replaced by a <span>. Previously, this only applied to <slot>
+            elements. Now, it applies to <slot> and DataDetectors links.
+
+            (WebCore::StyledMarkupAccumulator::appendStartTag):
+
+            If the element was created through DataDetection, append a <span>
+            rather than an <a>, to drop the link. The DataDetectors and href
+            attributes are also dropped from the markup string. Finally, remove
+            the text decoration style that was added by WebKit to style the
+            DataDetectors link.
+
+            (WebCore::StyledMarkupAccumulator::appendEndTag):
+
+            Consult shouldReplaceElementWithSpan when appending the end tag.
+
+2021-01-29  Alan Coon  <[email protected]>
+
         Cherry-pick r271503. rdar://problem/73473503
 
     Add a quirk to disable "return to element fullscreen from picture-in-picture" for some sites

Modified: branches/safari-611-branch/Source/WebCore/editing/cocoa/DataDetection.h (272110 => 272111)


--- branches/safari-611-branch/Source/WebCore/editing/cocoa/DataDetection.h	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/Source/WebCore/editing/cocoa/DataDetection.h	2021-01-30 05:41:34 UTC (rev 272111)
@@ -40,6 +40,7 @@
 namespace WebCore {
 
 class HitTestResult;
+class QualifiedName;
 
 struct DetectedItem {
     RetainPtr<DDActionContext> actionContext;
@@ -64,6 +65,8 @@
 
     static const String& dataDetectorURLProtocol();
     static bool isDataDetectorURL(const URL&);
+    static bool isDataDetectorAttribute(const QualifiedName&);
+    static bool isDataDetectorElement(const Element&);
 };
 
 } // namespace WebCore

Modified: branches/safari-611-branch/Source/WebCore/editing/cocoa/DataDetection.mm (272110 => 272111)


--- branches/safari-611-branch/Source/WebCore/editing/cocoa/DataDetection.mm	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/Source/WebCore/editing/cocoa/DataDetection.mm	2021-01-30 05:41:34 UTC (rev 272111)
@@ -42,6 +42,7 @@
 #import "HitTestResult.h"
 #import "NodeList.h"
 #import "NodeTraversal.h"
+#import "QualifiedName.h"
 #import "Range.h"
 #import "RenderObject.h"
 #import "StyleProperties.h"
@@ -654,6 +655,28 @@
     return url.protocolIs(dataDetectorURLProtocol());
 }
 
+bool DataDetection::isDataDetectorAttribute(const QualifiedName& name)
+{
+    if (name == x_apple_data_detectorsAttr)
+        return true;
+
+    if (name == x_apple_data_detectors_resultAttr)
+        return true;
+
+    if (name == x_apple_data_detectors_typeAttr)
+        return true;
+
+    if (name == hrefAttr)
+        return true;
+
+    return false;
+}
+
+bool DataDetection::isDataDetectorElement(const Element& element)
+{
+    return is<HTMLAnchorElement>(element) && equalIgnoringASCIICase(element.attributeWithoutSynchronization(x_apple_data_detectorsAttr), "true");
+}
+
 } // namespace WebCore
 
 #endif

Modified: branches/safari-611-branch/Source/WebCore/editing/cocoa/HTMLConverter.mm (272110 => 272111)


--- branches/safari-611-branch/Source/WebCore/editing/cocoa/HTMLConverter.mm	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/Source/WebCore/editing/cocoa/HTMLConverter.mm	2021-01-30 05:41:34 UTC (rev 272111)
@@ -68,6 +68,10 @@
 #import <wtf/ASCIICType.h>
 #import <wtf/text/StringBuilder.h>
 
+#if ENABLE(DATA_DETECTION)
+#import "DataDetection.h"
+#endif
+
 #if PLATFORM(IOS_FAMILY)
 
 #import "WAKAppKitStubs.h"
@@ -343,7 +347,8 @@
     
     void _processHeadElement(Element&);
     void _processMetaElementWithName(NSString *name, NSString *content);
-    
+
+    void _addLinkForElement(Element&, NSRange);
     void _addTableForElement(Element* tableElement);
     void _addTableCellForElement(Element* tableCellElement);
     void _addMarkersToList(NSTextList *list, NSRange range);
@@ -1632,6 +1637,25 @@
     return NO;
 }
 
+void HTMLConverter::_addLinkForElement(Element& element, NSRange range)
+{
+#if ENABLE(DATA_DETECTION)
+    if (DataDetection::isDataDetectorElement(element))
+        return;
+#endif
+
+    NSString *urlString = element.getAttribute(hrefAttr);
+    NSString *strippedString = [urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+    if (urlString && [urlString length] > 0 && strippedString && [strippedString length] > 0 && ![strippedString hasPrefix:@"#"]) {
+        NSURL *url = ""
+        if (!url)
+            url = ""
+        if (!url)
+            url = "" _web_URLWithString:strippedString relativeToURL:_baseURL];
+        [_attrStr addAttribute:NSLinkAttributeName value:url ? (id)url : (id)urlString range:range];
+    }
+}
+
 void HTMLConverter::_addTableForElement(Element *tableElement)
 {
     RetainPtr<NSTextTable> table = adoptNS([(NSTextTable *)[PlatformNSTextTable alloc] init]);
@@ -1963,18 +1987,8 @@
 {
     String displayValue = _caches->propertyValueForNode(element, CSSPropertyDisplay);
     NSRange range = NSMakeRange(startIndex, [_attrStr length] - startIndex);
-    if (range.length > 0 && element.hasTagName(aTag)) {
-        NSString *urlString = element.getAttribute(hrefAttr);
-        NSString *strippedString = [urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
-        if (urlString && [urlString length] > 0 && strippedString && [strippedString length] > 0 && ![strippedString hasPrefix:@"#"]) {
-            NSURL *url = ""
-            if (!url)
-                url = ""
-            if (!url)
-                url = "" _web_URLWithString:strippedString relativeToURL:_baseURL];
-            [_attrStr addAttribute:NSLinkAttributeName value:url ? (id)url : (id)urlString range:range];
-        }
-    }
+    if (range.length > 0 && element.hasTagName(aTag))
+        _addLinkForElement(element, range);
     if (!_flags.reachedEnd && _caches->isBlockElement(element)) {
         [_writingDirectionArray removeAllObjects];
         if (displayValue == "table-cell" && [_textBlocks count] == 0) {

Modified: branches/safari-611-branch/Source/WebCore/editing/markup.cpp (272110 => 272111)


--- branches/safari-611-branch/Source/WebCore/editing/markup.cpp	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/Source/WebCore/editing/markup.cpp	2021-01-30 05:41:34 UTC (rev 272111)
@@ -82,6 +82,10 @@
 #include <wtf/URLParser.h>
 #include <wtf/text/StringBuilder.h>
 
+#if ENABLE(DATA_DETECTION)
+#include "DataDetection.h"
+#endif
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -256,6 +260,15 @@
 
     bool shouldPreserveMSOListStyleForElement(const Element&);
 
+    enum class SpanReplacementType : uint8_t {
+        None,
+        Slot,
+#if ENABLE(DATA_DETECTION)
+        DataDetector,
+#endif
+    };
+    SpanReplacementType spanReplacementForElement(const Element&);
+
     void appendStartTag(StringBuilder& out, const Element&, bool addDisplayInline, RangeFullySelectsNode);
     void appendEndTag(StringBuilder& out, const Element&) override;
     void appendCustomAttributes(StringBuilder&, const Element&, Namespaces*) override;
@@ -506,11 +519,25 @@
     return false;
 }
 
+StyledMarkupAccumulator::SpanReplacementType StyledMarkupAccumulator::spanReplacementForElement(const Element& element)
+{
+    if (is<HTMLSlotElement>(element))
+        return SpanReplacementType::Slot;
+
+#if ENABLE(DATA_DETECTION)
+    if (DataDetection::isDataDetectorElement(element))
+        return SpanReplacementType::DataDetector;
+#endif
+
+    return SpanReplacementType::None;
+}
+
 void StyledMarkupAccumulator::appendStartTag(StringBuilder& out, const Element& element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
 {
     const bool documentIsHTML = element.document().isHTMLDocument();
-    const bool isSlotElement = is<HTMLSlotElement>(element);
-    if (UNLIKELY(isSlotElement))
+
+    auto replacementType = spanReplacementForElement(element);
+    if (UNLIKELY(replacementType != SpanReplacementType::None))
         out.append("<span");
     else
         appendOpenTag(out, element, nullptr);
@@ -518,7 +545,7 @@
     appendCustomAttributes(out, element, nullptr);
 
     const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldAnnotate() || addDisplayInline);
-    bool shouldOverrideStyleAttr = (shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element) || isSlotElement) && !shouldPreserveMSOListStyleForElement(element);
+    bool shouldOverrideStyleAttr = (shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element) || replacementType != SpanReplacementType::None) && !shouldPreserveMSOListStyleForElement(element);
     if (element.hasAttributes()) {
         for (const Attribute& attribute : element.attributesIterator()) {
             // We'll handle the style attribute separately, below.
@@ -526,6 +553,10 @@
                 continue;
             if (element.isEventHandlerAttribute(attribute) || element.isJavaScriptURLAttribute(attribute))
                 continue;
+#if ENABLE(DATA_DETECTION)
+            if (replacementType == SpanReplacementType::DataDetector && DataDetection::isDataDetectorAttribute(attribute.name()))
+                continue;
+#endif
             appendAttribute(out, element, attribute, 0);
         }
     }
@@ -540,12 +571,17 @@
         } else
             newInlineStyle = EditingStyle::create();
 
-        if (isSlotElement)
+        if (replacementType == SpanReplacementType::Slot)
             newInlineStyle->addDisplayContents();
 
         if (is<StyledElement>(element) && downcast<StyledElement>(element).inlineStyle())
             newInlineStyle->overrideWithStyle(*downcast<StyledElement>(element).inlineStyle());
 
+#if ENABLE(DATA_DETECTION)
+        if (replacementType == SpanReplacementType::DataDetector && newInlineStyle->style())
+            newInlineStyle->style()->removeProperty(CSSPropertyTextDecorationColor);
+#endif
+
         if (shouldAnnotateOrForceInline) {
             if (shouldAnnotate())
                 newInlineStyle->mergeStyleFromRulesForSerialization(downcast<HTMLElement>(*const_cast<Element*>(&element)), m_standardFontFamilySerializationMode);
@@ -576,7 +612,7 @@
 
 void StyledMarkupAccumulator::appendEndTag(StringBuilder& out, const Element& element)
 {
-    if (UNLIKELY(is<HTMLSlotElement>(element)))
+    if (UNLIKELY(spanReplacementForElement(element) != SpanReplacementType::None))
         out.append("</span>");
     else
         MarkupAccumulator::appendEndTag(out, element);

Modified: branches/safari-611-branch/Tools/ChangeLog (272110 => 272111)


--- branches/safari-611-branch/Tools/ChangeLog	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/Tools/ChangeLog	2021-01-30 05:41:34 UTC (rev 272111)
@@ -1,5 +1,102 @@
 2021-01-29  Alan Coon  <[email protected]>
 
+        Cherry-pick r271507. rdar://problem/73473467
+
+    [Cocoa] Strip DataDetectors links when copying content to the pasteboard
+    https://bugs.webkit.org/show_bug.cgi?id=220526
+    <rdar://problem/71045590>
+    
+    Reviewed by Ryosuke Niwa.
+    
+    Source/WebCore:
+    
+    Currently, when DataDetectors links are written to the pasteboard when
+    copied. This is problematic, since clicking on a DataDetector link
+    outside of a valid context results in an attempt to open an invalid
+    URL. Instead, DataDetectors links should be stripped when copied.
+    
+    To remove the link, while preserving any custom styles, the <a> element
+    created by Data Detection is replaced with a <span> element. Any
+    attributes and styles added by WebKit are removed as a part of this
+    transformation.
+    
+    Tests: editing/pasteboard/copy-paste-data-detected-links.html
+           CopyRTF.StripsDataDetectedLinks
+           PasteWebArchive.StripsDataDetectedLinks
+    
+    * editing/cocoa/DataDetection.h:
+    * editing/cocoa/DataDetection.mm:
+    (WebCore::DataDetection::isDataDetectorElement):
+    
+    Add a helper to check if an element was created through Data Detection.
+    
+    * editing/cocoa/HTMLConverter.mm:
+    (HTMLConverter::_addLinkForElement):
+    
+    Do not add NSLinkAttributeName for DataDetectors links.
+    
+    (HTMLConverter::_exitElement):
+    
+    Factor out link creation logic.
+    
+    * editing/markup.cpp:
+    (WebCore::StyledMarkupAccumulator::spanReplacementForElement):
+    
+    Centralize the logic that determines whether or not an element should
+    be replaced by a <span>. Previously, this only applied to <slot>
+    elements. Now, it applies to <slot> and DataDetectors links.
+    
+    (WebCore::StyledMarkupAccumulator::appendStartTag):
+    
+    If the element was created through DataDetection, append a <span>
+    rather than an <a>, to drop the link. The DataDetectors and href
+    attributes are also dropped from the markup string. Finally, remove
+    the text decoration style that was added by WebKit to style the
+    DataDetectors link.
+    
+    (WebCore::StyledMarkupAccumulator::appendEndTag):
+    
+    Consult shouldReplaceElementWithSpan when appending the end tag.
+    
+    Tools:
+    
+    Added API tests to verify DataDetectors links are not preserved when
+    copying/pasting WebArchives and rich text.
+    
+    * TestWebKitAPI/Tests/WebKitCocoa/CopyRTF.mm:
+    (StripsDataDetectorsLinks):
+    * TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm:
+    (StripsDataDetectorsLinks):
+    
+    LayoutTests:
+    
+    Added a test which copies content containing two data detected links
+    and verifies that the links are removed.
+    
+    * editing/pasteboard/copy-paste-data-detected-links-expected.txt: Added.
+    * editing/pasteboard/copy-paste-data-detected-links.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-01-14  Aditya Keerthi  <[email protected]>
+
+            [Cocoa] Strip DataDetectors links when copying content to the pasteboard
+            https://bugs.webkit.org/show_bug.cgi?id=220526
+            <rdar://problem/71045590>
+
+            Reviewed by Ryosuke Niwa.
+
+            Added API tests to verify DataDetectors links are not preserved when
+            copying/pasting WebArchives and rich text.
+
+            * TestWebKitAPI/Tests/WebKitCocoa/CopyRTF.mm:
+            (StripsDataDetectorsLinks):
+            * TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm:
+            (StripsDataDetectorsLinks):
+
+2021-01-29  Alan Coon  <[email protected]>
+
         Cherry-pick r271459. rdar://problem/73473665
 
     [macOS] "Correct Spelling Automatically" menu items are inconsistent when autocorrect="off"

Modified: branches/safari-611-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/CopyRTF.mm (272110 => 272111)


--- branches/safari-611-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/CopyRTF.mm	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/CopyRTF.mm	2021-01-30 05:41:34 UTC (rev 272111)
@@ -140,4 +140,27 @@
     EXPECT_EQ(i, 3UL);
 }
 
+#if ENABLE(DATA_DETECTION)
+
+TEST(CopyRTF, StripsDataDetectorsLinks)
+{
+    auto attributedString = copyAttributedStringFromHTML(@"<a href="" <a href="" dir=\"ltr\" x-apple-data-detectors=\"true\" x-apple-data-detectors-type=\"calendar-event\" x-apple-data-detectors-result=\"0\" style=\"color: currentcolor; text-decoration-color: rgba(128, 128, 128, 0.38);\">on Friday 11/6 at 4pm</a>", false);
+
+    __block size_t i = 0;
+    [attributedString enumerateAttribute:NSLinkAttributeName inRange:NSMakeRange(0, [attributedString length]) options:0 usingBlock:^(id value, NSRange attributeRange, BOOL *stop) {
+        if (!i)
+            EXPECT_NOT_NULL(value);
+        else if (i == 1)
+            EXPECT_NULL(value);
+        else
+            FAIL();
+
+        ++i;
+    }];
+
+    EXPECT_EQ(i, 2UL);
+}
+
+#endif // ENABLE(DATA_DETECTION)
+
 #endif // PLATFORM(COCOA)

Modified: branches/safari-611-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm (272110 => 272111)


--- branches/safari-611-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm	2021-01-30 05:41:28 UTC (rev 272110)
+++ branches/safari-611-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm	2021-01-30 05:41:34 UTC (rev 272111)
@@ -262,6 +262,27 @@
     EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(document.querySelector('strong')).color"]);
 }
 
+#if ENABLE(DATA_DETECTION)
+
+TEST(PasteWebArchive, StripsDataDetectorsLinks)
+{
+    auto* url = "" URLWithString:@"file:///some-file.html"];
+    auto* markup = [@"<!DOCTYPE html><html><body><span>Meeting <a href="" dir=\"ltr\" x-apple-data-detectors=\"true\" x-apple-data-detectors-type=\"calendar-event\" x-apple-data-detectors-result=\"0\" style=\"color: currentcolor; text-decoration-color: rgba(128, 128, 128, 0.38); font-weight: bold;\">on Friday 11/6 at 4pm</a> at <a href="" dir=\"ltr\" x-apple-data-detectors=\"true\" x-apple-data-detectors-type=\"address\" x-apple-data-detectors-result=\"1\" style=\"color: currentcolor; text-decoration-color: rgba(128, 128, 128, 0.38);\">1 Apple Park Way, Cupertino CA</a></span></body></html>" dataUsingEncoding:NSUTF8StringEncoding];
+    auto mainResource = adoptNS([[WebResource alloc] initWithData:markup URL:url MIMEType:@"text/html" textEncodingName:@"utf-8" frameName:nil]);
+    auto archive = adoptNS([[WebArchive alloc] initWithMainResource:mainResource.get() subresources:nil subframeArchives:nil]);
+
+    [[NSPasteboard generalPasteboard] declareTypes:@[WebArchivePboardType] owner:nil];
+    [[NSPasteboard generalPasteboard] setData:[archive data] forType:WebArchivePboardType];
+
+    auto webView = createWebViewWithCustomPasteboardDataEnabled();
+    [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
+    [webView paste:nil];
+
+    EXPECT_WK_STREQ("Meeting&nbsp;<span dir=\"ltr\" style=\"font-weight: bold;\">on Friday 11/6 at 4pm</span>&nbsp;at&nbsp;<span dir=\"ltr\">1 Apple Park Way, Cupertino CA</span>", [webView stringByEvaluatingJavaScript:@"editor.innerHTML"]);
+}
+
+#endif // ENABLE(DATA_DETECTION)
+
 #endif // PLATFORM(MAC)
 
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to