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)