Title: [184894] trunk
Revision
184894
Author
akl...@apple.com
Date
2015-05-26 21:13:54 -0700 (Tue, 26 May 2015)

Log Message

<font face> doesn't support plus character in font family names.
<https://webkit.org/b/145400>
<rdar://problem/21097484>

Reviewed by Darin Adler.

Source/WebCore:

Turn CSSParser::parseFontFaceValue() into a fast-path parser for
<font face> attributes.
Going through the full CSS parser was hurting us here, as it would
misunderstand unquoted family names and choke on e.g '+'.

Test: fast/dom/HTMLFontElement/face-attribute.html

* css/CSSParser.cpp:
(WebCore::CSSParser::parseFontFaceValue):

LayoutTests:

Add a little test for <font face> attributes to cover this problem
and some other interesting cases with spaces and commas.

* fast/dom/HTMLFontElement/face-attribute-expected.txt: Added.
* fast/dom/HTMLFontElement/face-attribute.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (184893 => 184894)


--- trunk/LayoutTests/ChangeLog	2015-05-27 02:44:40 UTC (rev 184893)
+++ trunk/LayoutTests/ChangeLog	2015-05-27 04:13:54 UTC (rev 184894)
@@ -1,3 +1,17 @@
+2015-05-26  Andreas Kling  <akl...@apple.com>
+
+        <font face> doesn't support plus character in font family names.
+        <https://webkit.org/b/145400>
+        <rdar://problem/21097484>
+
+        Reviewed by Darin Adler.
+
+        Add a little test for <font face> attributes to cover this problem
+        and some other interesting cases with spaces and commas.
+
+        * fast/dom/HTMLFontElement/face-attribute-expected.txt: Added.
+        * fast/dom/HTMLFontElement/face-attribute.html: Added.
+
 2015-05-26  Chris Fleizach  <cfleiz...@apple.com>
 
         AX: display:none content exposed to accessibility when aria-hidden is toggled on ancestor element

Added: trunk/LayoutTests/fast/dom/HTMLFontElement/face-attribute-expected.txt (0 => 184894)


--- trunk/LayoutTests/fast/dom/HTMLFontElement/face-attribute-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLFontElement/face-attribute-expected.txt	2015-05-27 04:13:54 UTC (rev 184894)
@@ -0,0 +1,37 @@
+HTMLFontElement face attribute test
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS fontFaceAttributeEffect("") is null
+PASS fontFaceAttributeEffect(" ") is null
+PASS fontFaceAttributeEffect(",") is null
+PASS fontFaceAttributeEffect(" ,") is null
+PASS fontFaceAttributeEffect(" , ") is null
+PASS fontFaceAttributeEffect(",,") is null
+PASS fontFaceAttributeEffect("serif") is "serif"
+PASS fontFaceAttributeEffect("serif ") is "serif"
+PASS fontFaceAttributeEffect(",serif,") is null
+PASS fontFaceAttributeEffect(" serif ") is "serif"
+PASS fontFaceAttributeEffect(" serif") is "serif"
+PASS fontFaceAttributeEffect("serif ,") is null
+PASS fontFaceAttributeEffect("serif , ") is null
+PASS fontFaceAttributeEffect("serif,,") is null
+PASS fontFaceAttributeEffect("Serif") is "serif"
+PASS fontFaceAttributeEffect(" Serif") is "serif"
+PASS fontFaceAttributeEffect(" Serif ") is "serif"
+PASS fontFaceAttributeEffect(",Serif ") is null
+PASS fontFaceAttributeEffect("Inherited") is "Inherited"
+PASS fontFaceAttributeEffect("Initial") is "Initial"
+PASS fontFaceAttributeEffect("foo + foo") is "'foo + foo'"
+PASS fontFaceAttributeEffect(" foo + foo") is "'foo + foo'"
+PASS fontFaceAttributeEffect(" foo + foo ") is "'foo + foo'"
+PASS fontFaceAttributeEffect("foo + foo ") is "'foo + foo'"
+PASS fontFaceAttributeEffect("foo + foo,serif") is "'foo + foo', serif"
+PASS fontFaceAttributeEffect("serif,foo + foo,serif") is "serif, 'foo + foo', serif"
+PASS fontFaceAttributeEffect(",foo + foo,serif") is null
+PASS fontFaceAttributeEffect("serif,foo + foo,") is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/HTMLFontElement/face-attribute.html (0 => 184894)


--- trunk/LayoutTests/fast/dom/HTMLFontElement/face-attribute.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLFontElement/face-attribute.html	2015-05-27 04:13:54 UTC (rev 184894)
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+</head>
+<body>
+<script>
+
+description("HTMLFontElement face attribute test");
+
+function fontFaceAttributeEffect(value)
+{
+    var element = document.createElement("font");
+    element.setAttribute("face", value);
+    var outerElement = document.createElement("p");
+    outerElement.setAttribute("style", "font-family: whatever");
+    document.body.appendChild(outerElement);
+    outerElement.appendChild(element);
+    var computedStyle = getComputedStyle(element, "");
+    var result = computedStyle.fontFamily;
+    document.body.removeChild(outerElement);
+    return result === "whatever" ? null : result;
+}
+
+shouldBe('fontFaceAttributeEffect("")', 'null');
+shouldBe('fontFaceAttributeEffect(" ")', 'null');
+shouldBe('fontFaceAttributeEffect(",")', 'null');
+shouldBe('fontFaceAttributeEffect(" ,")', 'null');
+shouldBe('fontFaceAttributeEffect(" , ")', 'null');
+shouldBe('fontFaceAttributeEffect(",,")', 'null');
+
+shouldBe('fontFaceAttributeEffect("serif")', '"serif"');
+shouldBe('fontFaceAttributeEffect("serif ")', '"serif"');
+shouldBe('fontFaceAttributeEffect(",serif,")', 'null');
+shouldBe('fontFaceAttributeEffect(" serif ")', '"serif"');
+shouldBe('fontFaceAttributeEffect(" serif")', '"serif"');
+shouldBe('fontFaceAttributeEffect("serif ,")', 'null');
+shouldBe('fontFaceAttributeEffect("serif , ")', 'null');
+shouldBe('fontFaceAttributeEffect("serif,,")', 'null');
+
+shouldBe('fontFaceAttributeEffect("Serif")', '"serif"');
+shouldBe('fontFaceAttributeEffect(" Serif")', '"serif"');
+shouldBe('fontFaceAttributeEffect(" Serif ")', '"serif"');
+shouldBe('fontFaceAttributeEffect(",Serif ")', 'null');
+
+shouldBe('fontFaceAttributeEffect("Inherited")', '"Inherited"');
+shouldBe('fontFaceAttributeEffect("Initial")', '"Initial"');
+
+shouldBe('fontFaceAttributeEffect("foo + foo")', '"\'foo + foo\'"');
+shouldBe('fontFaceAttributeEffect(" foo + foo")', '"\'foo + foo\'"');
+shouldBe('fontFaceAttributeEffect(" foo + foo ")', '"\'foo + foo\'"');
+shouldBe('fontFaceAttributeEffect("foo + foo ")', '"\'foo + foo\'"');
+
+shouldBe('fontFaceAttributeEffect("foo + foo,serif")', '"\'foo + foo\', serif"');
+shouldBe('fontFaceAttributeEffect("serif,foo + foo,serif")', '"serif, \'foo + foo\', serif"');
+shouldBe('fontFaceAttributeEffect(",foo + foo,serif")', 'null');
+shouldBe('fontFaceAttributeEffect("serif,foo + foo,")', 'null');
+
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (184893 => 184894)


--- trunk/Source/WebCore/ChangeLog	2015-05-27 02:44:40 UTC (rev 184893)
+++ trunk/Source/WebCore/ChangeLog	2015-05-27 04:13:54 UTC (rev 184894)
@@ -1,3 +1,21 @@
+2015-05-26  Andreas Kling  <akl...@apple.com>
+
+        <font face> doesn't support plus character in font family names.
+        <https://webkit.org/b/145400>
+        <rdar://problem/21097484>
+
+        Reviewed by Darin Adler.
+
+        Turn CSSParser::parseFontFaceValue() into a fast-path parser for
+        <font face> attributes.
+        Going through the full CSS parser was hurting us here, as it would
+        misunderstand unquoted family names and choke on e.g '+'.
+
+        Test: fast/dom/HTMLFontElement/face-attribute.html
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseFontFaceValue):
+
 2015-05-26  Chris Fleizach  <cfleiz...@apple.com>
 
         AX: display:none content exposed to accessibility when aria-hidden is toggled on ancestor element

Modified: trunk/Source/WebCore/css/CSSParser.cpp (184893 => 184894)


--- trunk/Source/WebCore/css/CSSParser.cpp	2015-05-27 02:44:40 UTC (rev 184893)
+++ trunk/Source/WebCore/css/CSSParser.cpp	2015-05-27 04:13:54 UTC (rev 184894)
@@ -1282,15 +1282,30 @@
 {
     if (string.isEmpty())
         return nullptr;
-    RefPtr<MutableStyleProperties> dummyStyle = MutableStyleProperties::create();
 
-    if (parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, CSSQuirksMode, nullptr) == ParseResult::Error)
-        return nullptr;
+    Ref<CSSValueList> valueList = CSSValueList::createCommaSeparated();
 
-    RefPtr<CSSValue> fontFamily = dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily);
-    if (!fontFamily->isValueList())
-        return nullptr; // FIXME: "initial" and "inherit" should be parsed as font names in the face attribute.
-    return static_pointer_cast<CSSValueList>(fontFamily.release());
+    Vector<String> familyNames;
+    string.string().split(',', true, familyNames);
+
+    for (auto& familyName : familyNames) {
+        String stripped = stripLeadingAndTrailingHTMLSpaces(familyName);
+        if (stripped.isEmpty())
+            return nullptr;
+
+        RefPtr<CSSValue> value;
+        for (auto propertyID : { CSSValueSerif, CSSValueSansSerif, CSSValueCursive, CSSValueFantasy, CSSValueMonospace, CSSValueWebkitBody }) {
+            if (equalIgnoringCase(stripped, getValueName(propertyID))) {
+                value = cssValuePool().createIdentifierValue(propertyID);
+                break;
+            }
+        }
+        if (!value)
+            value = cssValuePool().createFontFamilyValue(stripped);
+        valueList->append(value.releaseNonNull());
+    }
+
+    return WTF::move(valueList);
 }
 
 CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String& string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to