[css-ui] Implement caret-color support
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Aug 2017 17:29:34 +0000 (17:29 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Aug 2017 17:29:34 +0000 (17:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=166572
<rdar://problem/33852589>

Reviewed by David Hyatt.

Source/WebCore:

Add support for the CSS property caret-color as per <https://www.w3.org/TR/css-ui-3/#caret-color> (02 March 2017).
The property caret-color specifies the color of the text insertion caret in an editable element,
say an HTML textarea element.

Unlike other CSS color properties caret-color can have value "auto" and this is its initial
value. Internally we treat value "auto" as an invalid caret color to simplify the code.

Tests: editing/pasteboard/preserve-caret-color.html
       fast/css/caret-color-auto.html
       fast/css/caret-color-fallback-to-color.html
       fast/css/caret-color-inherit.html
       fast/css/caret-color-span-inside-editable-parent.html
       fast/css/caret-color.html
       fast/history/visited-link-caret-color.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::propertyValue):
* css/CSSProperties.json: Add property caret-color. We represent the initial  "auto" Also, fix up
wording in a comment while I am here.
* css/StyleResolver.cpp:
(WebCore::isValidVisitedLinkProperty): Add caret-color to the list of properties that can be
applied to visited hyperlinks.
* css/parser/CSSParserFastPaths.cpp:
(WebCore::parseCaretColor): Added.
(WebCore::CSSParserFastPaths::maybeParseValue): Unlike other CSS color properties caret-color
can be defined to be "auto". We explicitly check if the property is caret-color and use
parseCaretColor() to parse its value.
* css/parser/CSSPropertyParser.cpp:
(WebCore::consumeCaretColor): Added.
(WebCore::CSSPropertyParser::parseSingleValue): Similar to the change to CSSParserFastPaths::maybeParseValue()
use a dedicated code path to parse caret-color.
* editing/EditingStyle.cpp: Preserve caret-color during editing operations.
* editing/FrameSelection.cpp:
(WebCore::CaretBase::paintCaret const): Modified code to query property caret-color instead of
color for the color of the text insertion caret. Always honor the caret-color of the editable
element if it is valid color. Note that "caret-color: auto" is treated as an invalid color
internally. A caret-color can have an invalid color if its inherits from the CSS color property
with an invalid color. If caret-color is a valid color then we take it to be the color of the
text insertion caret. Otherwise, we do what we do today and use a heuristic to determine the
color of the text-insertion caret.
(WebCore::disappearsIntoBackground): Deleted; moved logic into CaretBase::paintCaret().
* page/animation/CSSPropertyAnimation.cpp:
(WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap): Add property wrapper
to support animating caret-color.
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline const): Modified to consider
changes to caret color.
(WebCore::RenderStyle::colorIncludingFallback const): Modified to compute the appropriate
color for property caret-color with respect to an unvisited or visited link.
* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::setCaretColor): Added.
(WebCore::RenderStyle::setVisitedLinkCaretColor): Added.
(WebCore::RenderStyle::caretColor const): Added.
(WebCore::RenderStyle::visitedLinkCaretColor const): Added.
* rendering/style/StyleRareInheritedData.cpp:
(WebCore::StyleRareInheritedData::StyleRareInheritedData): Modified to consider caret color.
(WebCore::StyleRareInheritedData::operator== const): Ditto.
* rendering/style/StyleRareInheritedData.h:

LayoutTests:

Add reference tests to ensure that we do not regress CSS property caret-color.

* TestExpectations: Unskip Web Platform Tests that now pass.
* editing/deleting/maintain-style-after-delete-expected.txt: Updated expected result.
* editing/inserting/insert-paragraph-with-font-and-background-color-expected.txt: Ditto.
* editing/pasteboard/do-not-copy-unnecessary-styles-2-expected.txt: Ditto.
* editing/pasteboard/onpaste-text-html-expected.txt: Ditto.
* editing/pasteboard/preserve-caret-color-expected.txt: Added.
* editing/pasteboard/preserve-caret-color.html: Added.
* editing/pasteboard/preserve-underline-color-expected.txt:
* fast/css/caret-color-auto-expected.html: Added.
* fast/css/caret-color-auto.html: Added.
* fast/css/caret-color-expected.html: Added.
* fast/css/caret-color-fallback-to-color-expected.html: Added.
* fast/css/caret-color-fallback-to-color.html: Added.
* fast/css/caret-color-inherit-expected.html: Added.
* fast/css/caret-color-inherit.html: Added.
* fast/css/caret-color-span-inside-editable-parent-expected.html: Added.
* fast/css/caret-color-span-inside-editable-parent.html: Added.
* fast/css/caret-color.html: Added.
* fast/events/before-input-events-prevent-drag-and-drop-expected.txt: Updated expected result.
* fast/events/input-events-paste-rich-datatransfer-expected.txt: Ditto.
* fast/events/ondrop-text-html-expected.txt: Ditto.
* fast/history/visited-link-caret-color-expected.html: Added.
* fast/history/visited-link-caret-color.html: Added.
* platform/ios/TestExpectations: Skip the tests on iOS as iOS does not enable
ENABLE(TEXT_CARET). UIKit renders the text insertion caret on iOS.
* platform/mac/editing/style/5065910-expected.txt: Updated expected result.
* platform/mac/editing/style/5084241-expected.png: Ditto.
* platform/mac/editing/style/5084241-expected.txt: Ditto.
* platform/ios-wk2/editing/style/5084241-expected.txt: Ditto.

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

42 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/editing/deleting/maintain-style-after-delete-expected.txt
LayoutTests/editing/inserting/insert-paragraph-with-font-and-background-color-expected.txt
LayoutTests/editing/pasteboard/do-not-copy-unnecessary-styles-2-expected.txt
LayoutTests/editing/pasteboard/onpaste-text-html-expected.txt
LayoutTests/editing/pasteboard/preserve-caret-color-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/preserve-caret-color.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/preserve-underline-color-expected.txt
LayoutTests/fast/css/caret-color-auto-expected.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color-auto.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color-expected.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color-fallback-to-color-expected.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color-fallback-to-color.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color-inherit-expected.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color-inherit.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color-span-inside-editable-parent-expected.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color-span-inside-editable-parent.html [new file with mode: 0644]
LayoutTests/fast/css/caret-color.html [new file with mode: 0644]
LayoutTests/fast/events/before-input-events-prevent-drag-and-drop-expected.txt
LayoutTests/fast/events/input-events-paste-rich-datatransfer-expected.txt
LayoutTests/fast/events/ondrop-text-html-expected.txt
LayoutTests/fast/history/visited-link-caret-color-expected.html [new file with mode: 0644]
LayoutTests/fast/history/visited-link-caret-color.html [new file with mode: 0644]
LayoutTests/platform/ios-wk2/editing/style/5084241-expected.txt
LayoutTests/platform/ios/TestExpectations
LayoutTests/platform/mac/editing/style/5065910-expected.txt
LayoutTests/platform/mac/editing/style/5084241-expected.png
LayoutTests/platform/mac/editing/style/5084241-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSProperties.json
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/parser/CSSParserFastPaths.cpp
Source/WebCore/css/parser/CSSPropertyParser.cpp
Source/WebCore/editing/EditingStyle.cpp
Source/WebCore/editing/FrameSelection.cpp
Source/WebCore/page/animation/CSSPropertyAnimation.cpp
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/StyleRareInheritedData.cpp
Source/WebCore/rendering/style/StyleRareInheritedData.h

index f071da0..909f66e 100644 (file)
@@ -1,3 +1,43 @@
+2017-08-14  Daniel Bates  <dabates@apple.com>
+
+        [css-ui] Implement caret-color support
+        https://bugs.webkit.org/show_bug.cgi?id=166572
+        <rdar://problem/33852589>
+
+        Reviewed by David Hyatt.
+
+        Add reference tests to ensure that we do not regress CSS property caret-color.
+
+        * TestExpectations: Unskip Web Platform Tests that now pass.
+        * editing/deleting/maintain-style-after-delete-expected.txt: Updated expected result.
+        * editing/inserting/insert-paragraph-with-font-and-background-color-expected.txt: Ditto.
+        * editing/pasteboard/do-not-copy-unnecessary-styles-2-expected.txt: Ditto.
+        * editing/pasteboard/onpaste-text-html-expected.txt: Ditto.
+        * editing/pasteboard/preserve-caret-color-expected.txt: Added.
+        * editing/pasteboard/preserve-caret-color.html: Added.
+        * editing/pasteboard/preserve-underline-color-expected.txt:
+        * fast/css/caret-color-auto-expected.html: Added.
+        * fast/css/caret-color-auto.html: Added.
+        * fast/css/caret-color-expected.html: Added.
+        * fast/css/caret-color-fallback-to-color-expected.html: Added.
+        * fast/css/caret-color-fallback-to-color.html: Added.
+        * fast/css/caret-color-inherit-expected.html: Added.
+        * fast/css/caret-color-inherit.html: Added.
+        * fast/css/caret-color-span-inside-editable-parent-expected.html: Added.
+        * fast/css/caret-color-span-inside-editable-parent.html: Added.
+        * fast/css/caret-color.html: Added.
+        * fast/events/before-input-events-prevent-drag-and-drop-expected.txt: Updated expected result.
+        * fast/events/input-events-paste-rich-datatransfer-expected.txt: Ditto.
+        * fast/events/ondrop-text-html-expected.txt: Ditto.
+        * fast/history/visited-link-caret-color-expected.html: Added.
+        * fast/history/visited-link-caret-color.html: Added.
+        * platform/ios/TestExpectations: Skip the tests on iOS as iOS does not enable
+        ENABLE(TEXT_CARET). UIKit renders the text insertion caret on iOS.
+        * platform/mac/editing/style/5065910-expected.txt: Updated expected result.
+        * platform/mac/editing/style/5084241-expected.png: Ditto.
+        * platform/mac/editing/style/5084241-expected.txt: Ditto.
+        * platform/ios-wk2/editing/style/5084241-expected.txt: Ditto.
+
 2017-08-14  Zan Dobersek  <zdobersek@igalia.com>
 
         REGRESSION(r220517-r220521) [GTK] Various compositing tests fail
index 3d48b74..b956189 100644 (file)
@@ -1432,22 +1432,3 @@ webkit.org/b/175288 imported/w3c/web-platform-tests/css/css-ui-3/outline-015.htm
 webkit.org/b/175288 imported/w3c/web-platform-tests/css/css-ui-3/outline-016.html [ ImageOnlyFailure ]
 webkit.org/b/175288 imported/w3c/web-platform-tests/css/css-ui-3/outline-019.html [ ImageOnlyFailure ]
 webkit.org/b/175290 imported/w3c/web-platform-tests/css/css-ui-3/text-overflow-005.html [ ImageOnlyFailure ]
-
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-001.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-002.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-003.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-004.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-005.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-006.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-007.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-008.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-009.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-010.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-011.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-012.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-013.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-014.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-015.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-016.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-017.html [ Failure ]
-webkit.org/b/166572 imported/w3c/web-platform-tests/css/css-ui-3/caret-color-021.html [ Failure ]
index c9fe8eb..892575b 100644 (file)
@@ -4,7 +4,9 @@ Deleting 'W' in blue color and then inserting 'O'. The following markup should s
 | "H "
 | <font>
 |   color="#0000ff"
-|   "O<#selection-caret>"
+|   <span>
+|     style="caret-color: rgb(0, 0, 255);"
+|     "O<#selection-caret>"
 
 Deleting the blue colored text and the preceding space and then inserting 'W'. 'W' should be not be in blue color in the following markup:
 | "HW<#selection-caret>"
index c722417..028d495 100644 (file)
@@ -15,7 +15,7 @@ The style and the font should be preserved in new line of text - the "Bar" shoul
 |   <font>
 |     color="#1b6f11"
 |     <span>
-|       style="background-color: rgb(191, 35, 28);"
+|       style="caret-color: rgb(27, 111, 17); background-color: rgb(191, 35, 28);"
 |       "Bar<#selection-caret>"
 |       <br>
 |   <br>
index 13a4d20..e0b3f36 100644 (file)
@@ -3,5 +3,5 @@ This test verifies that WebKit does not erroneously clone nodes hierarchy when c
 
 You should not see any borders:
 | <span>
-|   style="color: rgb(0, 0, 255); background-color: rgb(255, 255, 0);"
+|   style="caret-color: rgb(0, 0, 255); color: rgb(0, 0, 255); background-color: rgb(255, 255, 0);"
 |   "Hello<#selection-caret>"
index 35bf0c7..8c45c64 100644 (file)
@@ -1,5 +1,5 @@
 CONSOLE MESSAGE: line 21: text/plain: This test verifies that we can get text/html from the clipboard during an onpaste event. 
-CONSOLE MESSAGE: line 23: text/html: <span style="color: rgb(0, 0, 0); font-size: medium; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;">This test verifies that we can get text/html from the clipboard during an onpaste event.<span class="Apple-converted-space"> </span></span>
+CONSOLE MESSAGE: line 23: text/html: <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-size: medium; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;">This test verifies that we can get text/html from the clipboard during an onpaste event.<span class="Apple-converted-space"> </span></span>
 This test verifies that we can get text/html from the clipboard during an onpaste event. This test requires DRT.
 Paste content in this div.This test verifies that we can get text/html from the clipboard during an onpaste event. 
 PASS
diff --git a/LayoutTests/editing/pasteboard/preserve-caret-color-expected.txt b/LayoutTests/editing/pasteboard/preserve-caret-color-expected.txt
new file mode 100644 (file)
index 0000000..7e1fb0a
--- /dev/null
@@ -0,0 +1,8 @@
+This test that CSS property caret-color is preserved when copying and pasting.
+| <span>
+|   style="caret-color: rgb(0, 0, 255);"
+|   "caret-color: blue, "
+| <span>
+|   style="caret-color: magenta;"
+|   "caret-color: magenta<#selection-caret>"
+| <br>
diff --git a/LayoutTests/editing/pasteboard/preserve-caret-color.html b/LayoutTests/editing/pasteboard/preserve-caret-color.html
new file mode 100644 (file)
index 0000000..5270b8c
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This test that CSS property caret-color is preserved when copying and pasting.</p>
+<p>To manually test, copy "caret-color: blue, caret-color: magenta" and paste it on the second editable region. Then verify that the color of the text insertion caret is blue and magenta when placed inside the substring "caret-color: blue" and "caret-color: magenta", respectively.</p>
+<div id="copy" contenteditable="true"><span style="caret-color: blue">caret-color: blue, <span style="caret-color: magenta">caret-color: magenta</span></span></div>
+<div id="paste" contenteditable="true"><br></div>
+<script src="../../resources/dump-as-markup.js"></script>
+<script>
+if (!window.testRunner)
+    Markup.noAutoDump();
+else {
+    var copy = document.getElementById("copy");
+    copy.focus();
+    document.execCommand("SelectAll");
+    document.execCommand("Copy");
+    var paste = document.getElementById("paste");
+    paste.focus();
+    document.execCommand("Paste");
+
+    Markup.description(document.getElementsByTagName("p")[0].innerText);
+    Markup.dump("paste");
+}
+</script>
+</body>
+</html>
index 8af65f7..74e2494 100644 (file)
@@ -1,5 +1,5 @@
 This test for a bug copy/pasting underlined text. The color of the underline should be the color of the element that has the text-decoration property.
 | <span>
-|   style="color: rgb(255, 0, 0); text-decoration: underline;"
+|   style="caret-color: rgb(255, 0, 0); color: rgb(255, 0, 0); text-decoration: underline;"
 |   "This should be underlined.<#selection-caret>"
 | <br>
diff --git a/LayoutTests/fast/css/caret-color-auto-expected.html b/LayoutTests/fast/css/caret-color-auto-expected.html
new file mode 100644 (file)
index 0000000..ae7cde1
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#test {
+    background-color: white;
+    color: red;
+    caret-color: green;
+    transform-origin: left top;
+    transform: scale(50, 50);
+    font-size: 10px; /* Needed for the caret to render in Firefox. */
+}
+
+#test > span {
+    background-color: inherit;
+}
+</style>
+</head>
+<body>
+<p>Tests that "caret-color: auto" behaves identical to omitting property caret-color.</p>
+<div id="test-container">
+    <div id="test" contenteditable="true">
+        <span>&nbsp;<!-- Needed for the caret to render in Firefox. --></span>
+    </div>
+</div>
+<script>
+document.getElementById("test").focus();
+window.getSelection().modify("move", "left", "character"); // Place the caret at the start of the <span>.
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color-auto.html b/LayoutTests/fast/css/caret-color-auto.html
new file mode 100644 (file)
index 0000000..baf36b7
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#test {
+    background-color: white;
+    color: red;
+    caret-color: green;
+    transform-origin: left top;
+    transform: scale(50, 50);
+    font-size: 10px; /* Needed for the caret to render in Firefox. */
+}
+
+#test > span {
+    background-color: inherit;
+    caret-color: auto;
+}
+</style>
+</head>
+<body>
+<p>Tests that "caret-color: auto" behaves identical to omitting property caret-color.</p>
+<div id="test-container">
+    <div id="test" contenteditable="true">
+        <span>&nbsp;<!-- Needed for the caret to render in Firefox. --></span>
+    </div>
+</div>
+<script>
+document.getElementById("test").focus();
+window.getSelection().modify("move", "left", "character"); // Place the caret at the start of the <span>.
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color-expected.html b/LayoutTests/fast/css/caret-color-expected.html
new file mode 100644 (file)
index 0000000..7156bf8
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#mock-caret {
+    height: inherit;
+    width: inherit;
+    background-color: green;
+}
+</style>
+</head>
+<body>
+<p>This tests that the text insertion point is rendered with the color caret-color.</p>
+<div id="test-container">
+    <div id="mock-caret"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color-fallback-to-color-expected.html b/LayoutTests/fast/css/caret-color-fallback-to-color-expected.html
new file mode 100644 (file)
index 0000000..392084e
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#mock-caret {
+    height: inherit;
+    width: inherit;
+    background-color: green;
+}
+</style>
+</head>
+<body>
+<p>This tests that caret-color falls back to color.</p>
+<div id="test-container">
+    <div id="mock-caret"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color-fallback-to-color.html b/LayoutTests/fast/css/caret-color-fallback-to-color.html
new file mode 100644 (file)
index 0000000..246fb19
--- /dev/null
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#test {
+    height: inherit;
+    width: inherit;
+    color: green;
+    transform-origin: left top;
+    transform: scale(50, 50);
+    font-size: 10px; /* Needed for the caret to render in Firefox. */
+}
+</style>
+</head>
+<body>
+<p>This tests that caret-color falls back to color.</p>
+<div id="test-container">
+    <div id="test" contenteditable="true">&nbsp;<!-- Needed for the caret to render in Firefox. --></div>
+</div>
+<script>
+document.getElementById("test").focus();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color-inherit-expected.html b/LayoutTests/fast/css/caret-color-inherit-expected.html
new file mode 100644 (file)
index 0000000..1460757
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#mock-caret {
+    height: inherit;
+    width: inherit;
+    background-color: green;
+}
+</style>
+</head>
+<body>
+<p>This tests that caret-color is inherited.</p>
+<div id="test-container">
+    <div id="mock-caret"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color-inherit.html b/LayoutTests/fast/css/caret-color-inherit.html
new file mode 100644 (file)
index 0000000..4e8cb5d
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+    caret-color: green;
+}
+
+#test {
+    height: inherit;
+    width: inherit;
+    caret-color: inherit;
+    transform-origin: left top;
+    transform: scale(50, 50);
+    font-size: 10px; /* Needed for the caret to render in Firefox. */
+}
+</style>
+</head>
+<body>
+<p>This tests that caret-color is inherited.</p>
+<div id="test-container">
+    <div id="test" contenteditable="true">&nbsp;<!-- Needed for the caret to render in Firefox. --></div>
+</div>
+<script>
+document.getElementById("test").focus();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color-span-inside-editable-parent-expected.html b/LayoutTests/fast/css/caret-color-span-inside-editable-parent-expected.html
new file mode 100644 (file)
index 0000000..d93cd0b
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#mock-caret {
+    height: inherit;
+    width: inherit;
+    background-color: green;
+}
+</style>
+</head>
+<body>
+<p>This tests that the text insertion point color represents the caret-color of the inner-most focused element regardless whether the background color of the inner-most focused element cannot be visibly differentiated from the background color of its root editable element.</p>
+<div id="test-container">
+    <div id="mock-caret"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color-span-inside-editable-parent.html b/LayoutTests/fast/css/caret-color-span-inside-editable-parent.html
new file mode 100644 (file)
index 0000000..009aefc
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#test {
+    background-color: white;
+    color: red;
+    transform-origin: left top;
+    transform: scale(50, 50);
+    font-size: 10px; /* Needed for the caret to render in Firefox. */
+}
+
+#test > span {
+    background-color: inherit;
+    caret-color: green;
+}
+</style>
+</head>
+<body>
+<p>This tests that the text insertion point color represents the caret-color of the inner-most focused element regardless whether the background color of the inner-most focused element cannot be visibly differentiated from the background color of its root editable element.</p>
+<div id="test-container">
+    <div id="test" contenteditable="true">
+        <span>&nbsp;<!-- Needed for the caret to render in Firefox. --></span>
+    </div>
+</div>
+<script>
+document.getElementById("test").focus();
+window.getSelection().modify("move", "left", "character"); // Place the caret at the start of the <span>.
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/caret-color.html b/LayoutTests/fast/css/caret-color.html
new file mode 100644 (file)
index 0000000..74c528e
--- /dev/null
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#test {
+    height: inherit;
+    width: inherit;
+    caret-color: green;
+    transform-origin: left top;
+    transform: scale(50, 50);
+    font-size: 10px; /* Needed for the caret to render in Firefox. */
+}
+</style>
+</head>
+<body>
+<p>This tests that the text insertion point is rendered with the color caret-color.</p>
+<div id="test-container">
+    <div id="test" contenteditable="true">&nbsp;<!-- Needed for the caret to render in Firefox. --></div>
+</div>
+<script>
+document.getElementById("test").focus();
+</script>
+</body>
+</html>
index 1d5be58..e062f4e 100644 (file)
@@ -7,4 +7,4 @@ Destination:
 
 HTML content:
 
-<span style="color: rgb(0, 0, 0); font-family: monospace; font-size: 108px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: center; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;">input events</span>
+<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: monospace; font-size: 108px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: center; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;">input events</span>
index 38c1948..175632c 100644 (file)
@@ -2,7 +2,7 @@ To manually test this, copy and paste into the first contenteditable. The follow
 
 destination after pasting (text/html):
 | <b>
-|   style="color: rgb(255, 0, 0); font-family: -webkit-standard; font-style: normal; font-variant-caps: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"
+|   style="caret-color: rgb(255, 0, 0); color: rgb(255, 0, 0); font-family: -webkit-standard; font-style: normal; font-variant-caps: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"
 |   "LayoutTests"
 |   <i>
 |     "are"
index 9a68043..47616bc 100644 (file)
@@ -1,4 +1,4 @@
 CONSOLE MESSAGE: line 21: text/plain: This test verifies that we can get text/html from the drag object during an ondrop event. 
-CONSOLE MESSAGE: line 23: text/html: <span style="color: rgb(0, 0, 0); font-size: medium; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;">This test verifies that we can get text/html from the drag object during an ondrop event.<span class="Apple-converted-space"> </span></span>
+CONSOLE MESSAGE: line 23: text/html: <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-size: medium; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;">This test verifies that we can get text/html from the drag object during an ondrop event.<span class="Apple-converted-space"> </span></span>
 This test verifies that we can get text/html from the drag object during an ondrop event. This test requires DRT.
 PASS
diff --git a/LayoutTests/fast/history/visited-link-caret-color-expected.html b/LayoutTests/fast/history/visited-link-caret-color-expected.html
new file mode 100644 (file)
index 0000000..a8f32a2
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+}
+
+#mock-caret {
+    height: inherit;
+    width: inherit;
+    background-color: green;
+}
+</style>
+</head>
+<body>
+<p>This tests that we apply caret-color for a visited link.</p>
+<div id="test-container">
+    <div id="mock-caret"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/history/visited-link-caret-color.html b/LayoutTests/fast/history/visited-link-caret-color.html
new file mode 100644 (file)
index 0000000..6f990d7
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#test-container {
+    height: 50px;
+    width: 50px;
+    overflow: hidden;
+    outline: none;
+}
+
+a {
+    display: block;
+    height: inherit;
+    width: inherit;
+    transform-origin: left top;
+    transform: scale(50, 50);
+    font-size: 10px; /* Needed for the caret to render in Firefox. */
+}
+
+a:link {
+    caret-color: red;
+}
+
+a:visited {
+    caret-color: green;
+}
+</style>
+<script>
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.keepWebHistory();
+}
+
+function waitForStyleChange(failureTime)
+{
+    var aElement = document.querySelector("a");
+    if (internals.computedStyleIncludingVisitedInfo(aElement).caretColor === "rgb(255, 255, 255)")
+        testRunner.notifyDone();
+    else if (Date.now() > failureTime)
+        testRunner.notifyDone();
+    else
+        setTimeout(waitForStyleChange, 5, failureTime);
+}
+
+function doTest()
+{
+    document.querySelector("#test-container").focus();
+    window.getSelection().modify("move", "left", "character"); // Place the caret at the start of the <a>.
+
+    if (window.internals)
+        internals.toggleOverwriteModeEnabled(); // Disables caret blinking
+    if (window.testRunner)
+        waitForStyleChange(Date.now() + 500);
+}
+</script>
+</head>
+<body onload="doTest()">
+<p>This tests that we apply caret-color for a visited link.</p>
+<iframe src="resources/dummy.html" style="display:none"></iframe>
+<div id="test-container" contenteditable="true">
+    <a href="resources/dummy.html">&nbsp;<!-- Needed for the caret to render in Firefox. --></a>
+</div>
+</body>
+</html>
index 1a0cf5c..950ad32 100644 (file)
@@ -8,11 +8,12 @@ layer at (0,0) size 800x600
           text run at (0,0) width 758: "This tests for a bug where deleting everything in a paragraph of colored text would prevent the user from changing the"
           text run at (0,20) width 64: "text color."
       RenderBlock {DIV} at (0,56) size 784x20
-        RenderInline {FONT} at (0,0) size 151x19 [color=#FF0000]
-          RenderText {#text} at (0,0) size 151x19
-            text run at (0,0) width 151: "This text should be red."
-        RenderInline {FONT} at (0,0) size 159x19 [color=#0000FF]
-          RenderText {#text} at (150,0) size 159x19
-            text run at (150,0) width 159: "This text should be blue."
+        RenderInline {SPAN} at (0,0) size 309x19
+          RenderInline {FONT} at (0,0) size 151x19 [color=#FF0000]
+            RenderText {#text} at (0,0) size 151x19
+              text run at (0,0) width 151: "This text should be red."
+          RenderInline {FONT} at (0,0) size 159x19 [color=#0000FF]
+            RenderText {#text} at (150,0) size 159x19
+              text run at (150,0) width 159: "This text should be blue."
       RenderBlock (anonymous) at (0,76) size 784x0
-caret: position 25 of child 0 {#text} of child 1 {FONT} of child 2 {DIV} of body
+caret: position 25 of child 0 {#text} of child 1 {FONT} of child 0 {SPAN} of child 2 {DIV} of body
index 73a1fb5..e0f3826 100644 (file)
@@ -408,6 +408,13 @@ webkit.org/b/167795 http/tests/security/bypassing-cors-checks-for-extension-urls
 svg/animations/animations-paused-when-inserted-in-hidden-document.html [ Skip ]
 svg/animations/animations-paused-when-inserted-in-hidden-document2.html [ Skip ]
 
+# iOS does not enable ENABLE(TEXT_CARET). UIKit renders the text insertion caret.
+fast/css/caret-color-fallback-to-color.html [ Skip ]
+fast/css/caret-color-inherit.html [ Skip ]
+fast/css/caret-color-span-inside-editable-parent.html [ Skip ]
+fast/css/caret-color.html [ Skip ]
+fast/history/visited-link-caret-color.html [ Skip ]
+
 ###
 # Known failures
 ##
index 36fcd8a..fa923e7 100644 (file)
@@ -12,13 +12,14 @@ layer at (0,0) size 800x600
             RenderText {#text} at (0,0) size 151x18
               text run at (0,0) width 151: "This text should be red."
         RenderBlock {DIV} at (0,18) size 784x18
-          RenderInline {FONT} at (0,0) size 127x18 [color=#0000FF]
-            RenderText {#text} at (0,0) size 127x18
-              text run at (0,0) width 127: "This text should be "
-          RenderInline {FONT} at (0,0) size 240x18 [color=#008000]
-            RenderText {#text} at (126,0) size 240x18
-              text run at (126,0) width 240: "a combination of green and blue, not "
-          RenderInline {FONT} at (0,0) size 25x18 [color=#0000FF]
-            RenderText {#text} at (365,0) size 25x18
-              text run at (365,0) width 25: "red."
-caret: position 37 of child 0 {#text} of child 1 {FONT} of child 1 {DIV} of child 2 {DIV} of body
+          RenderInline {SPAN} at (0,0) size 390x18
+            RenderInline {FONT} at (0,0) size 127x18 [color=#0000FF]
+              RenderText {#text} at (0,0) size 127x18
+                text run at (0,0) width 127: "This text should be "
+            RenderInline {FONT} at (0,0) size 240x18 [color=#008000]
+              RenderText {#text} at (126,0) size 240x18
+                text run at (126,0) width 240: "a combination of green and blue, not "
+            RenderInline {FONT} at (0,0) size 25x18 [color=#0000FF]
+              RenderText {#text} at (365,0) size 25x18
+                text run at (365,0) width 25: "red."
+caret: position 37 of child 0 {#text} of child 1 {FONT} of child 0 {SPAN} of child 1 {DIV} of child 2 {DIV} of body
index f8b82c0..5ca9ea3 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/style/5084241-expected.png and b/LayoutTests/platform/mac/editing/style/5084241-expected.png differ
index c2f954c..4b61bce 100644 (file)
@@ -8,10 +8,11 @@ layer at (0,0) size 800x600
           text run at (0,0) width 758: "This tests for a bug where deleting everything in a paragraph of colored text would prevent the user from changing the"
           text run at (0,18) width 64: "text color."
       RenderBlock {DIV} at (0,52) size 784x18
-        RenderInline {FONT} at (0,0) size 151x18 [color=#FF0000]
-          RenderText {#text} at (0,0) size 151x18
-            text run at (0,0) width 151: "This text should be red."
-        RenderInline {FONT} at (0,0) size 159x18 [color=#0000FF]
-          RenderText {#text} at (150,0) size 159x18
-            text run at (150,0) width 159: "This text should be blue."
-caret: position 25 of child 0 {#text} of child 1 {FONT} of child 2 {DIV} of body
+        RenderInline {SPAN} at (0,0) size 309x18
+          RenderInline {FONT} at (0,0) size 151x18 [color=#FF0000]
+            RenderText {#text} at (0,0) size 151x18
+              text run at (0,0) width 151: "This text should be red."
+          RenderInline {FONT} at (0,0) size 159x18 [color=#0000FF]
+            RenderText {#text} at (150,0) size 159x18
+              text run at (150,0) width 159: "This text should be blue."
+caret: position 25 of child 0 {#text} of child 1 {FONT} of child 0 {SPAN} of child 2 {DIV} of body
index dfb7b80..050b43d 100644 (file)
@@ -1,3 +1,70 @@
+2017-08-14  Daniel Bates  <dabates@apple.com>
+
+        [css-ui] Implement caret-color support
+        https://bugs.webkit.org/show_bug.cgi?id=166572
+        <rdar://problem/33852589>
+
+        Reviewed by David Hyatt.
+
+        Add support for the CSS property caret-color as per <https://www.w3.org/TR/css-ui-3/#caret-color> (02 March 2017).
+        The property caret-color specifies the color of the text insertion caret in an editable element,
+        say an HTML textarea element.
+
+        Unlike other CSS color properties caret-color can have value "auto" and this is its initial
+        value. Internally we treat value "auto" as an invalid caret color to simplify the code.
+
+        Tests: editing/pasteboard/preserve-caret-color.html
+               fast/css/caret-color-auto.html
+               fast/css/caret-color-fallback-to-color.html
+               fast/css/caret-color-inherit.html
+               fast/css/caret-color-span-inside-editable-parent.html
+               fast/css/caret-color.html
+               fast/history/visited-link-caret-color.html
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::ComputedStyleExtractor::propertyValue):
+        * css/CSSProperties.json: Add property caret-color. We represent the initial  "auto" Also, fix up
+        wording in a comment while I am here.
+        * css/StyleResolver.cpp:
+        (WebCore::isValidVisitedLinkProperty): Add caret-color to the list of properties that can be
+        applied to visited hyperlinks.
+        * css/parser/CSSParserFastPaths.cpp:
+        (WebCore::parseCaretColor): Added.
+        (WebCore::CSSParserFastPaths::maybeParseValue): Unlike other CSS color properties caret-color
+        can be defined to be "auto". We explicitly check if the property is caret-color and use
+        parseCaretColor() to parse its value.
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::consumeCaretColor): Added.
+        (WebCore::CSSPropertyParser::parseSingleValue): Similar to the change to CSSParserFastPaths::maybeParseValue()
+        use a dedicated code path to parse caret-color.
+        * editing/EditingStyle.cpp: Preserve caret-color during editing operations.
+        * editing/FrameSelection.cpp:
+        (WebCore::CaretBase::paintCaret const): Modified code to query property caret-color instead of
+        color for the color of the text insertion caret. Always honor the caret-color of the editable
+        element if it is valid color. Note that "caret-color: auto" is treated as an invalid color
+        internally. A caret-color can have an invalid color if its inherits from the CSS color property
+        with an invalid color. If caret-color is a valid color then we take it to be the color of the
+        text insertion caret. Otherwise, we do what we do today and use a heuristic to determine the
+        color of the text-insertion caret.
+        (WebCore::disappearsIntoBackground): Deleted; moved logic into CaretBase::paintCaret().
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap): Add property wrapper
+        to support animating caret-color.
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline const): Modified to consider
+        changes to caret color.
+        (WebCore::RenderStyle::colorIncludingFallback const): Modified to compute the appropriate
+        color for property caret-color with respect to an unvisited or visited link.
+        * rendering/style/RenderStyle.h:
+        (WebCore::RenderStyle::setCaretColor): Added.
+        (WebCore::RenderStyle::setVisitedLinkCaretColor): Added.
+        (WebCore::RenderStyle::caretColor const): Added.
+        (WebCore::RenderStyle::visitedLinkCaretColor const): Added.
+        * rendering/style/StyleRareInheritedData.cpp:
+        (WebCore::StyleRareInheritedData::StyleRareInheritedData): Modified to consider caret color.
+        (WebCore::StyleRareInheritedData::operator== const): Ditto.
+        * rendering/style/StyleRareInheritedData.h:
+
 2017-08-14  Zan Dobersek  <zdobersek@igalia.com>
 
         REGRESSION(r220517-r220521) [GTK] Various compositing tests fail
index 7ec8eb8..7104dbe 100644 (file)
@@ -137,6 +137,7 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyBoxShadow,
     CSSPropertyBoxSizing,
     CSSPropertyCaptionSide,
+    CSSPropertyCaretColor,
     CSSPropertyClear,
     CSSPropertyClip,
     CSSPropertyColor,
@@ -2891,6 +2892,8 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return valueForShadow(style->boxShadow(), propertyID, *style);
         case CSSPropertyCaptionSide:
             return cssValuePool.createValue(style->captionSide());
+        case CSSPropertyCaretColor:
+            return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyCaretColor)) : currentColorOrValidColor(style, style->caretColor());
         case CSSPropertyClear:
             return cssValuePool.createValue(style->clear());
         case CSSPropertyColor:
index 011a959..717f265 100644 (file)
@@ -89,7 +89,7 @@
         "StyleResolver::applyPropertyToRegularStyle() returns true.",
         "",
         "* no-default-color:",
-        "Should only with used with \"VisitedLinkColorSupport\". It indicates that for",
+        "Should only be used with \"VisitedLinkColorSupport\". It indicates that when",
         "setting the inherited value, it will not fallback to using the parent's",
         "\"color\" property if the inherited color is invalid.",
         "",
         "to true is chosen for code generation."
     ],
     "properties": {
+        "caret-color" : {
+            "inherited": true,
+            "codegen-properties": {
+                "initial": "invalidColor",
+                "visited-link-color-support": true
+            },
+            "specification": {
+                "category": "css-ui",
+                "url": "https://drafts.csswg.org/css-ui-3/#propdef-caret-color"
+            }
+        },
         "color": {
             "inherited": true,
             "codegen-properties": {
index 7e7a183..b92b28d 100644 (file)
@@ -1455,6 +1455,7 @@ inline bool isValidVisitedLinkProperty(CSSPropertyID id)
     case CSSPropertyBorderRightColor:
     case CSSPropertyBorderTopColor:
     case CSSPropertyBorderBottomColor:
+    case CSSPropertyCaretColor:
     case CSSPropertyColor:
     case CSSPropertyOutlineColor:
     case CSSPropertyColumnRuleColor:
index 5ca6a4f..d23832c 100644 (file)
@@ -1317,11 +1317,22 @@ static RefPtr<CSSValue> parseSimpleTransform(CSSPropertyID propertyID, const Str
     return parseSimpleTransformList(string.characters16(), string.length());
 }
 
+static RefPtr<CSSValue> parseCaretColor(const String& string, CSSParserMode parserMode)
+{
+    ASSERT(!string.isEmpty());
+    CSSValueID valueID = cssValueKeywordID(string);
+    if (valueID == CSSValueAuto)
+        return CSSValuePool::singleton().createIdentifierValue(valueID);
+    return CSSParserFastPaths::parseColor(string, parserMode);
+}
+
 RefPtr<CSSValue> CSSParserFastPaths::maybeParseValue(CSSPropertyID propertyID, const String& string, CSSParserMode parserMode)
 {
     RefPtr<CSSValue> result = parseSimpleLengthValue(propertyID, string, parserMode);
     if (result)
         return result;
+    if (propertyID == CSSPropertyCaretColor)
+        return parseCaretColor(string, parserMode);
     if (isColorPropertyID(propertyID))
         return parseColor(string, parserMode);
     result = parseKeywordValue(propertyID, string, parserMode);
index 6116a49..7df81a2 100644 (file)
@@ -1811,6 +1811,13 @@ static RefPtr<CSSValue> consumeTextEmphasisStyle(CSSParserTokenRange& range)
     return nullptr;
 }
 
+static RefPtr<CSSPrimitiveValue> consumeCaretColor(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    if (range.peek().id() == CSSValueAuto)
+        return consumeIdent(range);
+    return consumeColor(range, cssParserMode);
+}
+
 static RefPtr<CSSValue> consumeOutlineColor(CSSParserTokenRange& range, CSSParserMode cssParserMode)
 {
     // Allow the special focus color even in HTML Standard parsing mode.
@@ -4020,6 +4027,8 @@ RefPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID property, CSS
     case CSSPropertyLightingColor:
     case CSSPropertyColumnRuleColor:
         return consumeColor(m_range, m_context.mode);
+    case CSSPropertyCaretColor:
+        return consumeCaretColor(m_range, m_context.mode);
     case CSSPropertyColor:
     case CSSPropertyBackgroundColor:
         return consumeColor(m_range, m_context.mode, inQuirksMode());
index c223d63..4d42d2b 100644 (file)
@@ -58,6 +58,7 @@ namespace WebCore {
 // Editing style properties must be preserved during editing operation.
 // e.g. when a user inserts a new paragraph, all properties listed here must be copied to the new paragraph.
 static const CSSPropertyID editingProperties[] = {
+    CSSPropertyCaretColor,
     CSSPropertyColor,
     CSSPropertyFontFamily,
     CSSPropertyFontSize,
index 2e06e17..071eb44 100644 (file)
@@ -1713,13 +1713,6 @@ void FrameSelection::paintCaret(GraphicsContext& context, const LayoutPoint& pai
         CaretBase::paintCaret(m_selection.start().deprecatedNode(), context, paintOffset, clipRect);
 }
 
-#if ENABLE(TEXT_CARET)
-static inline bool disappearsIntoBackground(const Color& foreground, const Color& background)
-{
-    return background.blend(foreground) == background;
-}
-#endif
-
 void CaretBase::paintCaret(Node* node, GraphicsContext& context, const LayoutPoint& paintOffset, const LayoutRect& clipRect) const
 {
 #if ENABLE(TEXT_CARET)
@@ -1736,22 +1729,21 @@ void CaretBase::paintCaret(Node* node, GraphicsContext& context, const LayoutPoi
 
     Color caretColor = Color::black;
     Element* element = is<Element>(*node) ? downcast<Element>(node) : node->parentElement();
-    Element* rootEditableElement = node->rootEditableElement();
-
     if (element && element->renderer()) {
-        bool setToRootEditableElement = false;
-        if (rootEditableElement && rootEditableElement->renderer()) {
-            const auto& rootEditableStyle = rootEditableElement->renderer()->style();
-            const auto& elementStyle = element->renderer()->style();
-            auto rootEditableBGColor = rootEditableStyle.visitedDependentColor(CSSPropertyBackgroundColor);
-            auto elementBGColor = elementStyle.visitedDependentColor(CSSPropertyBackgroundColor);
-            if (disappearsIntoBackground(elementBGColor, rootEditableBGColor)) {
-                caretColor = rootEditableStyle.visitedDependentColor(CSSPropertyColor);
-                setToRootEditableElement = true;
+        auto computeCaretColor = [] (const RenderStyle& elementStyle, const RenderStyle* rootEditableStyle) {
+            // CSS value "auto" is treated as an invalid color.
+            if (!elementStyle.caretColor().isValid() && rootEditableStyle) {
+                auto rootEditableBackgroundColor = rootEditableStyle->visitedDependentColor(CSSPropertyBackgroundColor);
+                auto elementBackgroundColor = elementStyle.visitedDependentColor(CSSPropertyBackgroundColor);
+                auto disappearsIntoBackground = rootEditableBackgroundColor.blend(elementBackgroundColor) == rootEditableBackgroundColor;
+                if (disappearsIntoBackground)
+                    return rootEditableStyle->visitedDependentColor(CSSPropertyCaretColor);
             }
-        }
-        if (!setToRootEditableElement)
-            caretColor = element->renderer()->style().visitedDependentColor(CSSPropertyColor);
+            return elementStyle.visitedDependentColor(CSSPropertyCaretColor);
+        };
+        auto* rootEditableElement = node->rootEditableElement();
+        auto* rootEditableStyle = rootEditableElement && rootEditableElement->renderer() ? &rootEditableElement->renderer()->style() : nullptr;
+        caretColor = computeCaretColor(element->renderer()->style(), rootEditableStyle);
     }
 
     context.fillRect(caret, caretColor);
index b4c3e22..2130887 100644 (file)
@@ -1493,6 +1493,9 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
         new LengthPropertyWrapper<Length>(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight),
         new LengthPropertyWrapper<Length>(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop),
         new LengthPropertyWrapper<Length>(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom),
+
+        new PropertyWrapperVisitedAffectedColor(CSSPropertyCaretColor, &RenderStyle::caretColor, &RenderStyle::setCaretColor, &RenderStyle::visitedLinkCaretColor, &RenderStyle::setVisitedLinkCaretColor),
+
         new PropertyWrapperVisitedAffectedColor(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor, &RenderStyle::visitedLinkColor, &RenderStyle::setVisitedLinkColor),
 
         new PropertyWrapperVisitedAffectedColor(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor, &RenderStyle::visitedLinkBackgroundColor, &RenderStyle::setVisitedLinkBackgroundColor),
index 5704cc5..f954d8f 100644 (file)
@@ -902,7 +902,8 @@ bool RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle
         || m_rareInheritedData->textStrokeColor != other.m_rareInheritedData->textStrokeColor
         || m_rareInheritedData->textEmphasisColor != other.m_rareInheritedData->textEmphasisColor
         || m_rareInheritedData->textEmphasisFill != other.m_rareInheritedData->textEmphasisFill
-        || m_rareInheritedData->strokeColor != other.m_rareInheritedData->strokeColor)
+        || m_rareInheritedData->strokeColor != other.m_rareInheritedData->strokeColor
+        || m_rareInheritedData->caretColor != other.m_rareInheritedData->caretColor)
         return true;
 
     return false;
@@ -1749,6 +1750,9 @@ Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c
         result = visitedLink ? visitedLinkBorderBottomColor() : borderBottomColor();
         borderStyle = borderBottomStyle();
         break;
+    case CSSPropertyCaretColor:
+        result = visitedLink ? visitedLinkCaretColor() : caretColor();
+        break;
     case CSSPropertyColor:
         result = visitedLink ? visitedLinkColor() : color();
         break;
index 5c15fb6..badab9d 100644 (file)
@@ -1036,6 +1036,7 @@ public:
     void setTextStrokeColor(const Color& c) { SET_VAR(m_rareInheritedData, textStrokeColor, c); }
     void setTextStrokeWidth(float w) { SET_VAR(m_rareInheritedData, textStrokeWidth, w); }
     void setTextFillColor(const Color& c) { SET_VAR(m_rareInheritedData, textFillColor, c); }
+    void setCaretColor(const Color& c) { SET_VAR(m_rareInheritedData, caretColor, c); }
     void setOpacity(float f) { float v = clampTo<float>(f, 0, 1); SET_VAR(m_rareNonInheritedData, opacity, v); }
     void setAppearance(ControlPart a) { SET_VAR(m_rareNonInheritedData, appearance, a); }
     // For valid values of box-align see http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/#alignment
@@ -1695,6 +1696,7 @@ public:
     void setVisitedLinkTextEmphasisColor(const Color& v) { SET_VAR(m_rareInheritedData, visitedLinkTextEmphasisColor, v); }
     void setVisitedLinkTextFillColor(const Color& v) { SET_VAR(m_rareInheritedData, visitedLinkTextFillColor, v); }
     void setVisitedLinkTextStrokeColor(const Color& v) { SET_VAR(m_rareInheritedData, visitedLinkTextStrokeColor, v); }
+    void setVisitedLinkCaretColor(const Color& v) { SET_VAR(m_rareInheritedData, visitedLinkCaretColor, v); }
 
     void inheritUnicodeBidiFrom(const RenderStyle* parent) { m_nonInheritedFlags.setUnicodeBidi(parent->m_nonInheritedFlags.unicodeBidi()); }
     void getShadowExtent(const ShadowData*, LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const;
@@ -1715,6 +1717,7 @@ public:
     const Color& textEmphasisColor() const { return m_rareInheritedData->textEmphasisColor; }
     const Color& textFillColor() const { return m_rareInheritedData->textFillColor; }
     const Color& textStrokeColor() const { return m_rareInheritedData->textStrokeColor; }
+    const Color& caretColor() const { return m_rareInheritedData->caretColor; }
     const Color& visitedLinkColor() const;
     const Color& visitedLinkBackgroundColor() const { return m_rareNonInheritedData->visitedLinkBackgroundColor; }
     const Color& visitedLinkBorderLeftColor() const { return m_rareNonInheritedData->visitedLinkBorderLeftColor; }
@@ -1728,6 +1731,7 @@ public:
     const Color& visitedLinkTextEmphasisColor() const { return m_rareInheritedData->visitedLinkTextEmphasisColor; }
     const Color& visitedLinkTextFillColor() const { return m_rareInheritedData->visitedLinkTextFillColor; }
     const Color& visitedLinkTextStrokeColor() const { return m_rareInheritedData->visitedLinkTextStrokeColor; }
+    const Color& visitedLinkCaretColor() const { return m_rareInheritedData->visitedLinkCaretColor; }
 
     const Color& stopColor() const { return svgStyle().stopColor(); }
     const Color& floodColor() const { return svgStyle().floodColor(); }
index 1231f3f..9dfa8c8 100644 (file)
@@ -38,7 +38,7 @@ struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<Greater
     void* styleImage;
     Color firstColor;
     float firstFloat;
-    Color colors[7];
+    Color colors[9];
     void* ownPtrs[1];
     AtomicString atomicStrings[5];
     void* refPtrs[2];
@@ -160,6 +160,8 @@ inline StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedDa
     , visitedLinkTextStrokeColor(o.visitedLinkTextStrokeColor)
     , visitedLinkTextFillColor(o.visitedLinkTextFillColor)
     , visitedLinkTextEmphasisColor(o.visitedLinkTextEmphasisColor)
+    , caretColor(o.caretColor)
+    , visitedLinkCaretColor(o.visitedLinkCaretColor)
     , textShadow(o.textShadow ? std::make_unique<ShadowData>(*o.textShadow) : nullptr)
     , cursorData(o.cursorData)
     , indent(o.indent)
@@ -261,6 +263,8 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
         && visitedLinkTextStrokeColor == o.visitedLinkTextStrokeColor
         && visitedLinkTextFillColor == o.visitedLinkTextFillColor
         && visitedLinkTextEmphasisColor == o.visitedLinkTextEmphasisColor
+        && caretColor == o.caretColor
+        && visitedLinkCaretColor == o.visitedLinkCaretColor
 #if ENABLE(TOUCH_EVENTS)
         && tapHighlightColor == o.tapHighlightColor
 #endif
index 87f09a9..24d47be 100644 (file)
@@ -66,7 +66,10 @@ public:
     
     Color visitedLinkTextStrokeColor;
     Color visitedLinkTextFillColor;
-    Color visitedLinkTextEmphasisColor;    
+    Color visitedLinkTextEmphasisColor;
+
+    Color caretColor;
+    Color visitedLinkCaretColor;
 
     std::unique_ptr<ShadowData> textShadow; // Our text shadow information for shadowed text drawing.