Convert the caps lock indicator to be implemented using the shadow DOM
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 22 Feb 2015 23:33:21 +0000 (23:33 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 22 Feb 2015 23:33:21 +0000 (23:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=141868

Reviewed by Dan Bernstein.

Source/WebCore:

- Re-adds 'caps-lock-indicator' as a valid -webkit-appearance value. It was removed
  in r74099 to work around a site bug, that should not be a problem anymore.
- Converts the caps lock indicator to be implemented as part of the shadow DOM rather
  than a paint time effect. This gives the proper overflow behavior (it now clips) and
  behaves correctly in RTL.

* css/CSSParser.cpp:
(WebCore::isValidKeywordPropertyAndValue):
Make 'caps-lock-indicator' a valid -webkit-appearance value.

* css/CSSValueKeywords.in:
Remove comment that indicated that caps-lock-indicator was not a valid
-webkit-appearance value.

* css/html.css:
(input::-webkit-caps-lock-indicator):
Add new default style for the new -webkit-caps-lock-indicator pseudo-element. The
trick employed here is to use a content: image to both implement the painting of
the caps lock indicator, and to get the sizing right (shrink-to-fit, height: 100%).

* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::capsLockIndicatorElement):
(WebCore::HTMLInputElement::capsLockStateMayHaveChanged):
* html/HTMLInputElement.h:
* html/InputType.cpp:
(WebCore::InputType::capsLockStateMayHaveChanged):
* html/InputType.h:
(WebCore::InputType::capsLockIndicatorElement):
Pipe notification of changes in the caps locks state to the <input> element
rather than the RenderTextControlSingleLine. Also add an accessor for the caps
lock indicator element in the shadow DOM.

* html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::forwardEvent):
(WebCore::TextFieldInputType::shouldHaveCapsLockIndicator):
(WebCore::TextFieldInputType::createShadowSubtree):
(WebCore::TextFieldInputType::capsLockIndicatorElement):
(WebCore::TextFieldInputType::destroyShadowSubtree):
(WebCore::TextFieldInputType::shouldDrawCapsLockIndicator):
(WebCore::TextFieldInputType::capsLockStateMayHaveChanged):
* html/TextFieldInputType.h:
Add a new element to the text field shadow DOM to act as the caps lock indicator.
Give it a pseudo-element ID of -webkit-caps-lock-indicator so it can be referenced
from CSS. The element is always in the DOM for a password field. It toggles between
display: none and display: block depending on the state of the caps lock key.

* page/EventHandler.cpp:
(WebCore::EventHandler::capsLockStateMayHaveChanged):
Pipe notification of changes in the caps locks state to the <input> element
rather than the RenderTextControlSingleLine.

* rendering/RenderTextControlSingleLine.cpp:
(WebCore::RenderTextControlSingleLine::RenderTextControlSingleLine):
(WebCore::RenderTextControlSingleLine::paint): Deleted.
(WebCore::RenderTextControlSingleLine::capsLockStateMayHaveChanged): Deleted.
* rendering/RenderTextControlSingleLine.h:
Remove logic for drawing the caps lock indicator.

* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::adjustStyle):
(WebCore::RenderTheme::paint):
(WebCore::RenderTheme::paintMeter):
(WebCore::RenderTheme::adjustCapsLockIndicatorStyle):
(WebCore::RenderTheme::paintCapsLockIndicator):
(WebCore::RenderTheme::shouldHaveCapsLockIndicator):
* rendering/RenderTheme.h:
(WebCore::RenderTheme::paintCapsLockIndicator): Deleted.
* rendering/RenderThemeIOS.h:
* rendering/RenderThemeIOS.mm:
(WebCore::RenderThemeIOS::shouldHaveCapsLockIndicator):
* rendering/RenderThemeMac.h:
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::shouldHaveCapsLockIndicator):
(WebCore::RenderThemeMac::paintCapsLockIndicator): Deleted.
Now that the caps lock indicator is implemented like other aspects of form controls,
the theme code can be converted to be similar as well.

LayoutTests:

* fast/css/appearance-caps-lock-indicator-expected.txt:
* fast/css/appearance-caps-lock-indicator.html:
* platform/mac/fast/css/text-overflow-input-expected.txt:
* platform/mac/fast/forms/basic-inputs-expected.txt:
* platform/mac/fast/forms/input-appearance-height-expected.txt:
* platform/mac/fast/forms/input-value-expected.txt:
* platform/mac/fast/forms/placeholder-pseudo-style-expected.txt:
* platform/mac/fast/forms/validation-message-appearance-expected.txt:

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

35 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css/appearance-caps-lock-indicator-expected.txt
LayoutTests/fast/css/appearance-caps-lock-indicator.html
LayoutTests/platform/mac-mavericks/fast/css/text-overflow-input-expected.txt
LayoutTests/platform/mac-mavericks/fast/forms/basic-inputs-expected.txt
LayoutTests/platform/mac-mavericks/fast/forms/input-appearance-height-expected.txt
LayoutTests/platform/mac-mavericks/fast/forms/input-value-expected.txt
LayoutTests/platform/mac-mavericks/fast/forms/placeholder-pseudo-style-expected.txt
LayoutTests/platform/mac-mavericks/fast/forms/validation-message-appearance-expected.txt
LayoutTests/platform/mac-mavericks/tables/mozilla_expected_failures/bugs/bug92647-1-expected.txt
LayoutTests/platform/mac/fast/css/text-overflow-input-expected.txt
LayoutTests/platform/mac/fast/forms/basic-inputs-expected.txt
LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt
LayoutTests/platform/mac/fast/forms/input-value-expected.txt
LayoutTests/platform/mac/fast/forms/placeholder-pseudo-style-expected.txt
LayoutTests/platform/mac/fast/forms/validation-message-appearance-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSValueKeywords.in
Source/WebCore/css/html.css
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLInputElement.h
Source/WebCore/html/InputType.cpp
Source/WebCore/html/InputType.h
Source/WebCore/html/TextFieldInputType.cpp
Source/WebCore/html/TextFieldInputType.h
Source/WebCore/page/EventHandler.cpp
Source/WebCore/rendering/RenderTextControlSingleLine.cpp
Source/WebCore/rendering/RenderTextControlSingleLine.h
Source/WebCore/rendering/RenderTheme.cpp
Source/WebCore/rendering/RenderTheme.h
Source/WebCore/rendering/RenderThemeIOS.h
Source/WebCore/rendering/RenderThemeIOS.mm
Source/WebCore/rendering/RenderThemeMac.h
Source/WebCore/rendering/RenderThemeMac.mm

index e90ea3c737ad28d62b13627962b247d56e0f61ce..cb0d47fe543c8dc1ad608e8998d48da78a469073 100644 (file)
@@ -1,3 +1,19 @@
+2015-02-21  Sam Weinig  <sam@webkit.org>
+
+        Convert the caps lock indicator to be implemented using the shadow DOM
+        https://bugs.webkit.org/show_bug.cgi?id=141868
+
+        Reviewed by Dan Bernstein.
+
+        * fast/css/appearance-caps-lock-indicator-expected.txt:
+        * fast/css/appearance-caps-lock-indicator.html:
+        * platform/mac/fast/css/text-overflow-input-expected.txt:
+        * platform/mac/fast/forms/basic-inputs-expected.txt:
+        * platform/mac/fast/forms/input-appearance-height-expected.txt:
+        * platform/mac/fast/forms/input-value-expected.txt:
+        * platform/mac/fast/forms/placeholder-pseudo-style-expected.txt:
+        * platform/mac/fast/forms/validation-message-appearance-expected.txt:
+
 2015-02-22  David Kilzer  <ddkilzer@apple.com>
 
         [iOS] Gardening: Clean up timeout test for ios-simulator-{wk1,wk2}
index 03d9b06f8c3797fb99a9f17917217a5414be8eb1..3171282151f2ddce199e05b5973bfe224ddcfac0 100644 (file)
@@ -1,3 +1,3 @@
-Test that the CSS parser does not accept caps-lock-indicator as a -webkit-appearance value.
+Test that the CSS parser accepts caps-lock-indicator as a -webkit-appearance value.
 
 PASS
index 5d100732fc4a6a785a1198bd3c8e2f9ab1abb6dc..d8453405a2bd3710ab16ed76c295a27976390118 100644 (file)
@@ -1,6 +1,5 @@
 <p>
-    Test that the CSS parser does not accept <tt>caps-lock-indicator</tt> as a <tt>-webkit-appearance</tt>
-    value.
+    Test that the CSS parser accepts <tt>caps-lock-indicator</tt> as a <tt>-webkit-appearance</tt> value.
 </p>
 <p id="result">FAIL: Test did not run</p>
 <div id="target" style="display: none; -webkit-appearance: caps-lock-indicator;"></div>
@@ -9,5 +8,5 @@
         testRunner.dumpAsText();
 
     var appearance = document.getElementById("target").style.webkitAppearance;
-    document.getElementById("result").innerText = appearance === "" ? "PASS" : "FAIL: parsed as " + appearance;
+    document.getElementById("result").innerText = appearance === "caps-lock-indicator" ? "PASS" : "FAIL: parsed as " + appearance;
 </script>
index e5dd1cbef60a8a90b73e288ce40a9335ba54b110..c33b975d690ff94efea36444562d8741b03814ed 100644 (file)
@@ -30,6 +30,8 @@ layer at (0,0) size 800x382
             RenderBlock {DIV} at (147,1) size 14x11
         RenderText {#text} at (0,0) size 0x0
         RenderTextControl {INPUT} at (2,43) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 140x13
+            RenderBlock {DIV} at (0,0) size 140x13
         RenderBR {BR} at (149,43) size 1x18
         RenderTextControl {INPUT} at (2,66) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
         RenderText {#text} at (149,66) size 5x18
@@ -51,6 +53,8 @@ layer at (0,0) size 800x382
             RenderBlock {DIV} at (147,1) size 14x11
         RenderText {#text} at (0,0) size 0x0
         RenderTextControl {INPUT} at (2,89) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 140x13
+            RenderBlock {DIV} at (0,0) size 140x13
         RenderText {#text} at (0,0) size 0x0
       RenderBlock {P} at (0,160) size 784x110
         RenderText {#text} at (0,0) size 546x18
@@ -76,6 +80,8 @@ layer at (0,0) size 800x382
             RenderBlock {DIV} at (147,1) size 14x11
         RenderText {#text} at (0,0) size 0x0
         RenderTextControl {INPUT} at (2,43) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 140x13
+            RenderBlock {DIV} at (0,0) size 140x13
         RenderBR {BR} at (149,43) size 1x18
         RenderTextControl {INPUT} at (2,66) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
         RenderText {#text} at (149,66) size 5x18
@@ -97,6 +103,8 @@ layer at (0,0) size 800x382
             RenderBlock {DIV} at (147,1) size 14x11
         RenderText {#text} at (0,0) size 0x0
         RenderTextControl {INPUT} at (2,89) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 140x13
+            RenderBlock {DIV} at (0,0) size 140x13
         RenderText {#text} at (0,0) size 0x0
       RenderBlock {P} at (0,286) size 784x64
         RenderText {#text} at (0,0) size 237x18
@@ -141,7 +149,7 @@ layer at (501,73) size 139x13 scrollWidth 294
     RenderText {#text} at (0,0) size 293x13
       text run at (0,0) width 293: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
 layer at (13,96) size 139x13 scrollWidth 341
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
     RenderText {#text} at (0,0) size 340x13
       text run at (0,0) width 340: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (13,119) size 139x13 scrollX 153 scrollWidth 293
@@ -165,7 +173,7 @@ layer at (501,119) size 139x13 scrollX 153 scrollWidth 293
     RenderText {#text} at (-153,0) size 294x13
       text run at (-153,0) width 293: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
 layer at (13,142) size 139x13 scrollX 200 scrollWidth 339
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
     RenderText {#text} at (-200,0) size 341x13
       text run at (-200,0) width 340 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (13,199) size 139x13 scrollWidth 293
@@ -189,7 +197,7 @@ layer at (501,199) size 139x13 scrollWidth 294
     RenderText {#text} at (0,0) size 293x13
       text run at (0,0) width 293: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
 layer at (13,222) size 139x13 scrollWidth 341
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
     RenderText {#text} at (0,0) size 340x13
       text run at (0,0) width 340: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (13,245) size 139x13 scrollX 153 scrollWidth 293
@@ -213,7 +221,7 @@ layer at (501,245) size 139x13 scrollX 153 scrollWidth 293
     RenderText {#text} at (-153,0) size 294x13
       text run at (-153,0) width 293: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
 layer at (13,268) size 139x13 scrollX 200 scrollWidth 339
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
     RenderText {#text} at (-200,0) size 341x13
       text run at (-200,0) width 340 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (259,325) size 139x13 scrollWidth 293
index 46597fedb0e81499de734e0411acb83196ceb5cb..ef15f96be327e7a540bf87ac7088b8e852549b07 100644 (file)
@@ -43,9 +43,13 @@ layer at (0,0) size 800x600
           text run at (334,3) width 13: "b "
           text run at (346,3) width 8: "a"
         RenderTextControl {INPUT} at (3,26) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 140x13
+            RenderBlock {DIV} at (0,0) size 140x13
         RenderText {#text} at (150,26) size 65x18
           text run at (150,26) width 65: "password "
         RenderTextControl {INPUT} at (216,26) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 140x13
+            RenderBlock {DIV} at (0,0) size 140x13
         RenderText {#text} at (363,26) size 9x18
           text run at (363,26) width 9: "b"
       RenderBlock {DIV} at (10,374) size 450x21 [border: (1px solid #FF0000)]
@@ -75,10 +79,10 @@ layer at (208,330) size 139x13
     RenderText {#text} at (0,0) size 18x13
       text run at (0,0) width 18: "foo"
 layer at (24,353) size 139x13
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
     RenderText {#text} at (0,0) size 19x13
       text run at (0,0) width 19: "\x{2022}\x{2022}\x{2022}"
 layer at (238,353) size 139x13
-  RenderBlock {DIV} at (3,3) size 140x13 [color=#545454]
+  RenderBlock {DIV} at (0,0) size 140x13 [color=#545454]
     RenderText {#text} at (0,0) size 19x13
       text run at (0,0) width 19: "\x{2022}\x{2022}\x{2022}"
index ce92dfb3b2f34f6e8184bb177cb8d4a0b4874040..0cca914c7fd24fa8f125ce369c705fe329bd5fe3 100644 (file)
@@ -83,6 +83,8 @@ layer at (0,0) size 800x600
         RenderText {#text} at (0,214) size 65x18
           text run at (0,214) width 65: "password "
         RenderTextControl {INPUT} at (66,214) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 140x13
+            RenderBlock {DIV} at (0,0) size 140x13
         RenderText {#text} at (213,214) size 5x18
           text run at (213,214) width 5: " "
         RenderBR {BR} at (217,228) size 1x0
@@ -101,6 +103,6 @@ layer at (41,54) size 139x13
 layer at (63,220) size 139x13
   RenderBlock {DIV} at (3,3) size 140x13
 layer at (77,243) size 139x13
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
 layer at (66,266) size 139x13
   RenderBlock {DIV} at (0,0) size 140x13
index 91fc6d4758f4bfefd2db39ca1c1c860f5e2ff0ce..a4df05844504d2616c010c3bee4c70fe62a91ade 100644 (file)
@@ -46,6 +46,8 @@ layer at (0,0) size 800x600
                   text run at (1,1) width 248: "password with value property changed"
               RenderTableCell {TD} at (396,27) size 243x25 [r=1 c=1 rs=1 cs=1]
                 RenderTextControl {INPUT} at (3,3) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+                  RenderFlexibleBox {DIV} at (3,3) size 140x13
+                    RenderBlock {DIV} at (0,0) size 140x13
               RenderTableCell {TD} at (641,29) size 63x20 [r=1 c=2 rs=1 cs=1]
                 RenderText {#text} at (1,1) size 30x18
                   text run at (1,1) width 30: "after"
@@ -205,7 +207,7 @@ layer at (410,134) size 139x13
     RenderText {#text} at (0,0) size 35x13
       text run at (0,0) width 35: "before"
 layer at (410,161) size 139x13
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
     RenderText {#text} at (0,0) size 37x13
       text run at (0,0) width 37: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (410,302) size 139x13
index 05b9ad3077a6f1a0eded399113728a081db7a516..6f84327c8a98a0a8be3fe009776b642b35e93e74 100644 (file)
@@ -17,6 +17,8 @@ layer at (0,0) size 800x600
       RenderText {#text} at (323,20) size 5x18
         text run at (323,20) width 5: " "
       RenderTextControl {INPUT} at (329,20) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+        RenderFlexibleBox {DIV} at (3,3) size 140x13
+          RenderBlock {DIV} at (0,0) size 140x13
       RenderText {#text} at (476,20) size 5x18
         text run at (476,20) width 5: " "
       RenderTextControl {INPUT} at (482,20) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
@@ -43,7 +45,7 @@ layer at (340,31) size 139x13
     RenderText {#text} at (0,0) size 50x13
       text run at (0,0) width 50: "password"
 layer at (340,31) size 139x13
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
 layer at (493,31) size 139x13
   RenderBlock {DIV} at (3,3) size 140x13 [color=#640000]
     RenderText {#text} at (0,0) size 69x13
index bd0d762ed76a0de43395e6b13f12c6b5b7d94aea..f35c8a266baaa7986e888b6de46d792353a6705c 100644 (file)
@@ -5,6 +5,8 @@ layer at (0,0) size 800x39
     RenderBody {BODY} at (8,8) size 784x23
       RenderBlock {FORM} at (0,0) size 784x23
         RenderTextControl {INPUT} at (2,2) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 140x13
+            RenderBlock {DIV} at (0,0) size 140x13
         RenderText {#text} at (149,2) size 5x18
           text run at (149,2) width 5: " "
         RenderButton {INPUT} at (155,3) size 54x18 [bgcolor=#C0C0C0]
@@ -13,7 +15,7 @@ layer at (0,0) size 800x39
               text run at (0,0) width 38: "Submit"
         RenderText {#text} at (0,0) size 0x0
 layer at (13,13) size 139x13
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
 layer at (10,29) size 220x100
   RenderBlock (positioned) zI: 2147483647 {DIV} at (10,29) size 220x100
 layer at (10,29) size 220x16 scrollHeight 25
@@ -34,4 +36,4 @@ layer at (10,41) size 220x84
           text run at (0,32) width 137: "the current password."
 layer at (42,29) size 18x18 backgroundClip at (10,29) size 220x16 clip at (10,29) size 220x16 outlineClip at (10,29) size 220x16
   RenderBlock (relative positioned) zI: 2147483645 {DIV} at (0,0) size 18x18 [bgcolor=#F8ECEC] [border: (2px solid #440000) none (2px solid #440000)]
-caret: position 0 of child 0 {DIV} of {#document-fragment} of child 1 {INPUT} of child 0 {FORM} of body
+caret: position 0 of child 0 {DIV} of child 0 {DIV} of child 0 {DIV} of {#document-fragment} of child 1 {INPUT} of child 0 {FORM} of body
index 76820bfda446c1ba6861e719ea7bb7779fba291d..310d39a6b470af61b78bbf76b037b1dad591c5e7 100644 (file)
@@ -24,9 +24,11 @@ layer at (0,0) size 800x600
                           text run at (2,2) width 31: "PIN:"
                       RenderTableCell {TD} at (85,44) size 193x27 [border: (1px inset #808080)] [r=1 c=1 rs=1 cs=1]
                         RenderTextControl {INPUT} at (4,4) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+                          RenderFlexibleBox {DIV} at (3,3) size 140x13
+                            RenderBlock {DIV} at (0,0) size 140x13
                         RenderText {#text} at (0,0) size 0x0
                       RenderTableCell {TD} at (280,55) size 4x4 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=1]
 layer at (107,30) size 139x13
   RenderBlock {DIV} at (3,3) size 140x13
 layer at (107,66) size 139x13
-  RenderBlock {DIV} at (3,3) size 140x13
+  RenderBlock {DIV} at (0,0) size 140x13
index c03fc7dcc9d34f146d711c5ee2e4d6c7fc7637ff..d0ecdffebfd02085190de5153d95b6b6b3a11e26 100644 (file)
@@ -31,6 +31,8 @@ layer at (0,0) size 800x290
         RenderText {#text} at (615,20) size 5x18
           text run at (615,20) width 5: " "
         RenderTextControl {INPUT} at (621,20) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 131x13
+            RenderBlock {DIV} at (0,0) size 131x13
         RenderBR {BR} at (759,20) size 1x18
         RenderTextControl {INPUT} at (2,43) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
         RenderText {#text} at (140,43) size 5x18
@@ -53,6 +55,8 @@ layer at (0,0) size 800x290
         RenderText {#text} at (615,43) size 5x18
           text run at (615,43) width 5: " "
         RenderTextControl {INPUT} at (621,43) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 131x13
+            RenderBlock {DIV} at (0,0) size 131x13
         RenderText {#text} at (0,0) size 0x0
       RenderBlock {P} at (0,114) size 784x64
         RenderText {#text} at (0,0) size 546x18
@@ -79,6 +83,8 @@ layer at (0,0) size 800x290
         RenderText {#text} at (615,20) size 5x18
           text run at (615,20) width 5: " "
         RenderTextControl {INPUT} at (621,20) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 131x13
+            RenderBlock {DIV} at (0,0) size 131x13
         RenderBR {BR} at (759,20) size 1x18
         RenderTextControl {INPUT} at (2,43) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
         RenderText {#text} at (140,43) size 5x18
@@ -101,6 +107,8 @@ layer at (0,0) size 800x290
         RenderText {#text} at (615,43) size 5x18
           text run at (615,43) width 5: " "
         RenderTextControl {INPUT} at (621,43) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 131x13
+            RenderBlock {DIV} at (0,0) size 131x13
         RenderText {#text} at (0,0) size 0x0
       RenderBlock {P} at (0,194) size 784x64
         RenderText {#text} at (0,0) size 237x18
@@ -145,7 +153,7 @@ layer at (475,73) size 130x13 scrollWidth 292
     RenderText {#text} at (0,0) size 291x13
       text run at (0,0) width 291: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
 layer at (632,73) size 130x13 scrollWidth 362
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
     RenderText {#text} at (0,0) size 361x13
       text run at (0,0) width 361: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (13,96) size 130x13 scrollX 160 scrollWidth 291
@@ -169,7 +177,7 @@ layer at (475,96) size 130x13 scrollX 160 scrollWidth 291
     RenderText {#text} at (-160,0) size 292x13
       text run at (-160,0) width 291: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
 layer at (632,96) size 130x13 scrollX 230 scrollWidth 361
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
     RenderText {#text} at (-230,0) size 362x13
       text run at (-230,0) width 361 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (13,153) size 130x13 scrollWidth 291
@@ -193,7 +201,7 @@ layer at (475,153) size 130x13 scrollWidth 292
     RenderText {#text} at (0,0) size 291x13
       text run at (0,0) width 291: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
 layer at (632,153) size 130x13 scrollWidth 362
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
     RenderText {#text} at (0,0) size 361x13
       text run at (0,0) width 361: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (13,176) size 130x13 scrollX 160 scrollWidth 291
@@ -217,7 +225,7 @@ layer at (475,176) size 130x13 scrollX 160 scrollWidth 291
     RenderText {#text} at (-160,0) size 292x13
       text run at (-160,0) width 291: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
 layer at (632,176) size 130x13 scrollX 230 scrollWidth 361
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
     RenderText {#text} at (-230,0) size 362x13
       text run at (-230,0) width 361 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (259,233) size 130x13 scrollWidth 291
index dc5b67675eb657a91f5763c9314455f6c17929d7..f0086bd8f3444534abf9c2ba6a4bfa4025d72fd2 100644 (file)
@@ -43,9 +43,13 @@ layer at (0,0) size 800x600
           text run at (316,3) width 13: "b "
           text run at (328,3) width 8: "a"
         RenderTextControl {INPUT} at (3,26) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 131x13
+            RenderBlock {DIV} at (0,0) size 131x13
         RenderText {#text} at (141,26) size 65x18
           text run at (141,26) width 65: "password "
         RenderTextControl {INPUT} at (207,26) size 138x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 131x13
+            RenderBlock {DIV} at (0,0) size 131x13
         RenderText {#text} at (346,26) size 9x18
           text run at (346,26) width 9: "b"
       RenderBlock {DIV} at (10,374) size 450x21 [border: (1px solid #FF0000)]
@@ -75,10 +79,10 @@ layer at (199,330) size 130x13
     RenderText {#text} at (0,0) size 18x13
       text run at (0,0) width 18: "foo"
 layer at (24,353) size 130x13
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
     RenderText {#text} at (0,0) size 20x13
       text run at (0,0) width 20: "\x{2022}\x{2022}\x{2022}"
 layer at (229,353) size 130x13
-  RenderBlock {DIV} at (3,3) size 131x13 [color=#545454]
+  RenderBlock {DIV} at (0,0) size 131x13 [color=#545454]
     RenderText {#text} at (0,0) size 20x13
       text run at (0,0) width 20: "\x{2022}\x{2022}\x{2022}"
index 5ddb96ccfa66270984402a1fe3144b5f8e96f676..6e5923b7eeab8f1f9fa6ad74bbb5ef362eecc96e 100644 (file)
@@ -83,6 +83,8 @@ layer at (0,0) size 800x600
         RenderText {#text} at (0,214) size 65x18
           text run at (0,214) width 65: "password "
         RenderTextControl {INPUT} at (66,214) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 131x13
+            RenderBlock {DIV} at (0,0) size 131x13
         RenderText {#text} at (204,214) size 5x18
           text run at (204,214) width 5: " "
         RenderBR {BR} at (208,228) size 1x0
@@ -101,6 +103,6 @@ layer at (41,54) size 130x13
 layer at (63,220) size 130x13
   RenderBlock {DIV} at (3,3) size 131x13
 layer at (77,243) size 130x13
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
 layer at (66,266) size 130x13
   RenderBlock {DIV} at (0,0) size 131x13
index f11c5896eb8952e09b30ad3057b49ca467602749..082e18eba54cc03fdd15e0a10491d0201ae44bf0 100644 (file)
@@ -46,6 +46,8 @@ layer at (0,0) size 800x600
                   text run at (1,1) width 248: "password with value property changed"
               RenderTableCell {TD} at (396,27) size 228x25 [r=1 c=1 rs=1 cs=1]
                 RenderTextControl {INPUT} at (3,3) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+                  RenderFlexibleBox {DIV} at (3,3) size 131x13
+                    RenderBlock {DIV} at (0,0) size 131x13
               RenderTableCell {TD} at (626,29) size 63x20 [r=1 c=2 rs=1 cs=1]
                 RenderText {#text} at (1,1) size 30x18
                   text run at (1,1) width 30: "after"
@@ -205,7 +207,7 @@ layer at (410,134) size 130x13
     RenderText {#text} at (0,0) size 34x13
       text run at (0,0) width 34: "before"
 layer at (410,161) size 130x13
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
     RenderText {#text} at (0,0) size 40x13
       text run at (0,0) width 40: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
 layer at (410,302) size 130x13
index a61d6c04bb6cb165ac84d3088e626df25a9fe1c7..1f926c74a3458fd6ce9a9cedbbe73827a6039b64 100644 (file)
@@ -17,6 +17,8 @@ layer at (0,0) size 800x600
       RenderText {#text} at (305,20) size 5x18
         text run at (305,20) width 5: " "
       RenderTextControl {INPUT} at (311,20) size 138x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+        RenderFlexibleBox {DIV} at (3,3) size 131x13
+          RenderBlock {DIV} at (0,0) size 131x13
       RenderText {#text} at (450,20) size 5x18
         text run at (450,20) width 5: " "
       RenderTextControl {INPUT} at (456,20) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
@@ -44,7 +46,7 @@ layer at (323,31) size 130x13
     RenderText {#text} at (0,0) size 52x13
       text run at (0,0) width 52: "password"
 layer at (323,31) size 130x13
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
 layer at (467,31) size 130x13
   RenderBlock {DIV} at (3,3) size 131x13 [color=#640000]
     RenderText {#text} at (0,0) size 69x13
index f472e82c5a149e30f0b3d6a418dfccdfdd21f5ce..c7e964dd32ba5904bfd54121863895d37bb05af2 100644 (file)
@@ -5,6 +5,8 @@ layer at (0,0) size 800x39
     RenderBody {BODY} at (8,8) size 784x23
       RenderBlock {FORM} at (0,0) size 784x23
         RenderTextControl {INPUT} at (2,2) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderFlexibleBox {DIV} at (3,3) size 131x13
+            RenderBlock {DIV} at (0,0) size 131x13
         RenderText {#text} at (140,2) size 5x18
           text run at (140,2) width 5: " "
         RenderButton {INPUT} at (146,3) size 54x18 [bgcolor=#C0C0C0]
@@ -13,7 +15,7 @@ layer at (0,0) size 800x39
               text run at (0,0) width 38: "Submit"
         RenderText {#text} at (0,0) size 0x0
 layer at (13,13) size 130x13
-  RenderBlock {DIV} at (3,3) size 131x13
+  RenderBlock {DIV} at (0,0) size 131x13
 layer at (10,29) size 220x100
   RenderBlock (positioned) zI: 2147483647 {DIV} at (10,29) size 220x100
 layer at (10,29) size 220x16 scrollHeight 25
@@ -34,4 +36,4 @@ layer at (10,41) size 220x84
           text run at (0,32) width 112: "current password."
 layer at (42,29) size 18x18 backgroundClip at (10,29) size 220x16 clip at (10,29) size 220x16 outlineClip at (10,29) size 220x16
   RenderBlock (relative positioned) zI: 2147483645 {DIV} at (0,0) size 18x18 [bgcolor=#F8ECEC] [border: (2px solid #440000) none (2px solid #440000)]
-caret: position 0 of child 0 {DIV} of {#document-fragment} of child 1 {INPUT} of child 0 {FORM} of body
+caret: position 0 of child 0 {DIV} of child 0 {DIV} of child 0 {DIV} of {#document-fragment} of child 1 {INPUT} of child 0 {FORM} of body
index fe352d7783f9d12fdaf5701f5eac7200bfff17d3..c95f3b6ce026e4f6cb4b59d5c5133b5287308135 100644 (file)
@@ -1,3 +1,87 @@
+2015-02-21  Sam Weinig  <sam@webkit.org>
+
+        Convert the caps lock indicator to be implemented using the shadow DOM
+        https://bugs.webkit.org/show_bug.cgi?id=141868
+
+        Reviewed by Dan Bernstein.
+
+        - Re-adds 'caps-lock-indicator' as a valid -webkit-appearance value. It was removed
+          in r74099 to work around a site bug, that should not be a problem anymore.
+        - Converts the caps lock indicator to be implemented as part of the shadow DOM rather
+          than a paint time effect. This gives the proper overflow behavior (it now clips) and
+          behaves correctly in RTL.
+
+        * css/CSSParser.cpp:
+        (WebCore::isValidKeywordPropertyAndValue):
+        Make 'caps-lock-indicator' a valid -webkit-appearance value.
+
+        * css/CSSValueKeywords.in:
+        Remove comment that indicated that caps-lock-indicator was not a valid
+        -webkit-appearance value.
+
+        * css/html.css:
+        (input::-webkit-caps-lock-indicator):
+        Add new default style for the new -webkit-caps-lock-indicator pseudo-element. The
+        trick employed here is to use a content: image to both implement the painting of
+        the caps lock indicator, and to get the sizing right (shrink-to-fit, height: 100%).
+
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::capsLockIndicatorElement):
+        (WebCore::HTMLInputElement::capsLockStateMayHaveChanged):
+        * html/HTMLInputElement.h:
+        * html/InputType.cpp:
+        (WebCore::InputType::capsLockStateMayHaveChanged):
+        * html/InputType.h:
+        (WebCore::InputType::capsLockIndicatorElement):
+        Pipe notification of changes in the caps locks state to the <input> element
+        rather than the RenderTextControlSingleLine. Also add an accessor for the caps
+        lock indicator element in the shadow DOM.
+
+        * html/TextFieldInputType.cpp:
+        (WebCore::TextFieldInputType::forwardEvent):
+        (WebCore::TextFieldInputType::shouldHaveCapsLockIndicator):
+        (WebCore::TextFieldInputType::createShadowSubtree):
+        (WebCore::TextFieldInputType::capsLockIndicatorElement):
+        (WebCore::TextFieldInputType::destroyShadowSubtree):
+        (WebCore::TextFieldInputType::shouldDrawCapsLockIndicator):
+        (WebCore::TextFieldInputType::capsLockStateMayHaveChanged):
+        * html/TextFieldInputType.h:
+        Add a new element to the text field shadow DOM to act as the caps lock indicator.
+        Give it a pseudo-element ID of -webkit-caps-lock-indicator so it can be referenced
+        from CSS. The element is always in the DOM for a password field. It toggles between
+        display: none and display: block depending on the state of the caps lock key.
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::capsLockStateMayHaveChanged):
+        Pipe notification of changes in the caps locks state to the <input> element
+        rather than the RenderTextControlSingleLine.
+
+        * rendering/RenderTextControlSingleLine.cpp:
+        (WebCore::RenderTextControlSingleLine::RenderTextControlSingleLine):
+        (WebCore::RenderTextControlSingleLine::paint): Deleted.
+        (WebCore::RenderTextControlSingleLine::capsLockStateMayHaveChanged): Deleted.
+        * rendering/RenderTextControlSingleLine.h:
+        Remove logic for drawing the caps lock indicator.
+
+        * rendering/RenderTheme.cpp:
+        (WebCore::RenderTheme::adjustStyle):
+        (WebCore::RenderTheme::paint):
+        (WebCore::RenderTheme::paintMeter):
+        (WebCore::RenderTheme::adjustCapsLockIndicatorStyle):
+        (WebCore::RenderTheme::paintCapsLockIndicator):
+        (WebCore::RenderTheme::shouldHaveCapsLockIndicator):
+        * rendering/RenderTheme.h:
+        (WebCore::RenderTheme::paintCapsLockIndicator): Deleted.
+        * rendering/RenderThemeIOS.h:
+        * rendering/RenderThemeIOS.mm:
+        (WebCore::RenderThemeIOS::shouldHaveCapsLockIndicator):
+        * rendering/RenderThemeMac.h:
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::shouldHaveCapsLockIndicator):
+        (WebCore::RenderThemeMac::paintCapsLockIndicator): Deleted.
+        Now that the caps lock indicator is implemented like other aspects of form controls,
+        the theme code can be converted to be similar as well.
+
 2015-02-21  David Kilzer  <ddkilzer@apple.com>
 
         [iOS] Fix build failure after including CoreMediaSoftLink.h in WebVideoFullscreenInterfaceAVKit.mm
index 9aa6619ba96b564ab83b3af487f25da20e57a022..3f9887026c3454c1363bb6e6df2238abc31d81b0 100644 (file)
@@ -807,7 +807,7 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int
             return true;
         break;
     case CSSPropertyWebkitAppearance:
-        if ((valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone)
+        if ((valueID >= CSSValueCheckbox && valueID <= CSSValueCapsLockIndicator) || valueID == CSSValueNone)
             return true;
         break;
     case CSSPropertyWebkitBackfaceVisibility:
index 4709aa8ce97edf87afb06b49dd4c76acca44a8d8..22bd1dd863b279799c9edc15339c2e808fbac0cd 100644 (file)
@@ -745,7 +745,6 @@ rating-level-indicator
 image-controls-button
 #endif
 textarea
-// An appearance value that should not be accepted by the parser:
 caps-lock-indicator
 
 //
index 638c6e09cc2473fae1b195308eb47233cd624ccc..5fbfee02fdbf4f701a1f2ca00c1f009ee408a02e 100644 (file)
@@ -544,6 +544,14 @@ input::-webkit-inner-spin-button {
     -webkit-user-select: none;
 }
 
+input::-webkit-caps-lock-indicator {
+    -webkit-appearance: caps-lock-indicator;
+    content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 17"><path fill="black" fill-opacity="0.4" d="M12.5 0.5A 4 4 0 0 1 16.5 4.5L 16.5 12.5A 4 4 0 0 1 12.5 16.5L 4.5 16.5A 4 4 0 0 1 0.5 12.5L 0.5 4.5A 4 4 0 0 1 4.5 0.5L 12.5 0.5M 8.5 2L 4 7L 6.25 7L 6.25 10.25L 10.75 10.25L 10.75 7L 13 7L 8.5 2M 10.75 12L 6.25 12L 6.25 14.25L 10.75 14.25L 10.75 12"/></svg>');
+    height: 100%;
+    -webkit-flex: none;
+    -webkit-user-select: none;
+}
+
 keygen, select {
     border-radius: 5px;
 }
index c378f4a8c01883aadf4b2caf3338ca097807477b..0ddabf9ce3e3e141025860965d3a438d63478a19 100644 (file)
@@ -199,6 +199,11 @@ HTMLElement* HTMLInputElement::innerSpinButtonElement() const
     return m_inputType->innerSpinButtonElement();
 }
 
+HTMLElement* HTMLInputElement::capsLockIndicatorElement() const
+{
+    return m_inputType->capsLockIndicatorElement();
+}
+
 HTMLElement* HTMLInputElement::resultsButtonElement() const
 {
     return m_inputType->resultsButtonElement();
@@ -1901,4 +1906,9 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
 }
 #endif
 
+void HTMLInputElement::capsLockStateMayHaveChanged()
+{
+    m_inputType->capsLockStateMayHaveChanged();
+}
+
 } // namespace
index b6a255122aa28a94354f59877d653ec8c686508b..0a38ea4063f571fdabd25c74d702b2df3047f7fc 100644 (file)
@@ -147,6 +147,7 @@ public:
     virtual TextControlInnerTextElement* innerTextElement() const override final;
     HTMLElement* innerBlockElement() const;
     HTMLElement* innerSpinButtonElement() const;
+    HTMLElement* capsLockIndicatorElement() const;
     HTMLElement* resultsButtonElement() const;
     HTMLElement* cancelButtonElement() const;
     HTMLElement* sliderThumbElement() const;
@@ -317,6 +318,8 @@ public:
     bool setupDateTimeChooserParameters(DateTimeChooserParameters&);
 #endif
 
+    void capsLockStateMayHaveChanged();
+
 protected:
     HTMLInputElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
 
index c089d75aa76ff4eb242ccf40029d30870a939183..15c70f19ac5159bd81cc7a9572b0bc59cce7ed8d 100644 (file)
@@ -489,6 +489,10 @@ void InputType::blur()
     element().defaultBlur();
 }
 
+void InputType::capsLockStateMayHaveChanged()
+{
+}
+
 void InputType::createShadowSubtree()
 {
 }
index 86ac8a9f8283e3c2f3977a56423fa32a5f631da7..3028bfe339fc6444ebc825500e61a71ecb03f625 100644 (file)
@@ -215,6 +215,8 @@ public:
 
     virtual void blur();
 
+    virtual void capsLockStateMayHaveChanged();
+
     // Shadow tree handling
 
     virtual void createShadowSubtree();
@@ -224,6 +226,7 @@ public:
     virtual HTMLElement* innerBlockElement() const { return nullptr; }
     virtual TextControlInnerTextElement* innerTextElement() const { return nullptr; }
     virtual HTMLElement* innerSpinButtonElement() const { return nullptr; }
+    virtual HTMLElement* capsLockIndicatorElement() const { return nullptr; }
     virtual HTMLElement* resultsButtonElement() const { return nullptr; }
     virtual HTMLElement* cancelButtonElement() const { return nullptr; }
     virtual HTMLElement* sliderThumbElement() const { return nullptr; }
index dffe4b2c1cdaf8032cbaff45a43735fb55522a36..bda36d2efb2634c5c8f7312b5e0b208e0544670c 100644 (file)
@@ -43,6 +43,7 @@
 #include "KeyboardEvent.h"
 #include "NodeRenderStyle.h"
 #include "Page.h"
+#include "PlatformKeyboardEvent.h"
 #include "RenderLayer.h"
 #include "RenderTextControlSingleLine.h"
 #include "RenderTheme.h"
@@ -202,9 +203,9 @@ void TextFieldInputType::forwardEvent(Event* event)
                     }
                 }
 
-                renderTextControl.capsLockStateMayHaveChanged();
+                capsLockStateMayHaveChanged();
             } else if (event->type() == eventNames().focusEvent)
-                renderTextControl.capsLockStateMayHaveChanged();
+                capsLockStateMayHaveChanged();
 
             element().forwardEvent(event);
         }
@@ -240,6 +241,13 @@ bool TextFieldInputType::shouldHaveSpinButton() const
     return theme->shouldHaveSpinButton(element());
 }
 
+bool TextFieldInputType::shouldHaveCapsLockIndicator() const
+{
+    Document& document = element().document();
+    RefPtr<RenderTheme> theme = document.page() ? &document.page()->theme() : RenderTheme::defaultTheme();
+    return theme->shouldHaveCapsLockIndicator(element());
+}
+
 void TextFieldInputType::createShadowSubtree()
 {
     ASSERT(element().shadowRoot());
@@ -250,7 +258,8 @@ void TextFieldInputType::createShadowSubtree()
 
     Document& document = element().document();
     bool shouldHaveSpinButton = this->shouldHaveSpinButton();
-    bool createsContainer = shouldHaveSpinButton || needsContainer();
+    bool shouldHaveCapsLockIndicator = this->shouldHaveCapsLockIndicator();
+    bool createsContainer = shouldHaveSpinButton || shouldHaveCapsLockIndicator || needsContainer();
 
     m_innerText = TextControlInnerTextElement::create(document);
     if (!createsContainer) {
@@ -274,6 +283,16 @@ void TextFieldInputType::createShadowSubtree()
         m_innerSpinButton = SpinButtonElement::create(document, *this);
         m_container->appendChild(m_innerSpinButton, IGNORE_EXCEPTION);
     }
+
+    if (shouldHaveCapsLockIndicator) {
+        m_capsLockIndicator = HTMLDivElement::create(document);
+        m_capsLockIndicator->setPseudo(AtomicString("-webkit-caps-lock-indicator", AtomicString::ConstructFromLiteral));
+
+        bool shouldDrawCapsLockIndicator = this->shouldDrawCapsLockIndicator();
+        m_capsLockIndicator->setInlineStyleProperty(CSSPropertyDisplay, shouldDrawCapsLockIndicator ? CSSValueBlock : CSSValueNone, true);
+
+        m_container->appendChild(m_capsLockIndicator, IGNORE_EXCEPTION);
+    }
 }
 
 HTMLElement* TextFieldInputType::containerElement() const
@@ -297,6 +316,11 @@ HTMLElement* TextFieldInputType::innerSpinButtonElement() const
     return m_innerSpinButton.get();
 }
 
+HTMLElement* TextFieldInputType::capsLockIndicatorElement() const
+{
+    return m_capsLockIndicator.get();
+}
+
 HTMLElement* TextFieldInputType::placeholderElement() const
 {
     return m_placeholder.get();
@@ -305,13 +329,14 @@ HTMLElement* TextFieldInputType::placeholderElement() const
 void TextFieldInputType::destroyShadowSubtree()
 {
     InputType::destroyShadowSubtree();
-    m_innerText.clear();
-    m_placeholder.clear();
-    m_innerBlock.clear();
+    m_innerText = nullptr;
+    m_placeholder = nullptr;
+    m_innerBlock = nullptr;
     if (m_innerSpinButton)
         m_innerSpinButton->removeSpinButtonOwner();
-    m_innerSpinButton.clear();
-    m_container.clear();
+    m_innerSpinButton = nullptr;
+    m_capsLockIndicator = nullptr;
+    m_container = nullptr;
 }
 
 void TextFieldInputType::attributeChanged()
@@ -514,4 +539,28 @@ bool TextFieldInputType::shouldSpinButtonRespondToWheelEvents()
     return shouldSpinButtonRespondToMouseEvents() && element().focused();
 }
 
+bool TextFieldInputType::shouldDrawCapsLockIndicator() const
+{
+    if (element().document().focusedElement() != &element())
+        return false;
+
+    Frame* frame = element().document().frame();
+    if (!frame)
+        return false;
+
+    if (!frame->selection().isFocusedAndActive())
+        return false;
+
+    return PlatformKeyboardEvent::currentCapsLockState();
+}
+
+void TextFieldInputType::capsLockStateMayHaveChanged()
+{
+    if (!m_capsLockIndicator)
+        return;
+
+    bool shouldDrawCapsLockIndicator = this->shouldDrawCapsLockIndicator();
+    m_capsLockIndicator->setInlineStyleProperty(CSSPropertyDisplay, shouldDrawCapsLockIndicator ? CSSValueBlock : CSSValueNone, true);
+}
+
 } // namespace WebCore
index 37cd3d3fc40fab5e3945501556ec84f23525a2a5..b4a5ecb5e0698c4ee6fe37e7ad99aa2a59d35b17 100644 (file)
@@ -52,10 +52,10 @@ protected:
     virtual HTMLElement* innerBlockElement() const override final;
     virtual TextControlInnerTextElement* innerTextElement() const override final;
     virtual HTMLElement* innerSpinButtonElement() const override final;
+    virtual HTMLElement* capsLockIndicatorElement() const override final;
 
 protected:
     virtual bool needsContainer() const;
-    virtual bool shouldHaveSpinButton() const final;
     virtual void createShadowSubtree() override;
     virtual void destroyShadowSubtree() override;
     virtual void attributeChanged() override final;
@@ -95,6 +95,7 @@ private:
     virtual void updatePlaceholderText() override final;
     virtual bool appendFormData(FormDataList&, bool multipart) const override final;
     virtual void subtreeHasChanged() override final;
+    virtual void capsLockStateMayHaveChanged() override final;
 
     // SpinButtonElement::SpinButtonOwner functions.
     virtual void focusAndSelectSpinButtonOwner() override final;
@@ -103,11 +104,16 @@ private:
     virtual void spinButtonStepDown() override final;
     virtual void spinButtonStepUp() override final;
 
+    bool shouldHaveSpinButton() const;
+    bool shouldHaveCapsLockIndicator() const;
+    bool shouldDrawCapsLockIndicator() const;
+
     RefPtr<HTMLElement> m_container;
     RefPtr<HTMLElement> m_innerBlock;
     RefPtr<TextControlInnerTextElement> m_innerText;
     RefPtr<HTMLElement> m_placeholder;
     RefPtr<SpinButtonElement> m_innerSpinButton;
+    RefPtr<HTMLElement> m_capsLockIndicator;
 };
 
 } // namespace WebCore
index d410abb473f5756302b526a34c028aa46d1ee568..efca61a3fca7ae10fe46d604a846a5c4fa304288 100644 (file)
@@ -3645,10 +3645,8 @@ void EventHandler::capsLockStateMayHaveChanged()
 {
     Document* document = m_frame.document();
     if (auto* element = document->focusedElement()) {
-        if (auto* renderer = element->renderer()) {
-            if (is<RenderTextControlSingleLine>(*renderer))
-                downcast<RenderTextControlSingleLine>(*renderer).capsLockStateMayHaveChanged();
-        }
+        if (is<HTMLInputElement>(*element))
+            downcast<HTMLInputElement>(*element).capsLockStateMayHaveChanged();
     }
 }
 
index 802f571e9a9a7eb310d8f9d78602a6e73e7cacaf..f4e3d2fa0be8177da9fc008a8313eb31de2bdfe4 100644 (file)
@@ -55,7 +55,6 @@ using namespace HTMLNames;
 
 RenderTextControlSingleLine::RenderTextControlSingleLine(HTMLInputElement& element, Ref<RenderStyle>&& style)
     : RenderTextControl(element, WTF::move(style))
-    , m_shouldDrawCapsLockIndicator(false)
     , m_desiredInnerTextLogicalHeight(-1)
 {
 }
@@ -69,25 +68,6 @@ inline HTMLElement* RenderTextControlSingleLine::innerSpinButtonElement() const
     return inputElement().innerSpinButtonElement();
 }
 
-void RenderTextControlSingleLine::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
-{
-    RenderTextControl::paint(paintInfo, paintOffset);
-
-    if (paintInfo.phase == PaintPhaseBlockBackground && m_shouldDrawCapsLockIndicator) {
-        LayoutRect contentsRect = contentBoxRect();
-
-        // Center in the block progression direction.
-        if (isHorizontalWritingMode())
-            contentsRect.setY((height() - contentsRect.height()) / 2);
-        else
-            contentsRect.setX((width() - contentsRect.width()) / 2);
-
-        // Convert the rect into the coords used for painting the content
-        contentsRect.moveBy(paintOffset + location());
-        theme().paintCapsLockIndicator(*this, paintInfo, snappedIntRect(contentsRect));
-    }
-}
-
 LayoutUnit RenderTextControlSingleLine::computeLogicalHeightLimit() const
 {
     return containerElement() ? contentLogicalHeight() : logicalHeight();
@@ -277,25 +257,6 @@ void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const Ren
     setHasOverflowClip(false);
 }
 
-void RenderTextControlSingleLine::capsLockStateMayHaveChanged()
-{
-    // Only draw the caps lock indicator if these things are true:
-    // 1) The field is a password field
-    // 2) The frame is active
-    // 3) The element is focused
-    // 4) The caps lock is on
-    bool shouldDrawCapsLockIndicator =
-        inputElement().isPasswordField()
-        && frame().selection().isFocusedAndActive()
-        && document().focusedElement() == &inputElement()
-        && PlatformKeyboardEvent::currentCapsLockState();
-
-    if (shouldDrawCapsLockIndicator != m_shouldDrawCapsLockIndicator) {
-        m_shouldDrawCapsLockIndicator = shouldDrawCapsLockIndicator;
-        repaint();
-    }
-}
-
 bool RenderTextControlSingleLine::hasControlClip() const
 {
     // Apply control clip for text fields with decorations.
index b333b78bacc1124d6f32c19db9253f13732392ae..9b162fe2d54a3c1b8423f3f52c2218b011be057f 100644 (file)
@@ -38,8 +38,6 @@ public:
     virtual Ref<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const override;
     Ref<RenderStyle> createInnerBlockStyle(const RenderStyle* startStyle) const;
 
-    void capsLockStateMayHaveChanged();
-
 protected:
     virtual void centerContainerIfNeeded(RenderBox*) const { }
     virtual LayoutUnit computeLogicalHeightLimit() const;
@@ -55,7 +53,6 @@ private:
     virtual LayoutRect controlClipRect(const LayoutPoint&) const override;
     virtual bool isTextField() const override final { return true; }
 
-    virtual void paint(PaintInfo&, const LayoutPoint&) override;
     virtual void layout() override;
 
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
@@ -83,7 +80,6 @@ private:
 
     HTMLElement* innerSpinButtonElement() const;
 
-    bool m_shouldDrawCapsLockIndicator;
     LayoutUnit m_desiredInnerTextLogicalHeight;
 };
 
index e8f6f53ec2b316ec0b90e0707ab429de0fdc0987..d4ed72ba47327e2a40bcaba5cc0ad00e9a2e2bb3 100644 (file)
@@ -250,6 +250,8 @@ void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style,
     case ImageControlsButtonPart:
         break;
 #endif
+    case CapsLockIndicatorPart:
+        return adjustCapsLockIndicatorStyle(styleResolver, style, e);
     default:
         break;
     }
@@ -386,6 +388,8 @@ bool RenderTheme::paint(const RenderObject& o, ControlStates* controlStates, con
     case ImageControlsButtonPart:
         return paintImageControlsButton(o, paintInfo, integralSnappedRect);
 #endif
+    case CapsLockIndicatorPart:
+        return paintCapsLockIndicator(o, paintInfo, integralSnappedRect);
     default:
         break;
     }
@@ -960,9 +964,17 @@ bool RenderTheme::paintMeter(const RenderObject&, const PaintInfo&, const IntRec
 {
     return true;
 }
-
 #endif
 
+void RenderTheme::adjustCapsLockIndicatorStyle(StyleResolver&, RenderStyle&, Element*) const
+{
+}
+
+bool RenderTheme::paintCapsLockIndicator(const RenderObject&, const PaintInfo&, const IntRect&)
+{
+    return false;
+}
+
 #if ENABLE(DATALIST_ELEMENT)
 LayoutUnit RenderTheme::sliderTickSnappingThreshold() const
 {
@@ -1076,6 +1088,11 @@ bool RenderTheme::shouldHaveSpinButton(HTMLInputElement& inputElement) const
     return inputElement.isSteppable() && !inputElement.isRangeControl();
 }
 
+bool RenderTheme::shouldHaveCapsLockIndicator(HTMLInputElement&) const
+{
+    return false;
+}
+
 void RenderTheme::adjustMenuListButtonStyle(StyleResolver&, RenderStyle&, Element*) const
 {
 }
index fd490fb6735d2482d9b4f9a94b2bee440226c555..cda2c6daa995216f553f15c9d6611f1152c8e9fa 100644 (file)
@@ -188,9 +188,6 @@ public:
 
     virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return RegularScrollbar; }
 
-    // Method for painting the caps lock indicator
-    virtual bool paintCapsLockIndicator(const RenderObject&, const PaintInfo&, const IntRect&) { return 0; };
-
     // Returns the repeat interval of the animation for the progress bar.
     virtual double animationRepeatIntervalForProgressBar(RenderProgress&) const;
     // Returns the duration of the animation for the progress bar.
@@ -232,6 +229,7 @@ public:
 
     virtual bool shouldShowPlaceholderWhenFocused() const { return false; }
     virtual bool shouldHaveSpinButton(HTMLInputElement&) const;
+    virtual bool shouldHaveCapsLockIndicator(HTMLInputElement&) const;
 
     // Functions for <select> elements.
     virtual bool delegatesMenuListRendering() const { return false; }
@@ -314,6 +312,9 @@ protected:
     virtual bool paintMeter(const RenderObject&, const PaintInfo&, const IntRect&);
 #endif
 
+    virtual void adjustCapsLockIndicatorStyle(StyleResolver&, RenderStyle&, Element*) const;
+    virtual bool paintCapsLockIndicator(const RenderObject&, const PaintInfo&, const IntRect&);
+
     virtual void adjustProgressBarStyle(StyleResolver&, RenderStyle&, Element*) const;
     virtual bool paintProgressBar(const RenderObject&, const PaintInfo&, const IntRect&) { return true; }
 
index b86310378c4513b82fae72fb6760cc38517cb5ae..ea3e5a4a435c46b28ffbb863ae14113efe134b6c 100644 (file)
@@ -104,6 +104,7 @@ protected:
 
     virtual bool shouldShowPlaceholderWhenFocused() const override;
     virtual bool shouldHaveSpinButton(HTMLInputElement&) const override;
+    virtual bool shouldHaveCapsLockIndicator(HTMLInputElement&) const override;
 
 #if ENABLE(VIDEO)
     virtual String mediaControlsStyleSheet() override;
index 3097c8c3fafac9ec37ca349fa55adcd0dbbc3d49..8bf888d42006615e2833ffcee9a98f3aa31b2334 100644 (file)
@@ -1079,6 +1079,11 @@ bool RenderThemeIOS::shouldHaveSpinButton(HTMLInputElement&) const
     return false;
 }
 
+bool RenderThemeIOS::shouldHaveCapsLockIndicator(HTMLInputElement&) const
+{
+    return false;
+}
+
 static FontWeight fromCTFontWeight(float fontWeight)
 {
     if (fontWeight <= -0.8)
index 5f54eb5b4b0823142b392b207c2966a9bcea6987..cbe2b03f9432a51a68105c74a6a19567f240e5ce 100644 (file)
@@ -81,8 +81,6 @@ public:
     virtual int popupInternalPaddingBottom(RenderStyle&) const override;
     virtual PopupMenuStyle::PopupMenuSize popupMenuSize(const RenderStyle&, IntRect&) const override;
 
-    virtual bool paintCapsLockIndicator(const RenderObject&, const PaintInfo&, const IntRect&) override;
-
     virtual bool popsMenuByArrowKeys() const override { return true; }
 
 #if ENABLE(METER_ELEMENT)
@@ -165,6 +163,7 @@ protected:
 #endif
 
     virtual bool shouldShowPlaceholderWhenFocused() const override;
+    virtual bool shouldHaveCapsLockIndicator(HTMLInputElement&) const override;
 
     virtual bool paintSnapshottedPluginOverlay(const RenderObject&, const PaintInfo&, const IntRect&) override;
 
index d499114da781e36c196e2987ca2c3459473ac7ec..1acd423f536722c8053125bd2cef42d00dd4e1ca 100644 (file)
@@ -827,17 +827,6 @@ void RenderThemeMac::adjustTextFieldStyle(StyleResolver&, RenderStyle&, Element*
 {
 }
 
-bool RenderThemeMac::paintCapsLockIndicator(const RenderObject&, const PaintInfo& paintInfo, const IntRect& r)
-{
-    if (paintInfo.context->paintingDisabled())
-        return true;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawCapsLockIndicator(localContext.cgContext(), r);
-
-    return false;
-}
-
 bool RenderThemeMac::paintTextArea(const RenderObject& o, const PaintInfo& paintInfo, const FloatRect& r)
 {
     LocalCurrentGraphicsContext localContext(paintInfo.context);
@@ -1900,6 +1889,11 @@ bool RenderThemeMac::shouldShowPlaceholderWhenFocused() const
     return true;
 }
 
+bool RenderThemeMac::shouldHaveCapsLockIndicator(HTMLInputElement& element) const
+{
+    return element.isPasswordField();
+}
+
 NSPopUpButtonCell* RenderThemeMac::popupButton() const
 {
     if (!m_popupButton) {