Title: [255532] trunk
Revision
255532
Author
[email protected]
Date
2020-01-31 16:44:07 -0800 (Fri, 31 Jan 2020)

Log Message

Add support for specifying background colors when setting marked text
https://bugs.webkit.org/show_bug.cgi?id=207065
<rdar://problem/57876140>

Reviewed by Tim Horton.

Source/WebCore:

Add support for rendering custom highlights (background colors) behind marked text in WebCore. To do this, we
plumb a Vector of CompositionHighlights alongside the Vector of CompositionUnderlines to Editor. At paint time,
we then consult this highlight data to determine which ranges of text in the composition should paint using
custom background colors.

Note that in the future, we should consider refactoring both composition underlines and highlights to use the
MarkedText mechanism for decorating ranges of text instead.

Test: editing/input/composition-highlights.html

* Headers.cmake:
* WebCore.xcodeproj/project.pbxproj:
* editing/CompositionHighlight.h: Added.
(WebCore::CompositionHighlight::CompositionHighlight):
(WebCore::CompositionHighlight::encode const):
(WebCore::CompositionHighlight::decode):

Add CompositionHighlight, which represents a range in the composition that should be highlighted with a given
background color.

* editing/Editor.cpp:
(WebCore::Editor::clear):
(WebCore::Editor::setComposition):

Add logic for clearing and updating m_customCompositionHighlights.

* editing/Editor.h:
(WebCore::Editor::compositionUsesCustomHighlights const):
(WebCore::Editor::customCompositionHighlights const):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paintCompositionBackground):

If custom composition highlights are given, use those when painting the composition background; otherwise,
default to painting the entire composition range using `Color::compositionFill`.

Source/WebCore/PAL:

Add an SPI soft-linking declaration for NSMarkedClauseSegmentAttributeName.

* pal/spi/cocoa/NSAttributedStringSPI.h:

Source/WebKit:

Implement -setAttributedMarkedText:selectedRange: on WKContentView, and have it extract highlight color
information from the given attributed string. Plumb this through to the web process by serializing and
deserializing `WebCore::CompositionHighlight`s.

* UIProcess/Cocoa/WebViewImpl.mm:
(WebKit::WebViewImpl::setMarkedText):
* UIProcess/WebPageProxy.cpp:
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(compositionHighlights):

For each marked text clause, grab the specified background color (defaulting to Color::compositionFill) and use
it to create a list of CompositionHighlights.

(-[WKContentView setAttributedMarkedText:selectedRange:]):
(-[WKContentView setMarkedText:selectedRange:]):
(-[WKContentView _setMarkedText:highlights:selectedRange:]):
* WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageSetComposition):

Add testing support for specifying highlight ranges when setting marked text.

* WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h:
* WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp:
(WebKit::WebEditorClient::didDispatchInputMethodKeydown):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setCompositionForTesting):
(WebKit::WebPage::setCompositionAsync):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Source/WebKitLegacy/mac:

Adjust some call sites of Editor::setComposition().

* WebView/WebFrame.mm:
(-[WebFrame setMarkedText:selectedRange:]):
(-[WebFrame setMarkedText:forCandidates:]):
* WebView/WebHTMLView.mm:
(-[WebHTMLView setMarkedText:selectedRange:]):

Source/WebKitLegacy/win:

Adjust some call sites of Editor::setComposition().

* WebView.cpp:
(WebView::onIMEComposition):
(WebView::setCompositionForTesting):

Tools:

Add support in WebKitTestRunner for specifying a list of highlight ranges when setting marked text. This comes
in the form of an additional argument to TextInputController::setMarkedText, which contains an array of objects,
each describing one range (in the composition) to highlight.

* DumpRenderTree/ios/TextInputControllerIOS.m:
(+[TextInputController isSelectorExcludedFromWebScript:]):
(+[TextInputController webScriptNameForSelector:]):
(-[TextInputController setMarkedText:selectedFrom:length:suppressUnderline:highlights:]):
(-[TextInputController setMarkedText:selectedFrom:length:suppressUnderline:]): Deleted.
* DumpRenderTree/mac/TextInputControllerMac.m:
(+[TextInputController isSelectorExcludedFromWebScript:]):
(+[TextInputController webScriptNameForSelector:]):
(-[TextInputController setMarkedText:selectedFrom:length:suppressUnderline:highlights:]):
(-[TextInputController setMarkedText:selectedFrom:length:suppressUnderline:]): Deleted.
* WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl:
* WebKitTestRunner/InjectedBundle/TextInputController.cpp:
(WTR::arrayLength):
(WTR::createCompositionHighlightData):

Add logic to convert a given JSObject containing the composition highlight information into a WKArrayRef, which
is then passed into WebKit via WKBundlePageSetComposition.

(WTR::TextInputController::setMarkedText):
* WebKitTestRunner/InjectedBundle/TextInputController.h:

LayoutTests:

Add a test to check that highlighting different parts of a composition range results in the same behavior as
applying background colors using CSS. This test is currently only supported in WebKit2.

* TestExpectations:
* editing/input/composition-highlights-expected.html: Added.
* editing/input/composition-highlights.html: Added.
* platform/wk2/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (255531 => 255532)


--- trunk/LayoutTests/ChangeLog	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/LayoutTests/ChangeLog	2020-02-01 00:44:07 UTC (rev 255532)
@@ -1,3 +1,19 @@
+2020-01-31  Wenson Hsieh  <[email protected]>
+
+        Add support for specifying background colors when setting marked text
+        https://bugs.webkit.org/show_bug.cgi?id=207065
+        <rdar://problem/57876140>
+
+        Reviewed by Tim Horton.
+
+        Add a test to check that highlighting different parts of a composition range results in the same behavior as
+        applying background colors using CSS. This test is currently only supported in WebKit2.
+
+        * TestExpectations:
+        * editing/input/composition-highlights-expected.html: Added.
+        * editing/input/composition-highlights.html: Added.
+        * platform/wk2/TestExpectations:
+
 2020-01-31  Justin Fan  <[email protected]>
 
         [WebGL] Revert logging added to investigate 205757

Modified: trunk/LayoutTests/TestExpectations (255531 => 255532)


--- trunk/LayoutTests/TestExpectations	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/LayoutTests/TestExpectations	2020-02-01 00:44:07 UTC (rev 255532)
@@ -75,6 +75,9 @@
 printing/printing-events.html [ Skip ]
 fast/forms/enterkeyhint-attribute-values.html [ Skip ]
 
+# Highlighting marked text ranges from layout tests is only supported in WebKit2.
+editing/input/composition-highlights.html [ Skip ]
+
 http/tests/security/xss-DENIED-xsl-external-entity-no-logging.xml [ Skip ]
 
 # window.showModalDialog is only tested in DumpRenderTree on Mac.

Added: trunk/LayoutTests/editing/input/composition-highlights-expected.html (0 => 255532)


--- trunk/LayoutTests/editing/input/composition-highlights-expected.html	                        (rev 0)
+++ trunk/LayoutTests/editing/input/composition-highlights-expected.html	2020-02-01 00:44:07 UTC (rev 255532)
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div[contenteditable] {
+    font-size: 20px;
+}
+#red { background-color: #FF000033; }
+#green { background-color: #00FF0033; }
+#blue { background-color: #0000FF33; }
+</style>
+</head>
+<body>
+This test verifies that highlights can be specified when setting marked text.
+<div contenteditable>Test:&nbsp;<span id="red">one</span><span id="green">two</span><span id="blue">three</span></div>
+</body>
+</html>

Added: trunk/LayoutTests/editing/input/composition-highlights.html (0 => 255532)


--- trunk/LayoutTests/editing/input/composition-highlights.html	                        (rev 0)
+++ trunk/LayoutTests/editing/input/composition-highlights.html	2020-02-01 00:44:07 UTC (rev 255532)
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div[contenteditable] {
+    font-size: 20px;
+    outline: none;
+    caret-color: transparent;
+}
+</style>
+</head>
+<body>
+This test verifies that highlights can be specified when setting marked text.
+<div contenteditable>Test:&nbsp;</div>
+
+<script>
+const editor = document.querySelector("div[contenteditable]");
+editor.focus();
+getSelection().setPosition(editor, 1);
+
+if (window.textInputController) {
+    textInputController.setMarkedText("onetwothree", 11, 11, true, [
+        { from: 0, length: 3, color: "#FF000033" },
+        { from: 3, length: 3, color: "#00FF0033" },
+        { from: 6, length: 5, color: "#0000FF33" }
+    ]);
+}
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/wk2/TestExpectations (255531 => 255532)


--- trunk/LayoutTests/platform/wk2/TestExpectations	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/LayoutTests/platform/wk2/TestExpectations	2020-02-01 00:44:07 UTC (rev 255532)
@@ -768,6 +768,9 @@
 # Target domain is only present in WebKit2.
 http/tests/inspector/target [ Pass ]
 
+# Highlighting marked text ranges from layout tests is only supported in WebKit2.
+editing/input/composition-highlights.html [ Pass ]
+
 ### END OF (5) Progressions, expected successes that are expected failures in WebKit1.
 ########################################
 

Modified: trunk/Source/WebCore/ChangeLog (255531 => 255532)


--- trunk/Source/WebCore/ChangeLog	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebCore/ChangeLog	2020-02-01 00:44:07 UTC (rev 255532)
@@ -1,3 +1,46 @@
+2020-01-31  Wenson Hsieh  <[email protected]>
+
+        Add support for specifying background colors when setting marked text
+        https://bugs.webkit.org/show_bug.cgi?id=207065
+        <rdar://problem/57876140>
+
+        Reviewed by Tim Horton.
+
+        Add support for rendering custom highlights (background colors) behind marked text in WebCore. To do this, we
+        plumb a Vector of CompositionHighlights alongside the Vector of CompositionUnderlines to Editor. At paint time,
+        we then consult this highlight data to determine which ranges of text in the composition should paint using
+        custom background colors.
+
+        Note that in the future, we should consider refactoring both composition underlines and highlights to use the
+        MarkedText mechanism for decorating ranges of text instead.
+
+        Test: editing/input/composition-highlights.html
+
+        * Headers.cmake:
+        * WebCore.xcodeproj/project.pbxproj:
+        * editing/CompositionHighlight.h: Added.
+        (WebCore::CompositionHighlight::CompositionHighlight):
+        (WebCore::CompositionHighlight::encode const):
+        (WebCore::CompositionHighlight::decode):
+
+        Add CompositionHighlight, which represents a range in the composition that should be highlighted with a given
+        background color.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::clear):
+        (WebCore::Editor::setComposition):
+
+        Add logic for clearing and updating m_customCompositionHighlights.
+
+        * editing/Editor.h:
+        (WebCore::Editor::compositionUsesCustomHighlights const):
+        (WebCore::Editor::customCompositionHighlights const):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paintCompositionBackground):
+
+        If custom composition highlights are given, use those when painting the composition background; otherwise,
+        default to painting the entire composition range using `Color::compositionFill`.
+
 2020-01-31  Justin Fan  <[email protected]>
 
         [WebGL] Revert logging added to investigate 205757

Modified: trunk/Source/WebCore/Headers.cmake (255531 => 255532)


--- trunk/Source/WebCore/Headers.cmake	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebCore/Headers.cmake	2020-02-01 00:44:07 UTC (rev 255532)
@@ -483,6 +483,7 @@
     dom/messageports/MessageWithMessagePorts.h
 
     editing/ClipboardAccessPolicy.h
+    editing/CompositionHighlight.h
     editing/CompositionUnderline.h
     editing/DictationAlternative.h
     editing/DictionaryPopupInfo.h

Modified: trunk/Source/WebCore/PAL/ChangeLog (255531 => 255532)


--- trunk/Source/WebCore/PAL/ChangeLog	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebCore/PAL/ChangeLog	2020-02-01 00:44:07 UTC (rev 255532)
@@ -1,3 +1,15 @@
+2020-01-31  Wenson Hsieh  <[email protected]>
+
+        Add support for specifying background colors when setting marked text
+        https://bugs.webkit.org/show_bug.cgi?id=207065
+        <rdar://problem/57876140>
+
+        Reviewed by Tim Horton.
+
+        Add an SPI soft-linking declaration for NSMarkedClauseSegmentAttributeName.
+
+        * pal/spi/cocoa/NSAttributedStringSPI.h:
+
 2020-01-30  Alex Christensen  <[email protected]>
 
         Add WKNavigationDelegate SPI to disable TLS 1.0 and 1.1

Modified: trunk/Source/WebCore/PAL/pal/spi/cocoa/NSAttributedStringSPI.h (255531 => 255532)


--- trunk/Source/WebCore/PAL/pal/spi/cocoa/NSAttributedStringSPI.h	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebCore/PAL/pal/spi/cocoa/NSAttributedStringSPI.h	2020-02-01 00:44:07 UTC (rev 255532)
@@ -93,6 +93,8 @@
 #define NSCocoaVersionDocumentAttribute getNSCocoaVersionDocumentAttribute()
 SOFT_LINK_CONSTANT(UIFoundation, NSBackgroundColorDocumentAttribute, NSString *)
 #define NSBackgroundColorDocumentAttribute getNSBackgroundColorDocumentAttribute()
+SOFT_LINK_CONSTANT(UIFoundation, NSMarkedClauseSegmentAttributeName, NSString *)
+#define NSMarkedClauseSegmentAttributeName getNSMarkedClauseSegmentAttributeName()
 
 // We don't softlink NSSuperscriptAttributeName because UIFoundation stopped exporting it.
 // This attribute is being deprecated at the API level, but internally UIFoundation

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (255531 => 255532)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-02-01 00:44:07 UTC (rev 255532)
@@ -4959,6 +4959,7 @@
 		F440E77A233D94D70063F9AB /* NavigatorClipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F440E76F233D94D30063F9AB /* NavigatorClipboard.h */; };
 		F440E77B233D94D70063F9AB /* ClipboardItem.h in Headers */ = {isa = PBXBuildFile; fileRef = F440E770233D94D40063F9AB /* ClipboardItem.h */; };
 		F440E77D233D94D70063F9AB /* Clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F440E772233D94D50063F9AB /* Clipboard.h */; };
+		F442C35923E3ADD200499582 /* CompositionHighlight.h in Headers */ = {isa = PBXBuildFile; fileRef = F442C35723E3AC5100499582 /* CompositionHighlight.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F44A5F591FED38F2007F5944 /* LegacyNSPasteboardTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F44A5F571FED3830007F5944 /* LegacyNSPasteboardTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F44EBBD91DB5D21400277334 /* StaticRange.h in Headers */ = {isa = PBXBuildFile; fileRef = F44EBBD81DB5D21400277334 /* StaticRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F45C231E1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h in Headers */ = {isa = PBXBuildFile; fileRef = F45C231C1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -15415,6 +15416,7 @@
 		F440E775233D94D60063F9AB /* ClipboardItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClipboardItem.cpp; sourceTree = "<group>"; };
 		F440E777233D94D70063F9AB /* ClipboardItem.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ClipboardItem.idl; sourceTree = "<group>"; };
 		F442850B2140412500CCDA22 /* FontAttributeChanges.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FontAttributeChanges.cpp; sourceTree = "<group>"; };
+		F442C35723E3AC5100499582 /* CompositionHighlight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CompositionHighlight.h; sourceTree = "<group>"; };
 		F44A5F571FED3830007F5944 /* LegacyNSPasteboardTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LegacyNSPasteboardTypes.h; sourceTree = "<group>"; };
 		F44EBBD61DB5D1B600277334 /* StaticRange.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = StaticRange.idl; sourceTree = "<group>"; };
 		F44EBBD81DB5D21400277334 /* StaticRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticRange.h; sourceTree = "<group>"; };
@@ -21517,6 +21519,7 @@
 				7C3A91E51C963B8800D1A7E3 /* ClipboardAccessPolicy.h */,
 				93309D8D099E64910056E581 /* CompositeEditCommand.cpp */,
 				93309D8E099E64910056E581 /* CompositeEditCommand.h */,
+				F442C35723E3AC5100499582 /* CompositionHighlight.h */,
 				2DD5A7261EBEE47D009BA597 /* CompositionUnderline.h */,
 				D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */,
 				D0B0556609C6700100307E43 /* CreateLinkCommand.h */,
@@ -29297,6 +29300,7 @@
 				71247E371FEA5F86008C08CE /* CompositeOperation.h in Headers */,
 				7111243E216FA71100EB7B67 /* CompositeOperationOrAuto.h in Headers */,
 				79F2F5A21091939A000D87CB /* CompositionEvent.h in Headers */,
+				F442C35923E3ADD200499582 /* CompositionHighlight.h in Headers */,
 				2DD5A7271EBEE47D009BA597 /* CompositionUnderline.h in Headers */,
 				7116E2CC1FED75DC00C06FDE /* ComputedEffectTiming.h in Headers */,
 				FD31608F12B026F700C1A359 /* Cone.h in Headers */,

Added: trunk/Source/WebCore/editing/CompositionHighlight.h (0 => 255532)


--- trunk/Source/WebCore/editing/CompositionHighlight.h	                        (rev 0)
+++ trunk/Source/WebCore/editing/CompositionHighlight.h	2020-02-01 00:44:07 UTC (rev 255532)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include "Color.h"
+#include <wtf/Optional.h>
+
+namespace WebCore {
+
+struct CompositionHighlight {
+    CompositionHighlight() = default;
+    CompositionHighlight(unsigned startOffset, unsigned endOffset, const Color& c)
+        : startOffset(startOffset)
+        , endOffset(endOffset)
+        , color(c)
+    {
+    }
+
+    unsigned startOffset { 0 };
+    unsigned endOffset { 0 };
+    Color color { Color::compositionFill };
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static Optional<CompositionHighlight> decode(Decoder&);
+};
+
+template<class Encoder>
+void CompositionHighlight::encode(Encoder& encoder) const
+{
+    encoder << startOffset;
+    encoder << endOffset;
+    encoder << color;
+}
+
+template<class Decoder>
+Optional<CompositionHighlight> CompositionHighlight::decode(Decoder& decoder)
+{
+    Optional<unsigned> startOffset;
+    decoder >> startOffset;
+    if (!startOffset)
+        return WTF::nullopt;
+
+    Optional<unsigned> endOffset;
+    decoder >> endOffset;
+    if (!endOffset)
+        return WTF::nullopt;
+
+    Optional<Color> color;
+    decoder >> color;
+    if (!color)
+        return WTF::nullopt;
+
+    return {{ *startOffset, *endOffset, *color }};
+}
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/editing/Editor.cpp (255531 => 255532)


--- trunk/Source/WebCore/editing/Editor.cpp	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebCore/editing/Editor.cpp	2020-02-01 00:44:07 UTC (rev 255532)
@@ -38,6 +38,7 @@
 #include "ChangeListTypeCommand.h"
 #include "ClipboardEvent.h"
 #include "CompositionEvent.h"
+#include "CompositionHighlight.h"
 #include "CreateLinkCommand.h"
 #include "CustomUndoStep.h"
 #include "DataTransfer.h"
@@ -1217,6 +1218,7 @@
             client->discardedComposition(&m_frame);
     }
     m_customCompositionUnderlines.clear();
+    m_customCompositionHighlights.clear();
     m_shouldStyleWithCSS = false;
     m_defaultParagraphSeparator = EditorParagraphSeparatorIsDiv;
     m_mark = { };
@@ -1970,6 +1972,7 @@
 
     m_compositionNode = nullptr;
     m_customCompositionUnderlines.clear();
+    m_customCompositionHighlights.clear();
 
     if (m_frame.selection().isNone())
         return;
@@ -1991,7 +1994,7 @@
     }
 }
 
-void Editor::setComposition(const String& text, const Vector<CompositionUnderline>& underlines, unsigned selectionStart, unsigned selectionEnd)
+void Editor::setComposition(const String& text, const Vector<CompositionUnderline>& underlines, const Vector<CompositionHighlight>& highlights, unsigned selectionStart, unsigned selectionEnd)
 {
     SetCompositionScope setCompositionScope(m_frame);
 
@@ -2063,6 +2066,7 @@
 
     m_compositionNode = nullptr;
     m_customCompositionUnderlines.clear();
+    m_customCompositionHighlights.clear();
 
     if (!text.isEmpty()) {
         TypingCommand::insertText(document(), text, TypingCommand::SelectInsertedText | TypingCommand::PreventSpellChecking, TypingCommand::TextCompositionPending);
@@ -2084,6 +2088,11 @@
                 underline.startOffset += baseOffset;
                 underline.endOffset += baseOffset;
             }
+            m_customCompositionHighlights = highlights;
+            for (auto& highlight : m_customCompositionHighlights) {
+                highlight.startOffset += baseOffset;
+                highlight.endOffset += baseOffset;
+            }
             if (baseNode->renderer())
                 baseNode->renderer()->repaint();
 

Modified: trunk/Source/WebCore/editing/Editor.h (255531 => 255532)


--- trunk/Source/WebCore/editing/Editor.h	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebCore/editing/Editor.h	2020-02-01 00:44:07 UTC (rev 255532)
@@ -83,6 +83,7 @@
 class TextCheckerClient;
 class TextEvent;
 
+struct CompositionHighlight;
 struct FontAttributes;
 struct PasteboardPlainText;
 struct PasteboardURL;
@@ -355,7 +356,7 @@
 
     // international text input composition
     bool hasComposition() const { return m_compositionNode; }
-    WEBCORE_EXPORT void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
+    WEBCORE_EXPORT void setComposition(const String&, const Vector<CompositionUnderline>&, const Vector<CompositionHighlight>&, unsigned selectionStart, unsigned selectionEnd);
     WEBCORE_EXPORT void confirmComposition();
     WEBCORE_EXPORT void confirmComposition(const String&); // if no existing composition, replaces selection
     WEBCORE_EXPORT void cancelComposition();
@@ -369,6 +370,8 @@
     unsigned compositionEnd() const { return m_compositionEnd; }
     bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
     const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
+    bool compositionUsesCustomHighlights() const { return !m_customCompositionHighlights.isEmpty(); }
+    const Vector<CompositionHighlight>& customCompositionHighlights() const { return m_customCompositionHighlights; }
 
     enum class RevealSelection { No, Yes };
     WEBCORE_EXPORT void setIgnoreSelectionChanges(bool, RevealSelection shouldRevealExistingSelection = RevealSelection::Yes);
@@ -601,6 +604,7 @@
     unsigned m_compositionStart;
     unsigned m_compositionEnd;
     Vector<CompositionUnderline> m_customCompositionUnderlines;
+    Vector<CompositionHighlight> m_customCompositionHighlights;
     bool m_ignoreSelectionChanges { false };
     bool m_shouldStartNewKillRingSequence { false };
     bool m_shouldStyleWithCSS { false };

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (255531 => 255532)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2020-02-01 00:44:07 UTC (rev 255532)
@@ -24,6 +24,7 @@
 #include "InlineTextBox.h"
 
 #include "BreakLines.h"
+#include "CompositionHighlight.h"
 #include "DashArray.h"
 #include "Document.h"
 #include "DocumentMarkerController.h"
@@ -1224,7 +1225,23 @@
 
 void InlineTextBox::paintCompositionBackground(PaintInfo& paintInfo, const FloatPoint& boxOrigin)
 {
-    paintMarkedTextBackground(paintInfo, boxOrigin, Color::compositionFill, clampedOffset(renderer().frame().editor().compositionStart()), clampedOffset(renderer().frame().editor().compositionEnd()));
+    if (!renderer().frame().editor().compositionUsesCustomHighlights()) {
+        paintMarkedTextBackground(paintInfo, boxOrigin, Color::compositionFill, clampedOffset(renderer().frame().editor().compositionStart()), clampedOffset(renderer().frame().editor().compositionEnd()));
+        return;
+    }
+
+    for (auto& highlight : renderer().frame().editor().customCompositionHighlights()) {
+        if (highlight.endOffset <= m_start)
+            continue;
+
+        if (highlight.startOffset >= end())
+            break;
+
+        paintMarkedTextBackground(paintInfo, boxOrigin, highlight.color, clampedOffset(highlight.startOffset), clampedOffset(highlight.endOffset));
+
+        if (highlight.endOffset > end())
+            break;
+    }
 }
 
 void InlineTextBox::paintCompositionUnderlines(PaintInfo& paintInfo, const FloatPoint& boxOrigin) const

Modified: trunk/Source/WebKit/ChangeLog (255531 => 255532)


--- trunk/Source/WebKit/ChangeLog	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/ChangeLog	2020-02-01 00:44:07 UTC (rev 255532)
@@ -1,3 +1,42 @@
+2020-01-31  Wenson Hsieh  <[email protected]>
+
+        Add support for specifying background colors when setting marked text
+        https://bugs.webkit.org/show_bug.cgi?id=207065
+        <rdar://problem/57876140>
+
+        Reviewed by Tim Horton.
+
+        Implement -setAttributedMarkedText:selectedRange: on WKContentView, and have it extract highlight color
+        information from the given attributed string. Plumb this through to the web process by serializing and
+        deserializing `WebCore::CompositionHighlight`s.
+
+        * UIProcess/Cocoa/WebViewImpl.mm:
+        (WebKit::WebViewImpl::setMarkedText):
+        * UIProcess/WebPageProxy.cpp:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (compositionHighlights):
+
+        For each marked text clause, grab the specified background color (defaulting to Color::compositionFill) and use
+        it to create a list of CompositionHighlights.
+
+        (-[WKContentView setAttributedMarkedText:selectedRange:]):
+        (-[WKContentView setMarkedText:selectedRange:]):
+        (-[WKContentView _setMarkedText:highlights:selectedRange:]):
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+        (WKBundlePageSetComposition):
+
+        Add testing support for specifying highlight ranges when setting marked text.
+
+        * WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h:
+        * WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp:
+        (WebKit::WebEditorClient::didDispatchInputMethodKeydown):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::setCompositionForTesting):
+        (WebKit::WebPage::setCompositionAsync):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2020-01-31  Andy Estes  <[email protected]>
 
         Unreviewed build fix after r255522.

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (255531 => 255532)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm	2020-02-01 00:44:07 UTC (rev 255532)
@@ -83,6 +83,7 @@
 #import <WebCore/AXObjectCache.h>
 #import <WebCore/ActivityState.h>
 #import <WebCore/ColorMac.h>
+#import <WebCore/CompositionHighlight.h>
 #import <WebCore/DictionaryLookup.h>
 #import <WebCore/DragData.h>
 #import <WebCore/DragItem.h>
@@ -5043,7 +5044,7 @@
         return;
     }
 
-    m_page->setCompositionAsync(text, underlines, selectedRange, replacementRange);
+    m_page->setCompositionAsync(text, underlines, { }, selectedRange, replacementRange);
 }
 
 // Synchronous NSTextInputClient is still implemented to catch spurious sync calls. Remove when that is no longer needed.

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (255531 => 255532)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-02-01 00:44:07 UTC (rev 255532)
@@ -139,6 +139,7 @@
 #include "WebsiteDataStore.h"
 #include <WebCore/AdClickAttribution.h>
 #include <WebCore/BitmapImage.h>
+#include <WebCore/CompositionHighlight.h>
 #include <WebCore/CrossSiteNavigationDataTransfer.h>
 #include <WebCore/DOMPasteAccess.h>
 #include <WebCore/DeprecatedGlobalSettings.h>
@@ -8499,7 +8500,7 @@
     send(Messages::WebPage::FirstRectForCharacterRangeAsync(range, callbackID));
 }
 
-void WebPageProxy::setCompositionAsync(const String& text, const Vector<CompositionUnderline>& underlines, const EditingRange& selectionRange, const EditingRange& replacementRange)
+void WebPageProxy::setCompositionAsync(const String& text, const Vector<CompositionUnderline>& underlines, const Vector<CompositionHighlight>& highlights, const EditingRange& selectionRange, const EditingRange& replacementRange)
 {
     if (!hasRunningProcess()) {
         // If this fails, we should call -discardMarkedText on input context to notify the input method.
@@ -8507,7 +8508,7 @@
         return;
     }
 
-    send(Messages::WebPage::SetCompositionAsync(text, underlines, selectionRange, replacementRange));
+    send(Messages::WebPage::SetCompositionAsync(text, underlines, highlights, selectionRange, replacementRange));
 }
 
 void WebPageProxy::confirmCompositionAsync()

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (255531 => 255532)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2020-02-01 00:44:07 UTC (rev 255532)
@@ -222,6 +222,7 @@
 
 struct ApplicationManifest;
 struct BackForwardItemIdentifier;
+struct CompositionHighlight;
 struct ContentRuleListResults;
 struct DataListSuggestionInformation;
 struct DictionaryPopupInfo;
@@ -841,7 +842,7 @@
     void getSelectedRangeAsync(WTF::Function<void (EditingRange, CallbackBase::Error)>&&);
     void characterIndexForPointAsync(const WebCore::IntPoint&, WTF::Function<void (uint64_t, CallbackBase::Error)>&&);
     void firstRectForCharacterRangeAsync(const EditingRange&, WTF::Function<void (const WebCore::IntRect&, const EditingRange&, CallbackBase::Error)>&&);
-    void setCompositionAsync(const String& text, const Vector<WebCore::CompositionUnderline>& underlines, const EditingRange& selectionRange, const EditingRange& replacementRange);
+    void setCompositionAsync(const String& text, const Vector<WebCore::CompositionUnderline>&, const Vector<WebCore::CompositionHighlight>&, const EditingRange& selectionRange, const EditingRange& replacementRange);
     void confirmCompositionAsync();
 
     void setScrollPerformanceDataCollectionEnabled(bool);

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (255531 => 255532)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2020-02-01 00:44:07 UTC (rev 255532)
@@ -90,6 +90,8 @@
 #import <CoreText/CTFontDescriptor.h>
 #import <MobileCoreServices/UTCoreTypes.h>
 #import <WebCore/Color.h>
+#import <WebCore/ColorIOS.h>
+#import <WebCore/CompositionHighlight.h>
 #import <WebCore/DOMPasteAccess.h>
 #import <WebCore/DataDetection.h>
 #import <WebCore/FloatQuad.h>
@@ -116,6 +118,7 @@
 #import <pal/spi/cg/CoreGraphicsSPI.h>
 #import <pal/spi/cocoa/DataDetectorsCoreSPI.h>
 #import <pal/spi/cocoa/LaunchServicesSPI.h>
+#import <pal/spi/cocoa/NSAttributedStringSPI.h>
 #import <pal/spi/ios/DataDetectorsUISPI.h>
 #import <pal/spi/ios/GraphicsServicesSPI.h>
 #import <pal/spi/ios/ManagedConfigurationSPI.h>
@@ -4519,13 +4522,41 @@
 {
 }
 
+static Vector<WebCore::CompositionHighlight> compositionHighlights(NSAttributedString *string)
+{
+    if (!string.length)
+        return { };
+
+    Vector<WebCore::CompositionHighlight> highlights;
+    [string enumerateAttributesInRange:NSMakeRange(0, string.length) options:0 usingBlock:[&highlights](NSDictionary<NSAttributedStringKey, id> *attributes, NSRange range, BOOL *) {
+        if (!attributes[NSMarkedClauseSegmentAttributeName])
+            return;
+
+        WebCore::Color highlightColor { WebCore::Color::compositionFill };
+        if (UIColor *uiColor = attributes[NSBackgroundColorAttributeName])
+            highlightColor = WebCore::colorFromUIColor(uiColor);
+        highlights.append({ static_cast<unsigned>(range.location), static_cast<unsigned>(NSMaxRange(range)), highlightColor });
+    }];
+    return highlights;
+}
+
+- (void)setAttributedMarkedText:(NSAttributedString *)markedText selectedRange:(NSRange)selectedRange
+{
+    [self _setMarkedText:markedText.string highlights:compositionHighlights(markedText) selectedRange:selectedRange];
+}
+
 - (void)setMarkedText:(NSString *)markedText selectedRange:(NSRange)selectedRange
 {
+    [self _setMarkedText:markedText highlights:Vector<WebCore::CompositionHighlight> { } selectedRange:selectedRange];
+}
+
+- (void)_setMarkedText:(NSString *)markedText highlights:(const Vector<WebCore::CompositionHighlight>&)highlights selectedRange:(NSRange)selectedRange
+{
 #if USE(UIKIT_KEYBOARD_ADDITIONS)
     _candidateViewNeedsUpdate = !self.hasMarkedText;
 #endif
     _markedText = markedText;
-    _page->setCompositionAsync(markedText, Vector<WebCore::CompositionUnderline>(), selectedRange, WebKit::EditingRange());
+    _page->setCompositionAsync(markedText, { }, highlights, selectedRange, { });
 }
 
 - (void)unmarkText

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp (255531 => 255532)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp	2020-02-01 00:44:07 UTC (rev 255532)
@@ -28,7 +28,9 @@
 #include "WKBundlePagePrivate.h"
 
 #include "APIArray.h"
+#include "APIDictionary.h"
 #include "APIFrameHandle.h"
+#include "APINumber.h"
 #include "APIString.h"
 #include "APIURL.h"
 #include "APIURLRequest.h"
@@ -58,6 +60,7 @@
 #include <WebCore/AXObjectCache.h>
 #include <WebCore/AccessibilityObjectInterface.h>
 #include <WebCore/ApplicationCacheStorage.h>
+#include <WebCore/CompositionHighlight.h>
 #include <WebCore/FocusController.h>
 #include <WebCore/Frame.h>
 #include <WebCore/Page.h>
@@ -610,9 +613,22 @@
     return WebKit::toAPI(&WebKit::toImpl(pageRef)->trackedRepaintRects().leakRef());
 }
 
-void WKBundlePageSetComposition(WKBundlePageRef pageRef, WKStringRef text, int from, int length, bool suppressUnderline)
+void WKBundlePageSetComposition(WKBundlePageRef pageRef, WKStringRef text, int from, int length, bool suppressUnderline, WKArrayRef highlightData)
 {
-    WebKit::toImpl(pageRef)->setCompositionForTesting(WebKit::toWTFString(text), from, length, suppressUnderline);
+    Vector<WebCore::CompositionHighlight> highlights;
+    if (highlightData) {
+        auto* highlightDataArray = WebKit::toImpl(highlightData);
+        highlights.reserveInitialCapacity(highlightDataArray->size());
+        for (auto dictionary : highlightDataArray->elementsOfType<API::Dictionary>()) {
+            auto startOffset = static_cast<API::UInt64*>(dictionary->get("from"))->value();
+            highlights.uncheckedAppend({
+                static_cast<unsigned>(startOffset),
+                static_cast<unsigned>(startOffset + static_cast<API::UInt64*>(dictionary->get("length"))->value()),
+                WebCore::Color(static_cast<API::String*>(dictionary->get("color"))->string())
+            });
+        }
+    }
+    WebKit::toImpl(pageRef)->setCompositionForTesting(WebKit::toWTFString(text), from, length, suppressUnderline, highlights);
 }
 
 bool WKBundlePageHasComposition(WKBundlePageRef pageRef)

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h (255531 => 255532)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h	2020-02-01 00:44:07 UTC (rev 255532)
@@ -84,7 +84,7 @@
 WK_EXPORT void WKBundlePageResetTrackedRepaints(WKBundlePageRef page);
 WK_EXPORT WKArrayRef WKBundlePageCopyTrackedRepaintRects(WKBundlePageRef page);
 
-WK_EXPORT void WKBundlePageSetComposition(WKBundlePageRef page, WKStringRef text, int from, int length, bool suppressUnderline);
+WK_EXPORT void WKBundlePageSetComposition(WKBundlePageRef page, WKStringRef text, int from, int length, bool suppressUnderline, WKArrayRef highlightData);
 WK_EXPORT bool WKBundlePageHasComposition(WKBundlePageRef page);
 WK_EXPORT void WKBundlePageConfirmComposition(WKBundlePageRef page);
 WK_EXPORT void WKBundlePageConfirmCompositionWithText(WKBundlePageRef page, WKStringRef text);

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp (255531 => 255532)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp	2020-02-01 00:44:07 UTC (rev 255532)
@@ -20,6 +20,7 @@
 #include "config.h"
 #include "WebEditorClient.h"
 
+#include <WebCore/CompositionHighlight.h>
 #include <WebCore/Document.h>
 #include <WebCore/Editor.h>
 #include <WebCore/Frame.h>
@@ -47,7 +48,7 @@
     if (const auto& underlines = platformEvent->preeditUnderlines()) {
         auto rangeStart = platformEvent->preeditSelectionRangeStart().valueOr(0);
         auto rangeLength = platformEvent->preeditSelectionRangeLength().valueOr(0);
-        frame->editor().setComposition(platformEvent->text(), underlines.value(), rangeStart, rangeStart + rangeLength);
+        frame->editor().setComposition(platformEvent->text(), underlines.value(), { }, rangeStart, rangeStart + rangeLength);
     } else
         frame->editor().confirmComposition(platformEvent->text());
 }

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (255531 => 255532)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-02-01 00:44:07 UTC (rev 255532)
@@ -5100,7 +5100,7 @@
     mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, 0, position, position, 0, 0, 0, 0, OptionSet<WebEvent::Modifier> { }, time, 0, WebMouseEvent::NoTap));
 }
 
-void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length, bool suppressUnderline)
+void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length, bool suppressUnderline, const Vector<CompositionHighlight>& highlights)
 {
     Frame& frame = m_page->focusController().focusedOrMainFrame();
     if (!frame.editor().canEdit())
@@ -5110,7 +5110,7 @@
     if (!suppressUnderline)
         underlines.append(CompositionUnderline(0, compositionString.length(), CompositionUnderlineColor::TextColor, Color(Color::black), false));
 
-    frame.editor().setComposition(compositionString, underlines, from, from + length);
+    frame.editor().setComposition(compositionString, underlines, highlights, from, from + length);
 }
 
 bool WebPage::hasCompositionForTesting()
@@ -5349,7 +5349,7 @@
     send(Messages::WebPageProxy::RectForCharacterRangeCallback(result, editingRange, callbackID));
 }
 
-void WebPage::setCompositionAsync(const String& text, const Vector<CompositionUnderline>& underlines, const EditingRange& selection, const EditingRange& replacementEditingRange)
+void WebPage::setCompositionAsync(const String& text, const Vector<CompositionUnderline>& underlines, const Vector<CompositionHighlight>& highlights, const EditingRange& selection, const EditingRange& replacementEditingRange)
 {
     platformWillPerformEditingCommand();
 
@@ -5363,7 +5363,7 @@
                 frame.selection().setSelection(VisibleSelection(*replacementRange, SEL_DEFAULT_AFFINITY));
         }
 
-        frame.editor().setComposition(text, underlines, selection.location, selection.location + selection.length);
+        frame.editor().setComposition(text, underlines, highlights, selection.location, selection.location + selection.length);
     }
 }
 

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (255531 => 255532)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2020-02-01 00:44:07 UTC (rev 255532)
@@ -196,6 +196,7 @@
 enum class WritingDirection : uint8_t;
 
 struct BackForwardItemIdentifier;
+struct CompositionHighlight;
 struct CompositionUnderline;
 struct DictationAlternative;
 struct ElementContext;
@@ -824,7 +825,7 @@
     void getSelectedRangeAsync(CallbackID);
     void characterIndexForPointAsync(const WebCore::IntPoint&, CallbackID);
     void firstRectForCharacterRangeAsync(const EditingRange&, CallbackID);
-    void setCompositionAsync(const String& text, const Vector<WebCore::CompositionUnderline>& underlines, const EditingRange& selectionRange, const EditingRange& replacementRange);
+    void setCompositionAsync(const String& text, const Vector<WebCore::CompositionUnderline>&, const Vector<WebCore::CompositionHighlight>&, const EditingRange& selectionRange, const EditingRange& replacementRange);
     void confirmCompositionAsync();
 
     void readSelectionFromPasteboard(const String& pasteboardName, CompletionHandler<void(bool&&)>&&);
@@ -845,7 +846,7 @@
     void replaceSelectionWithPasteboardData(const Vector<String>& types, const IPC::DataReference&);
 #endif
 
-    void setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length, bool suppressUnderline);
+    void setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length, bool suppressUnderline, const Vector<WebCore::CompositionHighlight>&);
     bool hasCompositionForTesting();
     void confirmCompositionForTesting(const String& compositionString);
 

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (255531 => 255532)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2020-02-01 00:44:07 UTC (rev 255532)
@@ -453,7 +453,7 @@
     GetSelectedRangeAsync(WebKit::CallbackID callbackID)
     CharacterIndexForPointAsync(WebCore::IntPoint point, WebKit::CallbackID callbackID);
     FirstRectForCharacterRangeAsync(struct WebKit::EditingRange range, WebKit::CallbackID callbackID);
-    SetCompositionAsync(String text, Vector<WebCore::CompositionUnderline> underlines, struct WebKit::EditingRange selectionRange, struct WebKit::EditingRange replacementRange)
+    SetCompositionAsync(String text, Vector<WebCore::CompositionUnderline> underlines, Vector<WebCore::CompositionHighlight> highlights, struct WebKit::EditingRange selectionRange, struct WebKit::EditingRange replacementRange)
     ConfirmCompositionAsync()
 #endif
 #if PLATFORM(MAC)

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (255531 => 255532)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2020-02-01 00:44:07 UTC (rev 255532)
@@ -1,3 +1,19 @@
+2020-01-31  Wenson Hsieh  <[email protected]>
+
+        Add support for specifying background colors when setting marked text
+        https://bugs.webkit.org/show_bug.cgi?id=207065
+        <rdar://problem/57876140>
+
+        Reviewed by Tim Horton.
+
+        Adjust some call sites of Editor::setComposition().
+
+        * WebView/WebFrame.mm:
+        (-[WebFrame setMarkedText:selectedRange:]):
+        (-[WebFrame setMarkedText:forCandidates:]):
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView setMarkedText:selectedRange:]):
+
 2020-01-31  Antoine Quint  <[email protected]>
 
         [WK1] hiddenPageCSSAnimationSuspensionEnabled should be enabled by default for Cocoa platforms

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm (255531 => 255532)


--- trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm	2020-02-01 00:44:07 UTC (rev 255532)
@@ -66,6 +66,7 @@
 #import <WebCore/CachedResourceLoader.h>
 #import <WebCore/Chrome.h>
 #import <WebCore/ColorMac.h>
+#import <WebCore/CompositionHighlight.h>
 #import <WebCore/DatabaseManager.h>
 #import <WebCore/DocumentFragment.h>
 #import <WebCore/DocumentLoader.h>
@@ -1649,7 +1650,7 @@
     
     Vector<WebCore::CompositionUnderline> underlines;
     frame->page()->chrome().client().suppressFormNotifications();
-    frame->editor().setComposition(text, underlines, newSelRange.location, NSMaxRange(newSelRange));
+    frame->editor().setComposition(text, underlines, { }, newSelRange.location, NSMaxRange(newSelRange));
     frame->page()->chrome().client().restoreFormNotifications();
 }
 
@@ -1660,7 +1661,7 @@
         return;
         
     Vector<WebCore::CompositionUnderline> underlines;
-    frame->editor().setComposition(text, underlines, 0, [text length]);
+    frame->editor().setComposition(text, underlines, { }, 0, [text length]);
 }
 
 - (void)confirmMarkedText:(NSString *)text

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm (255531 => 255532)


--- trunk/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm	2020-02-01 00:44:07 UTC (rev 255532)
@@ -80,6 +80,7 @@
 #import <WebCore/CachedResourceLoader.h>
 #import <WebCore/Chrome.h>
 #import <WebCore/ColorMac.h>
+#import <WebCore/CompositionHighlight.h>
 #import <WebCore/ContextMenu.h>
 #import <WebCore/ContextMenuController.h>
 #import <WebCore/DictionaryLookup.h>
@@ -6570,7 +6571,7 @@
     if (replacementRange.location != NSNotFound)
         [[self _frame] _selectNSRange:replacementRange];
 
-    coreFrame->editor().setComposition(text, underlines, newSelRange.location, NSMaxRange(newSelRange));
+    coreFrame->editor().setComposition(text, underlines, { }, newSelRange.location, NSMaxRange(newSelRange));
 }
 
 ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN

Modified: trunk/Source/WebKitLegacy/win/ChangeLog (255531 => 255532)


--- trunk/Source/WebKitLegacy/win/ChangeLog	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKitLegacy/win/ChangeLog	2020-02-01 00:44:07 UTC (rev 255532)
@@ -1,3 +1,17 @@
+2020-01-31  Wenson Hsieh  <[email protected]>
+
+        Add support for specifying background colors when setting marked text
+        https://bugs.webkit.org/show_bug.cgi?id=207065
+        <rdar://problem/57876140>
+
+        Reviewed by Tim Horton.
+
+        Adjust some call sites of Editor::setComposition().
+
+        * WebView.cpp:
+        (WebView::onIMEComposition):
+        (WebView::setCompositionForTesting):
+
 2020-01-27  Antoine Quint  <[email protected]>
 
         [Web Animations] Make Animation.timeline read-write only if a runtime flag is enabled

Modified: trunk/Source/WebKitLegacy/win/WebView.cpp (255531 => 255532)


--- trunk/Source/WebKitLegacy/win/WebView.cpp	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Source/WebKitLegacy/win/WebView.cpp	2020-02-01 00:44:07 UTC (rev 255532)
@@ -85,6 +85,7 @@
 #include <WebCore/BitmapInfo.h>
 #include <WebCore/CacheStorageProvider.h>
 #include <WebCore/Chrome.h>
+#include <WebCore/CompositionHighlight.h>
 #include <WebCore/ContextMenu.h>
 #include <WebCore/ContextMenuController.h>
 #include <WebCore/CookieJar.h>
@@ -6399,7 +6400,7 @@
 
         int cursorPosition = LOWORD(IMMDict::dict().getCompositionString(hInputContext, GCS_CURSORPOS, 0, 0));
 
-        targetFrame.editor().setComposition(compositionString, underlines, cursorPosition, 0);
+        targetFrame.editor().setComposition(compositionString, underlines, { }, cursorPosition, 0);
     }
 
     return true;
@@ -7692,7 +7693,7 @@
 
     Vector<CompositionUnderline> underlines;
     underlines.append(CompositionUnderline(0, compositionStr.length(), CompositionUnderlineColor::TextColor, Color(Color::black), false));
-    frame.editor().setComposition(compositionStr, underlines, from, from + length);
+    frame.editor().setComposition(compositionStr, underlines, { }, from, from + length);
 
     return S_OK;
 }

Modified: trunk/Tools/ChangeLog (255531 => 255532)


--- trunk/Tools/ChangeLog	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Tools/ChangeLog	2020-02-01 00:44:07 UTC (rev 255532)
@@ -1,3 +1,36 @@
+2020-01-31  Wenson Hsieh  <[email protected]>
+
+        Add support for specifying background colors when setting marked text
+        https://bugs.webkit.org/show_bug.cgi?id=207065
+        <rdar://problem/57876140>
+
+        Reviewed by Tim Horton.
+
+        Add support in WebKitTestRunner for specifying a list of highlight ranges when setting marked text. This comes
+        in the form of an additional argument to TextInputController::setMarkedText, which contains an array of objects,
+        each describing one range (in the composition) to highlight.
+
+        * DumpRenderTree/ios/TextInputControllerIOS.m:
+        (+[TextInputController isSelectorExcludedFromWebScript:]):
+        (+[TextInputController webScriptNameForSelector:]):
+        (-[TextInputController setMarkedText:selectedFrom:length:suppressUnderline:highlights:]):
+        (-[TextInputController setMarkedText:selectedFrom:length:suppressUnderline:]): Deleted.
+        * DumpRenderTree/mac/TextInputControllerMac.m:
+        (+[TextInputController isSelectorExcludedFromWebScript:]):
+        (+[TextInputController webScriptNameForSelector:]):
+        (-[TextInputController setMarkedText:selectedFrom:length:suppressUnderline:highlights:]):
+        (-[TextInputController setMarkedText:selectedFrom:length:suppressUnderline:]): Deleted.
+        * WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl:
+        * WebKitTestRunner/InjectedBundle/TextInputController.cpp:
+        (WTR::arrayLength):
+        (WTR::createCompositionHighlightData):
+
+        Add logic to convert a given JSObject containing the composition highlight information into a WKArrayRef, which
+        is then passed into WebKit via WKBundlePageSetComposition.
+
+        (WTR::TextInputController::setMarkedText):
+        * WebKitTestRunner/InjectedBundle/TextInputController.h:
+
 2020-01-31  Alex Christensen  <[email protected]>
 
         Add KVO SPI WKWebView._negotiatedLegacyTLS

Modified: trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m (255531 => 255532)


--- trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m	2020-02-01 00:44:07 UTC (rev 255532)
@@ -39,7 +39,7 @@
 + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
 {
     if (aSelector == @selector(insertText:)
-        || aSelector == @selector(setMarkedText:selectedFrom:length:suppressUnderline:)
+        || aSelector == @selector(setMarkedText:selectedFrom:length:suppressUnderline:highlights:)
         || aSelector == @selector(markedRange))
         return NO;
 
@@ -50,7 +50,7 @@
 {
     if (aSelector == @selector(insertText:))
         return @"insertText";
-    if (aSelector == @selector(setMarkedText:selectedFrom:length:suppressUnderline:))
+    if (aSelector == @selector(setMarkedText:selectedFrom:length:suppressUnderline:highlights:))
         return @"setMarkedText";
     if (aSelector == @selector(markedRange))
         return @"markedRange";
@@ -83,7 +83,7 @@
     [[webView mainFrame] confirmMarkedText:text];
 }
 
-- (void)setMarkedText:(NSString *)text selectedFrom:(NSInteger)selectionStart length:(NSInteger)selectionLength suppressUnderline:(BOOL)suppressUnderline
+- (void)setMarkedText:(NSString *)text selectedFrom:(NSInteger)selectionStart length:(NSInteger)selectionLength suppressUnderline:(BOOL)suppressUnderline highlights:(NSArray<NSDictionary *> *)highlights
 {
     if (selectionStart == -1)
         selectionStart = NSNotFound;

Modified: trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m (255531 => 255532)


--- trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m	2020-02-01 00:44:07 UTC (rev 255532)
@@ -224,7 +224,7 @@
 {
     if (aSelector == @selector(insertText:)
         || aSelector == @selector(doCommand:)
-        || aSelector == @selector(setMarkedText:selectedFrom:length:suppressUnderline:)
+        || aSelector == @selector(setMarkedText:selectedFrom:length:suppressUnderline:highlights:)
         || aSelector == @selector(unmarkText)
         || aSelector == @selector(hasMarkedText)
         || aSelector == @selector(conversationIdentifier)
@@ -251,7 +251,7 @@
         return @"insertText";
     if (aSelector == @selector(doCommand:))
         return @"doCommand";
-    if (aSelector == @selector(setMarkedText:selectedFrom:length:suppressUnderline:))
+    if (aSelector == @selector(setMarkedText:selectedFrom:length:suppressUnderline:highlights:))
         return @"setMarkedText";
     if (aSelector == @selector(substringFrom:length:))
         return @"substringFromRange";
@@ -314,7 +314,7 @@
         [textInput doCommandBySelector:NSSelectorFromString(aCommand)];
 }
 
-- (void)setMarkedText:(NSString *)aString selectedFrom:(int)from length:(int)length suppressUnderline:(BOOL)suppressUnderline
+- (void)setMarkedText:(NSString *)aString selectedFrom:(int)from length:(int)length suppressUnderline:(BOOL)suppressUnderline highlights:(NSArray<NSDictionary *> *)highlights
 {
     NSObject <NSTextInput> *textInput = [self textInput];
 

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl (255531 => 255532)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl	2020-02-01 00:44:07 UTC (rev 255532)
@@ -24,7 +24,7 @@
  */
 
 interface TextInputController {
-    void setMarkedText(DOMString string, long from, long length, boolean suppressUnderline);
+    void setMarkedText(DOMString string, long from, long length, boolean suppressUnderline, object highlights);
     boolean hasMarkedText();
     void unmarkText();
     void insertText(DOMString string);

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp (255531 => 255532)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp	2020-02-01 00:44:07 UTC (rev 255532)
@@ -30,6 +30,7 @@
 #include "InjectedBundlePage.h"
 #include "JSTextInputController.h"
 #include "StringFunctions.h"
+#include <WebKit/WKBundleFrame.h>
 #include <WebKit/WKBundlePagePrivate.h>
 
 namespace WTR {
@@ -57,11 +58,74 @@
     setProperty(context, windowObject, "textInputController", this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
 }
 
-void TextInputController::setMarkedText(JSStringRef text, int from, int length, bool suppressUnderline)
+static unsigned arrayLength(JSContextRef context, JSObjectRef array)
 {
-    WKBundlePageSetComposition(InjectedBundle::singleton().page()->page(), toWK(text).get(), from, length, suppressUnderline);
+    auto lengthString = adopt(JSStringCreateWithUTF8CString("length"));
+    if (auto lengthValue = JSObjectGetProperty(context, array, lengthString.get(), nullptr))
+        return static_cast<unsigned>(JSValueToNumber(context, lengthValue, nullptr));
+    return 0;
 }
 
+static WKArrayRef createCompositionHighlightData(JSContextRef context, JSValueRef jsHighlightsValue)
+{
+    if (!jsHighlightsValue || !JSValueIsArray(context, jsHighlightsValue))
+        return nullptr;
+
+    auto result = WKMutableArrayCreate();
+    auto jsHighlightsArray = const_cast<JSObjectRef>(jsHighlightsValue);
+    unsigned length = arrayLength(context, jsHighlightsArray);
+    if (!length)
+        return result;
+
+    auto jsFromKey = adopt(JSStringCreateWithUTF8CString("from"));
+    auto jsLengthKey = adopt(JSStringCreateWithUTF8CString("length"));
+    auto jsColorKey = adopt(JSStringCreateWithUTF8CString("color"));
+
+    auto wkFromKey = adoptWK(WKStringCreateWithUTF8CString("from"));
+    auto wkLengthKey = adoptWK(WKStringCreateWithUTF8CString("length"));
+    auto wkColorKey = adoptWK(WKStringCreateWithUTF8CString("color"));
+
+    for (size_t i = 0; i < length; ++i) {
+        JSValueRef exception = nullptr;
+        auto jsObjectValue = JSObjectGetPropertyAtIndex(context, jsHighlightsArray, i, &exception);
+        if (exception || !JSValueIsObject(context, jsObjectValue))
+            continue;
+
+        auto jsObject = const_cast<JSObjectRef>(jsObjectValue);
+        auto jsFromValue = JSObjectGetProperty(context, jsObject, jsFromKey.get(), nullptr);
+        if (!jsFromValue || !JSValueIsNumber(context, jsFromValue))
+            continue;
+
+        auto jsLengthValue = JSObjectGetProperty(context, jsObject, jsLengthKey.get(), nullptr);
+        if (!jsLengthValue || !JSValueIsNumber(context, jsLengthValue))
+            continue;
+
+        auto jsColorValue = JSObjectGetProperty(context, jsObject, jsColorKey.get(), nullptr);
+        if (!jsColorValue || !JSValueIsString(context, jsColorValue))
+            continue;
+
+        auto color = adopt(JSValueToStringCopy(context, jsColorValue, nullptr));
+        auto wkColor = adoptWK(WKStringCreateWithJSString(color.get()));
+        auto wkFrom = adoptWK(WKUInt64Create(lround(JSValueToNumber(context, jsFromValue, nullptr))));
+        auto wkLength = adoptWK(WKUInt64Create(lround(JSValueToNumber(context, jsLengthValue, nullptr))));
+
+        auto dictionary = adoptWK(WKMutableDictionaryCreate());
+        WKDictionarySetItem(dictionary.get(), wkFromKey.get(), wkFrom.get());
+        WKDictionarySetItem(dictionary.get(), wkLengthKey.get(), wkLength.get());
+        WKDictionarySetItem(dictionary.get(), wkColorKey.get(), wkColor.get());
+        WKArrayAppendItem(result, dictionary.get());
+    }
+
+    return result;
+}
+
+void TextInputController::setMarkedText(JSStringRef text, int from, int length, bool suppressUnderline, JSValueRef jsHighlightsValue)
+{
+    auto page = InjectedBundle::singleton().page()->page();
+    auto highlights = adoptWK(createCompositionHighlightData(WKBundleFrameGetJavaScriptContext(WKBundlePageGetMainFrame(page)), jsHighlightsValue));
+    WKBundlePageSetComposition(page, toWK(text).get(), from, length, suppressUnderline, highlights.get());
+}
+
 bool TextInputController::hasMarkedText()
 {
     return WKBundlePageHasComposition(InjectedBundle::singleton().page()->page());

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TextInputController.h (255531 => 255532)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TextInputController.h	2020-02-01 00:23:20 UTC (rev 255531)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TextInputController.h	2020-02-01 00:44:07 UTC (rev 255532)
@@ -40,7 +40,7 @@
 
     void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
 
-    void setMarkedText(JSStringRef text, int from, int length, bool suppressUnderline);
+    void setMarkedText(JSStringRef text, int from, int length, bool suppressUnderline, JSValueRef highlights);
     bool hasMarkedText();
     void unmarkText();
     void insertText(JSStringRef text);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to