Diff
Modified: trunk/Source/WebCore/ChangeLog (287952 => 287953)
--- trunk/Source/WebCore/ChangeLog 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebCore/ChangeLog 2022-01-12 22:59:04 UTC (rev 287953)
@@ -1,3 +1,18 @@
+2022-01-12 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [macOS] [WK2] NSFontPanel UI (font color, text decorations, font shadow) doesn't update on selection change
+ https://bugs.webkit.org/show_bug.cgi?id=190120
+ rdar://44897405
+
+ Reviewed by Darin Adler.
+
+ Add a boolean `hasMultipleFonts` flag to FontAttributes, and pass it as an out-reference when computing the
+ font at the current selection. See WebKit/ChangeLog for more details.
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::fontAttributesAtSelectionStart):
+ * editing/FontAttributes.h:
+
2022-01-12 Brandon Stewart <brandonstew...@apple.com>
Verify startNode is prior to the beyondEnd node
Modified: trunk/Source/WebCore/editing/Editor.cpp (287952 => 287953)
--- trunk/Source/WebCore/editing/Editor.cpp 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebCore/editing/Editor.cpp 2022-01-12 22:59:04 UTC (rev 287953)
@@ -4041,8 +4041,7 @@
FontAttributes Editor::fontAttributesAtSelectionStart()
{
FontAttributes attributes;
- bool hasMultipleFonts = false; // FIXME (190120): Add `hasMultipleFonts` as a member in `FontAttributes`.
- attributes.font = fontForSelection(hasMultipleFonts);
+ attributes.font = fontForSelection(attributes.hasMultipleFonts);
RefPtr<Node> nodeToRemove;
auto nodeRemovalScope = makeScopeExit([&nodeToRemove]() {
Modified: trunk/Source/WebCore/editing/FontAttributes.h (287952 => 287953)
--- trunk/Source/WebCore/editing/FontAttributes.h 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebCore/editing/FontAttributes.h 2022-01-12 22:59:04 UTC (rev 287953)
@@ -90,6 +90,7 @@
Vector<TextList> textLists;
bool hasUnderline { false };
bool hasStrikeThrough { false };
+ bool hasMultipleFonts { false };
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (287952 => 287953)
--- trunk/Source/WebKit/ChangeLog 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/ChangeLog 2022-01-12 22:59:04 UTC (rev 287953)
@@ -1,3 +1,71 @@
+2022-01-12 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [macOS] [WK2] NSFontPanel UI (font color, text decorations, font shadow) doesn't update on selection change
+ https://bugs.webkit.org/show_bug.cgi?id=190120
+ rdar://44897405
+
+ Reviewed by Darin Adler.
+
+ Currently, in WebKit2, there is no mechanism for updating the NSFontManager with new font attributes when the
+ selection changes. While we do update the selected NSFont, we do so by requesting font family and font size via
+ an IPC request, `FontAtSelection`, but this does not include attributes like underline, strike-through, color,
+ and text shadows.
+
+ Instead, we can remove this `FontAtSelection` IPC request mechanism entirely, and request `FontAttributes`. This
+ allows us to set the currently selected NSFont on the NSFontManager, and also update the font manager with the
+ full dictionary of font attributes.
+
+ Test: FontAttributes.FontAttributesAfterChangingSelection
+
+ * Shared/WebCoreArgumentCoders.cpp:
+ (IPC::ArgumentCoder<FontAttributes>::encode):
+ (IPC::ArgumentCoder<FontAttributes>::decode):
+
+ Encode and decode the new `hasMultipleFonts` flag in FontAttributes. Additionally, take this opportunity to
+ modernize some of the decoding-side logic by decoding each member into a `std::optional` and creating the final
+ deserialized FontAttributes at the end.
+
+ * UIProcess/Cocoa/WebViewImpl.mm:
+ (WebKit::WebViewImpl::updateFontManagerIfNeeded):
+
+ Rather than grabbing just the font family and font size using `fontAtSelection`, request FontAttributes instead
+ and convert it to a NSDictionary to call `-[NSFontManager setSelectedAttributes:isMultiple:]`.
+
+ (WebKit::WebViewImpl::typingAttributesWithCompletionHandler):
+ (WebKit::WebViewImpl::changeFontAttributesFromSender):
+ (WebKit::WebViewImpl::changeFontFromFontManager):
+
+ Remove code to update the font manager after changing font attributes. This is unnecessary because the process
+ of executing an edit command in order to change typing style will trigger an editor state update anyways, which
+ then causes us to request new font attributes.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::requestFontAttributesAtSelectionStart):
+
+ Move the check for cached fontattributes to WebPageProxy, from WebViewImpl. This allows us to get rid of a
+ helper function on WebPageProxy to grab the current cached font attributes.
+
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::didUpdateEditorState):
+ * UIProcess/mac/WebPageProxyMac.mm:
+ (WebKit::WebPageProxy::didUpdateEditorState):
+
+ Set cached FontAttributes (if present) *prior* to dispatching a selection change. This allows any subsequent
+ request for font attributes at the selection to return immediately with the result.
+
+ (WebKit::WebPageProxy::fontAtSelection): Deleted.
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
+ Remove the `FontAtSelectionCallback` IPC message (and all associated code). This codepath was previously only
+ exercised when updating the font panel on macOS, and is no longer necessary because we just use
+ `requestFontAttributesAtSelectionStart` instead, which allows us to grab not only the NSFont, but also all
+ platform typing attributes at the selection.
+
+ * WebProcess/WebPage/mac/WebPageMac.mm:
+ (WebKit::WebPage::fontAtSelection): Deleted.
+
2022-01-12 Alex Christensen <achristen...@webkit.org>
Build WebKitSwift when building with make or build-webkit
Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (287952 => 287953)
--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2022-01-12 22:59:04 UTC (rev 287953)
@@ -2930,7 +2930,13 @@
void ArgumentCoder<FontAttributes>::encode(Encoder& encoder, const FontAttributes& attributes)
{
- encoder << attributes.backgroundColor << attributes.foregroundColor << attributes.fontShadow << attributes.hasUnderline << attributes.hasStrikeThrough << attributes.textLists;
+ encoder << attributes.backgroundColor;
+ encoder << attributes.foregroundColor;
+ encoder << attributes.fontShadow;
+ encoder << attributes.hasUnderline;
+ encoder << attributes.hasStrikeThrough;
+ encoder << attributes.hasMultipleFonts;
+ encoder << attributes.textLists;
encoder << attributes.horizontalAlignment;
encoder << attributes.subscriptOrSuperscript;
encoder << attributes.font;
@@ -2938,30 +2944,49 @@
std::optional<FontAttributes> ArgumentCoder<FontAttributes>::decode(Decoder& decoder)
{
- FontAttributes attributes;
+ std::optional<Color> backgroundColor;
+ decoder >> backgroundColor;
+ if (!backgroundColor)
+ return std::nullopt;
- if (!decoder.decode(attributes.backgroundColor))
+ std::optional<Color> foregroundColor;
+ decoder >> foregroundColor;
+ if (!foregroundColor)
return std::nullopt;
- if (!decoder.decode(attributes.foregroundColor))
+ std::optional<FontShadow> fontShadow;
+ decoder >> fontShadow;
+ if (!fontShadow)
return std::nullopt;
- if (!decoder.decode(attributes.fontShadow))
+ std::optional<bool> hasUnderline;
+ decoder >> hasUnderline;
+ if (!hasUnderline)
return std::nullopt;
- if (!decoder.decode(attributes.hasUnderline))
+ std::optional<bool> hasStrikeThrough;
+ decoder >> hasStrikeThrough;
+ if (!hasStrikeThrough)
return std::nullopt;
- if (!decoder.decode(attributes.hasStrikeThrough))
+ std::optional<bool> hasMultipleFonts;
+ decoder >> hasMultipleFonts;
+ if (!hasMultipleFonts)
return std::nullopt;
- if (!decoder.decode(attributes.textLists))
+ std::optional<Vector<TextList>> textLists;
+ decoder >> textLists;
+ if (!textLists)
return std::nullopt;
- if (!decoder.decode(attributes.horizontalAlignment))
+ std::optional<FontAttributes::HorizontalAlignment> horizontalAlignment;
+ decoder >> horizontalAlignment;
+ if (!horizontalAlignment)
return std::nullopt;
- if (!decoder.decode(attributes.subscriptOrSuperscript))
+ std::optional<FontAttributes::SubscriptOrSuperscript> subscriptOrSuperscript;
+ decoder >> subscriptOrSuperscript;
+ if (!subscriptOrSuperscript)
return std::nullopt;
std::optional<RefPtr<Font>> font;
@@ -2969,9 +2994,7 @@
if (!font)
return std::nullopt;
- attributes.font = WTFMove(*font);
-
- return attributes;
+ return { { WTFMove(*font), WTFMove(*backgroundColor), WTFMove(*foregroundColor), WTFMove(*fontShadow), *subscriptOrSuperscript, *horizontalAlignment, WTFMove(*textLists), *hasUnderline, *hasStrikeThrough, *hasMultipleFonts } };
}
#if ENABLE(ATTACHMENT_ELEMENT)
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (287952 => 287953)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2022-01-12 22:59:04 UTC (rev 287953)
@@ -3055,32 +3055,21 @@
if (!fontPanelIsVisible && !m_page->editorState().isContentRichlyEditable)
return;
- m_page->fontAtSelection([](const FontInfo& fontInfo, double fontSize, bool selectionHasMultipleFonts) {
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- NSDictionary *attributeDictionary = (__bridge NSDictionary *)fontInfo.fontAttributeDictionary.get();
- if (!attributeDictionary)
+ m_page->requestFontAttributesAtSelectionStart([] (auto& attributes) {
+ if (!attributes.font)
return;
- auto font = fontWithAttributes(attributeDictionary, fontSize);
- if (!font)
+ auto nsFont = (__bridge NSFont *)attributes.font->getCTFont();
+ if (!nsFont)
return;
- [NSFontManager.sharedFontManager setSelectedFont:font isMultiple:selectionHasMultipleFonts];
-
- END_BLOCK_OBJC_EXCEPTIONS
+ [NSFontManager.sharedFontManager setSelectedFont:nsFont isMultiple:attributes.hasMultipleFonts];
+ [NSFontManager.sharedFontManager setSelectedAttributes:attributes.createDictionary().get() isMultiple:attributes.hasMultipleFonts];
});
}
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) {
auto attributesAsDictionary = attributes.createDictionary();
completion(attributesAsDictionary.get());
@@ -3112,7 +3101,6 @@
return;
m_page->changeFontAttributes(WebCore::computedFontAttributeChanges(NSFontManager.sharedFontManager, sender));
- updateFontManagerIfNeeded();
}
void WebViewImpl::changeFontFromFontManager()
@@ -3122,7 +3110,6 @@
return;
m_page->changeFont(WebCore::computedFontChanges(NSFontManager.sharedFontManager));
- updateFontManagerIfNeeded();
}
static NSMenuItem *menuItem(id <NSValidatedUserInterfaceItem> item)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (287952 => 287953)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2022-01-12 22:59:04 UTC (rev 287953)
@@ -2559,6 +2559,11 @@
if (!hasRunningProcess())
return callback({ });
+ if (auto attributes = m_cachedFontAttributesAtSelectionStart) {
+ callback(*attributes);
+ return;
+ }
+
sendWithAsyncReply(Messages::WebPage::RequestFontAttributesAtSelectionStart(), [this, protectedThis = Ref { *this }, callback = WTFMove(callback)] (const WebCore::FontAttributes& attributes) mutable {
m_cachedFontAttributesAtSelectionStart = attributes;
callback(attributes);
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (287952 => 287953)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2022-01-12 22:59:04 UTC (rev 287953)
@@ -788,8 +788,6 @@
void setBaseWritingDirection(WebCore::WritingDirection);
- std::optional<WebCore::FontAttributes> cachedFontAttributesAtSelectionStart() const { return m_cachedFontAttributesAtSelectionStart; }
-
#if HAVE(TOUCH_BAR)
const TouchBarMenuData& touchBarMenuData() const { return m_touchBarMenuData; }
#endif
@@ -991,7 +989,6 @@
#if PLATFORM(MAC)
void attributedSubstringForCharacterRangeAsync(const EditingRange&, CompletionHandler<void(const WebCore::AttributedString&, const EditingRange&)>&&);
- void fontAtSelection(CompletionHandler<void(const FontInfo&, double, bool)>&&);
void startWindowDrag();
NSWindow *platformWindow();
@@ -2345,9 +2342,6 @@
void didReceiveEvent(uint32_t opaqueType, bool handled);
void didUpdateRenderingAfterCommittingLoad();
-#if PLATFORM(MAC)
- void fontAtSelectionCallback(const FontInfo&, double, bool, CallbackID);
-#endif
#if PLATFORM(IOS_FAMILY)
void interpretKeyEvent(const EditorState&, bool isCharEvent, CompletionHandler<void(bool)>&&);
void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect, WebCore::RouteSharingPolicy, const String&);
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (287952 => 287953)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2022-01-12 22:59:04 UTC (rev 287953)
@@ -1051,10 +1051,10 @@
if (newEditorState.shouldIgnoreSelectionChanges)
return;
+ updateFontAttributesAfterEditorStateChange();
// We always need to notify the client on iOS to make sure the selection is redrawn,
// even during composition to support phrase boundary gesture.
pageClient().selectionDidChange();
- updateFontAttributesAfterEditorStateChange();
}
void WebPageProxy::dispatchDidUpdateEditorState()
Modified: trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm (287952 => 287953)
--- trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm 2022-01-12 22:59:04 UTC (rev 287953)
@@ -206,16 +206,6 @@
sendWithAsyncReply(Messages::WebPage::AttributedSubstringForCharacterRangeAsync(range), WTFMove(callbackFunction));
}
-void WebPageProxy::fontAtSelection(CompletionHandler<void(const FontInfo&, double, bool)>&& callback)
-{
- if (!hasRunningProcess()) {
- callback({ }, 0, false);
- return;
- }
-
- sendWithAsyncReply(Messages::WebPage::FontAtSelection(), WTFMove(callback));
-}
-
String WebPageProxy::stringSelectionForPasteboard()
{
String value;
@@ -573,9 +563,9 @@
if (newEditorState.shouldIgnoreSelectionChanges)
return;
-
+
+ updateFontAttributesAfterEditorStateChange();
pageClient().selectionDidChange();
- updateFontAttributesAfterEditorStateChange();
}
void WebPageProxy::startWindowDrag()
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (287952 => 287953)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2022-01-12 22:59:04 UTC (rev 287953)
@@ -954,7 +954,6 @@
#if PLATFORM(MAC)
void attributedSubstringForCharacterRangeAsync(const EditingRange&, CompletionHandler<void(const WebCore::AttributedString&, const EditingRange&)>&&);
- void fontAtSelection(CompletionHandler<void(const FontInfo&, double, bool)>&&);
void requestAcceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent&);
#endif
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (287952 => 287953)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2022-01-12 22:59:04 UTC (rev 287953)
@@ -467,7 +467,6 @@
#endif
#if PLATFORM(MAC)
AttributedSubstringForCharacterRangeAsync(struct WebKit::EditingRange range) -> (struct WebCore::AttributedString string, struct WebKit::EditingRange range) Async
- FontAtSelection() -> (struct WebKit::FontInfo fontInfo, double fontSize, bool selectionHasMultipleFonts) Async
RequestAcceptsFirstMouse(int eventNumber, WebKit::WebMouseEvent event)
#endif
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm (287952 => 287953)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2022-01-12 22:59:04 UTC (rev 287953)
@@ -359,39 +359,6 @@
completionHandler({ WTFMove(attributedString), nil }, rangeToSend);
}
-void WebPage::fontAtSelection(CompletionHandler<void(const FontInfo&, double, bool)>&& completionHandler)
-{
- bool selectionHasMultipleFonts = false;
- auto& frame = m_page->focusController().focusedOrMainFrame();
-
- if (frame.selection().selection().isNone()) {
- completionHandler({ }, 0, false);
- return;
- }
-
- auto font = frame.editor().fontForSelection(selectionHasMultipleFonts);
- if (!font) {
- completionHandler({ }, 0, false);
- return;
- }
-
- auto ctFont = font->getCTFont();
- if (!ctFont) {
- completionHandler({ }, 0, false);
- return;
- }
-
- auto fontDescriptor = adoptCF(CTFontCopyFontDescriptor(ctFont));
- if (!fontDescriptor) {
- completionHandler({ }, 0, false);
- return;
- }
-
- completionHandler({ adoptCF(CTFontDescriptorCopyAttributes(fontDescriptor.get())) }, CTFontGetSize(ctFont), selectionHasMultipleFonts);
-}
-
-
-
#if ENABLE(PDFKIT_PLUGIN)
DictionaryPopupInfo WebPage::dictionaryPopupInfoForSelectionInPDFPlugin(PDFSelection *selection, PDFPlugin& pdfPlugin, NSDictionary *options, WebCore::TextIndicatorPresentationTransition presentationTransition)
Modified: trunk/Tools/ChangeLog (287952 => 287953)
--- trunk/Tools/ChangeLog 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Tools/ChangeLog 2022-01-12 22:59:04 UTC (rev 287953)
@@ -1,3 +1,57 @@
+2022-01-12 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [macOS] [WK2] NSFontPanel UI (font color, text decorations, font shadow) doesn't update on selection change
+ https://bugs.webkit.org/show_bug.cgi?id=190120
+ rdar://44897405
+
+ Reviewed by Darin Adler.
+
+ Augment and adjust some existing API tests. See WebKit/ChangeLog for more information.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/FontAttributes.mm:
+
+ Augment an existing API test, FontAttributes.FontAttributesAfterChangingSelection, to additionally check shared
+ NSFontManager state (foreground/background color, shadow color and radius, etc.) on macOS.
+
+ (TestWebKitAPI::webViewForTestingFontAttributes):
+
+ On macOS, additionally make the font panel visible so that we can test font panel state.
+
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/Tests/mac/FontManagerTests.mm:
+
+ Relax some constraints on FontManagerTests.ChangeFontWithPanel, so that it verifies that the platform font in
+ the NSFontManager has all of the same attributes as the expectation, rather than being equal to the exact same
+ font object.
+
+ Adjust an existing API test, FontManagerTests.ChangeAttributesWithFontEffectsBox, to also vary the length of
+ font shadows. Updating font attributes on the font manager exposed an issue with this API test where, because
+ the font panel's attributes are never updated, the value of the shadow length slider remains at the default
+ value of 0.125, producing a shadow length of 1.25px. However, now that the selection moves to non-shadowed text
+ before moving to shadowed text again, we need to explicitly set the shadow length slider's value when testing
+ the second shadowed text selection.
+
+ (webViewForFontManagerTesting):
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/mac/NSFontPanelTesting.h:
+ * TestWebKitAPI/mac/NSFontPanelTesting.mm:
+
+ Add some additional testing helpers to query the state of controls in the font panel (e.g. font shadow sliders,
+ foreground color well, and strike-through/underline popup menu state).
+
+ (-[NSFontPanel underlineToolbarButton]):
+ (-[NSFontPanel strikeThroughToolbarButton]):
+ (-[NSFontPanel foregroundColorToolbarColorWell]):
+ (-[NSFontPanel chooseUnderlineMenuItemWithTitle:]):
+ (-[NSFontPanel chooseStrikeThroughMenuItemWithTitle:]):
+ (-[NSFontPanel shadowLengthSlider]):
+ (-[NSFontPanel hasShadow]):
+ (-[NSFontPanel shadowLength]):
+ (-[NSFontPanel setShadowLength:]):
+ (-[NSFontPanel hasUnderline]):
+ (-[NSFontPanel hasStrikeThrough]):
+ (-[NSFontPanel foregroundColor]):
+
2022-01-12 Jonathan Bedard <jbed...@apple.com>
[EWS] Accept GitHub hooks (Part 1)
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FontAttributes.mm (287952 => 287953)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FontAttributes.mm 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FontAttributes.mm 2022-01-12 22:59:04 UTC (rev 287953)
@@ -177,6 +177,11 @@
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 320, 500)]);
[webView synchronouslyLoadTestPageNamed:testPageName];
[webView stringByEvaluatingJavaScript:@"document.body.focus()"];
+#if PLATFORM(MAC)
+ NSFontManager *fontManager = NSFontManager.sharedFontManager;
+ [[fontManager fontPanel:YES] setIsVisible:YES];
+ fontManager.target = webView.get();
+#endif
return webView;
}
@@ -186,6 +191,31 @@
auto webView = webViewForTestingFontAttributes(@"rich-text-attributes");
[webView setUIDelegate:delegate.get()];
+ auto expectFontManagerState = [] (FontExpectation expectedFont, ColorExpectation expectedColor, std::optional<ShadowExpectation> expectedShadow, BOOL underline, BOOL strikeThrough, BOOL expectMultipleFonts) {
+#if PLATFORM(MAC)
+ NSFontManager *fontManager = NSFontManager.sharedFontManager;
+ NSFontPanel *fontPanel = NSFontPanel.sharedFontPanel;
+ if (expectedShadow) {
+ EXPECT_TRUE(fontPanel.hasShadow);
+ EXPECT_LT(std::abs(expectedShadow->opacity - fontPanel.shadowOpacity), 0.0001);
+ EXPECT_EQ(expectedShadow->blurRadius, fontPanel.shadowBlur);
+ } else
+ EXPECT_FALSE(fontPanel.hasShadow);
+ EXPECT_EQ(underline, fontPanel.hasUnderline);
+ EXPECT_EQ(strikeThrough, fontPanel.hasStrikeThrough);
+ checkColor([fontPanel.foregroundColor colorUsingColorSpace:NSColorSpace.sRGBColorSpace], { WTFMove(expectedColor) });
+ checkFont(fontManager.selectedFont, WTFMove(expectedFont));
+ EXPECT_EQ(expectMultipleFonts, fontManager.multiple);
+#else
+ UNUSED_PARAM(expectedFont);
+ UNUSED_PARAM(expectedColor);
+ UNUSED_PARAM(expectedShadow);
+ UNUSED_PARAM(underline);
+ UNUSED_PARAM(strikeThrough);
+ UNUSED_PARAM(expectMultipleFonts);
+#endif
+ };
+
{
[webView selectElementWithIdentifier:@"one"];
NSDictionary *attributes = [webView fontAttributesAfterNextPresentationUpdate];
@@ -197,6 +227,7 @@
EXPECT_EQ(NSUnderlineStyleSingle, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Helvetica-Bold", 48 }, { 227, 36, 0, 1 }, std::nullopt, NO, YES, NO);
}
{
[webView selectElementWithIdentifier:@"two"];
@@ -209,6 +240,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleSingle, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Helvetica-Bold", 48 }, { 102, 157, 52, 1 }, { { 0.470588, 5 } }, YES, NO, NO);
}
{
[webView selectElementWithIdentifier:@"three"];
@@ -221,6 +253,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Menlo-Italic", 18 }, { 255, 106, 0, 1 }, std::nullopt, NO, NO, NO);
}
{
[webView selectElementWithIdentifier:@"four"];
@@ -233,6 +266,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Avenir-Book", 24 }, { 255, 255, 255, 1 }, std::nullopt, NO, NO, NO);
}
{
[webView selectElementWithIdentifier:@"five"];
@@ -245,6 +279,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "TimesNewRomanPS-BoldMT", 24 }, { 131, 16, 0, 1 }, std::nullopt, NO, NO, NO);
}
{
[webView selectElementWithIdentifier:@"six"];
@@ -257,6 +292,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Avenir-Black", 18 }, { 255, 64, 19, 1 }, std::nullopt, NO, NO, NO);
}
{
[webView selectElementWithIdentifier:@"seven"];
@@ -269,6 +305,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(-1, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Avenir-BookOblique", 12 }, { 235, 235, 235, 1 }, std::nullopt, NO, NO, NO);
}
{
[webView selectElementWithIdentifier:@"eight"];
@@ -281,6 +318,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(1, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Avenir-Book", 12 }, { 0, 0, 0, 1 }, std::nullopt, NO, NO, NO);
}
{
[webView selectElementWithIdentifier:@"nine"];
@@ -293,6 +331,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Georgia", 36 }, { 0, 0, 0, 1 }, { { 0.658824, 9 } }, NO, NO, NO);
}
{
[webView selectElementWithIdentifier:@"ten"];
@@ -305,6 +344,7 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Avenir-BookOblique", 18 }, { 0, 0, 0, 1 }, std::nullopt, NO, NO, NO);
}
{
[webView selectElementWithIdentifier:@"eleven"];
@@ -317,7 +357,13 @@
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
+ expectFontManagerState({ "Menlo-Regular", 20 }, { 0, 0, 0, 1 }, std::nullopt, NO, NO, NO);
}
+#if PLATFORM(MAC)
+ [webView selectAll:nil];
+ [webView waitForNextPresentationUpdate];
+ EXPECT_TRUE(NSFontManager.sharedFontManager.multiple);
+#endif
}
TEST(FontAttributes, NestedTextListsWithHorizontalAlignment)
Modified: trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm (287952 => 287953)
--- trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm 2022-01-12 22:59:04 UTC (rev 287953)
@@ -94,6 +94,7 @@
[webView synchronouslyLoadHTMLString:markup];
[webView stringByEvaluatingJavaScript:@"document.body.focus()"];
[webView _setEditable:YES];
+ [[fontManager fontPanel:YES] setIsVisible:YES];
fontManager.target = webView.get();
return webView;
}
@@ -196,6 +197,15 @@
[fontPanel setIsVisible:YES];
[webView waitForNextPresentationUpdate];
+ auto expectSameAttributes = [](NSFont *font1, NSFont *font2) {
+ auto fontAttributes1 = font1.fontDescriptor.fontAttributes;
+ auto fontAttributes2 = font2.fontDescriptor.fontAttributes;
+ BOOL attributesAreEqual = [fontAttributes1 isEqualToDictionary:fontAttributes2];
+ EXPECT_TRUE(attributesAreEqual);
+ if (!attributesAreEqual)
+ NSLog(@"Expected %@ to have the same attributes as %@", font1, font2);
+ };
+
NSFont *largeHelveticaFont = [NSFont fontWithName:@"Helvetica" size:20];
[fontPanel setPanelFont:largeHelveticaFont isMultiple:NO];
[webView selectWord:nil];
@@ -204,7 +214,7 @@
EXPECT_WK_STREQ("Helvetica", [webView stylePropertyAtSelectionStart:@"font-family"]);
EXPECT_WK_STREQ("20px", [webView stylePropertyAtSelectionStart:@"font-size"]);
EXPECT_WK_STREQ("400", [webView stylePropertyAtSelectionStart:@"font-weight"]);
- EXPECT_EQ(largeHelveticaFont, fontManager.selectedFont);
+ expectSameAttributes(largeHelveticaFont, fontManager.selectedFont);
NSFont *smallBoldTimesFont = [fontManager fontWithFamily:@"Times New Roman" traits:NSBoldFontMask weight:NSFontWeightBold size:10];
[fontPanel setPanelFont:smallBoldTimesFont isMultiple:NO];
@@ -214,7 +224,7 @@
EXPECT_WK_STREQ("\"Times New Roman\"", [webView stylePropertyAtSelectionStart:@"font-family"]);
EXPECT_WK_STREQ("10px", [webView stylePropertyAtSelectionStart:@"font-size"]);
EXPECT_WK_STREQ("700", [webView stylePropertyAtSelectionStart:@"font-weight"]);
- EXPECT_EQ(smallBoldTimesFont, fontManager.selectedFont);
+ expectSameAttributes(smallBoldTimesFont, fontManager.selectedFont);
NSFont *boldItalicArialFont = [fontManager fontWithFamily:@"Arial" traits:NSBoldFontMask | NSItalicFontMask weight:NSFontWeightBold size:14];
[fontPanel setPanelFont:boldItalicArialFont isMultiple:NO];
@@ -224,7 +234,7 @@
EXPECT_WK_STREQ("Arial", [webView stylePropertyAtSelectionStart:@"font-family"]);
EXPECT_WK_STREQ("14px", [webView stylePropertyAtSelectionStart:@"font-size"]);
EXPECT_WK_STREQ("700", [webView stylePropertyAtSelectionStart:@"font-weight"]);
- EXPECT_EQ(boldItalicArialFont, fontManager.selectedFont);
+ expectSameAttributes(boldItalicArialFont, fontManager.selectedFont);
NSFont *largeItalicLightAvenirFont = [fontManager fontWithFamily:@"Avenir" traits:NSItalicFontMask weight:NSFontWeightLight size:24];
[fontPanel setPanelFont:largeItalicLightAvenirFont isMultiple:NO];
@@ -234,7 +244,7 @@
EXPECT_WK_STREQ("Avenir-LightOblique", [webView stylePropertyAtSelectionStart:@"font-family"]);
EXPECT_WK_STREQ("24px", [webView stylePropertyAtSelectionStart:@"font-size"]);
EXPECT_WK_STREQ("400", [webView stylePropertyAtSelectionStart:@"font-weight"]);
- EXPECT_EQ(largeItalicLightAvenirFont, fontManager.selectedFont);
+ expectSameAttributes(largeItalicLightAvenirFont, fontManager.selectedFont);
}
TEST(FontManagerTests, ChangeAttributesWithFontEffectsBox)
@@ -283,13 +293,14 @@
[webView selectNextWord];
fontPanel.shadowBlur = 8;
fontPanel.shadowOpacity = 1;
+ fontPanel.shadowLength = 0.25;
[fontPanel toggleShadow];
EXPECT_WK_STREQ("baz", [webView selectedText]);
- EXPECT_WK_STREQ("rgb(0, 0, 0) 0px 1.25px 8px", textShadowAroundSelection());
+ EXPECT_WK_STREQ("rgb(0, 0, 0) 0px 2.5px 8px", textShadowAroundSelection());
{
NSShadow *shadow = [webView typingAttributes][NSShadowAttributeName];
EXPECT_EQ(shadow.shadowOffset.width, 0);
- EXPECT_EQ(shadow.shadowOffset.height, 1.25);
+ EXPECT_EQ(shadow.shadowOffset.height, 2.5);
EXPECT_EQ(shadow.shadowBlurRadius, 8);
EXPECT_TRUE([shadow.shadowColor isEqual:[NSColor colorWithRed:0 green:0 blue:0 alpha:1]]);
}
@@ -302,11 +313,12 @@
[webView selectAll:nil];
fontPanel.shadowBlur = 5;
fontPanel.shadowOpacity = 0.2;
+ fontPanel.shadowLength = 0.5;
[fontPanel toggleShadow];
[fontPanel chooseUnderlineMenuItemWithTitle:@"single"];
[fontPanel chooseStrikeThroughMenuItemWithTitle:@"single"];
EXPECT_WK_STREQ("foo bar baz", [webView selectedText]);
- EXPECT_WK_STREQ("rgba(0, 0, 0, 0.2) 0px 1.25px 5px", textShadowAroundSelection());
+ EXPECT_WK_STREQ("rgba(0, 0, 0, 0.2) 0px 5px 5px", textShadowAroundSelection());
EXPECT_WK_STREQ("underline line-through", textDecorationsAroundSelection());
{
NSDictionary *typingAttributes = [webView typingAttributes];
@@ -315,7 +327,7 @@
NSShadow *shadow = typingAttributes[NSShadowAttributeName];
EXPECT_EQ(shadow.shadowOffset.width, 0);
- EXPECT_EQ(shadow.shadowOffset.height, 1.25);
+ EXPECT_EQ(shadow.shadowOffset.height, 5);
EXPECT_EQ(shadow.shadowBlurRadius, 5);
EXPECT_TRUE([shadow.shadowColor isEqual:[NSColor colorWithRed:0 green:0 blue:0 alpha:0.2]]);
}
Modified: trunk/Tools/TestWebKitAPI/mac/NSFontPanelTesting.h (287952 => 287953)
--- trunk/Tools/TestWebKitAPI/mac/NSFontPanelTesting.h 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Tools/TestWebKitAPI/mac/NSFontPanelTesting.h 2022-01-12 22:59:04 UTC (rev 287953)
@@ -31,7 +31,13 @@
@property (nonatomic) double shadowOpacity;
@property (nonatomic) double shadowBlur;
+@property (nonatomic) double shadowLength;
+@property (nonatomic, readonly) BOOL hasShadow;
+@property (nonatomic, readonly) BOOL hasUnderline;
+@property (nonatomic, readonly) BOOL hasStrikeThrough;
+@property (nonatomic, readonly) NSColor *foregroundColor;
+
- (void)toggleShadow;
- (void)chooseUnderlineMenuItemWithTitle:(NSString *)itemTitle;
- (void)chooseStrikeThroughMenuItemWithTitle:(NSString *)itemTitle;
Modified: trunk/Tools/TestWebKitAPI/mac/NSFontPanelTesting.mm (287952 => 287953)
--- trunk/Tools/TestWebKitAPI/mac/NSFontPanelTesting.mm 2022-01-12 22:49:05 UTC (rev 287952)
+++ trunk/Tools/TestWebKitAPI/mac/NSFontPanelTesting.mm 2022-01-12 22:59:04 UTC (rev 287953)
@@ -65,9 +65,24 @@
return static_cast<NSBox *>(result);
}
+- (NSPopUpButton *)underlineToolbarButton
+{
+ return (NSPopUpButton *)[self _toolbarItemWithIdentifier:@"NSFontPanelUnderlineToolbarItem"].view;
+}
+
+- (NSPopUpButton *)strikeThroughToolbarButton
+{
+ return (NSPopUpButton *)[self _toolbarItemWithIdentifier:@"NSFontPanelStrikethroughToolbarItem"].view;
+}
+
+- (NSColorWell *)foregroundColorToolbarColorWell
+{
+ return (NSColorWell *)[self _toolbarItemWithIdentifier:@"NSFontPanelTextColorToolbarItem"].view;
+}
+
- (void)chooseUnderlineMenuItemWithTitle:(NSString *)itemTitle
{
- NSPopUpButton *button = (NSPopUpButton *)[self _toolbarItemWithIdentifier:@"NSFontPanelUnderlineToolbarItem"].view;
+ NSPopUpButton *button = [self underlineToolbarButton];
[button selectItem:findMenuItemWithTitle(button, itemTitle)];
[self.fontEffectsBox _openEffectsButton:button];
[self _didChangeAttributes];
@@ -75,7 +90,7 @@
- (void)chooseStrikeThroughMenuItemWithTitle:(NSString *)itemTitle
{
- NSPopUpButton *button = (NSPopUpButton *)[self _toolbarItemWithIdentifier:@"NSFontPanelStrikethroughToolbarItem"].view;
+ NSPopUpButton *button = [self strikeThroughToolbarButton];
[button selectItem:findMenuItemWithTitle(button, itemTitle)];
[self.fontEffectsBox _openEffectsButton:button];
[self _didChangeAttributes];
@@ -98,11 +113,21 @@
return (NSSlider *)findSubviewOfClass([self _toolbarItemWithIdentifier:@"NSFontPanelShadowOpacityToolbarItem"].view, NSSlider.class);
}
+- (NSSlider *)shadowLengthSlider
+{
+ return (NSSlider *)findSubviewOfClass([self _toolbarItemWithIdentifier:@"NSFontPanelShadowOffsetToolbarItem"].view, NSSlider.class);
+}
+
- (NSButton *)shadowToggleButton
{
return (NSButton *)[self _toolbarItemWithIdentifier:@"NSFontPanelShadowToggleToolbarItem"].view;
}
+- (BOOL)hasShadow
+{
+ return self.shadowToggleButton.state == NSControlStateValueOn;
+}
+
- (void)toggleShadow
{
NSButton *shadowToggleButton = self.shadowToggleButton;
@@ -110,6 +135,16 @@
[self _didChangeAttributes];
}
+- (double)shadowLength
+{
+ return self.shadowLengthSlider.doubleValue;
+}
+
+- (void)setShadowLength:(double)shadowLength
+{
+ self.shadowLengthSlider.doubleValue = shadowLength;
+}
+
- (double)shadowOpacity
{
return self.shadowOpacitySlider.doubleValue;
@@ -143,6 +178,23 @@
return nil;
}
+- (BOOL)hasUnderline
+{
+ NSMenuItem *singleUnderlineMenuItem = [self.underlineToolbarButton itemAtIndex:2];
+ return singleUnderlineMenuItem.state == NSControlStateValueOn;
+}
+
+- (BOOL)hasStrikeThrough
+{
+ NSMenuItem *singleStrikeThroughMenuItem = [self.strikeThroughToolbarButton itemAtIndex:2];
+ return singleStrikeThroughMenuItem.state == NSControlStateValueOn;
+}
+
+- (NSColor *)foregroundColor
+{
+ return self.foregroundColorToolbarColorWell.color;
+}
+
@end
#endif // PLATFORM(MAC)