WebKit Bugzilla
Attachment 348984 Details for
Bug 189295
: [macOS] Cannot change font size at selection until font panel is shown
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Rebase on trunk
bug-189295-20180905172441.patch (text/plain), 78.34 KB, created by
Wenson Hsieh
on 2018-09-05 17:24:42 PDT
(
hide
)
Description:
Rebase on trunk
Filename:
MIME Type:
Creator:
Wenson Hsieh
Created:
2018-09-05 17:24:42 PDT
Size:
78.34 KB
patch
obsolete
>Subversion Revision: 235715 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 99072acb92685dde08ba0ebe077c4d5d643d1ffd..4a32c53c2d737686c5c2bc30d8313f0fa7e1d688 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,142 @@ >+2018-09-05 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ [macOS] Cannot change font size at selection until font panel is shown >+ https://bugs.webkit.org/show_bug.cgi?id=189295 >+ <rdar://problem/35593389> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Currently, attempting to alter the font size of currently selected editable text in WKWebView via menu items >+ will fail if the font panel has never been shown. This is because WebViewImpl::changeFontFromFontPanel, which is >+ responsible for converting the current font at the selection to the new font using -[NSFontManager convertFont:] >+ bails as a result of NSFontManager's currently selected font always being nil. >+ >+ WKWebView is responsible for keeping NSFontManager up-to-date with the currently selected font; in fact, this >+ was initially the case in r180465, which introduced NSFontManager support in WebKit2 by propagating EditorState >+ updates that contained font information for the current selection. However, this regressed performance due to >+ selected font computation triggering extra layout passes; r180768 addressed this by introducing a mechanism for >+ requesting the font at the current selection, and only updating NSFontManager with the new selected font when >+ the shared font panel is visible (determined by KVO on NSFontPanel). However, this again regressed WKWebView >+ launch performance, due to KVO registration always forcing the shared NSFontPanel to be created. r182037 >+ addressed this by only registering for KVO on the font panel if the WKWebView has been made editable (SPI on >+ WKWebView). >+ >+ This leads to two issues when attempting to alter font attributes using macOS UI: (1) in web views that have not >+ been made editable using SPI, showing the font panel and attempting to change the font fails due to the selected >+ font staying nil, because we've never begun registering for KVO notifications on the font panel so we don't try >+ to keep the font manager up to date. (2) Even if the web view is made editable, if the font panel is never >+ shown, then the font manager still won't be kept up to date with the current selection, so changing fonts using >+ menu items still does not work. >+ >+ We fix both of these problems by refactoring font manager support on WebKit2 such that an up-to-date selected >+ font in the UI process is no longer necessary in order to alter the font at the current selection. To do this, >+ we figure out what changes the NSFontManager would've made to the currently selected font in the UI process, and >+ then propagate this information to the web process, where we convert this information into an EditingStyle which >+ we apply to the current selection. >+ >+ The code to both determine the attributes changed by NSFontManager and to convert these attributes into editing >+ styles to be applied via Editor already exists in WebKitLegacy, in WebHTMLView.mm. This patch moves this >+ existing logic into WebCore and teases it apart into two portions: the first portion probes NSFontManager to >+ determine which aspects of the font changed and constructs FontChanges, which captures these differences. The >+ second portion maps FontChanges to an EditingStyle, which can then be applied to the current selection. In >+ WebKitLegacy, we construct FontChanges using the font manager, and then immediately use it to create and apply >+ an EditingStyle. In WebKit, we construct FontChanges in the UI process using the font manager, and then send >+ this over to the web process via WebPage::changeFont, which then creates and applies the EditingStyle. >+ >+ Note that this patch also introduces FontAttributeChanges, which is similar in concept to FontChanges, but >+ captures a broader range of changes possible via NSFontPanel. This was done so that we can eliminate all of the >+ font manager probing code (along with the two specimen fonts) from WebHTMLView, but is also necessary in order >+ to allow changing font shadow, strikethrough, and underlines via the font panel to work in WebKit2. This will be >+ fixed in a followup, by making FontAttributeChanges IPC encodable and by making WKWebView/WKView respond to the >+ -changeAttributes: selector. >+ >+ Changes in behavior to WebKit2 are covered by new API tests; legacy WebKit behavior should remain unchanged. >+ >+ Tests: FontManagerTests.ChangeFontSizeWithMenuItems >+ FontManagerTests.ChangeFontWithPanel >+ >+ * SourcesCocoa.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * editing/Editor.h: >+ >+ Remove applyFontStyles. >+ >+ * editing/FontAttributeChanges.cpp: Added. >+ (WebCore::FontChanges::platformFontFamilyNameForCSS const): >+ >+ Given a font family name and a font name, returns the string to use as the "font-family" style property value. >+ Originally from WebHTMLView.mm. >+ >+ (WebCore::FontChanges::createEditingStyle const): >+ >+ Converts font changes to an EditingStyle that can be used to apply these changes. >+ >+ (WebCore::FontChanges::createStyleProperties const): >+ >+ Introduce FontChanges, which encapsulates changes which are to be applied to the font in the current selection. >+ >+ (WebCore::cssValueListForShadow): >+ (WebCore::FontAttributeChanges::createEditingStyle const): >+ >+ Converts font attribute changes to an EditingStyle that can be used to apply these changes. >+ >+ * editing/FontAttributeChanges.h: Added. >+ >+ Introduce FontAttributeChanges, which encapsulates changes which are to be applied to the font attributes in the >+ current selection. This includes a set of FontChanges, as well as additional attributes such as strike-through >+ and underlines. >+ >+ (WebCore::FontChanges::setFontName): >+ (WebCore::FontChanges::setFontFamily): >+ (WebCore::FontChanges::setFontSize): >+ (WebCore::FontChanges::setFontSizeDelta): >+ (WebCore::FontChanges::setBold): >+ (WebCore::FontChanges::setItalic): >+ (WebCore::FontAttributeChanges::setVerticalAlign): >+ (WebCore::FontAttributeChanges::setBackgroundColor): >+ (WebCore::FontAttributeChanges::setForegroundColor): >+ (WebCore::FontAttributeChanges::setShadow): >+ (WebCore::FontAttributeChanges::setStrikeThrough): >+ (WebCore::FontAttributeChanges::setUnderline): >+ (WebCore::FontAttributeChanges::setFontChanges): >+ >+ Setters for FontChanges and FontAttributeChanges. Initially, most of these values are optional, indicating that >+ there should be no change. An exception to this is vertical align, which defaults to "baseline". This is >+ existing behavior in WebKit1, and it's unclear whether this was intended; since this patch aims to preserve >+ legacy WebKit behavior, we will always set the vertical alignment to "baseline" even if it hasn't been >+ explicitly specified via the font panel. This behavior seems like something we should revisit in the future. >+ >+ (WebCore::FontChanges::encode const): >+ (WebCore::FontChanges::decode): >+ >+ Add encoding/decoding support to FontChanges, so that it can be sent over IPC for WebKit2. >+ >+ * editing/cocoa/FontAttributeChangesCocoa.mm: Added. >+ (WebCore::FontChanges::platformFontFamilyNameForCSS const): >+ >+ Helper method to determine whether the font family or the font name should be used, by looking up the PostScript >+ font name using a FontDescriptor and comparing it against the result of -[NSFont fontName]. This logic was >+ originally in WebHTMLView.mm. >+ >+ * editing/mac/EditorMac.mm: >+ (WebCore::Editor::applyFontStyles): Deleted. >+ * platform/mac/WebCoreNSFontManagerExtras.h: Added. >+ * platform/mac/WebCoreNSFontManagerExtras.mm: Added. >+ >+ Add helper functions to compute FontChanges and FontAttributeChanges from NSFontManager. >+ >+ (WebCore::firstFontConversionSpecimen): >+ (WebCore::secondFontConversionSpecimen): >+ >+ Two "specimen fonts" used to determine what changes NSFontManager or NSFontPanel makes when performing font or >+ font attribute conversion. Moved from WebHTMLView.mm. >+ >+ (WebCore::computedFontChanges): >+ (WebCore::computedFontAttributeChanges): >+ >+ Moved here from WebHTMLView.mm. Instead of converting font attributes to NSStrings and setting properties on >+ DOMCSSStyleDeclaration, we instead specify properties on MutableStyleProperties using CSSValues. >+ > 2018-09-05 Youenn Fablet <youenn@apple.com> > > Expose RTCRtpSender.setParameters >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 5a5f554d1e5a293e1df79a0821ea69c044aabc4c..b49853ca7c7c41bbde281457ce1cc60da6fe40b8 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,37 @@ >+2018-09-05 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ [macOS] Cannot change font size at selection until font panel is shown >+ https://bugs.webkit.org/show_bug.cgi?id=189295 >+ <rdar://problem/35593389> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Refactors NSFontManager support in WebKit2. See WebCore ChangeLog for more details. >+ >+ * Scripts/webkit/messages.py: >+ * UIProcess/API/Cocoa/WKWebView.mm: >+ (-[WKWebView changeFont:]): >+ * UIProcess/API/mac/WKView.mm: >+ (-[WKView changeFont:]): >+ * UIProcess/Cocoa/WebViewImpl.h: >+ * UIProcess/Cocoa/WebViewImpl.mm: >+ (WebKit::WebViewImpl::changeFontFromFontManager): >+ (WebKit::WebViewImpl::changeFontFromFontPanel): Deleted. >+ >+ Renamed this from changeFontFromFontPanel to changeFontFromFontManager. This new name is more accurate in the >+ case where a menu item is used to alter the font, which doesn't involve NSFontPanel at all. >+ >+ * UIProcess/WebPageProxy.h: >+ * UIProcess/mac/WebPageProxyMac.mm: >+ (WebKit::WebPageProxy::changeFont): >+ (WebKit::WebPageProxy::setFont): Deleted. >+ * WebKit.xcodeproj/project.pbxproj: >+ * WebProcess/WebPage/WebPage.h: >+ * WebProcess/WebPage/WebPage.messages.in: >+ * WebProcess/WebPage/mac/WebPageMac.mm: >+ (WebKit::WebPage::changeFont): >+ (WebKit::WebPage::setFont): Deleted. >+ > 2018-09-05 David Kilzer <ddkilzer@apple.com> > > REGRESSION (r235489): WKSharingServicePickerDelegate.mm accidentally added back to Sources in WebKit project >diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog >index 4a645554957f3f5948bc797311fe6063851ff6cf..75c0f0038dced29ef5c9e32b6f9914a9d8906038 100644 >--- a/Source/WebKitLegacy/mac/ChangeLog >+++ b/Source/WebKitLegacy/mac/ChangeLog >@@ -1,3 +1,24 @@ >+2018-09-05 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ [macOS] Cannot change font size at selection until font panel is shown >+ https://bugs.webkit.org/show_bug.cgi?id=189295 >+ <rdar://problem/35593389> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Remove code in WebKitLegacy for diffing NSFonts to figure out which style properties need to be changed. See >+ WebCore ChangeLog for more details. >+ >+ * WebView/WebHTMLView.mm: >+ (-[WebHTMLView changeFont:]): >+ (-[WebHTMLView changeAttributes:]): >+ (-[WebHTMLView _originalFontA]): Deleted. >+ (-[WebHTMLView _originalFontB]): Deleted. >+ (fontNameForDescription): Deleted. >+ (-[WebHTMLView _addToStyle:fontA:fontB:]): Deleted. >+ (-[WebHTMLView _styleFromFontManagerOperation]): Deleted. >+ (-[WebHTMLView _styleForAttributeChange:]): Deleted. >+ > 2018-09-05 Jer Noble <jer.noble@apple.com> > > Add MediaCapabilities as an Experimental Feature >diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt >index 498208119f26f8a5b0f967f4a912a84797ec9497..5dc3823f2f309c3a9d4766ab1821de871f90b3f0 100644 >--- a/Source/WebCore/SourcesCocoa.txt >+++ b/Source/WebCore/SourcesCocoa.txt >@@ -78,6 +78,7 @@ editing/SmartReplaceCF.cpp > > editing/cocoa/DataDetection.mm > editing/cocoa/EditorCocoa.mm >+editing/cocoa/FontAttributeChangesCocoa.mm > editing/cocoa/HTMLConverter.mm @no-unify > editing/cocoa/WebArchiveResourceFromNSAttributedString.mm > editing/cocoa/WebArchiveResourceWebResourceHandler.mm >@@ -462,6 +463,7 @@ platform/mac/VideoFullscreenInterfaceMac.mm > platform/mac/WebCoreFullScreenPlaceholderView.mm > platform/mac/WebCoreFullScreenWarningView.mm > platform/mac/WebCoreFullScreenWindow.mm >+platform/mac/WebCoreNSFontManagerExtras.mm > platform/mac/WebCoreNSURLExtras.mm > platform/mac/WebCoreObjCExtras.mm > platform/mac/WebGLBlacklist.mm >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index a6452ca2d8942613b83936ece08b3253671b8db0..1f1705c947c29186827c5a2e187e07c2ebbe66a3 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -4822,6 +4822,7 @@ > F3ABFE0C130E9DA000E7F7D1 /* InstrumentingAgents.h in Headers */ = {isa = PBXBuildFile; fileRef = F3ABFE0B130E9DA000E7F7D1 /* InstrumentingAgents.h */; }; > F3D461491161D53200CA0D09 /* JSErrorHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D461471161D53200CA0D09 /* JSErrorHandler.h */; }; > F433E9031DBBDBA200EF0D14 /* StaticPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F433E9021DBBDBA200EF0D14 /* StaticPasteboard.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ F442850C2140412500CCDA22 /* FontAttributeChanges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F442850B2140412500CCDA22 /* FontAttributeChanges.cpp */; }; > F44A5F591FED38F2007F5944 /* LegacyNSPasteboardTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F44A5F571FED3830007F5944 /* LegacyNSPasteboardTypes.h */; settings = {ATTRIBUTES = (Private, ); }; }; > F44EBBD91DB5D21400277334 /* StaticRange.h in Headers */ = {isa = PBXBuildFile; fileRef = F44EBBD81DB5D21400277334 /* StaticRange.h */; settings = {ATTRIBUTES = (Private, ); }; }; > F45C231E1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h in Headers */ = {isa = PBXBuildFile; fileRef = F45C231C1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -4836,6 +4837,8 @@ > F49786881FF45FA500E060AB /* PasteboardItemInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F49786871FF45FA500E060AB /* PasteboardItemInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; > F4BFB9851E1DDF9B00862C24 /* DumpEditingHistory.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389831E1DDF2B0076B7EA /* DumpEditingHistory.js */; }; > F4BFB9861E1DDF9B00862C24 /* EditingHistoryUtil.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389841E1DDF2B0076B7EA /* EditingHistoryUtil.js */; }; >+ F4E57EDC213F3F5F004EA98E /* FontAttributeChanges.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E57EDA213F3F5F004EA98E /* FontAttributeChanges.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ F4E57EE1213F434A004EA98E /* WebCoreNSFontManagerExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E57EDF213F434A004EA98E /* WebCoreNSFontManagerExtras.h */; settings = {ATTRIBUTES = (Private, ); }; }; > F50664F8157F52DC00AC226F /* FormController.h in Headers */ = {isa = PBXBuildFile; fileRef = F50664F6157F52DC00AC226F /* FormController.h */; }; > F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; > F544F78915CFB2A800AF33A8 /* PlatformLocale.h in Headers */ = {isa = PBXBuildFile; fileRef = F544F78715CFB2A800AF33A8 /* PlatformLocale.h */; }; >@@ -14509,8 +14512,10 @@ > F3ABFE0B130E9DA000E7F7D1 /* InstrumentingAgents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InstrumentingAgents.h; sourceTree = "<group>"; }; > F3D461461161D53200CA0D09 /* JSErrorHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSErrorHandler.cpp; sourceTree = "<group>"; }; > F3D461471161D53200CA0D09 /* JSErrorHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSErrorHandler.h; sourceTree = "<group>"; }; >+ F42CEB54214031EE002DCA72 /* FontAttributeChangesCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FontAttributeChangesCocoa.mm; sourceTree = "<group>"; }; > F433E9021DBBDBA200EF0D14 /* StaticPasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticPasteboard.h; sourceTree = "<group>"; }; > F433E9041DBBDBC200EF0D14 /* StaticPasteboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StaticPasteboard.cpp; sourceTree = "<group>"; }; >+ F442850B2140412500CCDA22 /* FontAttributeChanges.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FontAttributeChanges.cpp; sourceTree = "<group>"; }; > F44A5F571FED3830007F5944 /* LegacyNSPasteboardTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LegacyNSPasteboardTypes.h; sourceTree = "<group>"; }; > F44EBBD61DB5D1B600277334 /* StaticRange.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = StaticRange.idl; sourceTree = "<group>"; }; > F44EBBD81DB5D21400277334 /* StaticRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticRange.h; sourceTree = "<group>"; }; >@@ -14531,6 +14536,9 @@ > F48389831E1DDF2B0076B7EA /* DumpEditingHistory.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = DumpEditingHistory.js; path = Scripts/DumpEditingHistory.js; sourceTree = "<group>"; }; > F48389841E1DDF2B0076B7EA /* EditingHistoryUtil.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = EditingHistoryUtil.js; path = Scripts/EditingHistoryUtil.js; sourceTree = "<group>"; }; > F49786871FF45FA500E060AB /* PasteboardItemInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PasteboardItemInfo.h; sourceTree = "<group>"; }; >+ F4E57EDA213F3F5F004EA98E /* FontAttributeChanges.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontAttributeChanges.h; sourceTree = "<group>"; }; >+ F4E57EDF213F434A004EA98E /* WebCoreNSFontManagerExtras.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCoreNSFontManagerExtras.h; sourceTree = "<group>"; }; >+ F4E57EE0213F434A004EA98E /* WebCoreNSFontManagerExtras.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreNSFontManagerExtras.mm; sourceTree = "<group>"; }; > F50664F5157F52DC00AC226F /* FormController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormController.cpp; sourceTree = "<group>"; }; > F50664F6157F52DC00AC226F /* FormController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormController.h; sourceTree = "<group>"; }; > F513A3E915FF4841001526DB /* ValidationMessageClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidationMessageClient.h; sourceTree = "<group>"; }; >@@ -19189,6 +19197,8 @@ > CDC69DD51632026C007C38DF /* WebCoreFullScreenWarningView.mm */, > CD127DEA14F3097900E84779 /* WebCoreFullScreenWindow.h */, > CD127DEB14F3097900E84779 /* WebCoreFullScreenWindow.mm */, >+ F4E57EDF213F434A004EA98E /* WebCoreNSFontManagerExtras.h */, >+ F4E57EE0213F434A004EA98E /* WebCoreNSFontManagerExtras.mm */, > C5B4C24B1509236C00A6EF37 /* WebCoreNSURLExtras.h */, > C5B4C24C1509236C00A6EF37 /* WebCoreNSURLExtras.mm */, > DD05FE0B0B8BA3C6009ACDFE /* WebCoreObjCExtras.h */, >@@ -19853,6 +19863,7 @@ > C5227DEF1C3C6DD700F5ED54 /* DataDetection.h */, > C5227DF01C3C6DD700F5ED54 /* DataDetection.mm */, > 9B55EEE81B3E8898005342BC /* EditorCocoa.mm */, >+ F42CEB54214031EE002DCA72 /* FontAttributeChangesCocoa.mm */, > 7C3E510818DF8F3500C112F7 /* HTMLConverter.h */, > 7C3E510918DF8F3500C112F7 /* HTMLConverter.mm */, > E18536811F4E472700FE091B /* WebArchiveResourceFromNSAttributedString.h */, >@@ -20153,6 +20164,8 @@ > 4BAE95B00B2FA9CE00AED8A0 /* EditorDeleteAction.h */, > 93FDAFC90B11307400E2746F /* EditorInsertAction.h */, > 372C00D8129619F8005C9575 /* FindOptions.h */, >+ F442850B2140412500CCDA22 /* FontAttributeChanges.cpp */, >+ F4E57EDA213F3F5F004EA98E /* FontAttributeChanges.h */, > D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */, > D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */, > 93309DBE099E64910056E581 /* FrameSelection.cpp */, >@@ -27959,6 +27972,7 @@ > B6D9D23514EABD260090D75E /* FocusEvent.h in Headers */, > B2C3DA650D006CD600EF6F26 /* Font.h in Headers */, > 1AC2D89D1B1E291F00D52E87 /* FontAntialiasingStateSaver.h in Headers */, >+ F4E57EDC213F3F5F004EA98E /* FontAttributeChanges.h in Headers */, > BCB92D4F1293550B00C8387F /* FontBaseline.h in Headers */, > B2C3DA630D006CD600EF6F26 /* FontCache.h in Headers */, > C2458E631FE897B000594759 /* FontCacheCoreText.h in Headers */, >@@ -30877,6 +30891,7 @@ > 93F199BB08245E59001E9ABC /* WebCoreKeyboardUIMode.h in Headers */, > 3140379B124BEA7F00AF40E4 /* WebCoreMotionManager.h in Headers */, > CDC979F51C498C0900DB50D4 /* WebCoreNSErrorExtras.h in Headers */, >+ F4E57EE1213F434A004EA98E /* WebCoreNSFontManagerExtras.h in Headers */, > C5B4C24D1509236C00A6EF37 /* WebCoreNSURLExtras.h in Headers */, > CD225C0C1C46FBF400140761 /* WebCoreNSURLSession.h in Headers */, > DD05FE0D0B8BA3C6009ACDFE /* WebCoreObjCExtras.h in Headers */, >@@ -31467,6 +31482,7 @@ > 5C4304B0191AC908000E2BC0 /* EXTShaderTextureLOD.cpp in Sources */, > 727AFED41A2EA6AE000442E8 /* EXTsRGB.cpp in Sources */, > 7728694E14F8882500F484DC /* EXTTextureFilterAnisotropic.cpp in Sources */, >+ F442850C2140412500CCDA22 /* FontAttributeChanges.cpp in Sources */, > 7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */, > 51A4BB0A1954D61600FA5C2E /* Gamepad.cpp in Sources */, > 518F4FF6194CA4E60081BAAE /* GamepadButton.cpp in Sources */, >diff --git a/Source/WebCore/editing/Editor.h b/Source/WebCore/editing/Editor.h >index 3d63ce14511745b94904df98039dff8e61d7c784..ab776464adba74e37e90ca43676fb47d26451ff4 100644 >--- a/Source/WebCore/editing/Editor.h >+++ b/Source/WebCore/editing/Editor.h >@@ -474,7 +474,6 @@ public: > WEBCORE_EXPORT void readSelectionFromPasteboard(const String& pasteboardName, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote); > WEBCORE_EXPORT void replaceNodeFromPasteboard(Node*, const String& pasteboardName); > WEBCORE_EXPORT RefPtr<SharedBuffer> dataSelectionForPasteboard(const String& pasteboardName); >- WEBCORE_EXPORT void applyFontStyles(const String& fontFamily, double fontSize, unsigned fontTraits); > #endif // !PLATFORM(IOS) > WEBCORE_EXPORT void replaceSelectionWithAttributedString(NSAttributedString *, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote); > #endif >diff --git a/Source/WebCore/editing/FontAttributeChanges.cpp b/Source/WebCore/editing/FontAttributeChanges.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..aa87af63d4974cef58891597b31cf6e13d4c02e5 >--- /dev/null >+++ b/Source/WebCore/editing/FontAttributeChanges.cpp >@@ -0,0 +1,132 @@ >+/* >+ * 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 "FontAttributeChanges.h" >+ >+#import "CSSPropertyNames.h" >+#import "CSSShadowValue.h" >+#import "CSSValueKeywords.h" >+#import "CSSValueList.h" >+#import "CSSValuePool.h" >+#import "EditingStyle.h" >+#import "StyleProperties.h" >+ >+namespace WebCore { >+ >+#if !PLATFORM(COCOA) >+ >+const String& FontChanges::platformFontFamilyNameForCSS() const >+{ >+ return m_fontFamily; >+} >+ >+#endif >+ >+Ref<EditingStyle> FontChanges::createEditingStyle() const >+{ >+ auto properties = createStyleProperties(); >+ return EditingStyle::create(properties.ptr()); >+} >+ >+Ref<MutableStyleProperties> FontChanges::createStyleProperties() const >+{ >+ String familyNameForCSS; >+ if (!!m_fontFamily) >+ familyNameForCSS = platformFontFamilyNameForCSS(); >+ >+ auto style = MutableStyleProperties::create(); >+ auto& cssValuePool = CSSValuePool::singleton(); >+ >+ if (!!familyNameForCSS) >+ style->setProperty(CSSPropertyFontFamily, cssValuePool.createFontFamilyValue(familyNameForCSS)); >+ >+ if (m_italic) >+ style->setProperty(CSSPropertyFontStyle, *m_italic ? CSSValueItalic : CSSValueNormal); >+ >+ if (m_bold) >+ style->setProperty(CSSPropertyFontWeight, *m_bold ? CSSValueBold : CSSValueNormal); >+ >+ if (m_fontSize) >+ style->setProperty(CSSPropertyFontSize, cssValuePool.createValue(*m_fontSize, CSSPrimitiveValue::CSS_PX)); >+ >+ if (m_fontSizeDelta) >+ style->setProperty(CSSPropertyWebkitFontSizeDelta, cssValuePool.createValue(*m_fontSizeDelta, CSSPrimitiveValue::CSS_PX)); >+ >+ return style; >+} >+ >+static RefPtr<CSSValueList> cssValueListForShadow(const FontShadow& shadow) >+{ >+ if (!shadow.width && !shadow.height && !shadow.blurRadius) >+ return nullptr; >+ >+ auto list = CSSValueList::createCommaSeparated(); >+ auto& cssValuePool = CSSValuePool::singleton(); >+ auto width = cssValuePool.createValue(shadow.width, CSSPrimitiveValue::CSS_PX); >+ auto height = cssValuePool.createValue(shadow.height, CSSPrimitiveValue::CSS_PX); >+ auto blurRadius = cssValuePool.createValue(shadow.blurRadius, CSSPrimitiveValue::CSS_PX); >+ auto color = cssValuePool.createValue(shadow.color); >+ list->prepend(CSSShadowValue::create(WTFMove(width), WTFMove(height), WTFMove(blurRadius), { }, { }, WTFMove(color))); >+ return list; >+} >+ >+Ref<EditingStyle> FontAttributeChanges::createEditingStyle() const >+{ >+ auto style = m_fontChanges.createStyleProperties(); >+ auto& cssValuePool = CSSValuePool::singleton(); >+ >+ if (m_backgroundColor) >+ style->setProperty(CSSPropertyBackgroundColor, cssValuePool.createValue(*m_backgroundColor)); >+ >+ if (m_foregroundColor) >+ style->setProperty(CSSPropertyColor, cssValuePool.createValue(*m_foregroundColor)); >+ >+ if (m_shadow) { >+ if (auto shadowValue = cssValueListForShadow(*m_shadow)) >+ style->setProperty(CSSPropertyTextShadow, WTFMove(shadowValue)); >+ else >+ style->setProperty(CSSPropertyTextShadow, CSSValueNone); >+ } >+ >+ if (m_verticalAlign == VerticalAlign::Super) >+ style->setProperty(CSSPropertyVerticalAlign, CSSValueSuper); >+ else if (m_verticalAlign == VerticalAlign::Sub) >+ style->setProperty(CSSPropertyVerticalAlign, CSSValueSub); >+ else if (m_verticalAlign == VerticalAlign::Baseline) >+ style->setProperty(CSSPropertyVerticalAlign, CSSValueBaseline); >+ >+ auto editingStyle = EditingStyle::create(style.ptr()); >+ >+ if (m_strikeThrough) >+ editingStyle->setStrikeThroughChange(*m_strikeThrough ? TextDecorationChange::Add : TextDecorationChange::Remove); >+ >+ if (m_underline) >+ editingStyle->setUnderlineChange(*m_underline ? TextDecorationChange::Add : TextDecorationChange::Remove); >+ >+ return editingStyle; >+} >+ >+} // namespace WebCore >diff --git a/Source/WebCore/editing/FontAttributeChanges.h b/Source/WebCore/editing/FontAttributeChanges.h >new file mode 100644 >index 0000000000000000000000000000000000000000..dd3e40979e7fe9e3bbaf0bf03ad95d5e19a21d3c >--- /dev/null >+++ b/Source/WebCore/editing/FontAttributeChanges.h >@@ -0,0 +1,126 @@ >+/* >+ * 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 >+ >+#include "Color.h" >+#include "RenderStyleConstants.h" >+#include <wtf/Forward.h> >+#include <wtf/Optional.h> >+ >+namespace WebCore { >+ >+class EditingStyle; >+class MutableStyleProperties; >+ >+class FontChanges { >+public: >+ template<class Encoder> void encode(Encoder&) const; >+ template<class Decoder> static bool decode(Decoder&, FontChanges&); >+ >+ void setFontName(const String& fontName) { m_fontName = fontName; } >+ void setFontFamily(const String& fontFamily) { m_fontFamily = fontFamily; } >+ void setFontSize(double fontSize) { m_fontSize = fontSize; } >+ void setFontSizeDelta(double fontSizeDelta) { m_fontSizeDelta = fontSizeDelta; } >+ void setBold(bool bold) { m_bold = bold; } >+ void setItalic(bool italic) { m_italic = italic; } >+ >+ WEBCORE_EXPORT Ref<EditingStyle> createEditingStyle() const; >+ Ref<MutableStyleProperties> createStyleProperties() const; >+ >+private: >+ const String& platformFontFamilyNameForCSS() const; >+ >+ String m_fontName; >+ String m_fontFamily; >+ std::optional<double> m_fontSize; >+ std::optional<double> m_fontSizeDelta; >+ std::optional<bool> m_bold; >+ std::optional<bool> m_italic; >+}; >+ >+struct FontShadow { >+ Color color; >+ double width { 0 }; >+ double height { 0 }; >+ double blurRadius { 0 }; >+}; >+ >+class FontAttributeChanges { >+public: >+ void setVerticalAlign(VerticalAlign align) { m_verticalAlign = align; } >+ void setBackgroundColor(const Color& color) { m_backgroundColor = color; } >+ void setForegroundColor(const Color& color) { m_foregroundColor = color; } >+ void setShadow(const FontShadow& shadow) { m_shadow = shadow; } >+ void setStrikeThrough(bool strikeThrough) { m_strikeThrough = strikeThrough; } >+ void setUnderline(bool underline) { m_underline = underline; } >+ void setFontChanges(const FontChanges& fontChanges) { m_fontChanges = fontChanges; } >+ >+ WEBCORE_EXPORT Ref<EditingStyle> createEditingStyle() const; >+ >+private: >+ // FIXME: Should m_verticalAlign be an optional, rather than defaulting to Baseline? >+ VerticalAlign m_verticalAlign { VerticalAlign::Baseline }; >+ std::optional<Color> m_backgroundColor; >+ std::optional<Color> m_foregroundColor; >+ std::optional<FontShadow> m_shadow; >+ std::optional<bool> m_strikeThrough; >+ std::optional<bool> m_underline; >+ FontChanges m_fontChanges; >+}; >+ >+template<class Encoder> >+void FontChanges::encode(Encoder& encoder) const >+{ >+ ASSERT(!m_fontSize || !m_fontSizeDelta); >+ encoder << m_fontName << m_fontFamily << m_fontSize << m_fontSizeDelta << m_bold << m_italic; >+} >+ >+template<class Decoder> >+bool FontChanges::decode(Decoder& decoder, FontChanges& changes) >+{ >+ if (!decoder.decode(changes.m_fontName)) >+ return false; >+ >+ if (!decoder.decode(changes.m_fontFamily)) >+ return false; >+ >+ if (!decoder.decode(changes.m_fontSize)) >+ return false; >+ >+ if (!decoder.decode(changes.m_fontSizeDelta)) >+ return false; >+ >+ if (!decoder.decode(changes.m_bold)) >+ return false; >+ >+ if (!decoder.decode(changes.m_italic)) >+ return false; >+ >+ ASSERT(!changes.m_fontSize || !changes.m_fontSizeDelta); >+ return true; >+} >+ >+} // namespace WebCore >diff --git a/Source/WebCore/editing/cocoa/FontAttributeChangesCocoa.mm b/Source/WebCore/editing/cocoa/FontAttributeChangesCocoa.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..ae6c2bd822ce6112d7ad5cdde7008dff0dfb05ba >--- /dev/null >+++ b/Source/WebCore/editing/cocoa/FontAttributeChangesCocoa.mm >@@ -0,0 +1,56 @@ >+/* >+ * 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 "FontAttributeChanges.h" >+ >+#if PLATFORM(COCOA) >+ >+#import "Font.h" >+#import "FontCache.h" >+#import "FontDescription.h" >+ >+namespace WebCore { >+ >+const String& FontChanges::platformFontFamilyNameForCSS() const >+{ >+ auto cfFontName = m_fontName.createCFString(); >+ RetainPtr<CFStringRef> fontNameFromDescription; >+ >+ FontDescription description; >+ description.setIsItalic(m_italic.value_or(false)); >+ description.setWeight(FontSelectionValue { m_bold.value_or(false) ? 900 : 500 }); >+ if (auto font = FontCache::singleton().fontForFamily(description, m_fontFamily)) >+ fontNameFromDescription = adoptCF(CTFontCopyPostScriptName(font->getCTFont())); >+ >+ if (fontNameFromDescription && CFStringCompare(cfFontName.get(), fontNameFromDescription.get(), 0) == kCFCompareEqualTo) >+ return m_fontFamily; >+ >+ return m_fontName; >+} >+ >+} // namespace WebCore >+ >+#endif >diff --git a/Source/WebCore/editing/mac/EditorMac.mm b/Source/WebCore/editing/mac/EditorMac.mm >index cf289bf70e400036767808d1a1699f68237aac00..671b2072bcbb7137ad3708fec53e306034ff334e 100644 >--- a/Source/WebCore/editing/mac/EditorMac.mm >+++ b/Source/WebCore/editing/mac/EditorMac.mm >@@ -289,17 +289,6 @@ RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard > return WTFMove(reader.fragment); > } > >-void Editor::applyFontStyles(const String& fontFamily, double fontSize, unsigned fontTraits) >-{ >- auto& cssValuePool = CSSValuePool::singleton(); >- Ref<MutableStyleProperties> style = MutableStyleProperties::create(); >- style->setProperty(CSSPropertyFontFamily, cssValuePool.createFontFamilyValue(fontFamily)); >- style->setProperty(CSSPropertyFontStyle, (fontTraits & NSFontItalicTrait) ? CSSValueItalic : CSSValueNormal); >- style->setProperty(CSSPropertyFontWeight, (fontTraits & NSFontBoldTrait) ? CSSValueBold : CSSValueNormal); >- style->setProperty(CSSPropertyFontSize, cssValuePool.createValue(fontSize, CSSPrimitiveValue::CSS_PX)); >- applyStyleToSelection(style.ptr(), EditActionSetFont); >-} >- > } // namespace WebCore > > #endif // PLATFORM(MAC) >diff --git a/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.h b/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.h >new file mode 100644 >index 0000000000000000000000000000000000000000..d8c95ce141855e9414a0ac531283616f728e62c7 >--- /dev/null >+++ b/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.h >@@ -0,0 +1,42 @@ >+/* >+ * 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 PLATFORM(MAC) >+ >+OBJC_CLASS NSFontManager; >+ >+namespace WebCore { >+ >+class FontAttributeChanges; >+class FontChanges; >+ >+WEBCORE_EXPORT FontChanges computedFontChanges(NSFontManager *); >+WEBCORE_EXPORT FontAttributeChanges computedFontAttributeChanges(NSFontManager *, id attributeConverter); >+ >+} // namespace WebCore >+ >+#endif >diff --git a/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.mm b/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..478db4acc436445d7e83025d8b03f0244b1d845a >--- /dev/null >+++ b/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.mm >@@ -0,0 +1,167 @@ >+/* >+ * 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 "WebCoreNSFontManagerExtras.h" >+ >+#if PLATFORM(MAC) >+ >+#import "ColorMac.h" >+#import "FontAttributeChanges.h" >+#import <AppKit/NSFontManager.h> >+ >+namespace WebCore { >+ >+static NSFont *firstFontConversionSpecimen(NSFontManager *fontManager) >+{ >+ const double standardWeight = 5.; >+ return [fontManager fontWithFamily:@"Helvetica" traits:0 weight:standardWeight size:10.]; >+} >+ >+static NSFont *secondFontConversionSpecimen(NSFontManager *fontManager) >+{ >+ const double standardBoldWeight = 9.; >+ return [fontManager fontWithFamily:@"Times" traits:NSFontItalicTrait weight:standardBoldWeight size:12.]; >+} >+ >+static FontChanges computedFontChanges(NSFontManager *fontManager, NSFont *originalFontA, NSFont *convertedFontA, NSFont *convertedFontB) >+{ >+ if (!convertedFontA || !convertedFontB) >+ return { }; >+ >+ // Since there's still no way to directly ask NSFontManager what style change it's going >+ // to do we instead pass two "specimen" fonts to it and let it change them. We then deduce >+ // what style change it was doing by looking at what happened to each of the two fonts. >+ // So if it was making the text bold, both fonts will be bold after the fact. >+ // This logic was originally from WebHTMLView, and is now in WebCore so that it is shared >+ // between WebKitLegacy and WebKit. >+ const double minimumBoldWeight = 7.; >+ >+ NSString *convertedFamilyNameA = convertedFontA.familyName; >+ NSString *convertedFamilyNameB = convertedFontB.familyName; >+ >+ auto convertedPointSizeA = convertedFontA.pointSize; >+ auto convertedPointSizeB = convertedFontB.pointSize; >+ >+ auto convertedFontWeightA = [fontManager weightOfFont:convertedFontA]; >+ auto convertedFontWeightB = [fontManager weightOfFont:convertedFontB]; >+ >+ bool convertedFontAIsItalic = !!([fontManager traitsOfFont:convertedFontA] & NSItalicFontMask); >+ bool convertedFontBIsItalic = !!([fontManager traitsOfFont:convertedFontB] & NSItalicFontMask); >+ >+ bool convertedFontAIsBold = convertedFontWeightA > minimumBoldWeight; >+ >+ FontChanges changes; >+ if ([convertedFamilyNameA isEqualToString:convertedFamilyNameB]) { >+ changes.setFontName(convertedFontA.fontName); >+ changes.setFontFamily(convertedFamilyNameA); >+ } >+ >+ int originalPointSizeA = originalFontA.pointSize; >+ if (convertedPointSizeA == convertedPointSizeB) >+ changes.setFontSize(convertedPointSizeA); >+ else if (convertedPointSizeA < originalPointSizeA) >+ changes.setFontSizeDelta(-1); >+ else if (convertedPointSizeA > originalPointSizeA) >+ changes.setFontSizeDelta(1); >+ >+ if (convertedFontWeightA == convertedFontWeightB) >+ changes.setBold(convertedFontAIsBold); >+ >+ if (convertedFontAIsItalic == convertedFontBIsItalic) >+ changes.setItalic(convertedFontAIsItalic); >+ >+ return changes; >+} >+ >+FontChanges computedFontChanges(NSFontManager *fontManager) >+{ >+ NSFont *originalFontA = firstFontConversionSpecimen(fontManager); >+ return computedFontChanges(fontManager, originalFontA, [fontManager convertFont:originalFontA], [fontManager convertFont:secondFontConversionSpecimen(fontManager)]); >+} >+ >+FontAttributeChanges computedFontAttributeChanges(NSFontManager *fontManager, id attributeConverter) >+{ >+ FontAttributeChanges changes; >+ >+ auto shadow = adoptNS([[NSShadow alloc] init]); >+ [shadow setShadowOffset:NSMakeSize(1, 1)]; >+ >+ NSFont *originalFontA = firstFontConversionSpecimen(fontManager); >+ NSDictionary *originalAttributesA = @{ NSFontAttributeName : originalFontA }; >+ NSDictionary *originalAttributesB = @{ >+ NSBackgroundColorAttributeName : NSColor.blackColor, >+ NSFontAttributeName : secondFontConversionSpecimen(fontManager), >+ NSForegroundColorAttributeName : NSColor.whiteColor, >+ NSShadowAttributeName : shadow.get(), >+ NSStrikethroughStyleAttributeName : @(NSUnderlineStyleSingle), >+ NSSuperscriptAttributeName : @1, >+ NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle) >+ }; >+ >+ NSDictionary *convertedAttributesA = [attributeConverter convertAttributes:originalAttributesA]; >+ NSDictionary *convertedAttributesB = [attributeConverter convertAttributes:originalAttributesB]; >+ >+ NSColor *convertedBackgroundColorA = [convertedAttributesA objectForKey:NSBackgroundColorAttributeName]; >+ if (convertedBackgroundColorA == [convertedAttributesB objectForKey:NSBackgroundColorAttributeName]) >+ changes.setBackgroundColor(colorFromNSColor(convertedBackgroundColorA)); >+ >+ changes.setFontChanges(computedFontChanges(fontManager, originalFontA, [convertedAttributesA objectForKey:NSFontAttributeName], [convertedAttributesB objectForKey:NSFontAttributeName])); >+ >+ NSColor *convertedForegroundColorA = [convertedAttributesA objectForKey:NSForegroundColorAttributeName]; >+ if (convertedForegroundColorA == [convertedAttributesB objectForKey:NSForegroundColorAttributeName]) >+ changes.setBackgroundColor(colorFromNSColor(convertedForegroundColorA ?: NSColor.blackColor)); >+ >+ NSShadow *convertedShadow = [convertedAttributesA objectForKey:NSShadowAttributeName]; >+ if (convertedShadow) { >+ auto offset = convertedShadow.shadowOffset; >+ changes.setShadow({ colorFromNSColor(convertedShadow.shadowColor ?: NSColor.blackColor), offset.width, offset.height, convertedShadow.shadowBlurRadius }); >+ } else if (![convertedAttributesB objectForKey:NSShadowAttributeName]) >+ changes.setShadow({ }); >+ >+ int convertedSuperscriptA = [[convertedAttributesA objectForKey:NSSuperscriptAttributeName] intValue]; >+ if (convertedSuperscriptA == [[convertedAttributesB objectForKey:NSSuperscriptAttributeName] intValue]) { >+ if (convertedSuperscriptA > 0) >+ changes.setVerticalAlign(VerticalAlign::Super); >+ else if (convertedSuperscriptA < 0) >+ changes.setVerticalAlign(VerticalAlign::Sub); >+ else >+ changes.setVerticalAlign(VerticalAlign::Baseline); >+ } >+ >+ int convertedStrikeThroughA = [[convertedAttributesA objectForKey:NSStrikethroughStyleAttributeName] intValue]; >+ if (convertedStrikeThroughA == [[convertedAttributesB objectForKey:NSStrikethroughStyleAttributeName] intValue]) >+ changes.setStrikeThrough(convertedStrikeThroughA != NSUnderlineStyleNone); >+ >+ int convertedUnderlineA = [[convertedAttributesA objectForKey:NSUnderlineStyleAttributeName] intValue]; >+ if (convertedUnderlineA == [[convertedAttributesB objectForKey:NSUnderlineStyleAttributeName] intValue]) >+ changes.setUnderline(convertedUnderlineA != NSUnderlineStyleNone); >+ >+ return changes; >+} >+ >+} // namespace WebCore >+ >+#endif // PLATFORM(MAC) >diff --git a/Source/WebKit/Scripts/webkit/messages.py b/Source/WebKit/Scripts/webkit/messages.py >index 9ac3728401ac361fc8b618184cc78567cbfe61dd..fc5846955d35e1a41bf19aae7d678c8aa12e1541 100644 >--- a/Source/WebKit/Scripts/webkit/messages.py >+++ b/Source/WebKit/Scripts/webkit/messages.py >@@ -381,6 +381,7 @@ def headers_for_type(type): > 'WebCore::ExceptionDetails': ['<WebCore/JSDOMExceptionHandling.h>'], > 'WebCore::FileChooserSettings': ['<WebCore/FileChooser.h>'], > 'WebCore::ShareDataWithParsedURL': ['<WebCore/ShareData.h>'], >+ 'WebCore::FontChanges': ['<WebCore/FontAttributeChanges.h>'], > 'WebCore::FrameLoadType': ['<WebCore/FrameLoaderTypes.h>'], > 'WebCore::GrammarDetail': ['<WebCore/TextCheckerClient.h>'], > 'WebCore::HasInsecureContent': ['<WebCore/FrameLoaderTypes.h>'], >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >index f349c1738b1b2cee5efe653a01f11b26a12db190..49f5180ed33603a454c51f401a7eb754f2f67d0c 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >@@ -3356,7 +3356,7 @@ WEBCORE_COMMAND(yankAndSelect) > > - (void)changeFont:(id)sender > { >- _impl->changeFontFromFontPanel(); >+ _impl->changeFontFromFontManager(); > } > > - (IBAction)startSpeaking:(id)sender >diff --git a/Source/WebKit/UIProcess/API/mac/WKView.mm b/Source/WebKit/UIProcess/API/mac/WKView.mm >index bc5de2b59f2f4c21ae54b60a3433dc84da2d50e4..fe97010375507b7d71119a4dafb0d528a72e4976 100644 >--- a/Source/WebKit/UIProcess/API/mac/WKView.mm >+++ b/Source/WebKit/UIProcess/API/mac/WKView.mm >@@ -316,7 +316,7 @@ WEBCORE_COMMAND(yankAndSelect) > > - (void)changeFont:(id)sender > { >- _data->_impl->changeFontFromFontPanel(); >+ _data->_impl->changeFontFromFontManager(); > } > > /* >diff --git a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h >index e54dd00140584fc1e19148a22e78fc2fe0b09742..c9f3b895c7ba8e77f0da639fad2eb971bf7347dd 100644 >--- a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h >+++ b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h >@@ -315,7 +315,7 @@ public: > void selectionDidChange(); > void didBecomeEditable(); > void updateFontPanelIfNeeded(); >- void changeFontFromFontPanel(); >+ void changeFontFromFontManager(); > bool validateUserInterfaceItem(id <NSValidatedUserInterfaceItem>); > void setEditableElementIsFocused(bool); > >diff --git a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm >index de48e0f8a895eb82c17b4f8753c63e1521688e5a..c25edf34f650abeecc529485b636a399c659d593 100644 >--- a/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm >+++ b/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm >@@ -80,6 +80,7 @@ > #import <WebCore/DragItem.h> > #import <WebCore/Editor.h> > #import <WebCore/FileSystem.h> >+#import <WebCore/FontAttributeChanges.h> > #import <WebCore/KeypressCommand.h> > #import <WebCore/LegacyNSPasteboardTypes.h> > #import <WebCore/LoaderNSURLExtras.h> >@@ -92,6 +93,7 @@ > #import <WebCore/WebCoreCALayerExtras.h> > #import <WebCore/WebCoreFullScreenPlaceholderView.h> > #import <WebCore/WebCoreFullScreenWindow.h> >+#import <WebCore/WebCoreNSFontManagerExtras.h> > #import <WebCore/WebPlaybackControlsManager.h> > #import <pal/spi/cg/CoreGraphicsSPI.h> > #import <pal/spi/cocoa/AVKitSPI.h> >@@ -2732,13 +2734,14 @@ void WebViewImpl::updateFontPanelIfNeeded() > } > } > >-void WebViewImpl::changeFontFromFontPanel() >+void WebViewImpl::changeFontFromFontManager() > { >- NSFontManager *fontManager = [NSFontManager sharedFontManager]; >- NSFont *font = [fontManager convertFont:fontManager.selectedFont]; >- if (!font) >+ auto& editorState = m_page->editorState(); >+ if (!editorState.isContentEditable || editorState.selectionIsNone) > return; >- m_page->setFont(font.familyName, font.pointSize, font.fontDescriptor.symbolicTraits); >+ >+ m_page->changeFont(WebCore::computedFontChanges(NSFontManager.sharedFontManager)); >+ updateFontPanelIfNeeded(); > } > > static NSMenuItem *menuItem(id <NSValidatedUserInterfaceItem> item) >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index 452814bc25fd2dd009b0dcdb1ebd2ffe5451d18e..380ba9efea10481db19d079a6b2415482e099047 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -162,6 +162,7 @@ class CertificateInfo; > class Cursor; > class DragData; > class FloatRect; >+class FontChanges; > class GraphicsLayer; > class IntSize; > class ProtectionSpace; >@@ -680,7 +681,7 @@ public: > #if PLATFORM(MAC) > void insertDictatedTextAsync(const String& text, const EditingRange& replacementRange, const Vector<WebCore::TextAlternativeWithRange>& dictationAlternatives, bool registerUndoGroup); > void attributedSubstringForCharacterRangeAsync(const EditingRange&, WTF::Function<void (const AttributedString&, const EditingRange&, CallbackBase::Error)>&&); >- void setFont(const String& fontFamily, double fontSize, uint64_t fontTraits); >+ void changeFont(WebCore::FontChanges&&); > void fontAtSelection(WTF::Function<void (const String&, double, bool, CallbackBase::Error)>&&); > > void startWindowDrag(); >diff --git a/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm b/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm >index d30afc809394427c2ec10cc8b0651daadbe20a73..1446ae0d12f135bcd2fa25387a0fbbaa979dd33b 100644 >--- a/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm >+++ b/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm >@@ -50,6 +50,7 @@ > #import <WebCore/DictationAlternative.h> > #import <WebCore/DictionaryLookup.h> > #import <WebCore/DragItem.h> >+#import <WebCore/FontAttributeChanges.h> > #import <WebCore/GraphicsLayer.h> > #import <WebCore/LegacyNSPasteboardTypes.h> > #import <WebCore/RuntimeApplicationChecks.h> >@@ -626,12 +627,12 @@ bool WebPageProxy::appleMailLinesClampEnabled() > return MacApplication::isAppleMail(); > } > >-void WebPageProxy::setFont(const String& fontFamily, double fontSize, uint64_t fontTraits) >+void WebPageProxy::changeFont(WebCore::FontChanges&& changes) > { > if (!isValid()) > return; > >- process().send(Messages::WebPage::SetFont(fontFamily, fontSize, fontTraits), m_pageID); >+ process().send(Messages::WebPage::ChangeFont(WTFMove(changes)), m_pageID); > } > > void WebPageProxy::editorStateChanged(const EditorState& editorState) >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h >index c7f6b54f6e3db868188cdd741bdb73e35ab1fbb8..fbaf780db3f8cb7669c2854e28104e2d222923ed 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.h >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h >@@ -135,6 +135,7 @@ namespace WebCore { > class CaptureDevice; > class DocumentLoader; > class DragData; >+class FontChanges; > class Frame; > class FrameSelection; > class FrameView; >@@ -1361,7 +1362,7 @@ private: > void immediateActionDidUpdate(); > void immediateActionDidCancel(); > void immediateActionDidComplete(); >- void setFont(const String& fontFamily, double fontSize, uint64_t fontTraits); >+ void changeFont(WebCore::FontChanges&&); > > void dataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID); > void dataDetectorsDidChangeUI(WebCore::PageOverlay::PageOverlayID); >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >index 8c411453a2e1e3c3231974b7ed1cd56fd179ce6b..70f220dd375aa95a8d210fe8e7105df21592f1c4 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >@@ -190,7 +190,7 @@ messages -> WebPage LegacyReceiver { > > #if PLATFORM(MAC) > PerformDictionaryLookupOfCurrentSelection() >- SetFont(String fontFamily, double fontSize, uint64_t fontTraits) >+ ChangeFont(WebCore::FontChanges changes) > #endif > > PreferencesDidChange(struct WebKit::WebPreferencesStore store) >diff --git a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm >index da7c98f68c48189073dbea474871ff2cab6a581a..8d20d2eff06bc46b0cfc99159c8e989f5db3f387 100644 >--- a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm >+++ b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm >@@ -63,6 +63,7 @@ > #import <WebCore/Editor.h> > #import <WebCore/EventHandler.h> > #import <WebCore/FocusController.h> >+#import <WebCore/FontAttributeChanges.h> > #import <WebCore/Frame.h> > #import <WebCore/FrameLoader.h> > #import <WebCore/FrameView.h> >@@ -1114,10 +1115,11 @@ void WebPage::dataDetectorsDidHideUI(PageOverlay::PageOverlayID overlayID) > } > } > >-void WebPage::setFont(const String& fontFamily, double fontSize, uint64_t fontTraits) >+void WebPage::changeFont(WebCore::FontChanges&& changes) > { >- Frame& frame = m_page->focusController().focusedOrMainFrame(); >- frame.editor().applyFontStyles(fontFamily, fontSize, fontTraits); >+ auto& frame = m_page->focusController().focusedOrMainFrame(); >+ if (frame.selection().selection().isContentEditable()) >+ frame.editor().applyStyleToSelection(changes.createEditingStyle(), EditActionSetFont, Editor::ColorFilterMode::InvertColor); > } > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) >diff --git a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm >index 6a7b140bd85d3f13de41c6dbfe52a3c448d45253..fb855005a16f55a52ccf91edf41af5f27c7a0e12 100644 >--- a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm >+++ b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm >@@ -95,6 +95,7 @@ > #import <WebCore/FloatRect.h> > #import <WebCore/FocusController.h> > #import <WebCore/Font.h> >+#import <WebCore/FontAttributeChanges.h> > #import <WebCore/FontCache.h> > #import <WebCore/Frame.h> > #import <WebCore/FrameLoader.h> >@@ -123,6 +124,7 @@ > #import <WebCore/TextAlternativeWithRange.h> > #import <WebCore/TextIndicator.h> > #import <WebCore/TextUndoInsertionMarkupMac.h> >+#import <WebCore/WebCoreNSFontManagerExtras.h> > #import <WebCore/WebCoreObjCExtras.h> > #import <WebCore/WebNSAttributedStringExtras.h> > #import <WebCore/markup.h> >@@ -5307,188 +5309,18 @@ static RefPtr<KeyboardEvent> currentKeyboardEvent(Frame* coreFrame) > [self _pasteWithPasteboard:[NSPasteboard generalPasteboard] allowPlainText:NO]; > } > >-- (NSFont *)_originalFontA >-{ >- return [[NSFontManager sharedFontManager] fontWithFamily:@"Helvetica" traits:0 weight:STANDARD_WEIGHT size:10.0f]; >-} >- >-- (NSFont *)_originalFontB >-{ >- return [[NSFontManager sharedFontManager] fontWithFamily:@"Times" traits:NSFontItalicTrait weight:STANDARD_BOLD_WEIGHT size:12.0f]; >-} >- >-static RetainPtr<CFStringRef> fontNameForDescription(NSString *familyName, BOOL italic, BOOL bold) >-{ >- // Find the font the same way the rendering code would later if it encountered this CSS. >- FontDescription fontDescription; >- fontDescription.setIsItalic(italic); >- fontDescription.setWeight(bold ? FontSelectionValue(900) : FontSelectionValue(500)); >- RefPtr<Font> font = FontCache::singleton().fontForFamily(fontDescription, familyName); >- return adoptCF(CTFontCopyPostScriptName(font->getCTFont())); >-} >- >-- (void)_addToStyle:(DOMCSSStyleDeclaration *)style fontA:(NSFont *)a fontB:(NSFont *)b >-{ >- // Since there's no way to directly ask NSFontManager what style change it's going to do >- // we instead pass two "specimen" fonts to it and let it change them. We then deduce what >- // style change it was doing by looking at what happened to each of the two fonts. >- // So if it was making the text bold, both fonts will be bold after the fact. >- >- if (a == nil || b == nil) >- return; >- >- NSFontManager *fm = [NSFontManager sharedFontManager]; >- >- NSFont *oa = [self _originalFontA]; >- >- NSString *aFamilyName = [a familyName]; >- NSString *bFamilyName = [b familyName]; >- >- int aPointSize = (int)[a pointSize]; >- int bPointSize = (int)[b pointSize]; >- >- int aWeight = [fm weightOfFont:a]; >- int bWeight = [fm weightOfFont:b]; >- >- BOOL aIsItalic = ([fm traitsOfFont:a] & NSItalicFontMask) != 0; >- BOOL bIsItalic = ([fm traitsOfFont:b] & NSItalicFontMask) != 0; >- >- BOOL aIsBold = aWeight > MIN_BOLD_WEIGHT; >- >- if ([aFamilyName isEqualToString:bFamilyName]) { >- NSString *familyNameForCSS = aFamilyName; >- >- // The family name may not be specific enough to get us the font specified. >- // In some cases, the only way to get exactly what we are looking for is to use >- // the Postscript name. >- // If we don't find a font with the same Postscript name, then we'll have to use the >- // Postscript name to make the CSS specific enough. >- auto fontName = fontNameForDescription(aFamilyName, aIsItalic, aIsBold); >- auto aName = [a fontName]; >- if (!fontName || !aName || !CFEqual(fontName.get(), static_cast<CFStringRef>(aName))) >- familyNameForCSS = aName; >- >- // FIXME: Need more sophisticated escaping code if we want to handle family names >- // with characters like single quote or backslash in their names. >- [style setFontFamily:[NSString stringWithFormat:@"'%@'", familyNameForCSS]]; >- } >- >- int soa = (int)[oa pointSize]; >- if (aPointSize == bPointSize) >- [style setFontSize:[NSString stringWithFormat:@"%dpx", aPointSize]]; >- else if (aPointSize < soa) >- [style _setFontSizeDelta:@"-1px"]; >- else if (aPointSize > soa) >- [style _setFontSizeDelta:@"1px"]; >- >- // FIXME: Map to the entire range of CSS weight values. >- if (aWeight == bWeight) >- [style setFontWeight:aIsBold ? @"bold" : @"normal"]; >- >- if (aIsItalic == bIsItalic) >- [style setFontStyle:aIsItalic ? @"italic" : @"normal"]; >-} >- >-- (DOMCSSStyleDeclaration *)_styleFromFontManagerOperation >-{ >- DOMCSSStyleDeclaration *style = [self _emptyStyle]; >- >- NSFontManager *fm = [NSFontManager sharedFontManager]; >- >- NSFont *oa = [self _originalFontA]; >- NSFont *ob = [self _originalFontB]; >- [self _addToStyle:style fontA:[fm convertFont:oa] fontB:[fm convertFont:ob]]; >- >- return style; >-} >- > - (void)changeFont:(id)sender > { > COMMAND_PROLOGUE > >- [self _applyStyleToSelection:[self _styleFromFontManagerOperation] withUndoAction:EditActionSetFont]; >-} >- >-- (Ref<EditingStyle>)_styleForAttributeChange:(id)sender >-{ >- DOMCSSStyleDeclaration *style = [self _emptyStyle]; >- >- auto shadow = adoptNS([[NSShadow alloc] init]); >- [shadow setShadowOffset:NSMakeSize(1, 1)]; >- >- NSDictionary *oa = [NSDictionary dictionaryWithObjectsAndKeys: >- [self _originalFontA], NSFontAttributeName, >- nil]; >- NSDictionary *ob = [NSDictionary dictionaryWithObjectsAndKeys: >- [NSColor blackColor], NSBackgroundColorAttributeName, >- [self _originalFontB], NSFontAttributeName, >- [NSColor whiteColor], NSForegroundColorAttributeName, >- shadow.get(), NSShadowAttributeName, >- [NSNumber numberWithInt:NSUnderlineStyleSingle], NSStrikethroughStyleAttributeName, >- [NSNumber numberWithInt:1], NSSuperscriptAttributeName, >- [NSNumber numberWithInt:NSUnderlineStyleSingle], NSUnderlineStyleAttributeName, >- nil]; >- >- NSDictionary *a = [sender convertAttributes:oa]; >- NSDictionary *b = [sender convertAttributes:ob]; >- >- NSColor *ca = [a objectForKey:NSBackgroundColorAttributeName]; >- NSColor *cb = [b objectForKey:NSBackgroundColorAttributeName]; >- if (ca == cb) { >- [style setBackgroundColor:[self _colorAsString:ca]]; >- } >- >- [self _addToStyle:style fontA:[a objectForKey:NSFontAttributeName] fontB:[b objectForKey:NSFontAttributeName]]; >- >- ca = [a objectForKey:NSForegroundColorAttributeName]; >- cb = [b objectForKey:NSForegroundColorAttributeName]; >- if (ca == cb) { >- if (!ca) >- ca = [NSColor blackColor]; >- [style setColor:[self _colorAsString:ca]]; >- } >- >- NSShadow *sha = [a objectForKey:NSShadowAttributeName]; >- if (sha) >- [style setTextShadow:[self _shadowAsString:sha]]; >- else if ([b objectForKey:NSShadowAttributeName] == nil) >- [style setTextShadow:@"none"]; >- >- int sa = [[a objectForKey:NSSuperscriptAttributeName] intValue]; >- int sb = [[b objectForKey:NSSuperscriptAttributeName] intValue]; >- if (sa == sb) { >- if (sa > 0) >- [style setVerticalAlign:@"super"]; >- else if (sa < 0) >- [style setVerticalAlign:@"sub"]; >- else >- [style setVerticalAlign:@"baseline"]; >- } >- >- auto editingStyle = EditingStyle::create(core(style)); >- >- int strikeThroughA = [[a objectForKey:NSStrikethroughStyleAttributeName] intValue]; >- int strikeThroughB = [[b objectForKey:NSStrikethroughStyleAttributeName] intValue]; >- if (strikeThroughA == strikeThroughB) { >- bool shouldRemoveStrikeThrough = strikeThroughA == NSUnderlineStyleNone; >- editingStyle->setStrikeThroughChange(shouldRemoveStrikeThrough ? TextDecorationChange::Remove : TextDecorationChange::Add); >- } >- >- int ua = [[a objectForKey:NSUnderlineStyleAttributeName] intValue]; >- int ub = [[b objectForKey:NSUnderlineStyleAttributeName] intValue]; >- if (ua == ub) { >- bool shouldRemoveUnderline = ua == NSUnderlineStyleNone; >- editingStyle->setUnderlineChange(shouldRemoveUnderline ? TextDecorationChange::Remove : TextDecorationChange::Add); >- } >- >- return editingStyle; >+ [self _applyEditingStyleToSelection:computedFontChanges(NSFontManager.sharedFontManager).createEditingStyle() withUndoAction:EditActionSetFont]; > } > > - (void)changeAttributes:(id)sender > { > COMMAND_PROLOGUE > >- [self _applyEditingStyleToSelection:[self _styleForAttributeChange:sender] withUndoAction:EditActionChangeAttributes]; >+ [self _applyEditingStyleToSelection:computedFontAttributeChanges(NSFontManager.sharedFontManager, sender).createEditingStyle() withUndoAction:EditActionChangeAttributes]; > } > > - (DOMCSSStyleDeclaration *)_styleFromColorPanelWithSelector:(SEL)selector >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 4607bcb86c474b508ce6ccd43f035100d162427b..550f4cbb1e9ecbc73702606e121b2b1aaad2825f 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,24 @@ >+2018-09-05 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ [macOS] Cannot change font size at selection until font panel is shown >+ https://bugs.webkit.org/show_bug.cgi?id=189295 >+ <rdar://problem/35593389> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add API tests to simulate using menu items to increase or decrease font size, and also simulate using >+ NSFontPanel to specify the font family, font size, and other traits. >+ >+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: >+ * TestWebKitAPI/Tests/mac/FontManagerTests.mm: Added. >+ (-[TestWKWebView selectedText]): >+ (-[TestWKWebView selectNextWord]): >+ (-[TestWKWebView stylePropertyAtSelectionStart:]): >+ (-[TestWKWebView stylePropertyAtSelectionEnd:]): >+ (webViewForFontManagerTesting): >+ (menuItemCellForFontAction): >+ (TestWebKitAPI::TEST): >+ > 2018-09-05 Woodrow Wang <woodrow_wang@apple.com> > > Add infrastructure to dump resource load statistics >diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >index 137cc081a5024d26dd4b6e451bbf5571963e9b09..236777a8358ece327611b7ce5b652f92cc1c0379 100644 >--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >@@ -806,6 +806,7 @@ > F4517B672054C49500C26721 /* TestWKWebViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4517B662054C49500C26721 /* TestWKWebViewController.mm */; }; > F4517B7F2055101B00C26721 /* ClassMethodSwizzler.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4517B692054E0AC00C26721 /* ClassMethodSwizzler.mm */; }; > F4538EF71E8473E600B5C953 /* large-red-square.png in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4538EF01E846B4100B5C953 /* large-red-square.png */; }; >+ F456AB1C213EDBA300CB2CEF /* FontManagerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F456AB1B213EDBA300CB2CEF /* FontManagerTests.mm */; }; > F457A9B8202D5CDC00F7E9D5 /* PasteMixedContent.mm in Sources */ = {isa = PBXBuildFile; fileRef = F457A9B6202D5CDC00F7E9D5 /* PasteMixedContent.mm */; }; > 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 */; }; >@@ -2050,6 +2051,7 @@ > F4517B682054E0AC00C26721 /* ClassMethodSwizzler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ClassMethodSwizzler.h; sourceTree = "<group>"; }; > F4517B692054E0AC00C26721 /* ClassMethodSwizzler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ClassMethodSwizzler.mm; sourceTree = "<group>"; }; > F4538EF01E846B4100B5C953 /* large-red-square.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "large-red-square.png"; sourceTree = "<group>"; }; >+ F456AB1B213EDBA300CB2CEF /* FontManagerTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FontManagerTests.mm; sourceTree = "<group>"; }; > F457A9B3202D535300F7E9D5 /* DataTransfer.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DataTransfer.html; sourceTree = "<group>"; }; > 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>"; }; >@@ -3207,6 +3209,7 @@ > 4BB4160316815F9100824238 /* ElementAtPointInWebFrame.mm */, > 9B79164F1BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm */, > C9E6DD311EA972D800DD78AA /* FirstResponderSuppression.mm */, >+ F456AB1B213EDBA300CB2CEF /* FontManagerTests.mm */, > 1A7E8B33181208DE00AEB74A /* FragmentNavigation.mm */, > CDBFCC431A9FF44800A7B691 /* FullscreenZoomInitialFrame.mm */, > 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */, >@@ -3774,6 +3777,7 @@ > 7A909A7F1D877480007E10F8 /* FloatRect.cpp in Sources */, > 7A909A801D877480007E10F8 /* FloatSize.cpp in Sources */, > 1CAD1F861E5CE7DA00AF2C2C /* FontCache.cpp in Sources */, >+ F456AB1C213EDBA300CB2CEF /* FontManagerTests.mm in Sources */, > 7CCE7EF51A411AE600447C4C /* ForceRepaint.cpp in Sources */, > 7CCE7EC01A411A7E00447C4C /* FragmentNavigation.mm in Sources */, > 376C8C061D6E197C007D2BB9 /* FrameHandle.cpp in Sources */, >diff --git a/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm b/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..f733c3a1b4aa29bdef1f058308ec7ed01f9ca306 >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm >@@ -0,0 +1,183 @@ >+/* >+ * 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" >+ >+#if PLATFORM(MAC) >+ >+#import "PlatformUtilities.h" >+#import "TestWKWebView.h" >+#import <WebKit/WKWebViewPrivate.h> >+ >+@interface TestWKWebView (FontManagerTests) >+ >+@property (nonatomic, readonly) NSString *selectedText; >+ >+- (NSString *)stylePropertyAtSelectionStart:(NSString *)propertyName; >+- (NSString *)stylePropertyAtSelectionEnd:(NSString *)propertyName; >+- (void)selectNextWord; >+ >+@end >+ >+@implementation TestWKWebView (FontManagerTests) >+ >+- (NSString *)selectedText >+{ >+ return [self stringByEvaluatingJavaScript:@"getSelection().toString()"]; >+} >+ >+- (void)selectNextWord >+{ >+ [self moveRight:nil]; >+ [self moveRight:nil]; >+ [self selectWord:nil]; >+} >+ >+- (NSString *)stylePropertyAtSelectionStart:(NSString *)propertyName >+{ >+ NSString *script = [NSString stringWithFormat:@"getComputedStyle(getSelection().getRangeAt(0).startContainer.parentElement)['%@']", propertyName]; >+ return [self stringByEvaluatingJavaScript:script]; >+} >+ >+- (NSString *)stylePropertyAtSelectionEnd:(NSString *)propertyName >+{ >+ NSString *script = [NSString stringWithFormat:@"getComputedStyle(getSelection().getRangeAt(0).endContainer.parentElement)['%@']", propertyName]; >+ return [self stringByEvaluatingJavaScript:script]; >+} >+ >+@end >+ >+static RetainPtr<TestWKWebView> webViewForFontManagerTesting(NSFontManager *fontManager) >+{ >+ auto webView = adoptNS([[TestWKWebView 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>"]; >+ [webView stringByEvaluatingJavaScript:@"document.body.focus()"]; >+ fontManager.target = webView.get(); >+ return webView; >+} >+ >+static RetainPtr<NSMenuItemCell> menuItemCellForFontAction(NSFontAction action) >+{ >+ auto menuItem = adoptNS([[NSMenuItem alloc] init]); >+ auto menuItemCell = adoptNS([[NSMenuItemCell alloc] init]); >+ [menuItemCell setMenuItem:menuItem.get()]; >+ [menuItemCell setTag:action]; >+ return menuItemCell; >+} >+ >+namespace TestWebKitAPI { >+ >+TEST(FontManagerTests, ChangeFontSizeWithMenuItems) >+{ >+ NSFontManager *fontManager = [NSFontManager sharedFontManager]; >+ auto webView = webViewForFontManagerTesting(fontManager); >+ >+ auto sizeIncreaseMenuItemCell = menuItemCellForFontAction(NSSizeUpFontAction); >+ auto sizeDecreaseMenuItemCell = menuItemCellForFontAction(NSSizeDownFontAction); >+ >+ // Select "foo" and increase font size. >+ [webView selectWord:nil]; >+ [fontManager modifyFont:sizeIncreaseMenuItemCell.get()]; >+ [fontManager modifyFont:sizeIncreaseMenuItemCell.get()]; >+ >+ // Now select "baz" and decrease font size. >+ [webView moveToEndOfParagraph:nil]; >+ [webView selectWord:nil]; >+ [fontManager modifyFont:sizeDecreaseMenuItemCell.get()]; >+ [fontManager modifyFont:sizeDecreaseMenuItemCell.get()]; >+ >+ // Lastly, select just the "r" in "bar" and increase font size. >+ [webView evaluateJavaScript:@"getSelection().setBaseAndExtent(bar.childNodes[0], 2, bar.childNodes[0], 3)" completionHandler:nil]; >+ [fontManager modifyFont:sizeIncreaseMenuItemCell.get()]; >+ >+ [webView moveToBeginningOfParagraph:nil]; >+ [webView selectWord:nil]; >+ EXPECT_WK_STREQ(@"foo", [webView selectedText]); >+ EXPECT_WK_STREQ(@"18px", [webView stylePropertyAtSelectionStart:@"font-size"]); >+ EXPECT_WK_STREQ(@"18px", [webView stylePropertyAtSelectionEnd:@"font-size"]); >+ >+ [webView selectNextWord]; >+ EXPECT_WK_STREQ(@"bar", [webView selectedText]); >+ EXPECT_WK_STREQ(@"16px", [webView stylePropertyAtSelectionStart:@"font-size"]); >+ EXPECT_WK_STREQ(@"17px", [webView stylePropertyAtSelectionEnd:@"font-size"]); >+ >+ [webView selectNextWord]; >+ EXPECT_WK_STREQ(@"baz", [webView selectedText]); >+ EXPECT_WK_STREQ(@"14px", [webView stylePropertyAtSelectionStart:@"font-size"]); >+ EXPECT_WK_STREQ(@"14px", [webView stylePropertyAtSelectionEnd:@"font-size"]); >+} >+ >+TEST(FontManagerTests, ChangeFontWithPanel) >+{ >+ NSFontManager *fontManager = [NSFontManager sharedFontManager]; >+ auto webView = webViewForFontManagerTesting(fontManager); >+ >+ NSFontPanel *fontPanel = [fontManager fontPanel:YES]; >+ [fontPanel setIsVisible:YES]; >+ >+ NSFont *largeHelveticaFont = [NSFont fontWithName:@"Helvetica" size:20]; >+ [fontPanel setPanelFont:largeHelveticaFont isMultiple:NO]; >+ [webView selectWord:nil]; >+ [fontManager modifyFontViaPanel:fontPanel]; >+ EXPECT_WK_STREQ("foo", [webView selectedText]); >+ EXPECT_WK_STREQ("Helvetica", [webView stylePropertyAtSelectionStart:@"font-family"]); >+ EXPECT_WK_STREQ("20px", [webView stylePropertyAtSelectionStart:@"font-size"]); >+ EXPECT_WK_STREQ("normal", [webView stylePropertyAtSelectionStart:@"font-weight"]); >+ EXPECT_EQ(largeHelveticaFont, fontManager.selectedFont); >+ >+ NSFont *smallBoldTimesFont = [fontManager fontWithFamily:@"Times New Roman" traits:NSBoldFontMask weight:NSFontWeightBold size:10]; >+ [fontPanel setPanelFont:smallBoldTimesFont isMultiple:NO]; >+ [webView selectNextWord]; >+ [fontManager modifyFontViaPanel:fontPanel]; >+ EXPECT_WK_STREQ("bar", [webView selectedText]); >+ EXPECT_WK_STREQ("\"Times New Roman\"", [webView stylePropertyAtSelectionStart:@"font-family"]); >+ EXPECT_WK_STREQ("10px", [webView stylePropertyAtSelectionStart:@"font-size"]); >+ EXPECT_WK_STREQ("bold", [webView stylePropertyAtSelectionStart:@"font-weight"]); >+ EXPECT_EQ(smallBoldTimesFont, fontManager.selectedFont); >+ >+ NSFont *boldItalicArialFont = [fontManager fontWithFamily:@"Arial" traits:NSBoldFontMask | NSItalicFontMask weight:NSFontWeightBold size:14]; >+ [fontPanel setPanelFont:boldItalicArialFont isMultiple:NO]; >+ [webView selectNextWord]; >+ [fontManager modifyFontViaPanel:fontPanel]; >+ EXPECT_WK_STREQ("baz", [webView selectedText]); >+ EXPECT_WK_STREQ("Arial", [webView stylePropertyAtSelectionStart:@"font-family"]); >+ EXPECT_WK_STREQ("14px", [webView stylePropertyAtSelectionStart:@"font-size"]); >+ EXPECT_WK_STREQ("bold", [webView stylePropertyAtSelectionStart:@"font-weight"]); >+ EXPECT_EQ(boldItalicArialFont, fontManager.selectedFont); >+ >+ NSFont *largeItalicLightAvenirFont = [fontManager fontWithFamily:@"Avenir" traits:NSItalicFontMask weight:NSFontWeightLight size:24]; >+ [fontPanel setPanelFont:largeItalicLightAvenirFont isMultiple:NO]; >+ [webView selectAll:nil]; >+ [fontManager modifyFontViaPanel:fontPanel]; >+ EXPECT_WK_STREQ("foo bar baz", [webView selectedText]); >+ EXPECT_WK_STREQ("Avenir-LightOblique", [webView stylePropertyAtSelectionStart:@"font-family"]); >+ EXPECT_WK_STREQ("24px", [webView stylePropertyAtSelectionStart:@"font-size"]); >+ EXPECT_WK_STREQ("normal", [webView stylePropertyAtSelectionStart:@"font-weight"]); >+ EXPECT_EQ(largeItalicLightAvenirFont, fontManager.selectedFont); >+} >+ >+} // namespace TestWebKitAPI >+ >+#endif // PLATFORM(MAC)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189295
:
348892
|
348947
|
348981
|
348984
|
348986
|
348989
|
348995
|
349029
|
349050