[Cocoa] [WK2] Add support for text alignment and text lists in font attributes
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Oct 2018 01:52:49 +0000 (01:52 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Oct 2018 01:52:49 +0000 (01:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190342
<rdar://problem/44767118>

Reviewed by Tim Horton.

Source/WebCore:

Adds support for computing and encoding information about text alignment and enclosing list elements in the font
attributes dictionary, exposed to the UI delegate on Cocoa platforms. This is exposed through NSParagraphStyle,
which contains properties for both `NSTextAlignment` and an array of enclosing `NSTextList` objects.

Test:   FontAttributes.NestedTextListsWithHorizontalAlignment
        FontAttributes.FontAttributesAfterChangingSelection

* editing/Editor.cpp:
(WebCore::editableTextListsAtPositionInDescendingOrder):

Add a helper function to ascend the DOM, starting at the given position, in search of enclosing list elements.
For each enclosing list element we find within the scope of the editable root, we create a `TextList`
representing the list element.

(WebCore::Editor::fontAttributesAtSelectionStart const):

Compute and set enclosing text lists and text alignment. For text alignment, we convert the initial text-align
value, `start`, to NSTextAlignmentNatural (the default text alignment type on Cocoa platforms); other values
then map to Left, Right, Center, and Justified as expected (taking direction into account).

* editing/FontAttributes.h:
(WebCore::TextList::encode const):
(WebCore::TextList::decode):

Introduce TextList, a platform-agnostic representation of an unordered or ordered list. On Cocoa, this can be
used to construct a corresponding NSTextList.

* editing/cocoa/FontAttributesCocoa.mm:
(WebCore::cocoaTextListMarkerName):

Attempt to map a WebCore list style type to a `NSTextListMarker*` constant. While most of the Cocoa marker
formats have a corresponding web-exposed list style type, many web-exposed types have no Cocoa equivalent; as
such, fall back to default marker formats: "{disc}" for unordered lists and "{decimal}" for ordered lists.

(WebCore::TextList::createTextList const):
(WebCore::FontAttributes::createDictionary const):

Include an NSParagraphStyle in the dictionary of font attributes that includes information about text alignment
and enclosing text lists (per Cocoa convention, in order from outermost list to innermost list).

Source/WebCore/PAL:

* pal/ios/UIKitSoftLink.h:
* pal/ios/UIKitSoftLink.mm:

Add NSParagraphStyle and NSTextList to the UIKit soft link header.

* pal/spi/cocoa/NSAttributedStringSPI.h:
* pal/spi/ios/UIKitSPI.h:

Add some SPI declarations for NSMutableParagraphStyle and NSTextList when building with a non-internal iOS SDK,
and import <UIKit/NSParagraphStyle_Private.h> and <UIKit/NSTextList.h> when building with an internal iOS SDK.
Additionally, define some internal UIFoundation string constants that denote NSTextList marker formats. These
constants are API on macOS, but are neither exposed as API nor SPI on iOS.

Source/WebKit:

Add encoding and decoding for text alignment and text lists in FontAttributes.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<FontAttributes>::encode):
(IPC::ArgumentCoder<FontAttributes>::decode):

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/FontAttributes.mm:

Add a new API test to check that the font attributes dictionary contains the correct NSParagraphStyles when
moving the selection around text inside nested list elements.

(TestWebKitAPI::checkParagraphStyles):

Add a new helper to check an NSParagraphStyle against expected results.

(TestWebKitAPI::webViewForTestingFontAttributes):

Allow each test to pass in the name of the test page to load.

(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKitCocoa/nested-lists.html: Added.

Add a new test page that contains text enclosed in multiple levels of unordered and ordered lists.

* TestWebKitAPI/Tests/WebKitCocoa/rich-text-attributes.html:

Remove `text-align: left` from one of these elements, to test for NSTextAlignmentNatural.

LayoutTests:

* editing/mac/attributed-string/attributed-string-for-typing-expected.txt:
* editing/mac/attributed-string/attributed-string-for-typing-with-color-filter-expected.txt:
* platform/mac-sierra/editing/mac/attributed-string/attributed-string-for-typing-expected.txt:
* platform/mac-sierra/editing/mac/attributed-string/attributed-string-for-typing-with-color-filter-expected.txt:

Rebaseline these two layout tests, now that typing attributes include an NSParagraphStyle.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236955 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/mac/attributed-string/attributed-string-for-typing-expected.txt
LayoutTests/editing/mac/attributed-string/attributed-string-for-typing-with-color-filter-expected.txt
LayoutTests/platform/mac-sierra/editing/mac/attributed-string/attributed-string-for-typing-expected.txt
LayoutTests/platform/mac-sierra/editing/mac/attributed-string/attributed-string-for-typing-with-color-filter-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/PAL/ChangeLog
Source/WebCore/PAL/pal/ios/UIKitSoftLink.h
Source/WebCore/PAL/pal/ios/UIKitSoftLink.mm
Source/WebCore/PAL/pal/spi/cocoa/NSAttributedStringSPI.h
Source/WebCore/PAL/pal/spi/ios/UIKitSPI.h
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/FontAttributes.h
Source/WebCore/editing/cocoa/FontAttributesCocoa.mm
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/FontAttributes.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/nested-lists.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/rich-text-attributes.html

index 858aa49..b64d56e 100644 (file)
@@ -1,3 +1,18 @@
+2018-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Cocoa] [WK2] Add support for text alignment and text lists in font attributes
+        https://bugs.webkit.org/show_bug.cgi?id=190342
+        <rdar://problem/44767118>
+
+        Reviewed by Tim Horton.
+
+        * editing/mac/attributed-string/attributed-string-for-typing-expected.txt:
+        * editing/mac/attributed-string/attributed-string-for-typing-with-color-filter-expected.txt:
+        * platform/mac-sierra/editing/mac/attributed-string/attributed-string-for-typing-expected.txt:
+        * platform/mac-sierra/editing/mac/attributed-string/attributed-string-for-typing-with-color-filter-expected.txt:
+
+        Rebaseline these two layout tests, now that typing attributes include an NSParagraphStyle.
+
 2018-10-08  Justin Fan  <justin_fan@apple.com>
 
         WebGPU: Rename old WebGPU prototype to WebMetal
index 36be1cc..d387bcc 100644 (file)
@@ -3,6 +3,39 @@ Input:
 <div id="editor" style="color: rgba(23, 45, 56, 0.4);" contenteditable="">Some text here</div>
 
 Output:
+NSParagraphStyle:
+Alignment 4
+    LineSpacing: 0
+    ParagraphSpacing: 0
+    ParagraphSpacingBefore: 0
+    HeadIndent: 0
+    TailIndent: 0
+    FirstLineHeadIndent: 0
+    LineHeight: 0/0
+    LineHeightMultiple: 0
+    LineBreakMode: 0
+    Tabs: (    28L,
+    56L,
+    84L,
+    112L,
+    140L,
+    168L,
+    196L,
+    224L,
+    252L,
+    280L,
+    308L,
+    336L
+)
+    DefaultTabInterval: 0
+    Blocks: (
+)
+    Lists: (
+)
+    BaseWritingDirection: -1
+    HyphenationFactor: 0
+    TighteningForTruncation: YES
+    HeaderLevel: 0
 [ ]
     NSColor: rgba(23, 45, 56, 0.4) (sRGB)
     NSFont: Times-Roman 16.00 pt.
index ac8cd04..e7e28c0 100644 (file)
@@ -3,6 +3,39 @@ Input:
 <div id="editor" style="-apple-color-filter: apple-invert-lightness(); color: rgba(20, 20, 20, 0.4); background: #ccc;" contenteditable="">Some text here</div>
 
 Output:
+NSParagraphStyle:
+Alignment 4
+    LineSpacing: 0
+    ParagraphSpacing: 0
+    ParagraphSpacingBefore: 0
+    HeadIndent: 0
+    TailIndent: 0
+    FirstLineHeadIndent: 0
+    LineHeight: 0/0
+    LineHeightMultiple: 0
+    LineBreakMode: 0
+    Tabs: (    28L,
+    56L,
+    84L,
+    112L,
+    140L,
+    168L,
+    196L,
+    224L,
+    252L,
+    280L,
+    308L,
+    336L
+)
+    DefaultTabInterval: 0
+    Blocks: (
+)
+    Lists: (
+)
+    BaseWritingDirection: -1
+    HyphenationFactor: 0
+    TighteningForTruncation: YES
+    HeaderLevel: 0
 [ ]
     NSBackgroundColor: #5c5c5c (sRGB)
     NSColor: rgba(239, 239, 239, 0.4) (sRGB)
index a881ff1..07b79c5 100644 (file)
@@ -3,6 +3,39 @@ Input:
 <div id="editor" style="color: rgba(23, 45, 56, 0.4);" contenteditable="">Some text here</div>
 
 Output:
+NSParagraphStyle:
+Alignment 4
+    LineSpacing: 0
+    ParagraphSpacing: 0
+    ParagraphSpacingBefore: 0
+    HeadIndent: 0
+    TailIndent: 0
+    FirstLineHeadIndent: 0
+    LineHeight: 0/0
+    LineHeightMultiple: 0
+    LineBreakMode: 0
+    Tabs: (    28L,
+    56L,
+    84L,
+    112L,
+    140L,
+    168L,
+    196L,
+    224L,
+    252L,
+    280L,
+    308L,
+    336L
+)
+    DefaultTabInterval: 0
+    Blocks: (
+)
+    Lists: (
+)
+    BaseWritingDirection: -1
+    HyphenationFactor: 0
+    TighteningForTruncation: YES
+    HeaderLevel: 0
 [ ]
     NSColor: rgba(23, 45, 56, 0.4) (NSCustomColorSpace)
     NSFont: Times-Roman 16.00 pt.
index 196d494..5813d27 100644 (file)
@@ -3,6 +3,39 @@ Input:
 <div id="editor" style="-apple-color-filter: apple-invert-lightness(); color: rgba(20, 20, 20, 0.4); background: #ccc;" contenteditable="">Some text here</div>
 
 Output:
+NSParagraphStyle:
+Alignment 4
+    LineSpacing: 0
+    ParagraphSpacing: 0
+    ParagraphSpacingBefore: 0
+    HeadIndent: 0
+    TailIndent: 0
+    FirstLineHeadIndent: 0
+    LineHeight: 0/0
+    LineHeightMultiple: 0
+    LineBreakMode: 0
+    Tabs: (    28L,
+    56L,
+    84L,
+    112L,
+    140L,
+    168L,
+    196L,
+    224L,
+    252L,
+    280L,
+    308L,
+    336L
+)
+    DefaultTabInterval: 0
+    Blocks: (
+)
+    Lists: (
+)
+    BaseWritingDirection: -1
+    HyphenationFactor: 0
+    TighteningForTruncation: YES
+    HeaderLevel: 0
 [ ]
     NSBackgroundColor: #5c5c5c (NSCustomColorSpace)
     NSColor: rgba(239, 239, 239, 0.4) (NSCustomColorSpace)
index 75d1fa5..ec96959 100644 (file)
@@ -1,3 +1,51 @@
+2018-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Cocoa] [WK2] Add support for text alignment and text lists in font attributes
+        https://bugs.webkit.org/show_bug.cgi?id=190342
+        <rdar://problem/44767118>
+
+        Reviewed by Tim Horton.
+
+        Adds support for computing and encoding information about text alignment and enclosing list elements in the font
+        attributes dictionary, exposed to the UI delegate on Cocoa platforms. This is exposed through NSParagraphStyle,
+        which contains properties for both `NSTextAlignment` and an array of enclosing `NSTextList` objects.
+
+        Test:   FontAttributes.NestedTextListsWithHorizontalAlignment
+                FontAttributes.FontAttributesAfterChangingSelection
+
+        * editing/Editor.cpp:
+        (WebCore::editableTextListsAtPositionInDescendingOrder):
+
+        Add a helper function to ascend the DOM, starting at the given position, in search of enclosing list elements.
+        For each enclosing list element we find within the scope of the editable root, we create a `TextList`
+        representing the list element.
+
+        (WebCore::Editor::fontAttributesAtSelectionStart const):
+
+        Compute and set enclosing text lists and text alignment. For text alignment, we convert the initial text-align
+        value, `start`, to NSTextAlignmentNatural (the default text alignment type on Cocoa platforms); other values
+        then map to Left, Right, Center, and Justified as expected (taking direction into account).
+
+        * editing/FontAttributes.h:
+        (WebCore::TextList::encode const):
+        (WebCore::TextList::decode):
+
+        Introduce TextList, a platform-agnostic representation of an unordered or ordered list. On Cocoa, this can be
+        used to construct a corresponding NSTextList.
+
+        * editing/cocoa/FontAttributesCocoa.mm:
+        (WebCore::cocoaTextListMarkerName):
+
+        Attempt to map a WebCore list style type to a `NSTextListMarker*` constant. While most of the Cocoa marker
+        formats have a corresponding web-exposed list style type, many web-exposed types have no Cocoa equivalent; as
+        such, fall back to default marker formats: "{disc}" for unordered lists and "{decimal}" for ordered lists.
+
+        (WebCore::TextList::createTextList const):
+        (WebCore::FontAttributes::createDictionary const):
+
+        Include an NSParagraphStyle in the dictionary of font attributes that includes information about text alignment
+        and enclosing text lists (per Cocoa convention, in order from outermost list to innermost list).
+
 2018-10-08  Justin Fan  <justin_fan@apple.com>
 
         WebGPU: Rename old WebGPU prototype to WebMetal
index 29fede1..650f653 100644 (file)
@@ -1,3 +1,24 @@
+2018-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Cocoa] [WK2] Add support for text alignment and text lists in font attributes
+        https://bugs.webkit.org/show_bug.cgi?id=190342
+        <rdar://problem/44767118>
+
+        Reviewed by Tim Horton.
+
+        * pal/ios/UIKitSoftLink.h:
+        * pal/ios/UIKitSoftLink.mm:
+
+        Add NSParagraphStyle and NSTextList to the UIKit soft link header.
+
+        * pal/spi/cocoa/NSAttributedStringSPI.h:
+        * pal/spi/ios/UIKitSPI.h:
+
+        Add some SPI declarations for NSMutableParagraphStyle and NSTextList when building with a non-internal iOS SDK,
+        and import <UIKit/NSParagraphStyle_Private.h> and <UIKit/NSTextList.h> when building with an internal iOS SDK.
+        Additionally, define some internal UIFoundation string constants that denote NSTextList marker formats. These
+        constants are API on macOS, but are neither exposed as API nor SPI on iOS.
+
 2018-10-08  Justin Fan  <justin_fan@apple.com>
 
         WebGPU: Rename old WebGPU prototype to WebMetal
index 913d72e..cb0263c 100644 (file)
@@ -32,7 +32,9 @@
 
 SOFT_LINK_FRAMEWORK_FOR_HEADER(PAL, UIKit)
 
+SOFT_LINK_CLASS_FOR_HEADER(PAL, UIKit, NSParagraphStyle)
 SOFT_LINK_CLASS_FOR_HEADER(PAL, UIKit, NSShadow)
+SOFT_LINK_CLASS_FOR_HEADER(PAL, UIKit, NSTextList)
 SOFT_LINK_CLASS_FOR_HEADER(PAL, UIKit, UIApplication)
 SOFT_LINK_CLASS_FOR_HEADER(PAL, UIKit, UIScreen)
 SOFT_LINK_CLASS_FOR_HEADER(PAL, UIKit, UIColor)
index c0b4579..627c64d 100644 (file)
@@ -32,7 +32,9 @@
 
 SOFT_LINK_FRAMEWORK_FOR_SOURCE(PAL, UIKit)
 
+SOFT_LINK_CLASS_FOR_SOURCE(PAL, UIKit, NSParagraphStyle)
 SOFT_LINK_CLASS_FOR_SOURCE(PAL, UIKit, NSShadow)
+SOFT_LINK_CLASS_FOR_SOURCE(PAL, UIKit, NSTextList)
 SOFT_LINK_CLASS_FOR_SOURCE(PAL, UIKit, UIApplication)
 SOFT_LINK_CLASS_FOR_SOURCE(PAL, UIKit, UIScreen)
 SOFT_LINK_CLASS_FOR_SOURCE(PAL, UIKit, UIColor)
index d751090..0daf7ef 100644 (file)
@@ -105,4 +105,20 @@ static NSString *const NSSuperscriptAttributeName = @"NSSuperscript";
 - (BOOL)containsAttachments;
 @end
 
-#endif
+#endif // PLATFORM(IOS)
+
+#if PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED < 101300)
+static NSString *const NSTextListMarkerCircle = @"{circle}";
+static NSString *const NSTextListMarkerDisc = @"{disc}";
+static NSString *const NSTextListMarkerSquare = @"{square}";
+static NSString *const NSTextListMarkerLowercaseHexadecimal = @"{lower-hexadecimal}";
+static NSString *const NSTextListMarkerUppercaseHexadecimal = @"{upper-hexadecimal}";
+static NSString *const NSTextListMarkerOctal = @"{octal}";
+static NSString *const NSTextListMarkerLowercaseAlpha = @"{lower-alpha}";
+static NSString *const NSTextListMarkerUppercaseAlpha = @"{upper-alpha}";
+static NSString *const NSTextListMarkerLowercaseLatin = @"{lower-latin}";
+static NSString *const NSTextListMarkerUppercaseLatin = @"{upper-latin}";
+static NSString *const NSTextListMarkerLowercaseRoman = @"{lower-roman}";
+static NSString *const NSTextListMarkerUppercaseRoman = @"{upper-roman}";
+static NSString *const NSTextListMarkerDecimal = @"{decimal}";
+#endif // PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED < 101300)
index 5f850d9..c5e3ccb 100644 (file)
@@ -25,6 +25,8 @@
 
 #if USE(APPLE_INTERNAL_SDK)
 
+#import <UIKit/NSParagraphStyle_Private.h>
+#import <UIKit/NSTextList.h>
 #import <UIKit/UIApplicationSceneConstants.h>
 #import <UIKit/UIApplication_Private.h>
 #import <UIKit/UIColor_Private.h>
@@ -59,6 +61,20 @@ typedef NS_ENUM(NSInteger, UIApplicationSceneClassicMode) {
     UIApplicationSceneClassicModeOriginalPad = 4,
 };
 
+@interface NSParagraphStyle ()
+- (NSArray *)textLists;
+@end
+
+@interface NSMutableParagraphStyle ()
+- (void)setTextLists:(NSArray *)textLists;
+@end
+
+@interface NSTextList : NSObject
+- (instancetype)initWithMarkerFormat:(NSString *)format options:(NSUInteger)mask;
+@property (readonly, copy) NSString *markerFormat;
+@property NSInteger startingItemNumber;
+@end
+
 @interface UIApplication ()
 
 - (BOOL)_isClassic;
index b7f3e8c..a9e6967 100644 (file)
@@ -3867,6 +3867,40 @@ void Editor::platformFontAttributesAtSelectionStart(FontAttributes&, const Rende
 
 #endif
 
+static Vector<TextList> editableTextListsAtPositionInDescendingOrder(const Position& position)
+{
+    auto startContainer = makeRefPtr(position.containerNode());
+    if (!startContainer)
+        return { };
+
+    auto* editableRoot = highestEditableRoot(firstPositionInOrBeforeNode(startContainer.get()));
+    if (!editableRoot)
+        return { };
+
+    Vector<Ref<HTMLElement>> enclosingLists;
+    for (auto& ancestor : ancestorsOfType<HTMLElement>(*startContainer)) {
+        if (&ancestor == editableRoot)
+            break;
+
+        auto* renderer = ancestor.renderer();
+        if (!renderer)
+            continue;
+
+        if (is<HTMLUListElement>(ancestor) || is<HTMLOListElement>(ancestor))
+            enclosingLists.append(ancestor);
+    }
+
+    Vector<TextList> textLists;
+    textLists.reserveCapacity(enclosingLists.size());
+    for (auto iterator = enclosingLists.rbegin(); iterator != enclosingLists.rend(); ++iterator) {
+        auto& list = iterator->get();
+        bool ordered = is<HTMLOListElement>(list);
+        textLists.uncheckedAppend({ list.renderer()->style().listStyleType(), ordered ? downcast<HTMLOListElement>(list).start() : 1, ordered });
+    }
+
+    return textLists;
+}
+
 FontAttributes Editor::fontAttributesAtSelectionStart() const
 {
     FontAttributes attributes;
@@ -3905,10 +3939,36 @@ FontAttributes Editor::fontAttributesAtSelectionStart() const
     case VerticalAlign::Top:
         break;
     case VerticalAlign::Sub:
-        attributes.subscriptOrSuperscript = SubscriptOrSuperscript::Subscript;
+        attributes.subscriptOrSuperscript = FontAttributes::SubscriptOrSuperscript::Subscript;
         break;
     case VerticalAlign::Super:
-        attributes.subscriptOrSuperscript = SubscriptOrSuperscript::Superscript;
+        attributes.subscriptOrSuperscript = FontAttributes::SubscriptOrSuperscript::Superscript;
+        break;
+    }
+
+    attributes.textLists = editableTextListsAtPositionInDescendingOrder(m_frame.selection().selection().start());
+
+    switch (style->textAlign()) {
+    case TextAlignMode::Right:
+    case TextAlignMode::WebKitRight:
+        attributes.horizontalAlignment = FontAttributes::HorizontalAlignment::Right;
+        break;
+    case TextAlignMode::Left:
+    case TextAlignMode::WebKitLeft:
+        attributes.horizontalAlignment = FontAttributes::HorizontalAlignment::Left;
+        break;
+    case TextAlignMode::Center:
+    case TextAlignMode::WebKitCenter:
+        attributes.horizontalAlignment = FontAttributes::HorizontalAlignment::Center;
+        break;
+    case TextAlignMode::Justify:
+        attributes.horizontalAlignment = FontAttributes::HorizontalAlignment::Justify;
+        break;
+    case TextAlignMode::Start:
+        attributes.horizontalAlignment = FontAttributes::HorizontalAlignment::Natural;
+        break;
+    case TextAlignMode::End:
+        attributes.horizontalAlignment = style->isLeftToRightDirection() ? FontAttributes::HorizontalAlignment::Right : FontAttributes::HorizontalAlignment::Left;
         break;
     }
 
index fb2db4f..9124234 100644 (file)
 #pragma once
 
 #include "FontShadow.h"
+#include "RenderStyleConstants.h"
 #include <wtf/RetainPtr.h>
 
 OBJC_CLASS NSDictionary;
 OBJC_CLASS NSFont;
+OBJC_CLASS NSTextList;
 OBJC_CLASS UIFont;
 
 namespace WebCore {
 
-enum class SubscriptOrSuperscript : uint8_t { None, Subscript, Superscript };
+struct TextList {
+    ListStyleType style { ListStyleType::None };
+    int startingItemNumber { 0 };
+    bool ordered { false };
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<TextList> decode(Decoder&);
+
+#if PLATFORM(COCOA)
+    RetainPtr<NSTextList> createTextList() const;
+#endif
+};
+
+template<class Encoder> inline void TextList::encode(Encoder& encoder) const
+{
+    encoder << static_cast<uint8_t>(style) << startingItemNumber << ordered;
+}
+
+template<class Decoder> inline std::optional<TextList> TextList::decode(Decoder& decoder)
+{
+    std::optional<uint8_t> style;
+    decoder >> style;
+    if (!style)
+        return std::nullopt;
+
+    std::optional<int> startingItemNumber;
+    decoder >> startingItemNumber;
+    if (!startingItemNumber)
+        return std::nullopt;
+
+    std::optional<bool> ordered;
+    decoder >> ordered;
+    if (!ordered)
+        return std::nullopt;
+
+    return {{ static_cast<ListStyleType>(WTFMove(*style)), WTFMove(*startingItemNumber), WTFMove(*ordered) }};
+}
 
 struct FontAttributes {
+    enum class SubscriptOrSuperscript : uint8_t { None, Subscript, Superscript };
+    enum class HorizontalAlignment : uint8_t { Left, Center, Right, Justify, Natural };
+
 #if PLATFORM(COCOA)
     WEBCORE_EXPORT RetainPtr<NSDictionary> createDictionary() const;
 #endif
@@ -50,6 +91,8 @@ struct FontAttributes {
     Color foregroundColor;
     FontShadow fontShadow;
     SubscriptOrSuperscript subscriptOrSuperscript { SubscriptOrSuperscript::None };
+    HorizontalAlignment horizontalAlignment { HorizontalAlignment::Left };
+    Vector<TextList> textLists;
     bool hasUnderline { false };
     bool hasStrikeThrough { false };
 };
@@ -58,12 +101,23 @@ struct FontAttributes {
 
 namespace WTF {
 
-template<> struct EnumTraits<WebCore::SubscriptOrSuperscript> {
+template<> struct EnumTraits<WebCore::FontAttributes::SubscriptOrSuperscript> {
+    using values = EnumValues<
+        WebCore::FontAttributes::SubscriptOrSuperscript,
+        WebCore::FontAttributes::SubscriptOrSuperscript::None,
+        WebCore::FontAttributes::SubscriptOrSuperscript::Subscript,
+        WebCore::FontAttributes::SubscriptOrSuperscript::Superscript
+    >;
+};
+
+template<> struct EnumTraits<WebCore::FontAttributes::HorizontalAlignment> {
     using values = EnumValues<
-        WebCore::SubscriptOrSuperscript,
-        WebCore::SubscriptOrSuperscript::None,
-        WebCore::SubscriptOrSuperscript::Subscript,
-        WebCore::SubscriptOrSuperscript::Superscript
+        WebCore::FontAttributes::HorizontalAlignment,
+        WebCore::FontAttributes::HorizontalAlignment::Left,
+        WebCore::FontAttributes::HorizontalAlignment::Center,
+        WebCore::FontAttributes::HorizontalAlignment::Right,
+        WebCore::FontAttributes::HorizontalAlignment::Justify,
+        WebCore::FontAttributes::HorizontalAlignment::Natural
     >;
 };
 
index aabeb20..51f0b13 100644 (file)
 #import "FontAttributes.h"
 
 #import "ColorCocoa.h"
+#import <pal/spi/cocoa/NSAttributedStringSPI.h>
+
+#if PLATFORM(IOS)
+#import <pal/ios/UIKitSoftLink.h>
+#endif
 
 namespace WebCore {
 
+static NSString *cocoaTextListMarkerName(ListStyleType style, bool ordered)
+{
+    switch (style) {
+    case ListStyleType::Disc:
+        return NSTextListMarkerDisc;
+    case ListStyleType::Circle:
+        return NSTextListMarkerCircle;
+    case ListStyleType::Square:
+        return NSTextListMarkerSquare;
+    case ListStyleType::Decimal:
+        return NSTextListMarkerDecimal;
+    case ListStyleType::Octal:
+        return NSTextListMarkerOctal;
+    case ListStyleType::LowerRoman:
+        return NSTextListMarkerLowercaseRoman;
+    case ListStyleType::UpperRoman:
+        return NSTextListMarkerUppercaseRoman;
+    case ListStyleType::LowerAlpha:
+        return NSTextListMarkerLowercaseAlpha;
+    case ListStyleType::UpperAlpha:
+        return NSTextListMarkerUppercaseAlpha;
+    case ListStyleType::LowerLatin:
+        return NSTextListMarkerLowercaseLatin;
+    case ListStyleType::UpperLatin:
+        return NSTextListMarkerUppercaseLatin;
+    case ListStyleType::LowerHexadecimal:
+        return NSTextListMarkerLowercaseHexadecimal;
+    case ListStyleType::UpperHexadecimal:
+        return NSTextListMarkerUppercaseHexadecimal;
+    default:
+        // The remaining web-exposed list style types have no Cocoa equivalents.
+        // Fall back to default styles for ordered and unordered lists.
+        return ordered ? NSTextListMarkerDecimal : NSTextListMarkerDisc;
+    }
+}
+
+RetainPtr<NSTextList> TextList::createTextList() const
+{
+#if PLATFORM(MAC)
+    Class textListClass = NSTextList.class;
+#else
+    Class textListClass = PAL::get_UIKit_NSTextListClass();
+#endif
+    auto result = adoptNS([[textListClass alloc] initWithMarkerFormat:cocoaTextListMarkerName(style, ordered) options:0]);
+    [result setStartingItemNumber:startingItemNumber];
+    return result;
+}
+
 RetainPtr<NSDictionary> FontAttributes::createDictionary() const
 {
     NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
@@ -50,6 +103,40 @@ RetainPtr<NSDictionary> FontAttributes::createDictionary() const
     else if (subscriptOrSuperscript == SubscriptOrSuperscript::Superscript)
         attributes[NSSuperscriptAttributeName] = @1;
 
+#if PLATFORM(MAC)
+    Class paragraphStyleClass = NSParagraphStyle.class;
+#else
+    Class paragraphStyleClass = PAL::get_UIKit_NSParagraphStyleClass();
+#endif
+    auto style = adoptNS([[paragraphStyleClass defaultParagraphStyle] mutableCopy]);
+
+    switch (horizontalAlignment) {
+    case HorizontalAlignment::Left:
+        [style setAlignment:NSTextAlignmentLeft];
+        break;
+    case HorizontalAlignment::Center:
+        [style setAlignment:NSTextAlignmentCenter];
+        break;
+    case HorizontalAlignment::Right:
+        [style setAlignment:NSTextAlignmentRight];
+        break;
+    case HorizontalAlignment::Justify:
+        [style setAlignment:NSTextAlignmentJustified];
+        break;
+    case HorizontalAlignment::Natural:
+        [style setAlignment:NSTextAlignmentNatural];
+        break;
+    }
+
+    if (!textLists.isEmpty()) {
+        auto textListArray = adoptNS([[NSMutableArray alloc] initWithCapacity:textLists.size()]);
+        for (auto& textList : textLists)
+            [textListArray addObject:textList.createTextList().get()];
+        [style setTextLists:textListArray.get()];
+    }
+
+    attributes[NSParagraphStyleAttributeName] = style.get();
+
     if (hasUnderline)
         attributes[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
 
index 19e90a7..232478d 100644 (file)
@@ -1,3 +1,17 @@
+2018-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Cocoa] [WK2] Add support for text alignment and text lists in font attributes
+        https://bugs.webkit.org/show_bug.cgi?id=190342
+        <rdar://problem/44767118>
+
+        Reviewed by Tim Horton.
+
+        Add encoding and decoding for text alignment and text lists in FontAttributes.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<FontAttributes>::encode):
+        (IPC::ArgumentCoder<FontAttributes>::decode):
+
 2018-10-08  Justin Fan  <justin_fan@apple.com>
 
         WebGPU: Rename old WebGPU prototype to WebMetal
index e507bf8..d2148bf 100644 (file)
@@ -2980,7 +2980,8 @@ bool ArgumentCoder<Vector<RefPtr<SecurityOrigin>>>::decode(Decoder& decoder, Vec
 
 void ArgumentCoder<FontAttributes>::encode(Encoder& encoder, const FontAttributes& attributes)
 {
-    encoder << attributes.backgroundColor << attributes.foregroundColor << attributes.fontShadow << attributes.hasUnderline << attributes.hasStrikeThrough;
+    encoder << attributes.backgroundColor << attributes.foregroundColor << attributes.fontShadow << attributes.hasUnderline << attributes.hasStrikeThrough << attributes.textLists;
+    encoder.encodeEnum(attributes.horizontalAlignment);
     encoder.encodeEnum(attributes.subscriptOrSuperscript);
 #if PLATFORM(COCOA)
     bool hasFont = attributes.font;
@@ -3009,6 +3010,12 @@ std::optional<FontAttributes> ArgumentCoder<FontAttributes>::decode(Decoder& dec
     if (!decoder.decode(attributes.hasStrikeThrough))
         return std::nullopt;
 
+    if (!decoder.decode(attributes.textLists))
+        return std::nullopt;
+
+    if (!decoder.decodeEnum(attributes.horizontalAlignment))
+        return std::nullopt;
+
     if (!decoder.decodeEnum(attributes.subscriptOrSuperscript))
         return std::nullopt;
 
index 99e0a97..58a6d92 100644 (file)
@@ -1,3 +1,34 @@
+2018-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Cocoa] [WK2] Add support for text alignment and text lists in font attributes
+        https://bugs.webkit.org/show_bug.cgi?id=190342
+        <rdar://problem/44767118>
+
+        Reviewed by Tim Horton.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/FontAttributes.mm:
+
+        Add a new API test to check that the font attributes dictionary contains the correct NSParagraphStyles when
+        moving the selection around text inside nested list elements.
+
+        (TestWebKitAPI::checkParagraphStyles):
+
+        Add a new helper to check an NSParagraphStyle against expected results.
+
+        (TestWebKitAPI::webViewForTestingFontAttributes):
+
+        Allow each test to pass in the name of the test page to load.
+
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/nested-lists.html: Added.
+
+        Add a new test page that contains text enclosed in multiple levels of unordered and ordered lists.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/rich-text-attributes.html:
+
+        Remove `text-align: left` from one of these elements, to test for NSTextAlignmentNatural.
+
 2018-10-08  Justin Fan  <justin_fan@apple.com>
 
         WebGPU: Rename old WebGPU prototype to WebMetal
index 70207d9..762d4d1 100644 (file)
@@ -99,6 +99,7 @@
                2E1DFDEF1D42A6F200714A00 /* large-videos-with-audio-autoplay.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */; };
                2E1DFDF11D42E1E400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */; };
                2E205BA41F527746005952DD /* AccessibilityTestsIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E205BA31F527746005952DD /* AccessibilityTestsIOS.mm */; };
+               2E4838472169DF30002F4531 /* nested-lists.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E4838462169DD42002F4531 /* nested-lists.html */; };
                2E54F40D1D7BC84200921ADF /* large-video-mutes-onplaying.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E54F40C1D7BC83900921ADF /* large-video-mutes-onplaying.html */; };
                2E5C77071FA70136005932C3 /* WKAttachmentTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E5C77061FA70136005932C3 /* WKAttachmentTests.mm */; };
                2E691AEA1D78B53600129407 /* large-videos-paused-video-hides-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E691AE81D78B52B00129407 /* large-videos-paused-video-hides-controls.html */; };
                                9BCD411A206DBCA3001D71BE /* mso-list-on-h4.html in Copy Resources */,
                                9BF356CD202D458500F71160 /* mso-list.html in Copy Resources */,
                                5797FE331EB15AB100B2F4A0 /* navigation-client-default-crypto.html in Copy Resources */,
+                               2E4838472169DF30002F4531 /* nested-lists.html in Copy Resources */,
                                C99B675F1E39736F00FC6C80 /* no-autoplay-with-controls.html in Copy Resources */,
                                466C3843210637DE006A88DE /* notify-resourceLoadObserver.html in Copy Resources */,
                                CDB5DFFF213610FA00D3E189 /* now-playing.html in Copy Resources */,
                2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-with-audio-autoplay.html"; sourceTree = "<group>"; };
                2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-to-beginning-and-play-after-ending.html"; sourceTree = "<group>"; };
                2E205BA31F527746005952DD /* AccessibilityTestsIOS.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AccessibilityTestsIOS.mm; sourceTree = "<group>"; };
+               2E4838462169DD42002F4531 /* nested-lists.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "nested-lists.html"; sourceTree = "<group>"; };
                2E54F40C1D7BC83900921ADF /* large-video-mutes-onplaying.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-mutes-onplaying.html"; sourceTree = "<group>"; };
                2E5C77061FA70136005932C3 /* WKAttachmentTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WKAttachmentTests.mm; sourceTree = "<group>"; };
                2E691AE81D78B52B00129407 /* large-videos-paused-video-hides-controls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-paused-video-hides-controls.html"; sourceTree = "<group>"; };
                                9B59F12920340854009E63D5 /* mso-list-compat-mode.html */,
                                9BCD4119206D5ED7001D71BE /* mso-list-on-h4.html */,
                                9BF356CC202D44F200F71160 /* mso-list.html */,
+                               2E4838462169DD42002F4531 /* nested-lists.html */,
                                466C3842210637CE006A88DE /* notify-resourceLoadObserver.html */,
                                CDB5DFFE21360ED800D3E189 /* now-playing.html */,
                                93E2D2751ED7D51700FA76F6 /* offscreen-iframe-of-media-document.html */,
index 0b98b39..ffd5d97 100644 (file)
 #import "TestWKWebView.h"
 #import <WebKit/WKUIDelegatePrivate.h>
 #import <cmath>
+#import <pal/spi/cocoa/NSAttributedStringSPI.h>
 #import <wtf/Optional.h>
+#import <wtf/Vector.h>
+
+#if PLATFORM(IOS)
+#import <pal/spi/ios/UIKitSPI.h>
+#endif
 
 @interface FontAttributesListener : NSObject <WKUIDelegatePrivate>
 @property (nonatomic, readonly) NSDictionary *lastFontAttributes;
 #else
 #define PlatformColor UIColor
 #define PlatformFont UIFont
-static NSString *const NSSuperscriptAttributeName = @"NSSuperscript";
 #endif
 
 namespace TestWebKitAPI {
 
 enum class Nullity : uint8_t { Null, NonNull };
 
+struct ListExpectation {
+    NSString *markerFormat { nil };
+    int startingItemNumber { 0 };
+};
+
+struct ParagraphStyleExpectation {
+    NSTextAlignment alignment;
+    Vector<ListExpectation> textLists;
+};
+
 struct ColorExpectation {
     ColorExpectation(CGFloat redValue, CGFloat greenValue, CGFloat blueValue, CGFloat alphaValue)
         : red(redValue)
@@ -173,10 +188,25 @@ static void checkFont(PlatformFont *font, FontExpectation&& expectation)
     EXPECT_EQ(expectation.fontSize, font.pointSize);
 }
 
-static RetainPtr<TestWKWebView> webViewForTestingFontAttributes()
+static void checkParagraphStyles(NSParagraphStyle *style, ParagraphStyleExpectation&& expectation)
+{
+    EXPECT_EQ(expectation.alignment, style.alignment);
+    EXPECT_EQ(expectation.textLists.size(), style.textLists.count);
+    [style.textLists enumerateObjectsUsingBlock:^(NSTextList *textList, NSUInteger index, BOOL *stop) {
+        if (index >= expectation.textLists.size()) {
+            *stop = YES;
+            return;
+        }
+        auto& expectedList = expectation.textLists[index];
+        EXPECT_EQ(expectedList.startingItemNumber, textList.startingItemNumber);
+        EXPECT_WK_STREQ(expectedList.markerFormat, textList.markerFormat);
+    }];
+}
+
+static RetainPtr<TestWKWebView> webViewForTestingFontAttributes(NSString *testPageName)
 {
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 320, 500)]);
-    [webView synchronouslyLoadTestPageNamed:@"rich-text-attributes"];
+    [webView synchronouslyLoadTestPageNamed:testPageName];
     [webView stringByEvaluatingJavaScript:@"document.body.focus()"];
     return webView;
 }
@@ -184,7 +214,7 @@ static RetainPtr<TestWKWebView> webViewForTestingFontAttributes()
 TEST(FontAttributes, FontAttributesAfterChangingSelection)
 {
     auto delegate = adoptNS([FontAttributesListener new]);
-    auto webView = webViewForTestingFontAttributes();
+    auto webView = webViewForTestingFontAttributes(@"rich-text-attributes");
     [webView setUIDelegate:delegate.get()];
 
     {
@@ -194,6 +224,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { 255, 199, 119, 1 });
         checkFont(attributes[NSFontAttributeName], { "Helvetica-Bold", 48 });
         checkShadow(attributes[NSShadowAttributeName], { });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentNatural, { } });
         EXPECT_EQ(NSUnderlineStyleSingle, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -205,6 +236,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { 255, 197, 171, 1 });
         checkFont(attributes[NSFontAttributeName], { "Helvetica-Bold", 48 });
         checkShadow(attributes[NSShadowAttributeName], { 0.470588, 5 });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentNatural, { } });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleSingle, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -216,6 +248,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { });
         checkFont(attributes[NSFontAttributeName], { "Menlo-Italic", 18 });
         checkShadow(attributes[NSShadowAttributeName], { });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentCenter, { } });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -227,6 +260,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { 0, 0, 0, 1 });
         checkFont(attributes[NSFontAttributeName], { "Avenir-Book", 24 });
         checkShadow(attributes[NSShadowAttributeName], { });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentCenter, { } });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -238,6 +272,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { });
         checkFont(attributes[NSFontAttributeName], { "TimesNewRomanPS-BoldMT", 24 });
         checkShadow(attributes[NSShadowAttributeName], { });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentCenter, { } });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -249,6 +284,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { });
         checkFont(attributes[NSFontAttributeName], { "Avenir-Black", 18 });
         checkShadow(attributes[NSShadowAttributeName], { });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentLeft, {{ NSTextListMarkerDisc, 1 }} });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -260,6 +296,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { 78, 122, 39, 1 });
         checkFont(attributes[NSFontAttributeName], { "Avenir-BookOblique", 12 });
         checkShadow(attributes[NSShadowAttributeName], { });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentLeft, {{ NSTextListMarkerDisc, 1 }} });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(-1, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -271,6 +308,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { });
         checkFont(attributes[NSFontAttributeName], { "Avenir-Book", 12 });
         checkShadow(attributes[NSShadowAttributeName], { });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentLeft, {{ NSTextListMarkerDecimal, 1 }} });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(1, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -282,6 +320,7 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { });
         checkFont(attributes[NSFontAttributeName], { "Georgia", 36 });
         checkShadow(attributes[NSShadowAttributeName], { 0.658824, 9 });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentLeft, {{ NSTextListMarkerDecimal, 1 }} });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
@@ -293,12 +332,62 @@ TEST(FontAttributes, FontAttributesAfterChangingSelection)
         checkColor(attributes[NSBackgroundColorAttributeName], { });
         checkFont(attributes[NSFontAttributeName], { "Avenir-BookOblique", 18 });
         checkShadow(attributes[NSShadowAttributeName], { });
+        checkParagraphStyles(attributes[NSParagraphStyleAttributeName], { NSTextAlignmentRight, { } });
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSStrikethroughStyleAttributeName] integerValue]);
         EXPECT_EQ(NSUnderlineStyleNone, [attributes[NSUnderlineStyleAttributeName] integerValue]);
         EXPECT_EQ(0, [attributes[NSSuperscriptAttributeName] integerValue]);
     }
 }
 
+TEST(FontAttributes, NestedTextListsWithHorizontalAlignment)
+{
+    auto delegate = adoptNS([FontAttributesListener new]);
+    auto webView = webViewForTestingFontAttributes(@"nested-lists");
+    [webView setUIDelegate:delegate.get()];
+
+    [webView selectElementWithIdentifier:@"one"];
+    checkParagraphStyles([webView fontAttributesAfterNextPresentationUpdate][NSParagraphStyleAttributeName], {
+        NSTextAlignmentNatural,
+        {{ NSTextListMarkerDecimal, 1 }}
+    });
+
+    [webView selectElementWithIdentifier:@"two"];
+    checkParagraphStyles([webView fontAttributesAfterNextPresentationUpdate][NSParagraphStyleAttributeName], {
+        NSTextAlignmentLeft,
+        {{ NSTextListMarkerDecimal, 1 }, { NSTextListMarkerCircle, 1 }}
+    });
+
+    [webView selectElementWithIdentifier:@"three"];
+    checkParagraphStyles([webView fontAttributesAfterNextPresentationUpdate][NSParagraphStyleAttributeName], {
+        NSTextAlignmentCenter,
+        {{ NSTextListMarkerDecimal, 1 }, { NSTextListMarkerCircle, 1 }, { NSTextListMarkerUppercaseRoman, 50 }}
+    });
+
+    [webView selectElementWithIdentifier:@"four"];
+    checkParagraphStyles([webView fontAttributesAfterNextPresentationUpdate][NSParagraphStyleAttributeName], {
+        NSTextAlignmentLeft,
+        {{ NSTextListMarkerDecimal, 1 }, { NSTextListMarkerCircle, 1 }}
+    });
+
+    [webView selectElementWithIdentifier:@"five"];
+    checkParagraphStyles([webView fontAttributesAfterNextPresentationUpdate][NSParagraphStyleAttributeName], {
+        NSTextAlignmentRight,
+        {{ NSTextListMarkerDecimal, 1 }, { NSTextListMarkerCircle, 1 }, { NSTextListMarkerLowercaseLatin, 0 }}
+    });
+
+    [webView selectElementWithIdentifier:@"six"];
+    checkParagraphStyles([webView fontAttributesAfterNextPresentationUpdate][NSParagraphStyleAttributeName], {
+        NSTextAlignmentLeft,
+        {{ NSTextListMarkerDecimal, 1 }}
+    });
+
+    [webView selectElementWithIdentifier:@"seven"];
+    checkParagraphStyles([webView fontAttributesAfterNextPresentationUpdate][NSParagraphStyleAttributeName], {
+        NSTextAlignmentNatural,
+        { }
+    });
+}
+
 } // namespace TestWebKitAPI
 
 #endif
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/nested-lists.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/nested-lists.html
new file mode 100644 (file)
index 0000000..731055c
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<head>
+</head>
+<html>
+<body contenteditable>
+<ol>
+    <li style="text-align: start;" id="one">one</li>
+    <li>
+        <div>
+            <ul>
+                <li>
+                    <div id="two">two</div>
+                    <ol style="list-style-type: upper-roman;" start="50">
+                        <li style="text-align: center;" id="three">three</li>
+                    </ol>
+                </li>
+                <li>
+                    <div>
+                        <div style="text-align: left;" id="four">four</div>
+                        <ol style="list-style-type: lower-latin;" start="0">
+                            <li style="text-align: right;" id="five">five</li>
+                        </ol>
+                    </div>
+                </li>
+            </ul>
+            <div style="text-align: end;" dir="rtl" id="six">six</div>
+        </div>
+    </li>
+</ol>
+<div id="seven">seven</div>
+</body>
+</html>
\ No newline at end of file
index 5e8ce04..a9e8977 100644 (file)
@@ -10,7 +10,7 @@
 </head>
 <body contenteditable>
     <div>
-        <div style="text-align: left;">
+        <div>
             <span id="one" style="font-size: 48px; font-weight: bold; color: rgb(227, 36, 0); background-color: rgb(255, 199, 119); text-decoration: line-through;">One</span><span id="two" style="caret-color: rgb(102, 157, 52); color: rgb(102, 157, 52); background-color: rgb(255, 197, 171); text-decoration: underline; font-weight: bold; font-size: 48px; text-shadow: rgba(0, 0, 0, 0.470588) 0px 0px 5px;">Two</span>
         </div>
         <div style="text-align: center;">
@@ -31,4 +31,4 @@
         </div>
     </div>
 </body>
-</html>
\ No newline at end of file
+</html>