WebCore: CSS support for the text-emphasis properties
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 Dec 2010 00:36:15 +0000 (00:36 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 Dec 2010 00:36:15 +0000 (00:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=48539

Reviewed by Dave Hyatt.

Test: fast/css/parsing-text-emphasis.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): Added text-emphasis-color,
text-emphasis-position and text-emphasis-style. Left the text-emphasis shorthand unsupported.
* css/CSSParser.cpp:
(WebCore::CSSParser::parseValue): Parse the properties.
(WebCore::CSSParser::parseTextEmphasisStyle): Added.
* css/CSSParser.h:
* css/CSSPrimitiveValueMappings.h:
(WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Added TextEmphasisPosition, TextEmphasisFill
and TextEmphasisMark mappings.
(WebCore::CSSPrimitiveValue::operator TextEmphasisPosition): Added.
(WebCore::CSSPrimitiveValue::operator TextEmphasisFill): Added.
(WebCore::CSSPrimitiveValue::operator TextEmphasisMark): Added.
* css/CSSPropertyLonghand.cpp:
(WebCore::initShorthandMap): Added the text-emphasis shorthand.
* css/CSSPropertyNames.in: Added -webkit-text-emphasis, -webkit-text-emphasis-color,
-webkit-text-emphasis-position, and -webkit-text-emphasis-style.
* css/CSSStyleSelector.cpp:
(WebCore::isValidVisitedLinkProperty): Added text-emphasis-color.
(WebCore::CSSStyleSelector::applyProperty): Handle the properties.
* css/CSSValueKeywords.in: Added 'over' and 'under' for text-emphasis-position. Added 'dot',
'double-circle', 'triangle', 'sesame', 'filled' and 'open' for text-emphasis-style.
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::colorIncludingFallback): Handle text-emphasis-color.
(WebCore::RenderStyle::textEmphasisMark): Added. Maps the fake 'auto' value to 'dot' or
'sesame' based on writing direction.
* rendering/style/RenderStyle.h: Added accessors.
(WebCore::InheritedFlags::textEmphasisFill):
(WebCore::InheritedFlags::textEmphasisCustomMark):
(WebCore::InheritedFlags::textEmphasisPosition):
(WebCore::InheritedFlags::setTextEmphasisColor):
(WebCore::InheritedFlags::setTextEmphasisFill):
(WebCore::InheritedFlags::setTextEmphasisMark):
(WebCore::InheritedFlags::setTextEmphasisCustomMark):
(WebCore::InheritedFlags::setTextEmphasisPosition):
(WebCore::InheritedFlags::initialTextEmphasisColor):
(WebCore::InheritedFlags::initialTextEmphasisFill):
(WebCore::InheritedFlags::initialTextEmphasisMark):
(WebCore::InheritedFlags::initialTextEmphasisCustomMark):
(WebCore::InheritedFlags::initialTextEmphasisPosition):
(WebCore::InheritedFlags::textEmphasisColor):
* rendering/style/RenderStyleConstants.h:
* rendering/style/StyleRareInheritedData.cpp:
(WebCore::StyleRareInheritedData::StyleRareInheritedData):
(WebCore::StyleRareInheritedData::operator==):
* rendering/style/StyleRareInheritedData.h:

LayoutTests: Test parsing of the text-emphasis CSS properties
https://bugs.webkit.org/show_bug.cgi?id=48539

Reviewed by Dave Hyatt.

* fast/css/parsing-text-emphasis-expected.txt: Added.
* fast/css/parsing-text-emphasis.html: Added.

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

17 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css/parsing-text-emphasis-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/parsing-text-emphasis.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/css/CSSComputedStyleDeclaration.cpp
WebCore/css/CSSParser.cpp
WebCore/css/CSSParser.h
WebCore/css/CSSPrimitiveValueMappings.h
WebCore/css/CSSPropertyLonghand.cpp
WebCore/css/CSSPropertyNames.in
WebCore/css/CSSStyleSelector.cpp
WebCore/css/CSSValueKeywords.in
WebCore/rendering/style/RenderStyle.cpp
WebCore/rendering/style/RenderStyle.h
WebCore/rendering/style/RenderStyleConstants.h
WebCore/rendering/style/StyleRareInheritedData.cpp
WebCore/rendering/style/StyleRareInheritedData.h

index 93cc450..e5df0f9 100644 (file)
@@ -1,3 +1,13 @@
+2010-12-02  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        Test parsing of the text-emphasis CSS properties
+        https://bugs.webkit.org/show_bug.cgi?id=48539
+
+        * fast/css/parsing-text-emphasis-expected.txt: Added.
+        * fast/css/parsing-text-emphasis.html: Added.
+
 2010-12-02  Victor Wang  <victorw@chromium.org>
 
         Unreviewed.
diff --git a/LayoutTests/fast/css/parsing-text-emphasis-expected.txt b/LayoutTests/fast/css/parsing-text-emphasis-expected.txt
new file mode 100644 (file)
index 0000000..722def9
--- /dev/null
@@ -0,0 +1,50 @@
+PASS: '-webkit-text-emphasis-color: initial;' parsed as ['initial', '', '', '']
+PASS: '-webkit-text-emphasis-color: inherit;' parsed as ['inherit', '', '', '']
+PASS: '-webkit-text-emphasis-color: currentcolor;' parsed as ['currentcolor', '', '', '']
+PASS: '-webkit-text-emphasis-color: cyan;' parsed as ['rgb(0, 255, 255)', '', '', '']
+PASS: '-webkit-text-emphasis-color: bold;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-color: 1px;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-color: "cyan";' parsed as ['', '', '', '']
+
+PASS: '-webkit-text-emphasis-position: initial;' parsed as ['', 'initial', '', '']
+PASS: '-webkit-text-emphasis-position: inherit;' parsed as ['', 'inherit', '', '']
+PASS: '-webkit-text-emphasis-position: over;' parsed as ['', 'over', '', '']
+PASS: '-webkit-text-emphasis-position: under;' parsed as ['', 'under', '', '']
+PASS: '-webkit-text-emphasis-position: bold;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-position: 1px;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-position: "over";' parsed as ['', '', '', '']
+
+PASS: '-webkit-text-emphasis-style: initial;' parsed as ['', '', 'initial', '']
+PASS: '-webkit-text-emphasis-style: inherit;' parsed as ['', '', 'inherit', '']
+PASS: '-webkit-text-emphasis-style: none;' parsed as ['', '', 'none', '']
+PASS: '-webkit-text-emphasis-style: filled;' parsed as ['', '', 'filled', '']
+PASS: '-webkit-text-emphasis-style: open;' parsed as ['', '', 'open', '']
+PASS: '-webkit-text-emphasis-style: dot;' parsed as ['', '', 'dot', '']
+PASS: '-webkit-text-emphasis-style: circle;' parsed as ['', '', 'circle', '']
+PASS: '-webkit-text-emphasis-style: double-circle;' parsed as ['', '', 'double-circle', '']
+PASS: '-webkit-text-emphasis-style: triangle;' parsed as ['', '', 'triangle', '']
+PASS: '-webkit-text-emphasis-style: sesame;' parsed as ['', '', 'sesame', '']
+PASS: '-webkit-text-emphasis-style: "cheese";' parsed as ['', '', 'cheese', '']
+PASS: '-webkit-text-emphasis-style: 1px;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-style: red;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-style: open dot;' parsed as ['', '', 'open dot', '']
+PASS: '-webkit-text-emphasis-style: dot open;' parsed as ['', '', 'open dot', '']
+PASS: '-webkit-text-emphasis-style: dot dot;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-style: open open;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-style: none open;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-style: none none;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-style: "cheese" open;' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis-style: open "cheese";' parsed as ['', '', '', '']
+
+PASS: '-webkit-text-emphasis: initial' parsed as ['', '', '', 'initial']
+PASS: '-webkit-text-emphasis: inherit' parsed as ['', '', '', 'inherit']
+PASS: '-webkit-text-emphasis: red' parsed as ['red', '', 'initial', '']
+PASS: '-webkit-text-emphasis: "cheese"' parsed as ['initial', '', 'cheese', '']
+PASS: '-webkit-text-emphasis: red "cheese"' parsed as ['red', '', 'cheese', '']
+PASS: '-webkit-text-emphasis: "cheese" red' parsed as ['red', '', 'cheese', '']
+PASS: '-webkit-text-emphasis: filled sesame red' parsed as ['red', '', 'filled sesame', '']
+PASS: '-webkit-text-emphasis: red filled sesame' parsed as ['red', '', 'filled sesame', '']
+PASS: '-webkit-text-emphasis: filled red sesame' parsed as ['', '', '', '']
+PASS: '-webkit-text-emphasis: red sesame filled' parsed as ['red', '', 'filled sesame', '']
+PASS: '-webkit-text-emphasis: sesame filled red' parsed as ['red', '', 'filled sesame', '']
+
diff --git a/LayoutTests/fast/css/parsing-text-emphasis.html b/LayoutTests/fast/css/parsing-text-emphasis.html
new file mode 100644 (file)
index 0000000..cec054d
--- /dev/null
@@ -0,0 +1,81 @@
+<pre id="console"></pre>
+<script>
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+
+    function log(message)
+    {
+        document.getElementById("console").appendChild(document.createTextNode(message + "\n"));
+    }
+
+    function test(declaration, expectedColor, expectedPosition, expectedStyle, expectedTextEmphasis)
+    {
+        if (!expectedTextEmphasis)
+            expectedTextEmphasis = "";
+
+        var element = document.createElement("div");
+        element.style.cssText = declaration;
+        var color = element.style.webkitTextEmphasisColor;
+        var position = element.style.webkitTextEmphasisPosition;
+        var style = element.style.webkitTextEmphasisStyle;
+        var textEmphasis = element.style.webkitTextEmphasis;
+        if (color === expectedColor && position === expectedPosition && style === expectedStyle && textEmphasis === expectedTextEmphasis)
+            log("PASS: '" + declaration + "' parsed as ['" + color + "', '" + position + "', '" + style + "', '" + textEmphasis + "']");
+        else
+            log("FAIL: '" + declaration + "' parsed as ['" + color + "', '" + position + "', '" + style + "', '" + textEmphasis + "'] rather than ['" + expectedColor + "', '" + expectedPosition + "', '" + expectedStyle + "', '" + expectedTextEmphasis + "']");
+    }
+
+    test('-webkit-text-emphasis-color: initial;', 'initial', '', '');
+    test('-webkit-text-emphasis-color: inherit;', 'inherit', '', '');
+    test('-webkit-text-emphasis-color: currentcolor;', 'currentcolor', '', '');
+    test('-webkit-text-emphasis-color: cyan;', 'rgb(0, 255, 255)', '', '');
+    test('-webkit-text-emphasis-color: bold;', '', '', '');
+    test('-webkit-text-emphasis-color: 1px;', '', '', '');
+    test('-webkit-text-emphasis-color: "cyan";', '', '', '');
+
+    log("");
+    test('-webkit-text-emphasis-position: initial;', '', 'initial', '');
+    test('-webkit-text-emphasis-position: inherit;', '', 'inherit', '');
+    test('-webkit-text-emphasis-position: over;', '', 'over', '');
+    test('-webkit-text-emphasis-position: under;', '', 'under', '');
+    test('-webkit-text-emphasis-position: bold;', '', '', '');
+    test('-webkit-text-emphasis-position: 1px;', '', '', '');
+    test('-webkit-text-emphasis-position: "over";', '', '', '');
+
+    log("");
+    test('-webkit-text-emphasis-style: initial;', '', '', 'initial');
+    test('-webkit-text-emphasis-style: inherit;', '', '', 'inherit');
+    test('-webkit-text-emphasis-style: none;', '', '', 'none');
+    test('-webkit-text-emphasis-style: filled;', '', '', 'filled');
+    test('-webkit-text-emphasis-style: open;', '', '', 'open');
+    test('-webkit-text-emphasis-style: dot;', '', '', 'dot');
+    test('-webkit-text-emphasis-style: circle;', '', '', 'circle');
+    test('-webkit-text-emphasis-style: double-circle;', '', '', 'double-circle');
+    test('-webkit-text-emphasis-style: triangle;', '', '', 'triangle');
+    test('-webkit-text-emphasis-style: sesame;', '', '', 'sesame');
+    test('-webkit-text-emphasis-style: "cheese";', '', '', 'cheese');
+    test('-webkit-text-emphasis-style: 1px;', '', '', '');
+    test('-webkit-text-emphasis-style: red;', '', '', '');
+
+    test('-webkit-text-emphasis-style: open dot;', '', '', 'open dot');
+    test('-webkit-text-emphasis-style: dot open;', '', '', 'open dot');
+    test('-webkit-text-emphasis-style: dot dot;', '', '', '');
+    test('-webkit-text-emphasis-style: open open;', '', '', '');
+    test('-webkit-text-emphasis-style: none open;', '', '', '');
+    test('-webkit-text-emphasis-style: none none;', '', '', '');
+    test('-webkit-text-emphasis-style: "cheese" open;', '', '', '');
+    test('-webkit-text-emphasis-style: open "cheese";', '', '', '');
+
+    log("");
+    test('-webkit-text-emphasis: initial', '', '', '', 'initial');
+    test('-webkit-text-emphasis: inherit', '', '', '', 'inherit');
+    test('-webkit-text-emphasis: red', 'red', '', 'initial');
+    test('-webkit-text-emphasis: "cheese"', 'initial', '', 'cheese');
+    test('-webkit-text-emphasis: red "cheese"', 'red', '', 'cheese');
+    test('-webkit-text-emphasis: "cheese" red', 'red', '', 'cheese');
+    test('-webkit-text-emphasis: filled sesame red', 'red', '', 'filled sesame');
+    test('-webkit-text-emphasis: red filled sesame', 'red', '', 'filled sesame');
+    test('-webkit-text-emphasis: filled red sesame', '', '', '');
+    test('-webkit-text-emphasis: red sesame filled', 'red', '', 'filled sesame');
+    test('-webkit-text-emphasis: sesame filled red', 'red', '', 'filled sesame');
+</script>
index 5722617..f0b2b99 100644 (file)
@@ -1,3 +1,59 @@
+2010-12-02  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        CSS support for the text-emphasis properties
+        https://bugs.webkit.org/show_bug.cgi?id=48539
+
+        Test: fast/css/parsing-text-emphasis.html
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): Added text-emphasis-color,
+        text-emphasis-position and text-emphasis-style. Left the text-emphasis shorthand unsupported.
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseValue): Parse the properties.
+        (WebCore::CSSParser::parseTextEmphasisStyle): Added.
+        * css/CSSParser.h:
+        * css/CSSPrimitiveValueMappings.h:
+        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Added TextEmphasisPosition, TextEmphasisFill
+        and TextEmphasisMark mappings.
+        (WebCore::CSSPrimitiveValue::operator TextEmphasisPosition): Added.
+        (WebCore::CSSPrimitiveValue::operator TextEmphasisFill): Added.
+        (WebCore::CSSPrimitiveValue::operator TextEmphasisMark): Added.
+        * css/CSSPropertyLonghand.cpp:
+        (WebCore::initShorthandMap): Added the text-emphasis shorthand.
+        * css/CSSPropertyNames.in: Added -webkit-text-emphasis, -webkit-text-emphasis-color,
+        -webkit-text-emphasis-position, and -webkit-text-emphasis-style.
+        * css/CSSStyleSelector.cpp:
+        (WebCore::isValidVisitedLinkProperty): Added text-emphasis-color.
+        (WebCore::CSSStyleSelector::applyProperty): Handle the properties.
+        * css/CSSValueKeywords.in: Added 'over' and 'under' for text-emphasis-position. Added 'dot',
+        'double-circle', 'triangle', 'sesame', 'filled' and 'open' for text-emphasis-style.
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::colorIncludingFallback): Handle text-emphasis-color.
+        (WebCore::RenderStyle::textEmphasisMark): Added. Maps the fake 'auto' value to 'dot' or
+        'sesame' based on writing direction.
+        * rendering/style/RenderStyle.h: Added accessors.
+        (WebCore::InheritedFlags::textEmphasisFill):
+        (WebCore::InheritedFlags::textEmphasisCustomMark):
+        (WebCore::InheritedFlags::textEmphasisPosition):
+        (WebCore::InheritedFlags::setTextEmphasisColor):
+        (WebCore::InheritedFlags::setTextEmphasisFill):
+        (WebCore::InheritedFlags::setTextEmphasisMark):
+        (WebCore::InheritedFlags::setTextEmphasisCustomMark):
+        (WebCore::InheritedFlags::setTextEmphasisPosition):
+        (WebCore::InheritedFlags::initialTextEmphasisColor):
+        (WebCore::InheritedFlags::initialTextEmphasisFill):
+        (WebCore::InheritedFlags::initialTextEmphasisMark):
+        (WebCore::InheritedFlags::initialTextEmphasisCustomMark):
+        (WebCore::InheritedFlags::initialTextEmphasisPosition):
+        (WebCore::InheritedFlags::textEmphasisColor):
+        * rendering/style/RenderStyleConstants.h:
+        * rendering/style/StyleRareInheritedData.cpp:
+        (WebCore::StyleRareInheritedData::StyleRareInheritedData):
+        (WebCore::StyleRareInheritedData::operator==):
+        * rendering/style/StyleRareInheritedData.h:
+
 2010-12-02  Chris Marrin  <cmarrin@apple.com>
 
         Reviewed by Simon Fraser.
index c804694..c29a6dc 100644 (file)
@@ -1218,6 +1218,30 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
         case CSSPropertyWebkitTextFillColor:
             return currentColorOrValidColor(style.get(), style->textFillColor());
+        case CSSPropertyWebkitTextEmphasisColor:
+            return currentColorOrValidColor(style.get(), style->textEmphasisColor());
+        case CSSPropertyWebkitTextEmphasisPosition:
+            return CSSPrimitiveValue::create(style->textEmphasisPosition());
+        case CSSPropertyWebkitTextEmphasisStyle:
+            switch (style->textEmphasisMark()) {
+            case TextEmphasisMarkNone:
+                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+            case TextEmphasisMarkCustom:
+                return CSSPrimitiveValue::create(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
+            case TextEmphasisMarkAuto:
+                ASSERT_NOT_REACHED();
+                // Fall through
+            case TextEmphasisMarkDot:
+            case TextEmphasisMarkCircle:
+            case TextEmphasisMarkDoubleCircle:
+            case TextEmphasisMarkTriangle:
+            case TextEmphasisMarkSesame: {
+                RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+                list->append(CSSPrimitiveValue::create(style->textEmphasisFill()));
+                list->append(CSSPrimitiveValue::create(style->textEmphasisMark()));
+                return list.release();
+            }
+            }
         case CSSPropertyTextIndent:
             return CSSPrimitiveValue::create(style->textIndent());
         case CSSPropertyTextShadow:
@@ -1555,6 +1579,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             break;
 
         /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
+        case CSSPropertyWebkitTextEmphasis:
         case CSSPropertyTextLineThrough:
         case CSSPropertyTextLineThroughColor:
         case CSSPropertyTextLineThroughMode:
index f7a5918..a59253d 100644 (file)
@@ -827,6 +827,7 @@ bool CSSParser::parseValue(int propId, bool important)
     case CSSPropertyTextUnderlineColor:
     case CSSPropertyTextOverlineColor:
     case CSSPropertyWebkitColumnRuleColor:
+    case CSSPropertyWebkitTextEmphasisColor:
     case CSSPropertyWebkitTextFillColor:
     case CSSPropertyWebkitTextStrokeColor:
         if (id == CSSValueWebkitText)
@@ -1782,6 +1783,19 @@ bool CSSParser::parseValue(int propId, bool important)
             validPrimitive = true;
         break;
 
+    case CSSPropertyWebkitTextEmphasis: {
+        const int properties[] = { CSSPropertyWebkitTextEmphasisStyle, CSSPropertyWebkitTextEmphasisColor };
+        return parseShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
+    }
+
+    case CSSPropertyWebkitTextEmphasisPosition:
+        if (id == CSSValueOver || id == CSSValueUnder)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitTextEmphasisStyle:
+        return parseTextEmphasisStyle(important);
+
 #if ENABLE(SVG)
     default:
         return parseSVGValue(propId, important);
@@ -5080,6 +5094,63 @@ bool CSSParser::parsePerspectiveOrigin(int propId, int& propId1, int& propId2, R
     return value;
 }
 
+bool CSSParser::parseTextEmphasisStyle(bool important)
+{
+    unsigned valueListSize = m_valueList->size();
+
+    RefPtr<CSSPrimitiveValue> fill;
+    RefPtr<CSSPrimitiveValue> shape;
+
+    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+        if (value->unit == CSSPrimitiveValue::CSS_STRING) {
+            if (fill || shape || (valueListSize != 1 && !inShorthand()))
+                return false;
+            addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING), important);
+            m_valueList->next();
+            return true;
+        }
+
+        if (value->id == CSSValueNone) {
+            if (fill || shape || (valueListSize != 1 && !inShorthand()))
+                return false;
+            addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSPrimitiveValue::createIdentifier(CSSValueNone), important);
+            m_valueList->next();
+            return true;
+        }
+
+        if (value->id == CSSValueOpen || value->id == CSSValueFilled) {
+            if (fill)
+                return false;
+            fill = CSSPrimitiveValue::createIdentifier(value->id);
+        } else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) {
+            if (shape)
+                return false;
+            shape = CSSPrimitiveValue::createIdentifier(value->id);
+        } else if (!inShorthand())
+            return false;
+        else
+            break;
+    }
+
+    if (fill && shape) {
+        RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
+        parsedValues->append(fill.release());
+        parsedValues->append(shape.release());
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, parsedValues.release(), important);
+        return true;
+    }
+    if (fill) {
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, fill.release(), important);
+        return true;
+    }
+    if (shape) {
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, shape.release(), important);
+        return true;
+    }
+
+    return false;
+}
+
 static inline int yyerror(const char*) { return 1; }
 
 #define END_TOKEN 0
index 191249c..eb8bb2d 100644 (file)
@@ -161,6 +161,8 @@ namespace WebCore {
         bool parseTransformOrigin(int propId, int& propId1, int& propId2, int& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
         bool parsePerspectiveOrigin(int propId, int& propId1, int& propId2,  RefPtr<CSSValue>&, RefPtr<CSSValue>&);
 
+        bool parseTextEmphasisStyle(bool important);
+
         int yyparse();
 
         CSSSelector* createFloatingSelector();
index c055875..c209bc0 100644 (file)
@@ -2072,6 +2072,110 @@ template<> inline CSSPrimitiveValue::operator TextCombine() const
     }
 }
 
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextEmphasisPosition position)
+    : m_type(CSS_IDENT)
+    , m_hasCachedCSSText(false)
+{
+    switch (position) {
+    case TextEmphasisPositionOver:
+        m_value.ident = CSSValueOver;
+        break;
+    case TextEmphasisPositionUnder:
+        m_value.ident = CSSValueUnder;
+        break;
+    }
+}
+
+template<> inline CSSPrimitiveValue::operator TextEmphasisPosition() const
+{
+    switch (m_value.ident) {
+    case CSSValueOver:
+        return TextEmphasisPositionOver;
+    case CSSValueUnder:
+        return TextEmphasisPositionUnder;
+    default:
+        ASSERT_NOT_REACHED();
+        return TextEmphasisPositionOver;
+    }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextEmphasisFill fill)
+    : m_type(CSS_IDENT)
+    , m_hasCachedCSSText(false)
+{
+    switch (fill) {
+    case TextEmphasisFillFilled:
+        m_value.ident = CSSValueFilled;
+        break;
+    case TextEmphasisFillOpen:
+        m_value.ident = CSSValueOpen;
+        break;
+    }
+}
+
+template<> inline CSSPrimitiveValue::operator TextEmphasisFill() const
+{
+    switch (m_value.ident) {
+    case CSSValueFilled:
+        return TextEmphasisFillFilled;
+    case CSSValueOpen:
+        return TextEmphasisFillOpen;
+    default:
+        ASSERT_NOT_REACHED();
+        return TextEmphasisFillFilled;
+    }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextEmphasisMark mark)
+    : m_type(CSS_IDENT)
+    , m_hasCachedCSSText(false)
+{
+    switch (mark) {
+    case TextEmphasisMarkDot:
+        m_value.ident = CSSValueDot;
+        break;
+    case TextEmphasisMarkCircle:
+        m_value.ident = CSSValueCircle;
+        break;
+    case TextEmphasisMarkDoubleCircle:
+        m_value.ident = CSSValueDoubleCircle;
+        break;
+    case TextEmphasisMarkTriangle:
+        m_value.ident = CSSValueTriangle;
+        break;
+    case TextEmphasisMarkSesame:
+        m_value.ident = CSSValueSesame;
+        break;
+    case TextEmphasisMarkNone:
+    case TextEmphasisMarkAuto:
+    case TextEmphasisMarkCustom:
+        ASSERT_NOT_REACHED();
+        m_value.ident = CSSValueNone;
+        break;
+    }
+}
+
+template<> inline CSSPrimitiveValue::operator TextEmphasisMark() const
+{
+    switch (m_value.ident) {
+    case CSSValueNone:
+        return TextEmphasisMarkNone;
+    case CSSValueDot:
+        return TextEmphasisMarkDot;
+    case CSSValueCircle:
+        return TextEmphasisMarkCircle;
+    case CSSValueDoubleCircle:
+        return TextEmphasisMarkDoubleCircle;
+    case CSSValueTriangle:
+        return TextEmphasisMarkTriangle;
+    case CSSValueSesame:
+        return TextEmphasisMarkSesame;
+    default:
+        ASSERT_NOT_REACHED();
+        return TextEmphasisMarkNone;
+    }
+}
+
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EPointerEvents e)
     : m_type(CSS_IDENT)
     , m_hasCachedCSSText(false)
index 4df5d62..7372a54 100644 (file)
@@ -207,6 +207,12 @@ static void initShorthandMap(ShorthandMap& shorthandMap)
     };
     SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTransformOrigin, transformOriginProperties);
     
+    static const int textEmphasisProperties[] = {
+        CSSPropertyWebkitTextEmphasisColor,
+        CSSPropertyWebkitTextEmphasisStyle
+    };
+    SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTextEmphasis, textEmphasisProperties);
+    
     #undef SET_SHORTHAND_MAP_ENTRY
 }
 
index 28b393c..8ace6d6 100644 (file)
@@ -278,6 +278,10 @@ z-index
 -webkit-rtl-ordering
 -webkit-text-combine
 -webkit-text-decorations-in-effect
+-webkit-text-emphasis
+-webkit-text-emphasis-color
+-webkit-text-emphasis-position
+-webkit-text-emphasis-style
 -webkit-text-fill-color
 -webkit-text-security
 -webkit-text-stroke
index 2f2f3b5..72b4a97 100644 (file)
@@ -3034,6 +3034,7 @@ inline bool isValidVisitedLinkProperty(int id)
         case CSSPropertyColor:
         case CSSPropertyOutlineColor:
         case CSSPropertyWebkitColumnRuleColor:
+        case CSSPropertyWebkitTextEmphasisColor:
         case CSSPropertyWebkitTextFillColor:
         case CSSPropertyWebkitTextStrokeColor:
         // Also allow shorthands so that inherit/initial still work.
@@ -3511,6 +3512,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
     case CSSPropertyOutlineColor:
     case CSSPropertyWebkitColumnRuleColor:
     case CSSPropertyWebkitTextStrokeColor:
+    case CSSPropertyWebkitTextEmphasisColor:
     case CSSPropertyWebkitTextFillColor: {
         Color col;
         if (isInherit) {
@@ -3523,6 +3525,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyOutlineColor, outlineColor, color, OutlineColor)
             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitColumnRuleColor, columnRuleColor, color, ColumnRuleColor)
             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitTextStrokeColor, textStrokeColor, color, TextStrokeColor)
+            HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitTextEmphasisColor, textEmphasisColor, color, TextEmphasisColor)
             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitTextFillColor, textFillColor, color, TextFillColor)
             return;
         }
@@ -3566,6 +3569,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
         case CSSPropertyWebkitTextStrokeColor:
             m_style->setTextStrokeColor(col);
             break;
+        case CSSPropertyWebkitTextEmphasisColor:
+            m_style->setTextEmphasisColor(col);
+            break;
         case CSSPropertyWebkitTextFillColor:
             m_style->setTextFillColor(col);
             break;
@@ -5522,6 +5528,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
     case CSSPropertyWebkitFontSizeDelta:
     case CSSPropertyWebkitTextDecorationsInEffect:
     case CSSPropertyWebkitTextStroke:
+    case CSSPropertyWebkitTextEmphasis:
         return;
 #if ENABLE(WCSS)
     case CSSPropertyWapInputFormat:
@@ -5556,6 +5563,56 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textCombine, TextCombine)
         return;
 
+    case CSSPropertyWebkitTextEmphasisPosition:
+        HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textEmphasisPosition, TextEmphasisPosition)
+        return;
+
+    case CSSPropertyWebkitTextEmphasisStyle:
+        HANDLE_INHERIT_AND_INITIAL(textEmphasisFill, TextEmphasisFill)
+        HANDLE_INHERIT_AND_INITIAL(textEmphasisMark, TextEmphasisMark)
+        HANDLE_INHERIT_AND_INITIAL(textEmphasisCustomMark, TextEmphasisCustomMark)
+        if (isInherit || isInitial)
+            return;
+
+        if (value->isValueList()) {
+            CSSValueList* list = static_cast<CSSValueList*>(value);
+            ASSERT(list->length() == 2);
+            if (list->length() != 2)
+                return;
+            for (unsigned i = 0; i < 2; ++i) {
+                ASSERT(list->itemWithoutBoundsCheck(i)->isPrimitiveValue());
+                CSSPrimitiveValue* value = static_cast<CSSPrimitiveValue*>(list->itemWithoutBoundsCheck(i));
+                if (value->getIdent() == CSSValueFilled || value->getIdent() == CSSValueOpen)
+                    m_style->setTextEmphasisFill(*value);
+                else
+                    m_style->setTextEmphasisMark(*value);
+            }
+            m_style->setTextEmphasisCustomMark(nullAtom);
+            return;
+        }
+
+        if (!primitiveValue)
+            return;
+
+        if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_STRING) {
+            m_style->setTextEmphasisFill(TextEmphasisFillFilled);
+            m_style->setTextEmphasisMark(TextEmphasisMarkCustom);
+            m_style->setTextEmphasisCustomMark(primitiveValue->getStringValue());
+            return;
+        }
+
+        m_style->setTextEmphasisCustomMark(nullAtom);
+
+        if (primitiveValue->getIdent() == CSSValueFilled || primitiveValue->getIdent() == CSSValueOpen) {
+            m_style->setTextEmphasisFill(*primitiveValue);
+            m_style->setTextEmphasisMark(TextEmphasisMarkAuto);
+        } else {
+            m_style->setTextEmphasisFill(TextEmphasisFillFilled);
+            m_style->setTextEmphasisMark(*primitiveValue);
+        }
+
+        return;
+
 #if ENABLE(SVG)
     default:
         // Try the SVG properties
index cd37519..bd07fca 100644 (file)
@@ -768,3 +768,16 @@ horizontal-bt
 # -webkit-text-combine
 cluster
 upright
+
+# -webkit-text-emphasis-position
+over
+under
+
+# -webkit-text-emphasis-style
+filled
+open
+dot
+# circle
+double-circle
+triangle
+sesame
index 0ea3673..fcca465 100644 (file)
@@ -402,7 +402,10 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
             rareInheritedData->textSecurity != other->rareInheritedData->textSecurity ||
             rareInheritedData->hyphens != other->rareInheritedData->hyphens ||
             rareInheritedData->hyphenationString != other->rareInheritedData->hyphenationString ||
-            rareInheritedData->hyphenationLocale != other->rareInheritedData->hyphenationLocale)
+            rareInheritedData->hyphenationLocale != other->rareInheritedData->hyphenationLocale ||
+            rareInheritedData->textEmphasisMark != other->rareInheritedData->textEmphasisMark ||
+            rareInheritedData->textEmphasisPosition != other->rareInheritedData->textEmphasisPosition ||
+            rareInheritedData->textEmphasisCustomMark != other->rareInheritedData->textEmphasisCustomMark)
             return StyleDifferenceLayout;
 
         if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
@@ -553,7 +556,9 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
         rareNonInheritedData->userDrag != other->rareNonInheritedData->userDrag ||
         rareNonInheritedData->m_borderFit != other->rareNonInheritedData->m_borderFit ||
         rareInheritedData->textFillColor != other->rareInheritedData->textFillColor ||
-        rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor)
+        rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor ||
+        rareInheritedData->textEmphasisColor != other->rareInheritedData->textEmphasisColor ||
+        rareInheritedData->textEmphasisFill != other->rareInheritedData->textEmphasisFill)
         return StyleDifferenceRepaint;
 
 #if USE(ACCELERATED_COMPOSITING)
@@ -1067,6 +1072,9 @@ const Color RenderStyle::colorIncludingFallback(int colorProperty, EBorderStyle
     case CSSPropertyWebkitColumnRuleColor:
         result = columnRuleColor();
         break;
+    case CSSPropertyWebkitTextEmphasisColor:
+        result = textEmphasisColor();
+        break;
     case CSSPropertyWebkitTextFillColor:
         result = textFillColor();
         break;
@@ -1408,4 +1416,16 @@ Length RenderStyle::paddingEnd() const
     return isLeftToRightDirection() ? paddingBottom() : paddingTop();
 }
 
+TextEmphasisMark RenderStyle::textEmphasisMark() const
+{
+    TextEmphasisMark mark = static_cast<TextEmphasisMark>(rareInheritedData->textEmphasisMark);
+    if (mark != TextEmphasisMarkAuto)
+        return mark;
+
+    if (isHorizontalWritingMode())
+        return TextEmphasisMarkDot;
+
+    return TextEmphasisMarkSesame;
+}
+
 } // namespace WebCore
index aa5622a..e606056 100644 (file)
@@ -713,6 +713,11 @@ public:
     Length transformOriginY() const { return rareNonInheritedData->m_transform->m_y; }
     float transformOriginZ() const { return rareNonInheritedData->m_transform->m_z; }
     bool hasTransform() const { return !rareNonInheritedData->m_transform->m_operations.operations().isEmpty(); }
+
+    TextEmphasisFill textEmphasisFill() const { return static_cast<TextEmphasisFill>(rareInheritedData->textEmphasisFill); }
+    TextEmphasisMark textEmphasisMark() const;
+    const AtomicString& textEmphasisCustomMark() const { return rareInheritedData->textEmphasisCustomMark; }
+    TextEmphasisPosition textEmphasisPosition() const { return static_cast<TextEmphasisPosition>(rareInheritedData->textEmphasisPosition); }
     
     // Return true if any transform related property (currently transform, transformStyle3D or perspective) 
     // indicates that we are transforming
@@ -1064,6 +1069,11 @@ public:
     void setTransformOriginZ(float f) { SET_VAR(rareNonInheritedData.access()->m_transform, m_z, f); }
     void setSpeak(ESpeak s) { SET_VAR(rareInheritedData, speak, s); }
     void setTextCombine(TextCombine v) { SET_VAR(rareNonInheritedData, m_textCombine, v); }
+    void setTextEmphasisColor(const Color& c) { SET_VAR(rareInheritedData, textEmphasisColor, c) }
+    void setTextEmphasisFill(TextEmphasisFill fill) { SET_VAR(rareInheritedData, textEmphasisFill, fill); }
+    void setTextEmphasisMark(TextEmphasisMark mark) { SET_VAR(rareInheritedData, textEmphasisMark, mark); }
+    void setTextEmphasisCustomMark(const AtomicString& mark) { SET_VAR(rareInheritedData, textEmphasisCustomMark, mark); }
+    void setTextEmphasisPosition(TextEmphasisPosition position) { SET_VAR(rareInheritedData, textEmphasisPosition, position); }
     // End CSS3 Setters
 
     // Apple-specific property setters
@@ -1276,6 +1286,11 @@ public:
     static Length initialPerspectiveOriginX() { return Length(50.0, Percent); }
     static Length initialPerspectiveOriginY() { return Length(50.0, Percent); }
     static Color initialBackgroundColor() { return Color::transparent; }
+    static Color initialTextEmphasisColor() { return TextEmphasisFillFilled; }
+    static TextEmphasisFill initialTextEmphasisFill() { return TextEmphasisFillFilled; }
+    static TextEmphasisMark initialTextEmphasisMark() { return TextEmphasisMarkNone; }
+    static const AtomicString& initialTextEmphasisCustomMark() { return nullAtom; }
+    static TextEmphasisPosition initialTextEmphasisPosition() { return TextEmphasisPositionOver; }
 
     // Keep these at the end.
     static LineClampValue initialLineClamp() { return LineClampValue(); }
@@ -1308,6 +1323,7 @@ private:
     const Color& color() const { return inherited->color; }
     const Color& columnRuleColor() const { return rareNonInheritedData->m_multiCol->m_rule.color(); }
     const Color& outlineColor() const { return m_background->outline().color(); }
+    const Color& textEmphasisColor() const { return rareInheritedData->textEmphasisColor; }
     const Color& textFillColor() const { return rareInheritedData->textFillColor; }
     const Color& textStrokeColor() const { return rareInheritedData->textStrokeColor; }
     
index b8e2079..cc99d92 100644 (file)
@@ -420,7 +420,13 @@ enum ELineClampType { LineClampLineCount, LineClampPercentage };
 enum Hyphens { HyphensNone, HyphensManual, HyphensAuto };
 
 enum ESpeak { SpeakNone, SpeakNormal, SpeakSpellOut, SpeakDigits, SpeakLiteralPunctuation, SpeakNoPunctuation };
-    
+
+enum TextEmphasisFill { TextEmphasisFillFilled, TextEmphasisFillOpen };
+
+enum TextEmphasisMark { TextEmphasisMarkNone, TextEmphasisMarkAuto, TextEmphasisMarkDot, TextEmphasisMarkCircle, TextEmphasisMarkDoubleCircle, TextEmphasisMarkTriangle, TextEmphasisMarkSesame, TextEmphasisMarkCustom };
+
+enum TextEmphasisPosition { TextEmphasisPositionOver, TextEmphasisPositionUnder };
+
 } // namespace WebCore
 
 #endif // RenderStyleConstants_h
index 8e34813..5a3f4f4 100644 (file)
@@ -46,6 +46,9 @@ StyleRareInheritedData::StyleRareInheritedData()
     , colorSpace(ColorSpaceDeviceRGB)
     , speak(SpeakNormal)
     , hyphens(HyphensManual)
+    , textEmphasisFill(TextEmphasisFillFilled)
+    , textEmphasisMark(TextEmphasisMarkNone)
+    , textEmphasisPosition(TextEmphasisPositionOver)
 {
 }
 
@@ -54,6 +57,7 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
     , textStrokeColor(o.textStrokeColor)
     , textStrokeWidth(o.textStrokeWidth)
     , textFillColor(o.textFillColor)
+    , textEmphasisColor(o.textEmphasisColor)
     , textShadow(o.textShadow ? new ShadowData(*o.textShadow) : 0)
     , highlight(o.highlight)
     , cursorData(o.cursorData)
@@ -73,8 +77,12 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
     , colorSpace(o.colorSpace)
     , speak(o.speak)
     , hyphens(o.hyphens)
+    , textEmphasisFill(o.textEmphasisFill)
+    , textEmphasisMark(o.textEmphasisMark)
+    , textEmphasisPosition(o.textEmphasisPosition)
     , hyphenationString(o.hyphenationString)
     , hyphenationLocale(o.hyphenationLocale)
+    , textEmphasisCustomMark(o.textEmphasisCustomMark)
 {
 }
 
@@ -97,6 +105,7 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
     return textStrokeColor == o.textStrokeColor
         && textStrokeWidth == o.textStrokeWidth
         && textFillColor == o.textFillColor
+        && textEmphasisColor == o.textEmphasisColor
         && shadowDataEquivalent(o)
         && highlight == o.highlight
         && cursorDataEquivalent(cursorData.get(), o.cursorData.get())
@@ -116,8 +125,12 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
         && colorSpace == o.colorSpace
         && speak == o.speak
         && hyphens == o.hyphens
+        && textEmphasisFill == o.textEmphasisFill
+        && textEmphasisMark == o.textEmphasisMark
+        && textEmphasisPosition == o.textEmphasisPosition
         && hyphenationString == o.hyphenationString
-        && hyphenationLocale == o.hyphenationLocale;
+        && hyphenationLocale == o.hyphenationLocale
+        && textEmphasisCustomMark == o.textEmphasisCustomMark;
 }
 
 bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
index 3a78976..d26ca83 100644 (file)
@@ -55,6 +55,7 @@ public:
     Color textStrokeColor;
     float textStrokeWidth;
     Color textFillColor;
+    Color textEmphasisColor;
 
     ShadowData* textShadow; // Our text shadow information for shadowed text drawing.
     AtomicString highlight; // Apple-specific extension for custom highlight rendering.
@@ -79,10 +80,15 @@ public:
     unsigned colorSpace : 1; // ColorSpace
     unsigned speak : 3; // ESpeak
     unsigned hyphens : 2; // Hyphens
+    unsigned textEmphasisFill : 1; // TextEmphasisFill
+    unsigned textEmphasisMark : 3; // TextEmphasisMark
+    unsigned textEmphasisPosition : 1; // TextEmphasisPosition
 
     AtomicString hyphenationString;
     AtomicString hyphenationLocale;
 
+    AtomicString textEmphasisCustomMark;
+
 private:
     StyleRareInheritedData();
     StyleRareInheritedData(const StyleRareInheritedData&);