Title: [236724] trunk
Revision
236724
Author
wenson_hs...@apple.com
Date
2018-10-02 03:39:40 -0700 (Tue, 02 Oct 2018)

Log Message

[macOS] Implement a way for the UI process to request typing attributes at the current selection
https://bugs.webkit.org/show_bug.cgi?id=189983
<rdar://problem/44648705>

Reviewed by Ryosuke Niwa.

Source/WebKit:

Implements `-[WKWebView typingAttributesWithCompletionHandler:]`, which asynchronously retrieves an NSDictionary
containing the typing attributes at the start of the current selection. This is a new asynchronous text input
client hook on macOS that is needed in order to support NSInspectorBar on WKWebView.

At a high level, this patch builds on top of refactoring done in r236445 to make it possible to send typing
attributes from the web process to the UI process, and then adds plumbing in the WebKit2 client layer to surface
typing attributes to WKWebView on macOS.

Tests:  FontManagerTests.TypingAttributesAfterSubscriptAndSuperscript
        FontManagerTests.ChangeTypingAttributesWithInspectorBar
        FontManagerTests.ChangeAttributesWithFontEffectsBox

* Platform/spi/mac/AppKitSPI.h:
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<FontAttributes>::encode):
(IPC::ArgumentCoder<FontAttributes>::decode):

Implement IPC coding support for FontAttributes.

* Shared/WebCoreArgumentCoders.h:
* Shared/mac/ArgumentCodersMac.h:
* Shared/mac/ArgumentCodersMac.mm:
(IPC::encode):
(IPC::decode):

Add the ability to encode and decode UIFont. This allows Cocoa platforms to send `FontAttributes.font` over IPC
with a single call to IPC::encode/IPC::decode.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView typingAttributesWithCompletionHandler:]):

Add plumbing to WebViewImpl.

* UIProcess/Cocoa/WebViewImpl.h:
* UIProcess/Cocoa/WebViewImpl.mm:
(WebKit::WebViewImpl::selectionDidChange):

Update the NSInspectorBar on selection change, but only if it is present and visible, and WKWebView is currently
first responder.

(WebKit::WebViewImpl::typingAttributesWithCompletionHandler):

Call into WebPageProxy to retrieve FontAttributes from the web process, and invoke the callback with an
NSDictionary constructed from the retrieved FontAttributes.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestFontAttributesAtSelectionStart):
(WebKit::WebPageProxy::fontAttributesCallback):

Add plumbing to retrieve FontAttributes from the web process at the current selection. Additionally, cache the
font attributes to avoid doing extra work during subsequent requests.

(WebKit::WebPageProxy::resetStateAfterProcessExited):
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::cachedFontAttributesAtSelectionStart const):
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::editorStateChanged):
* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::editorStateChanged):

Invalidate cached font attributes.

* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::requestFontAttributesAtSelectionStart):

Use the currently focused frame's Editor to compute FontAttributes at the current selection, and send the
computed FontAttributes back to the UI process.

* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

Adds new FontManagerTests that exercise -typingAttributesWithCompletionHandler:. See below for more detail.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h:
* TestWebKitAPI/Tests/mac/FontManagerTests.mm:

Add a new test that exercises font attribute modification via inspector bar. Also, add a new test that checks
typing attributes when using subscript/superscript/unscript. Lastly, augment an existing NSFontPanel test to
additionally check that shadowed text and strike-through are reflected in typing attributes.

(-[FontManagerTestWKWebView inspectorBarItemIdentifiers]):
(-[TestWKWebView typingAttributes]):

Add a synchronous wrapper around `-typingAttributesWithCompletionHandler:` by spinning the runloop.

(-[TestWKWebView collapseToStart]):
(webViewForFontManagerTesting):
(TestWebKitAPI::TEST):
* TestWebKitAPI/cocoa/TestWKWebView.h:
* TestWebKitAPI/mac/TestInspectorBar.h: Copied from Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h.
* TestWebKitAPI/mac/TestInspectorBar.mm: Added.

Introduce subclasses of `__InspectorBarItemController` and `NSInspectorBar` for testing inspector bar interaction.

(-[TestInspectorBarItemController initWithInspectorBar:]):
(-[TestInspectorBarItemController inspectorBar]):
(-[TestInspectorBarItemController updateSelectedAttributes]):
(-[TestInspectorBar initWithWebView:]):
(+[TestInspectorBar standardItemControllerClass]):
(+[TestInspectorBar standardTextItemIdentifiers]):
(-[TestInspectorBar _setStyleControlSelected:atIndex:]):
(-[TestInspectorBar chooseFontSize:]):
(-[TestInspectorBar chooseFontFamily:]):
(-[TestInspectorBar _chooseColor:inColorWell:]):
(-[TestInspectorBar chooseForegroundColor:]):
(-[TestInspectorBar chooseBackgroundColor:]):
(-[TestInspectorBar formatBold:]):
(-[TestInspectorBar formatItalic:]):
(-[TestInspectorBar formatUnderline:]):

Add helper methods to TestInspectorBar to simulate interacting with various controls (e.g. color wells and font
styling controls).

(-[TestInspectorBar itemController]):
(-[TestInspectorBar setItemController:]):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (236723 => 236724)


--- trunk/Source/WebKit/ChangeLog	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/ChangeLog	2018-10-02 10:39:40 UTC (rev 236724)
@@ -1,3 +1,84 @@
+2018-10-02  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [macOS] Implement a way for the UI process to request typing attributes at the current selection
+        https://bugs.webkit.org/show_bug.cgi?id=189983
+        <rdar://problem/44648705>
+
+        Reviewed by Ryosuke Niwa.
+
+        Implements `-[WKWebView typingAttributesWithCompletionHandler:]`, which asynchronously retrieves an NSDictionary
+        containing the typing attributes at the start of the current selection. This is a new asynchronous text input
+        client hook on macOS that is needed in order to support NSInspectorBar on WKWebView.
+
+        At a high level, this patch builds on top of refactoring done in r236445 to make it possible to send typing
+        attributes from the web process to the UI process, and then adds plumbing in the WebKit2 client layer to surface
+        typing attributes to WKWebView on macOS.
+
+        Tests:  FontManagerTests.TypingAttributesAfterSubscriptAndSuperscript
+                FontManagerTests.ChangeTypingAttributesWithInspectorBar
+                FontManagerTests.ChangeAttributesWithFontEffectsBox
+
+        * Platform/spi/mac/AppKitSPI.h:
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<FontAttributes>::encode):
+        (IPC::ArgumentCoder<FontAttributes>::decode):
+
+        Implement IPC coding support for FontAttributes.
+
+        * Shared/WebCoreArgumentCoders.h:
+        * Shared/mac/ArgumentCodersMac.h:
+        * Shared/mac/ArgumentCodersMac.mm:
+        (IPC::encode):
+        (IPC::decode):
+
+        Add the ability to encode and decode UIFont. This allows Cocoa platforms to send `FontAttributes.font` over IPC
+        with a single call to IPC::encode/IPC::decode.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView typingAttributesWithCompletionHandler:]):
+
+        Add plumbing to WebViewImpl.
+
+        * UIProcess/Cocoa/WebViewImpl.h:
+        * UIProcess/Cocoa/WebViewImpl.mm:
+        (WebKit::WebViewImpl::selectionDidChange):
+
+        Update the NSInspectorBar on selection change, but only if it is present and visible, and WKWebView is currently
+        first responder.
+
+        (WebKit::WebViewImpl::typingAttributesWithCompletionHandler):
+
+        Call into WebPageProxy to retrieve FontAttributes from the web process, and invoke the callback with an
+        NSDictionary constructed from the retrieved FontAttributes.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestFontAttributesAtSelectionStart):
+        (WebKit::WebPageProxy::fontAttributesCallback):
+
+        Add plumbing to retrieve FontAttributes from the web process at the current selection. Additionally, cache the
+        font attributes to avoid doing extra work during subsequent requests.
+
+        (WebKit::WebPageProxy::resetStateAfterProcessExited):
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::cachedFontAttributesAtSelectionStart const):
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::editorStateChanged):
+        * UIProcess/mac/WebPageProxyMac.mm:
+        (WebKit::WebPageProxy::editorStateChanged):
+
+        Invalidate cached font attributes.
+
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::requestFontAttributesAtSelectionStart):
+
+        Use the currently focused frame's Editor to compute FontAttributes at the current selection, and send the
+        computed FontAttributes back to the UI process.
+
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2018-10-01  Devin Rousso  <drou...@apple.com>
 
         Web Inspector: remove analyzer manager

Copied: trunk/Source/WebKit/Platform/spi/mac/AppKitSPI.h (from rev 236723, trunk/Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h) (0 => 236724)


--- trunk/Source/WebKit/Platform/spi/mac/AppKitSPI.h	                        (rev 0)
+++ trunk/Source/WebKit/Platform/spi/mac/AppKitSPI.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 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. AND ITS CONTRIBUTORS ``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 ITS 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
+
+#import <AppKit/AppKit.h>
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#import <AppKit/NSInspectorBar.h>
+#import <AppKit/NSTextInputClient_Private.h>
+#import <AppKit/NSWindow_Private.h>
+
+#else
+
+@interface NSInspectorBar : NSObject
+@property (getter=isVisible) BOOL visible;
+@end
+
+@protocol NSTextInputClient_Async
+@end
+
+@interface NSWindow (NSInspectorBarSupport)
+- (NSInspectorBar *)inspectorBar;
+- (void)setInspectorBar:(NSInspectorBar *)bar;
+@end
+
+#endif
+
+@interface NSInspectorBar (IPI)
+- (void)_update;
+@end

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (236723 => 236724)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2018-10-02 10:39:40 UTC (rev 236724)
@@ -45,6 +45,7 @@
 #include <WebCore/FileChooser.h>
 #include <WebCore/FilterOperation.h>
 #include <WebCore/FilterOperations.h>
+#include <WebCore/FontAttributes.h>
 #include <WebCore/GraphicsContext.h>
 #include <WebCore/GraphicsLayer.h>
 #include <WebCore/IDBGetResult.h>
@@ -2979,4 +2980,50 @@
     return true;
 }
 
+void ArgumentCoder<FontAttributes>::encode(Encoder& encoder, const FontAttributes& attributes)
+{
+    encoder << attributes.backgroundColor << attributes.foregroundColor << attributes.fontShadow << attributes.hasUnderline << attributes.hasStrikeThrough;
+    encoder.encodeEnum(attributes.subscriptOrSuperscript);
+#if PLATFORM(COCOA)
+    bool hasFont = attributes.font;
+    encoder << hasFont;
+    if (hasFont)
+        IPC::encode(encoder, attributes.font.get());
+#endif
+}
+
+std::optional<FontAttributes> ArgumentCoder<FontAttributes>::decode(Decoder& decoder)
+{
+    FontAttributes attributes;
+
+    if (!decoder.decode(attributes.backgroundColor))
+        return std::nullopt;
+
+    if (!decoder.decode(attributes.foregroundColor))
+        return std::nullopt;
+
+    if (!decoder.decode(attributes.fontShadow))
+        return std::nullopt;
+
+    if (!decoder.decode(attributes.hasUnderline))
+        return std::nullopt;
+
+    if (!decoder.decode(attributes.hasStrikeThrough))
+        return std::nullopt;
+
+    if (!decoder.decodeEnum(attributes.subscriptOrSuperscript))
+        return std::nullopt;
+
+#if PLATFORM(COCOA)
+    bool hasFont = false;
+    if (!decoder.decode(hasFont))
+        return std::nullopt;
+
+    if (hasFont && !IPC::decode(decoder, attributes.font))
+        return std::nullopt;
+#endif
+
+    return attributes;
+}
+
 } // namespace IPC

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h (236723 => 236724)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -101,6 +101,7 @@
 struct DictionaryPopupInfo;
 struct EventTrackingRegions;
 struct ExceptionDetails;
+struct FontAttributes;
 struct FileChooserSettings;
 struct ShareData;
 struct ShareDataWithParsedURL;
@@ -720,6 +721,11 @@
     static bool decode(Decoder&, Vector<RefPtr<WebCore::SecurityOrigin>>&);
 };
 
+template<> struct ArgumentCoder<WebCore::FontAttributes> {
+    static void encode(Encoder&, const WebCore::FontAttributes&);
+    static std::optional<WebCore::FontAttributes> decode(Decoder&);
+};
+
 } // namespace IPC
 
 namespace WTF {

Modified: trunk/Source/WebKit/Shared/mac/ArgumentCodersMac.h (236723 => 236724)


--- trunk/Source/WebKit/Shared/mac/ArgumentCodersMac.h	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/Shared/mac/ArgumentCodersMac.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -38,6 +38,7 @@
 OBJC_CLASS NSNumber;
 OBJC_CLASS NSString;
 OBJC_CLASS NSURL;
+OBJC_CLASS UIFont;
 
 namespace IPC {
 
@@ -72,6 +73,11 @@
 bool decode(Decoder&, RetainPtr<NSFont>&);
 #endif
 
+#if PLATFORM(IOS)
+void encode(Encoder&, UIFont *);
+bool decode(Decoder&, RetainPtr<UIFont>&);
+#endif
+
 // NSNumber
 void encode(Encoder&, NSNumber *);
 bool decode(Decoder&, RetainPtr<NSNumber>&);

Modified: trunk/Source/WebKit/Shared/mac/ArgumentCodersMac.mm (236723 => 236724)


--- trunk/Source/WebKit/Shared/mac/ArgumentCodersMac.mm	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/Shared/mac/ArgumentCodersMac.mm	2018-10-02 10:39:40 UTC (rev 236724)
@@ -407,7 +407,7 @@
 void encode(Encoder& encoder, NSFont *font)
 {
     // NSFont could use CTFontRef code if we had it in ArgumentCodersCF.
-    encode(encoder, [[font fontDescriptor] fontAttributes]);
+    encode(encoder, font.fontDescriptor.fontAttributes);
 }
 
 bool decode(Decoder& decoder, RetainPtr<NSFont>& result)
@@ -421,8 +421,29 @@
 
     return result;
 }
-#endif
+#endif // USE(APPKIT)
 
+#if PLATFORM(IOS)
+
+void encode(Encoder& encoder, UIFont *font)
+{
+    encode(encoder, font.fontDescriptor.fontAttributes);
+}
+
+bool decode(Decoder& decoder, RetainPtr<UIFont>& result)
+{
+    RetainPtr<NSDictionary> fontAttributes;
+    if (!decode(decoder, fontAttributes))
+        return false;
+
+    UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:fontAttributes.get()];
+    result = [UIFont fontWithDescriptor:fontDescriptor size:0];
+
+    return result;
+}
+
+#endif // PLATFORM(IOS)
+
 void encode(Encoder& encoder, NSNumber *number)
 {
     encode(encoder, (__bridge CFNumberRef)number);

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (236723 => 236724)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2018-10-02 10:39:40 UTC (rev 236724)
@@ -176,11 +176,12 @@
 #endif
 
 #if PLATFORM(MAC)
+#import "AppKitSPI.h"
 #import "WKTextFinderClient.h"
 #import "WKViewInternal.h"
 #import <WebCore/ColorMac.h>
 
-@interface WKWebView () <WebViewImplDelegate, NSTextInputClient>
+@interface WKWebView () <WebViewImplDelegate, NSTextInputClient, NSTextInputClient_Async>
 @end
 
 #if HAVE(TOUCH_BAR)
@@ -3720,6 +3721,11 @@
     return _impl->characterIndexForPoint(thePoint);
 }
 
+- (void)typingAttributesWithCompletionHandler:(void(^)(NSDictionary<NSString *, id> *))completion
+{
+    _impl->typingAttributesWithCompletionHandler(completion);
+}
+
 - (NSRect)firstRectForCharacterRange:(NSRange)theRange actualRange:(NSRangePointer)actualRange
 {
     return _impl->firstRectForCharacterRange(theRange, actualRange);

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h (236723 => 236724)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -524,6 +524,7 @@
     void attributedSubstringForProposedRange(NSRange, void(^)(NSAttributedString *attrString, NSRange actualRange));
     void firstRectForCharacterRange(NSRange, void(^)(NSRect firstRect, NSRange actualRange));
     void characterIndexForPoint(NSPoint, void(^)(NSUInteger));
+    void typingAttributesWithCompletionHandler(void(^)(NSDictionary<NSString *, id> *));
 
     void mouseMoved(NSEvent *);
     void mouseDown(NSEvent *);

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (236723 => 236724)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm	2018-10-02 10:39:40 UTC (rev 236724)
@@ -31,6 +31,7 @@
 #import "APIAttachment.h"
 #import "APILegacyContextHistoryClient.h"
 #import "APINavigation.h"
+#import "AppKitSPI.h"
 #import "AttributedString.h"
 #import "ColorSpaceData.h"
 #import "FullscreenClient.h"
@@ -81,6 +82,7 @@
 #import <WebCore/Editor.h>
 #import <WebCore/FileSystem.h>
 #import <WebCore/FontAttributeChanges.h>
+#import <WebCore/FontAttributes.h>
 #import <WebCore/KeypressCommand.h>
 #import <WebCore/LegacyNSPasteboardTypes.h>
 #import <WebCore/LoaderNSURLExtras.h>
@@ -2743,6 +2745,13 @@
         requestCandidatesForSelectionIfNeeded();
 #endif
 
+    NSWindow *window = [m_view window];
+    if (window.firstResponder == m_view.get().get()) {
+        NSInspectorBar *inspectorBar = window.inspectorBar;
+        if (inspectorBar.visible)
+            [inspectorBar _update];
+    }
+
     [m_view _web_editorStateDidChange];
 }
 
@@ -2792,6 +2801,25 @@
     }
 }
 
+void WebViewImpl::typingAttributesWithCompletionHandler(void(^completion)(NSDictionary<NSString *, id> *))
+{
+    if (auto attributes = m_page->cachedFontAttributesAtSelectionStart()) {
+        auto attributesAsDictionary = attributes->createDictionary();
+        completion(attributesAsDictionary.get());
+        return;
+    }
+
+    m_page->requestFontAttributesAtSelectionStart([completion = makeBlockPtr(completion)] (const WebCore::FontAttributes& attributes, CallbackBase::Error error) {
+        if (error != CallbackBase::Error::None) {
+            completion(nil);
+            return;
+        }
+
+        auto attributesAsDictionary = attributes.createDictionary();
+        completion(attributesAsDictionary.get());
+    });
+}
+
 void WebViewImpl::changeFontColorFromSender(id sender)
 {
     if (![sender respondsToSelector:@selector(color)])

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (236723 => 236724)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-10-02 10:39:40 UTC (rev 236724)
@@ -1764,6 +1764,25 @@
     m_process->send(Messages::WebPage::ExecuteEditCommand(commandName, argument), m_pageID);
 }
 
+void WebPageProxy::requestFontAttributesAtSelectionStart(Function<void(const WebCore::FontAttributes&, CallbackBase::Error)>&& callback)
+{
+    if (!isValid()) {
+        callback({ }, CallbackBase::Error::Unknown);
+        return;
+    }
+
+    auto callbackID = m_callbacks.put(WTFMove(callback), m_process->throttler().backgroundActivityToken());
+    m_process->send(Messages::WebPage::RequestFontAttributesAtSelectionStart(callbackID), m_pageID);
+}
+
+void WebPageProxy::fontAttributesCallback(const WebCore::FontAttributes& attributes, CallbackID callbackID)
+{
+    m_cachedFontAttributesAtSelectionStart = attributes;
+
+    if (auto callback = m_callbacks.take<FontAttributesCallback>(callbackID))
+        callback->performCallbackWithReturnValue(attributes);
+}
+
 void WebPageProxy::setEditable(bool editable)
 {
     if (editable == m_isEditable)
@@ -6190,6 +6209,7 @@
     m_needsToFinishInitializingWebPageAfterProcessLaunch = false;
 
     m_editorState = EditorState();
+    m_cachedFontAttributesAtSelectionStart.reset();
 
     if (terminationReason == ProcessTerminationReason::NavigationSwap)
         pageClient().processWillSwap();

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (236723 => 236724)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -71,6 +71,7 @@
 #include <WebCore/Color.h>
 #include <WebCore/DragActions.h>
 #include <WebCore/EventTrackingRegions.h>
+#include <WebCore/FontAttributes.h>
 #include <WebCore/FrameLoaderTypes.h>
 #include <WebCore/FrameView.h> // FIXME: Move LayoutViewportConstraint to its own file and stop including this.
 #include <WebCore/LayoutPoint.h>
@@ -274,6 +275,7 @@
 typedef GenericCallback<EditingRange> EditingRangeCallback;
 typedef GenericCallback<const String&> StringCallback;
 typedef GenericCallback<API::SerializedScriptValue*, bool, const WebCore::ExceptionDetails&> ScriptValueCallback;
+typedef GenericCallback<const WebCore::FontAttributes&> FontAttributesCallback;
 
 #if PLATFORM(GTK)
 typedef GenericCallback<API::Error*> PrintFinishedCallback;
@@ -542,6 +544,8 @@
     bool hasSelectedRange() const { return m_editorState.selectionIsRange; }
     bool isContentEditable() const { return m_editorState.isContentEditable; }
 
+    std::optional<WebCore::FontAttributes> cachedFontAttributesAtSelectionStart() const { return m_cachedFontAttributesAtSelectionStart; }
+
 #if PLATFORM(COCOA)
     const TouchBarMenuData& touchBarMenuData() const { return m_touchBarMenuData; }
 #endif
@@ -556,6 +560,9 @@
     void setMediaStreamCaptureMuted(bool);
     void executeEditCommand(const String& commandName, const String& argument, WTF::Function<void(CallbackBase::Error)>&&);
         
+    void requestFontAttributesAtSelectionStart(Function<void(const WebCore::FontAttributes&, CallbackBase::Error)>&&);
+    void fontAttributesCallback(const WebCore::FontAttributes&, CallbackID);
+
 #if PLATFORM(IOS)
     double displayedContentScale() const { return m_lastVisibleContentRectUpdate.scale(); }
     const WebCore::FloatRect& exposedContentRect() const { return m_lastVisibleContentRectUpdate.exposedContentRect(); }
@@ -2218,6 +2225,8 @@
     WebCore::FloatSize m_maximumUnobscuredSize;
 #endif
 
+    std::optional<WebCore::FontAttributes> m_cachedFontAttributesAtSelectionStart;
+
 #if ENABLE(POINTER_LOCK)
     bool m_isPointerLockPending { false };
     bool m_isPointerLocked { false };

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (236723 => 236724)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in	2018-10-02 10:39:40 UTC (rev 236724)
@@ -186,6 +186,7 @@
     AttributedStringForCharacterRangeCallback(struct WebKit::AttributedString string, struct WebKit::EditingRange actualRange, WebKit::CallbackID callbackID)
     FontAtSelectionCallback(String fontName, double fontSize, bool selectioHasMultipleFonts, WebKit::CallbackID callbackID)
 #endif
+    FontAttributesCallback(struct WebCore::FontAttributes attributes, WebKit::CallbackID callbackID)
 #if PLATFORM(IOS)
     GestureCallback(WebCore::IntPoint point, uint32_t gestureType, uint32_t gestureState, uint32_t flags, WebKit::CallbackID callbackID)
     TouchesCallback(WebCore::IntPoint point, uint32_t touches, uint32_t flags, WebKit::CallbackID callbackID)

Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (236723 => 236724)


--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2018-10-02 10:39:40 UTC (rev 236724)
@@ -1053,6 +1053,7 @@
     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
     
     m_editorState = editorState;
+    m_cachedFontAttributesAtSelectionStart.reset();
     
     // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
     if (couldChangeSecureInputState && !editorState.selectionIsNone)

Modified: trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm (236723 => 236724)


--- trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm	2018-10-02 10:39:40 UTC (rev 236724)
@@ -650,6 +650,7 @@
     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
     
     m_editorState = editorState;
+    m_cachedFontAttributesAtSelectionStart.reset();
     
     // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
     if (couldChangeSecureInputState && !editorState.selectionIsNone)

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (236723 => 236724)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2018-10-02 10:39:40 UTC (rev 236724)
@@ -1589,6 +1589,7 @@
 		F44291921FA591C9002CC93E /* _WKAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = F44291911FA59107002CC93E /* _WKAttachment.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F44291961FA5942A002CC93E /* _WKAttachmentInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = F44291951FA5942A002CC93E /* _WKAttachmentInternal.h */; };
 		F44DFEB21E9E752F0038D196 /* WebIconUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = F44DFEB01E9E752F0038D196 /* WebIconUtilities.h */; };
+		F48D2A8521583A7E00C6752B /* AppKitSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2A8421583A0200C6752B /* AppKitSPI.h */; };
 		F496A4311F58A272004C1757 /* DragDropInteractionState.h in Headers */ = {isa = PBXBuildFile; fileRef = F496A42F1F58A272004C1757 /* DragDropInteractionState.h */; };
 		F4D5F51D206087A10038BBA8 /* WKTextInputListViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D5F519206087A00038BBA8 /* WKTextInputListViewController.h */; };
 		F4D5F51F206087A10038BBA8 /* WKQuickboardListViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D5F51B206087A10038BBA8 /* WKQuickboardListViewController.h */; };
@@ -4428,6 +4429,7 @@
 		F44291951FA5942A002CC93E /* _WKAttachmentInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKAttachmentInternal.h; sourceTree = "<group>"; };
 		F44DFEB01E9E752F0038D196 /* WebIconUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebIconUtilities.h; path = ios/WebIconUtilities.h; sourceTree = "<group>"; };
 		F44DFEB11E9E752F0038D196 /* WebIconUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebIconUtilities.mm; path = ios/WebIconUtilities.mm; sourceTree = "<group>"; };
+		F48D2A8421583A0200C6752B /* AppKitSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppKitSPI.h; sourceTree = "<group>"; };
 		F496A42F1F58A272004C1757 /* DragDropInteractionState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DragDropInteractionState.h; path = ios/DragDropInteractionState.h; sourceTree = "<group>"; };
 		F496A4301F58A272004C1757 /* DragDropInteractionState.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = DragDropInteractionState.mm; path = ios/DragDropInteractionState.mm; sourceTree = "<group>"; };
 		F4D5F519206087A00038BBA8 /* WKTextInputListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKTextInputListViewController.h; path = ios/forms/WKTextInputListViewController.h; sourceTree = "<group>"; };
@@ -6947,6 +6949,7 @@
 		A1E6886E1F6E2B82007006A6 /* mac */ = {
 			isa = PBXGroup;
 			children = (
+				F48D2A8421583A0200C6752B /* AppKitSPI.h */,
 				A1E6886F1F6E2BAB007006A6 /* QuarantineSPI.h */,
 			);
 			path = mac;
@@ -8797,6 +8800,7 @@
 				1AE286841C7F93860069AC4F /* APIWebsiteDataRecord.h in Headers */,
 				1A3635AA1A3144A300ED6197 /* APIWebsiteDataStore.h in Headers */,
 				1A6563E51B7A8C50009CF787 /* APIWindowFeatures.h in Headers */,
+				F48D2A8521583A7E00C6752B /* AppKitSPI.h in Headers */,
 				1AD4C1931B39F33200ABC28E /* ApplicationStateTracker.h in Headers */,
 				1AEFD27911D16C81008219D3 /* ArgumentCoder.h in Headers */,
 				1AEFD2F711D1807B008219D3 /* ArgumentCoders.h in Headers */,

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (236723 => 236724)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2018-10-02 10:39:40 UTC (rev 236724)
@@ -155,6 +155,7 @@
 #include <WebCore/EventNames.h>
 #include <WebCore/File.h>
 #include <WebCore/FocusController.h>
+#include <WebCore/FontAttributes.h>
 #include <WebCore/FormState.h>
 #include <WebCore/Frame.h>
 #include <WebCore/FrameLoadRequest.h>
@@ -2509,6 +2510,12 @@
     restoreSessionInternal(itemStates, WasRestoredByAPIRequest::No, WebBackForwardListProxy::OverwriteExistingItem::Yes);
 }
 
+void WebPage::requestFontAttributesAtSelectionStart(CallbackID callbackID)
+{
+    auto attributes = m_page->focusController().focusedOrMainFrame().editor().fontAttributesAtSelectionStart();
+    send(Messages::WebPageProxy::FontAttributesCallback(attributes, callbackID));
+}
+
 #if ENABLE(TOUCH_EVENTS)
 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
 {

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (236723 => 236724)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -1205,6 +1205,8 @@
     void didRemoveBackForwardItem(const WebCore::BackForwardItemIdentifier&);
     void updateBackForwardListForReattach(const Vector<WebKit::BackForwardListItemState>&);
 
+    void requestFontAttributesAtSelectionStart(CallbackID);
+
 #if ENABLE(REMOTE_INSPECTOR)
     void setAllowsRemoteInspection(bool);
     void setRemoteInspectionNameOverride(const String&);

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (236723 => 236724)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2018-10-02 10:39:40 UTC (rev 236724)
@@ -209,6 +209,8 @@
     ValidateCommand(String name, WebKit::CallbackID callbackID)
     ExecuteEditCommand(String name, String argument)
 
+    RequestFontAttributesAtSelectionStart(WebKit::CallbackID callbackID)
+
     DidRemoveEditCommand(uint64_t commandID)
     ReapplyEditCommand(uint64_t commandID)
     UnapplyEditCommand(uint64_t commandID)

Modified: trunk/Tools/ChangeLog (236723 => 236724)


--- trunk/Tools/ChangeLog	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Tools/ChangeLog	2018-10-02 10:39:40 UTC (rev 236724)
@@ -1,3 +1,57 @@
+2018-10-02  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [macOS] Implement a way for the UI process to request typing attributes at the current selection
+        https://bugs.webkit.org/show_bug.cgi?id=189983
+        <rdar://problem/44648705>
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds new FontManagerTests that exercise -typingAttributesWithCompletionHandler:. See below for more detail.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h:
+        * TestWebKitAPI/Tests/mac/FontManagerTests.mm:
+
+        Add a new test that exercises font attribute modification via inspector bar. Also, add a new test that checks
+        typing attributes when using subscript/superscript/unscript. Lastly, augment an existing NSFontPanel test to
+        additionally check that shadowed text and strike-through are reflected in typing attributes.
+
+        (-[FontManagerTestWKWebView inspectorBarItemIdentifiers]):
+        (-[TestWKWebView typingAttributes]):
+
+        Add a synchronous wrapper around `-typingAttributesWithCompletionHandler:` by spinning the runloop.
+
+        (-[TestWKWebView collapseToStart]):
+        (webViewForFontManagerTesting):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/cocoa/TestWKWebView.h:
+        * TestWebKitAPI/mac/TestInspectorBar.h: Copied from Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h.
+        * TestWebKitAPI/mac/TestInspectorBar.mm: Added.
+
+        Introduce subclasses of `__InspectorBarItemController` and `NSInspectorBar` for testing inspector bar interaction.
+
+        (-[TestInspectorBarItemController initWithInspectorBar:]):
+        (-[TestInspectorBarItemController inspectorBar]):
+        (-[TestInspectorBarItemController updateSelectedAttributes]):
+        (-[TestInspectorBar initWithWebView:]):
+        (+[TestInspectorBar standardItemControllerClass]):
+        (+[TestInspectorBar standardTextItemIdentifiers]):
+        (-[TestInspectorBar _setStyleControlSelected:atIndex:]):
+        (-[TestInspectorBar chooseFontSize:]):
+        (-[TestInspectorBar chooseFontFamily:]):
+        (-[TestInspectorBar _chooseColor:inColorWell:]):
+        (-[TestInspectorBar chooseForegroundColor:]):
+        (-[TestInspectorBar chooseBackgroundColor:]):
+        (-[TestInspectorBar formatBold:]):
+        (-[TestInspectorBar formatItalic:]):
+        (-[TestInspectorBar formatUnderline:]):
+
+        Add helper methods to TestInspectorBar to simulate interacting with various controls (e.g. color wells and font
+        styling controls).
+
+        (-[TestInspectorBar itemController]):
+        (-[TestInspectorBar setItemController:]):
+
 2018-10-02  Thibault Saunier  <tsaun...@igalia.com>
 
         [Flatpak] Implement icecream and ccache support

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (236723 => 236724)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2018-10-02 10:39:40 UTC (rev 236724)
@@ -813,6 +813,7 @@
 		F457A9D6202D68AF00F7E9D5 /* DataTransfer.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F457A9B3202D535300F7E9D5 /* DataTransfer.html */; };
 		F45B63FB1F197F4A009D38B9 /* image-map.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F45B63FA1F197F33009D38B9 /* image-map.html */; };
 		F45B63FE1F19D410009D38B9 /* ActionSheetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45B63FC1F19D410009D38B9 /* ActionSheetTests.mm */; };
+		F45D3891215A7B4B002A2979 /* TestInspectorBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45D3890215A7B4B002A2979 /* TestInspectorBar.mm */; };
 		F45E15732112CE2900307E82 /* KeyboardInputTestsIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */; };
 		F45E15762112CE6200307E82 /* TestInputDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45E15752112CE6200307E82 /* TestInputDelegate.mm */; };
 		F46128B7211C8ED500D9FADB /* DragAndDropSimulatorMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = F46128B6211C8ED500D9FADB /* DragAndDropSimulatorMac.mm */; };
@@ -2063,6 +2064,8 @@
 		F457A9B6202D5CDC00F7E9D5 /* PasteMixedContent.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteMixedContent.mm; sourceTree = "<group>"; };
 		F45B63FA1F197F33009D38B9 /* image-map.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "image-map.html"; sourceTree = "<group>"; };
 		F45B63FC1F19D410009D38B9 /* ActionSheetTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ActionSheetTests.mm; sourceTree = "<group>"; };
+		F45D388F215A7B4B002A2979 /* TestInspectorBar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestInspectorBar.h; sourceTree = "<group>"; };
+		F45D3890215A7B4B002A2979 /* TestInspectorBar.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestInspectorBar.mm; sourceTree = "<group>"; };
 		F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyboardInputTestsIOS.mm; sourceTree = "<group>"; };
 		F45E15742112CE6200307E82 /* TestInputDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestInputDelegate.h; sourceTree = "<group>"; };
 		F45E15752112CE6200307E82 /* TestInputDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestInputDelegate.mm; sourceTree = "<group>"; };
@@ -3171,6 +3174,8 @@
 				F46128CA211D475100D9FADB /* TestDraggingInfo.mm */,
 				F4E0A2B62122847400AF7C7F /* TestFilePromiseReceiver.h */,
 				F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */,
+				F45D388F215A7B4B002A2979 /* TestInspectorBar.h */,
+				F45D3890215A7B4B002A2979 /* TestInspectorBar.mm */,
 				C08587BE13FE956C001EF4E5 /* WebKitAgnosticTest.h */,
 				C08587BD13FE956C001EF4E5 /* WebKitAgnosticTest.mm */,
 			);
@@ -3991,6 +3996,7 @@
 				F46128CB211D475100D9FADB /* TestDraggingInfo.mm in Sources */,
 				F4E0A2B82122847400AF7C7F /* TestFilePromiseReceiver.mm in Sources */,
 				F45E15762112CE6200307E82 /* TestInputDelegate.mm in Sources */,
+				F45D3891215A7B4B002A2979 /* TestInspectorBar.mm in Sources */,
 				2D1C04A71D76298B000A6816 /* TestNavigationDelegate.mm in Sources */,
 				A14FC5901B8AE36F00D107EB /* TestProtocol.mm in Sources */,
 				7CCE7EAE1A411A3400447C4C /* TestsController.cpp in Sources */,

Modified: trunk/Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h (236723 => 236724)


--- trunk/Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -27,8 +27,12 @@
 
 #if USE(APPLE_INTERNAL_SDK)
 
+#import <AppKit/NSInspectorBar.h>
+#import <AppKit/NSInspectorBarItemController.h>
+#import <AppKit/NSInspectorBar_Private.h>
 #import <AppKit/NSTextInputClient_Private.h>
 #import <AppKit/NSTextInputContext_Private.h>
+#import <AppKit/NSWindow_Private.h>
 
 #else
 
@@ -43,6 +47,60 @@
 - (void)handleEventByInputMethod:(NSEvent *)event completionHandler:(void(^)(BOOL handled))completionHandler;
 @end
 
+@protocol NSInspectorBarClient <NSObject>
+@property (readonly) NSArray<NSString *> *inspectorBarItemIdentifiers;
+@property (readonly) NSWindow *window;
+@end
+
+@interface NSInspectorBar : NSObject
++ (Class)standardItemControllerClass;
++ (NSArray<NSString *> *)standardTextItemIdentifiers;
+@property (strong) id <NSInspectorBarClient> client;
+@property (getter=isVisible) BOOL visible;
+@end
+
+NSString * const NSInspectorBarFontFamilyItemIdentifier = @"NSInspectorBarFontFamilyItemIdentifier";
+NSString * const NSInspectorBarFontSizeItemIdentifier = @"NSInspectorBarFontSizeItemIdentifier";
+NSString * const NSInspectorBarTextForegroundColorItemIdentifier = @"NSInspectorBarTextForegroundColorItemIdentifier";
+NSString * const NSInspectorBarTextBackgroundColorItemIdentifier = @"NSInspectorBarTextBackgroundColorItemIdentifier";
+NSString * const NSInspectorBarFontStyleItemIdentifier = @"NSInspectorBarFontStyleItemIdentifier";
+NSString * const NSInspectorBarTextAlignmentItemIdentifier = @"NSInspectorBarTextAlignmentItemIdentifier";
+
+@interface __NSInspectorBarItemController : NSObject
+- (instancetype)initWithInspectorBar:(NSInspectorBar *)bar NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+- (void)updateSelectedAttributes;
+- (void)fontSizeItemWasClicked:(NSNumber *)size;
+@property (readonly) NSPopUpButton *stylePopup;
+@property (readonly) NSPopUpButton *fontFamilyPopup;
+@property (readonly) NSComboBox *fontSizeComboBox;
+@property (readonly) NSColorWell *foregroundColorWell;
+@property (readonly) NSColorWell *backgroundColorWell;
+@property (readonly) NSSegmentedControl *textStyleSwitches;
+@end
+
+@interface NSWindow (NSInspectorBarSupport)
+- (NSInspectorBar *)inspectorBar;
+- (void)setInspectorBar:(NSInspectorBar *)bar;
+@end
+
 #endif
 
+@protocol NSTextInputClient_Async_Staging_44648564
+@optional
+- (void)typingAttributesWithCompletionHandler:(void(^)(NSDictionary<NSString *, id> *))completionHandler;
+@end
+
+@interface NSInspectorBar (IPI)
+- (NSFont *)convertFont:(NSFont *)font;
+- (NSDictionary *)convertAttributes:(NSDictionary *)attributes;
+@end
+
+@interface __NSInspectorBarItemController (IPI)
+- (void)_fontPopupAction:(id)sender;
+- (void)_fontStyleAction:(id)sender;
+- (void)_colorAction:(id)sender;
+- (void)menuNeedsUpdate:(NSMenu *)menu;
+@end
+
 #endif // PLATFORM(MAC)

Modified: trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm (236723 => 236724)


--- trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm	2018-10-02 10:39:40 UTC (rev 236724)
@@ -24,6 +24,7 @@
  */
 
 #import "config.h"
+#import "Test.h"
 
 #if PLATFORM(MAC) && WK_API_ENABLED
 
@@ -30,22 +31,52 @@
 #import "AppKitSPI.h"
 #import "NSFontPanelTesting.h"
 #import "PlatformUtilities.h"
+#import "TestInspectorBar.h"
 #import "TestWKWebView.h"
 #import <WebKit/WKWebViewPrivate.h>
 
+@interface WKWebView (NSTextInputClient_Async) <NSTextInputClient_Async, NSTextInputClient_Async_Staging_44648564, NSInspectorBarClient>
+@end
+
 @interface TestWKWebView (FontManagerTests)
 
 @property (nonatomic, readonly) NSString *selectedText;
 
+- (NSDictionary<NSString *, id> *)typingAttributes;
 - (NSString *)stylePropertyAtSelectionStart:(NSString *)propertyName;
 - (NSString *)stylePropertyAtSelectionEnd:(NSString *)propertyName;
 - (void)selectNextWord;
+- (void)collapseToStart;
 - (void)collapseToEnd;
 
 @end
 
+@interface FontManagerTestWKWebView : TestWKWebView
+@end
+
+@implementation FontManagerTestWKWebView
+
+- (NSArray<NSString *> *)inspectorBarItemIdentifiers
+{
+    return [TestInspectorBar standardTextItemIdentifiers];
+}
+
+@end
+
 @implementation TestWKWebView (FontManagerTests)
 
+- (NSDictionary<NSString *, id> *)typingAttributes
+{
+    __block bool done = false;
+    __block RetainPtr<NSDictionary> result;
+    [self typingAttributesWithCompletionHandler:^(NSDictionary<NSString *, id> *attributes) {
+        result = attributes;
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    return result.autorelease();
+}
+
 - (NSString *)selectedText
 {
     return [self stringByEvaluatingJavaScript:@"getSelection().toString()"];
@@ -58,6 +89,11 @@
     [self selectWord:nil];
 }
 
+- (void)collapseToStart
+{
+    [self evaluateJavaScript:@"getSelection().collapseToStart()" completionHandler:nil];
+}
+
 - (void)collapseToEnd
 {
     [self evaluateJavaScript:@"getSelection().collapseToEnd()" completionHandler:nil];
@@ -77,9 +113,9 @@
 
 @end
 
-static RetainPtr<TestWKWebView> webViewForFontManagerTesting(NSFontManager *fontManager)
+static RetainPtr<FontManagerTestWKWebView> webViewForFontManagerTesting(NSFontManager *fontManager)
 {
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+    auto webView = adoptNS([[FontManagerTestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
     [webView synchronouslyLoadHTMLString:@"<body contenteditable>"
         "<span id='foo'>foo</span> <span id='bar'>bar</span> <span id='baz'>baz</span>"
         "</body><script>document.body.addEventListener('input', event => lastInputEvent = event)</script>"];
@@ -224,9 +260,11 @@
     [fontPanel chooseStrikeThroughMenuItemWithTitle:@"single"];
     EXPECT_WK_STREQ("bar", [webView selectedText]);
     EXPECT_WK_STREQ("line-through", textDecorationsAroundSelection());
+    EXPECT_EQ(NSUnderlineStyleSingle, [[webView typingAttributes][NSStrikethroughStyleAttributeName] intValue]);
 
     [fontPanel chooseStrikeThroughMenuItemWithTitle:@"none"];
     EXPECT_WK_STREQ("none", textDecorationsAroundSelection());
+    EXPECT_EQ(NSUnderlineStyleNone, [[webView typingAttributes][NSStrikethroughStyleAttributeName] intValue]);
 
     [webView selectNextWord];
     fontPanel.shadowBlur = 8;
@@ -234,9 +272,17 @@
     [fontPanel toggleShadow];
     EXPECT_WK_STREQ("baz", [webView selectedText]);
     EXPECT_WK_STREQ("rgb(0, 0, 0) 0px 1px 8px", textShadowAroundSelection());
+    {
+        NSShadow *shadow = [webView typingAttributes][NSShadowAttributeName];
+        EXPECT_EQ(shadow.shadowOffset.width, 0);
+        EXPECT_EQ(shadow.shadowOffset.height, 1);
+        EXPECT_EQ(shadow.shadowBlurRadius, 8);
+        EXPECT_TRUE([shadow.shadowColor isEqual:[NSColor colorWithRed:0 green:0 blue:0 alpha:1]]);
+    }
 
     [fontPanel toggleShadow];
     EXPECT_WK_STREQ("none", textShadowAroundSelection());
+    EXPECT_NULL([webView typingAttributes][NSShadowAttributeName]);
 
     // Now combine all three attributes together.
     [webView selectAll:nil];
@@ -248,12 +294,25 @@
     EXPECT_WK_STREQ("foo bar baz", [webView selectedText]);
     EXPECT_WK_STREQ("rgba(0, 0, 0, 0.2) 0px 1px 5px", textShadowAroundSelection());
     EXPECT_WK_STREQ("underline line-through", textDecorationsAroundSelection());
+    {
+        NSDictionary *typingAttributes = [webView typingAttributes];
+        EXPECT_EQ(NSUnderlineStyleSingle, [typingAttributes[NSUnderlineStyleAttributeName] intValue]);
+        EXPECT_EQ(NSUnderlineStyleSingle, [typingAttributes[NSStrikethroughStyleAttributeName] intValue]);
 
+        NSShadow *shadow = typingAttributes[NSShadowAttributeName];
+        EXPECT_EQ(shadow.shadowOffset.width, 0);
+        EXPECT_EQ(shadow.shadowOffset.height, 1);
+        EXPECT_EQ(shadow.shadowBlurRadius, 5);
+        EXPECT_TRUE([shadow.shadowColor isEqual:[NSColor colorWithRed:0 green:0 blue:0 alpha:0.2]]);
+    }
+
     [fontPanel toggleShadow];
     [fontPanel chooseUnderlineMenuItemWithTitle:@"none"];
     [fontPanel chooseStrikeThroughMenuItemWithTitle:@"none"];
     EXPECT_WK_STREQ("none", textShadowAroundSelection());
     EXPECT_WK_STREQ("none", textDecorationsAroundSelection());
+    EXPECT_EQ(NSUnderlineStyleNone, [[webView typingAttributes][NSStrikethroughStyleAttributeName] intValue]);
+    EXPECT_NULL([webView typingAttributes][NSShadowAttributeName]);
 }
 
 TEST(FontManagerTests, ChangeFontColorWithColorPanel)
@@ -310,6 +369,83 @@
     EXPECT_WK_STREQ("rgb(0, 255, 0)", [webView stylePropertyAtSelectionEnd:@"color"]);
 }
 
+TEST(FontManagerTests, ChangeTypingAttributesWithInspectorBar)
+{
+    auto webView = webViewForFontManagerTesting(NSFontManager.sharedFontManager);
+    auto inspectorBar = adoptNS([[TestInspectorBar alloc] initWithWebView:webView.get()]);
+    {
+        [webView selectAll:nil];
+        NSFont *originalFont = [webView typingAttributes][NSFontAttributeName];
+        EXPECT_WK_STREQ("Times", originalFont.familyName);
+        EXPECT_EQ(16, originalFont.pointSize);
+    }
+    {
+        // Change font family.
+        [inspectorBar chooseFontFamily:@"Helvetica"];
+        [webView waitForNextPresentationUpdate];
+        NSFont *fontAfterSpecifyingHelvetica = [webView typingAttributes][NSFontAttributeName];
+        EXPECT_WK_STREQ("Helvetica", fontAfterSpecifyingHelvetica.familyName);
+        EXPECT_EQ(16, fontAfterSpecifyingHelvetica.pointSize);
+    }
+    {
+        // Change font size.
+        [webView collapseToStart];
+        [webView selectWord:nil];
+        [inspectorBar chooseFontSize:32];
+        [webView collapseToEnd];
+        [webView waitForNextPresentationUpdate];
+        NSFont *fontAfterDoublingFontSize = [webView typingAttributes][NSFontAttributeName];
+        EXPECT_WK_STREQ("Helvetica", fontAfterDoublingFontSize.familyName);
+        EXPECT_EQ(32, fontAfterDoublingFontSize.pointSize);
+    }
+    {
+        // Bold, italic, and underline.
+        [webView selectNextWord];
+        [inspectorBar formatBold:YES];
+        [inspectorBar formatItalic:YES];
+        [inspectorBar formatUnderline:YES];
+        [webView waitForNextPresentationUpdate];
+        NSDictionary *attributes = [webView typingAttributes];
+        EXPECT_WK_STREQ("Helvetica-BoldOblique", [attributes[NSFontAttributeName] fontName]);
+        EXPECT_EQ(16, [attributes[NSFontAttributeName] pointSize]);
+        EXPECT_EQ(NSUnderlineStyleSingle, [attributes[NSUnderlineStyleAttributeName] integerValue]);
+    }
+    {
+        // Add foreground and background colors.
+        [webView selectNextWord];
+        NSColor *foregroundColor = [NSColor colorWithRed:1 green:1 blue:1 alpha:0.2];
+        NSColor *backgroundColor = [NSColor colorWithRed:0.8 green:0.2 blue:0.6 alpha:1];
+        [inspectorBar chooseForegroundColor:foregroundColor];
+        [inspectorBar chooseBackgroundColor:backgroundColor];
+        [webView waitForNextPresentationUpdate];
+        NSDictionary *attributes = [webView typingAttributes];
+        EXPECT_TRUE([attributes[NSForegroundColorAttributeName] isEqual:foregroundColor]);
+        EXPECT_TRUE([attributes[NSBackgroundColorAttributeName] isEqual:backgroundColor]);
+    }
+}
+
+TEST(FontManagerTests, TypingAttributesAfterSubscriptAndSuperscript)
+{
+    auto webView = webViewForFontManagerTesting(NSFontManager.sharedFontManager);
+
+    [webView moveToBeginningOfDocument:nil];
+    [webView selectWord:nil];
+    [webView superscript:nil];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_EQ(1, [[webView typingAttributes][NSSuperscriptAttributeName] integerValue]);
+
+    [webView selectNextWord];
+    [webView subscript:nil];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_EQ(-1, [[webView typingAttributes][NSSuperscriptAttributeName] integerValue]);
+
+    [webView selectNextWord];
+    [webView subscript:nil];
+    [webView unscript:nil];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_EQ(0, [[webView typingAttributes][NSSuperscriptAttributeName] integerValue]);
+}
+
 } // namespace TestWebKitAPI
 
 #endif // PLATFORM(MAC) && WK_API_ENABLED

Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h (236723 => 236724)


--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h	2018-10-02 10:17:43 UTC (rev 236723)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -40,6 +40,9 @@
 - (void)paste:(id)sender;
 - (void)changeAttributes:(id)sender;
 - (void)changeColor:(id)sender;
+- (void)superscript:(id)sender;
+- (void)subscript:(id)sender;
+- (void)unscript:(id)sender;
 #endif
 @end
 

Copied: trunk/Tools/TestWebKitAPI/mac/TestInspectorBar.h (from rev 236723, trunk/Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/AppKitSPI.h) (0 => 236724)


--- trunk/Tools/TestWebKitAPI/mac/TestInspectorBar.h	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/mac/TestInspectorBar.h	2018-10-02 10:39:40 UTC (rev 236724)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 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. AND ITS CONTRIBUTORS ``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 ITS 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
+
+#if WK_API_ENABLED && PLATFORM(MAC)
+
+#import "AppKitSPI.h"
+
+@class TestInspectorBar;
+
+@interface TestInspectorBarItemController : __NSInspectorBarItemController
+@property (nonatomic, weak, readonly) TestInspectorBar *inspectorBar;
+@end
+
+@interface TestInspectorBar : NSInspectorBar
+@property (nonatomic, weak) TestInspectorBarItemController *itemController;
+- (instancetype)initWithWebView:(WKWebView<NSInspectorBarClient> *)webView;
+- (void)formatBold:(BOOL)bold;
+- (void)formatItalic:(BOOL)italic;
+- (void)formatUnderline:(BOOL)underline;
+- (void)chooseFontFamily:(NSString *)fontFamilyName;
+- (void)chooseFontSize:(CGFloat)fontSize;
+- (void)chooseForegroundColor:(NSColor *)color;
+- (void)chooseBackgroundColor:(NSColor *)color;
+@end
+
+#endif // WK_API_ENABLED && PLATFORM(MAC)

Added: trunk/Tools/TestWebKitAPI/mac/TestInspectorBar.mm (0 => 236724)


--- trunk/Tools/TestWebKitAPI/mac/TestInspectorBar.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/mac/TestInspectorBar.mm	2018-10-02 10:39:40 UTC (rev 236724)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2018 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#import "config.h"
+#import "TestInspectorBar.h"
+
+#if WK_API_ENABLED && PLATFORM(MAC)
+
+#import <objc/runtime.h>
+#import <wtf/WeakObjCPtr.h>
+
+@implementation TestInspectorBarItemController {
+    WeakObjCPtr<TestInspectorBar> _testInspectorBar;
+}
+
+- (instancetype)initWithInspectorBar:(TestInspectorBar *)inspectorBar
+{
+    if (self = [super initWithInspectorBar:inspectorBar]) {
+        inspectorBar.itemController = self;
+        _testInspectorBar = inspectorBar;
+    }
+    return self;
+}
+
+- (TestInspectorBar *)inspectorBar
+{
+    return _testInspectorBar.get().get();
+}
+
+- (void)updateSelectedAttributes
+{
+    // Older versions of AppKit only invoke synchronous NSTextInputClient methods, which immediately causes a debug
+    // assertion in WebKit. To prevent this assertion, we suppress selection updates for versions of macOS where AppKit
+    // only knows how to update selected attributes using synchronous text input client methods. That being said, the
+    // inspector bar item controller still needs to set its _client pointer to the inspector bar's client; otherwise,
+    // attempts to send @selector(changeAttributes:) when changing font attributes will become no-ops.
+    object_setInstanceVariable(self, "_client", [_testInspectorBar client]);
+}
+
+@end
+
+@implementation TestInspectorBar {
+    WeakObjCPtr<TestInspectorBarItemController> _testItemController;
+}
+
+- (instancetype)initWithWebView:(WKWebView<NSInspectorBarClient> *)webView
+{
+    if (self = [super init]) {
+        self.visible = YES;
+        self.client = webView;
+        [webView.window setInspectorBar:self];
+    }
+    return self;
+}
+
++ (Class)standardItemControllerClass
+{
+    return TestInspectorBarItemController.class;
+}
+
++ (NSArray<NSString *> *)standardTextItemIdentifiers
+{
+    static NSArray<NSString *> *identifiers = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        identifiers = @[
+            NSInspectorBarFontFamilyItemIdentifier,
+            NSInspectorBarFontSizeItemIdentifier,
+            NSInspectorBarTextForegroundColorItemIdentifier,
+            NSInspectorBarTextBackgroundColorItemIdentifier,
+            NSInspectorBarFontStyleItemIdentifier
+        ];
+    });
+    return identifiers;
+}
+
+- (void)_setStyleControlSelected:(BOOL)selected atIndex:(NSInteger)index
+{
+    NSSegmentedControl *styleControls = [_testItemController textStyleSwitches];
+    styleControls.selectedSegment = index;
+    [styleControls setSelected:selected forSegment:index];
+    [_testItemController _fontStyleAction:styleControls];
+}
+
+- (void)chooseFontSize:(CGFloat)fontSize
+{
+    [_testItemController fontSizeItemWasClicked:@(fontSize)];
+}
+
+- (void)chooseFontFamily:(NSString *)fontFamily
+{
+    NSPopUpButton *fontFamilyPopup = [_testItemController fontFamilyPopup];
+    [_testItemController menuNeedsUpdate:fontFamilyPopup.cell.menu];
+    for (NSMenuItem *item in [fontFamilyPopup itemArray]) {
+        if ([item.representedObject isKindOfClass:NSString.class] && [fontFamily isEqualToString:item.representedObject]) {
+            [fontFamilyPopup selectItem:item];
+            [_testItemController _fontPopupAction:fontFamilyPopup];
+            return;
+        }
+    }
+    ASSERT_NOT_REACHED();
+}
+
+- (void)_chooseColor:(NSColor *)color inColorWell:(NSColorWell *)colorWell
+{
+    [colorWell setColor:color];
+    [_testItemController _colorAction:colorWell];
+}
+
+- (void)chooseForegroundColor:(NSColor *)color
+{
+    [self _chooseColor:color inColorWell:[_testItemController foregroundColorWell]];
+}
+
+- (void)chooseBackgroundColor:(NSColor *)color
+{
+    [self _chooseColor:color inColorWell:[_testItemController backgroundColorWell]];
+}
+
+- (void)formatBold:(BOOL)bold
+{
+    [self _setStyleControlSelected:bold atIndex:0];
+}
+
+- (void)formatItalic:(BOOL)italic
+{
+    [self _setStyleControlSelected:italic atIndex:1];
+}
+
+- (void)formatUnderline:(BOOL)underline
+{
+    [self _setStyleControlSelected:underline atIndex:2];
+}
+
+- (TestInspectorBarItemController *)itemController
+{
+    return _testItemController.get().get();
+}
+
+- (void)setItemController:(TestInspectorBarItemController *)itemController
+{
+    _testItemController = itemController;
+}
+
+@end
+
+#endif // WK_API_ENABLED && PLATFORM(MAC)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to