Diff
Modified: trunk/Source/WebCore/ChangeLog (235747 => 235748)
--- trunk/Source/WebCore/ChangeLog 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebCore/ChangeLog 2018-09-06 19:46:38 UTC (rev 235748)
@@ -1,3 +1,139 @@
+2018-09-06 Wenson Hsieh <[email protected]>
+
+ [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 Ryosuke Niwa.
+
+ 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.
+
+ (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-06 Zalan Bujtas <[email protected]>
[LFC][BFC] Add support for min(max)-width
Modified: trunk/Source/WebCore/SourcesCocoa.txt (235747 => 235748)
--- trunk/Source/WebCore/SourcesCocoa.txt 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebCore/SourcesCocoa.txt 2018-09-06 19:46:38 UTC (rev 235748)
@@ -78,6 +78,7 @@
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/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
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (235747 => 235748)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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 */; };
@@ -14510,8 +14513,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>"; };
@@ -14532,6 +14537,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>"; };
@@ -19191,6 +19199,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 */,
@@ -19855,6 +19865,7 @@
C5227DEF1C3C6DD700F5ED54 /* DataDetection.h */,
C5227DF01C3C6DD700F5ED54 /* DataDetection.mm */,
9B55EEE81B3E8898005342BC /* EditorCocoa.mm */,
+ F42CEB54214031EE002DCA72 /* FontAttributeChangesCocoa.mm */,
7C3E510818DF8F3500C112F7 /* HTMLConverter.h */,
7C3E510918DF8F3500C112F7 /* HTMLConverter.mm */,
E18536811F4E472700FE091B /* WebArchiveResourceFromNSAttributedString.h */,
@@ -20155,6 +20166,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 */,
@@ -27961,6 +27974,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 */,
@@ -30879,6 +30893,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 */,
@@ -31469,6 +31484,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 */,
Modified: trunk/Source/WebCore/editing/Editor.h (235747 => 235748)
--- trunk/Source/WebCore/editing/Editor.h 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebCore/editing/Editor.h 2018-09-06 19:46:38 UTC (rev 235748)
@@ -474,7 +474,6 @@
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
Added: trunk/Source/WebCore/editing/FontAttributeChanges.cpp (0 => 235748)
--- trunk/Source/WebCore/editing/FontAttributeChanges.cpp (rev 0)
+++ trunk/Source/WebCore/editing/FontAttributeChanges.cpp 2018-09-06 19:46:38 UTC (rev 235748)
@@ -0,0 +1,136 @@
+/*
+ * 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.ptr();
+}
+
+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) {
+ 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);
+ else
+ ASSERT_NOT_REACHED();
+ }
+
+ 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
Added: trunk/Source/WebCore/editing/FontAttributeChanges.h (0 => 235748)
--- trunk/Source/WebCore/editing/FontAttributeChanges.h (rev 0)
+++ trunk/Source/WebCore/editing/FontAttributeChanges.h 2018-09-06 19:46:38 UTC (rev 235748)
@@ -0,0 +1,125 @@
+/*
+ * 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:
+ std::optional<VerticalAlign> m_verticalAlign;
+ 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
Added: trunk/Source/WebCore/editing/cocoa/FontAttributeChangesCocoa.mm (0 => 235748)
--- trunk/Source/WebCore/editing/cocoa/FontAttributeChangesCocoa.mm (rev 0)
+++ trunk/Source/WebCore/editing/cocoa/FontAttributeChangesCocoa.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -0,0 +1,62 @@
+/*
+ * 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
+{
+ // 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.
+ // This logic was originally from WebHTMLView, and is now in WebCore so that it can
+ // be shared between WebKitLegacy and WebKit.
+ 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
Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (235747 => 235748)
--- trunk/Source/WebCore/editing/mac/EditorMac.mm 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -289,17 +289,6 @@
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)
Added: trunk/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.h (0 => 235748)
--- trunk/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.h (rev 0)
+++ trunk/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.h 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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
Added: trunk/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.mm (0 => 235748)
--- trunk/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.mm (rev 0)
+++ trunk/Source/WebCore/platform/mac/WebCoreNSFontManagerExtras.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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.setForegroundColor(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)
Modified: trunk/Source/WebKit/ChangeLog (235747 => 235748)
--- trunk/Source/WebKit/ChangeLog 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/ChangeLog 2018-09-06 19:46:38 UTC (rev 235748)
@@ -1,3 +1,37 @@
+2018-09-06 Wenson Hsieh <[email protected]>
+
+ [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 Ryosuke Niwa.
+
+ 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-06 Frederic Wang <[email protected]>
Use more generic names than "overflow" for functions that can be used for subframes
Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (235747 => 235748)
--- trunk/Source/WebKit/Scripts/webkit/messages.py 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py 2018-09-06 19:46:38 UTC (rev 235748)
@@ -381,6 +381,7 @@
'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>'],
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (235747 => 235748)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -3356,7 +3356,7 @@
- (void)changeFont:(id)sender
{
- _impl->changeFontFromFontPanel();
+ _impl->changeFontFromFontManager();
}
- (IBAction)startSpeaking:(id)sender
Modified: trunk/Source/WebKit/UIProcess/API/mac/WKView.mm (235747 => 235748)
--- trunk/Source/WebKit/UIProcess/API/mac/WKView.mm 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/UIProcess/API/mac/WKView.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -316,7 +316,7 @@
- (void)changeFont:(id)sender
{
- _data->_impl->changeFontFromFontPanel();
+ _data->_impl->changeFontFromFontManager();
}
/*
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h (235747 => 235748)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h 2018-09-06 19:46:38 UTC (rev 235748)
@@ -315,7 +315,7 @@
void selectionDidChange();
void didBecomeEditable();
void updateFontPanelIfNeeded();
- void changeFontFromFontPanel();
+ void changeFontFromFontManager();
bool validateUserInterfaceItem(id <NSValidatedUserInterfaceItem>);
void setEditableElementIsFocused(bool);
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (235747 => 235748)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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::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)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (235747 => 235748)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-09-06 19:46:38 UTC (rev 235748)
@@ -162,6 +162,7 @@
class Cursor;
class DragData;
class FloatRect;
+class FontChanges;
class GraphicsLayer;
class IntSize;
class ProtectionSpace;
@@ -680,7 +681,7 @@
#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();
Modified: trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm (235747 => 235748)
--- trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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 @@
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)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (235747 => 235748)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-09-06 19:46:38 UTC (rev 235748)
@@ -135,6 +135,7 @@
class CaptureDevice;
class DocumentLoader;
class DragData;
+class FontChanges;
class Frame;
class FrameSelection;
class FrameView;
@@ -1361,7 +1362,7 @@
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);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (235747 => 235748)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-09-06 19:46:38 UTC (rev 235748)
@@ -190,7 +190,7 @@
#if PLATFORM(MAC)
PerformDictionaryLookupOfCurrentSelection()
- SetFont(String fontFamily, double fontSize, uint64_t fontTraits)
+ ChangeFont(WebCore::FontChanges changes)
#endif
PreferencesDidChange(struct WebKit::WebPreferencesStore store)
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm (235747 => 235748)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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::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)
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (235747 => 235748)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2018-09-06 19:46:38 UTC (rev 235748)
@@ -1,3 +1,24 @@
+2018-09-06 Wenson Hsieh <[email protected]>
+
+ [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 Ryosuke Niwa.
+
+ 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 <[email protected]>
Add MediaCapabilities as an Experimental Feature
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm (235747 => 235748)
--- trunk/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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 @@
[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];
+ [self _applyEditingStyleToSelection:computedFontChanges(NSFontManager.sharedFontManager).createEditingStyle() 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;
-}
-
- (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
Modified: trunk/Tools/ChangeLog (235747 => 235748)
--- trunk/Tools/ChangeLog 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Tools/ChangeLog 2018-09-06 19:46:38 UTC (rev 235748)
@@ -1,3 +1,24 @@
+2018-09-06 Wenson Hsieh <[email protected]>
+
+ [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 Ryosuke Niwa.
+
+ 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-06 Zalan Bujtas <[email protected]>
[LFC][BFC] Add support for min(max)-width
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (235747 => 235748)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-09-06 18:52:17 UTC (rev 235747)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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 */,
Added: trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm (0 => 235748)
--- trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm 2018-09-06 19:46:38 UTC (rev 235748)
@@ -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) && WK_API_ENABLED
+
+#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) && WK_API_ENABLED