Implement painting slider tick marks
authorkeishi@webkit.org <keishi@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jul 2012 05:30:14 +0000 (05:30 +0000)
committerkeishi@webkit.org <keishi@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jul 2012 05:30:14 +0000 (05:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=87844

Reviewed by Kent Tamura.

Source/WebCore:

This implements painting slider tick marks for <datalist> support for input type=range.
This does not support automatic update when list target changes, and it will be fixed
in a follow up patch (Bug 89544).

Tests: fast/forms/datalist/input-appearance-range-with-datalist-rtl.html
       fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html
       fast/forms/datalist/input-appearance-range-with-datalist.html

* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::sliderThumbElement):
(WebCore):
* html/HTMLInputElement.h:
(HTMLInputElement):
* html/InputType.h:
(WebCore::InputType::sliderThumbElement):
* html/RangeInputType.cpp:
(WebCore::RangeInputType::typeMismatchFor): We need HTMLInputElement::isValidValue("foo") to return false.
(WebCore):
(WebCore::RangeInputType::sliderThumbElement):
* html/RangeInputType.h:
(RangeInputType):
* html/shadow/SliderThumbElement.cpp:
(WebCore::RenderSliderContainer::layout): Slider height needs to be increased for the tick marks.
* platform/efl/RenderThemeEfl.cpp:
(WebCore):
(WebCore::RenderThemeEfl::sliderTickSize):
(WebCore::RenderThemeEfl::sliderTickOffsetFromTrackCenter):
* platform/efl/RenderThemeEfl.h:
(RenderThemeEfl):
* platform/qt/RenderThemeQt.cpp:
(WebCore::RenderThemeQt::sliderTickSize):
(WebCore):
(WebCore::RenderThemeQt::sliderTickOffsetFromTrackCenter):
* platform/qt/RenderThemeQt.h:
(RenderThemeQt):
* rendering/RenderTheme.cpp:
(WebCore):
(WebCore::RenderTheme::paintSliderTicks):
* rendering/RenderTheme.h:
(RenderTheme):
* rendering/RenderThemeChromiumCommon.cpp:
(WebCore::RenderThemeChromiumCommon::supportsDataListUI):
* rendering/RenderThemeChromiumLinux.cpp:
(WebCore):
(WebCore::RenderThemeChromiumLinux::sliderTickSize): Tick size for horizontal slider. i.e. Width is length along the track.
(WebCore::RenderThemeChromiumLinux::sliderTickOffsetFromTrackCenter): Offset from
middle of draw rect to draw the ticks. Minus value means above the track.
(WebCore::RenderThemeChromiumLinux::paintSliderTrack):
* rendering/RenderThemeChromiumLinux.h:
(RenderThemeChromiumLinux):
* rendering/RenderThemeChromiumWin.cpp:
(WebCore):
(WebCore::RenderThemeChromiumWin::sliderTickSize):
(WebCore::RenderThemeChromiumWin::sliderTickOffsetFromTrackCenter):
(WebCore::RenderThemeChromiumWin::paintSliderTrack):
(WebCore::RenderThemeChromiumWin::paintSliderThumb):
* rendering/RenderThemeChromiumWin.h:
(RenderThemeChromiumWin):
* rendering/RenderThemeMac.h:
(RenderThemeMac):
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::paintSliderTrack):
(WebCore):
(WebCore::RenderThemeMac::sliderTickSize):
(WebCore::RenderThemeMac::sliderTickOffsetFromTrackCenter):

LayoutTests:

* fast/forms/datalist/input-appearance-range-with-datalist-expected.txt: Added.
* fast/forms/datalist/input-appearance-range-with-datalist-rtl-expected.html: Added.
* fast/forms/datalist/input-appearance-range-with-datalist-rtl.html: Added. The ticks should go from right to left.
* fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.txt: Added.
* fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html: Added. The ticks should zoom properly.
* fast/forms/datalist/input-appearance-range-with-datalist.html: Added.
* platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-expected.png: Added.
* platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png: Added.
* platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png: Added.
* platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png: Added.
* platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-expected.png: Added.
* platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png: Added.
* platform/chromium/TestExpectations:
* platform/chromium/fast/forms/datalist/input-list-expected.txt:

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

35 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-rtl-expected.html [new file with mode: 0644]
LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-rtl.html [new file with mode: 0644]
LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html [new file with mode: 0644]
LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist.html [new file with mode: 0644]
LayoutTests/platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-expected.png [new file with mode: 0644]
LayoutTests/platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png [new file with mode: 0644]
LayoutTests/platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png [new file with mode: 0644]
LayoutTests/platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png [new file with mode: 0644]
LayoutTests/platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-expected.png [new file with mode: 0644]
LayoutTests/platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png [new file with mode: 0644]
LayoutTests/platform/chromium/TestExpectations
LayoutTests/platform/chromium/fast/forms/datalist/input-list-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLInputElement.h
Source/WebCore/html/InputType.h
Source/WebCore/html/RangeInputType.cpp
Source/WebCore/html/RangeInputType.h
Source/WebCore/html/shadow/SliderThumbElement.cpp
Source/WebCore/platform/efl/RenderThemeEfl.cpp
Source/WebCore/platform/efl/RenderThemeEfl.h
Source/WebCore/platform/qt/RenderThemeQt.cpp
Source/WebCore/platform/qt/RenderThemeQt.h
Source/WebCore/rendering/RenderTheme.cpp
Source/WebCore/rendering/RenderTheme.h
Source/WebCore/rendering/RenderThemeChromiumCommon.cpp
Source/WebCore/rendering/RenderThemeChromiumLinux.cpp
Source/WebCore/rendering/RenderThemeChromiumLinux.h
Source/WebCore/rendering/RenderThemeChromiumWin.cpp
Source/WebCore/rendering/RenderThemeChromiumWin.h
Source/WebCore/rendering/RenderThemeMac.h
Source/WebCore/rendering/RenderThemeMac.mm

index 66083e2..de362a2 100644 (file)
@@ -1,3 +1,25 @@
+2012-07-18  Keishi Hattori  <keishi@webkit.org>
+
+        Implement painting slider tick marks
+        https://bugs.webkit.org/show_bug.cgi?id=87844
+
+        Reviewed by Kent Tamura.
+
+        * fast/forms/datalist/input-appearance-range-with-datalist-expected.txt: Added.
+        * fast/forms/datalist/input-appearance-range-with-datalist-rtl-expected.html: Added.
+        * fast/forms/datalist/input-appearance-range-with-datalist-rtl.html: Added. The ticks should go from right to left.
+        * fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.txt: Added.
+        * fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html: Added. The ticks should zoom properly.
+        * fast/forms/datalist/input-appearance-range-with-datalist.html: Added.
+        * platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-expected.png: Added.
+        * platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png: Added.
+        * platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png: Added.
+        * platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png: Added.
+        * platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-expected.png: Added.
+        * platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png: Added.
+        * platform/chromium/TestExpectations:
+        * platform/chromium/fast/forms/datalist/input-list-expected.txt:
+
 2012-07-18  Takashi Sakamoto  <tasak@google.com>
 
         Shadow DOM drop event tests are very flaky.
diff --git a/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-expected.txt b/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-expected.txt
new file mode 100644 (file)
index 0000000..b055673
--- /dev/null
@@ -0,0 +1 @@
+     
diff --git a/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-rtl-expected.html b/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-rtl-expected.html
new file mode 100644 (file)
index 0000000..6afdbd2
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<input type=range list=foo />
+<datalist id=foo>
+    <option>90</option>
+    <option>100</option>
+</datalist>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-rtl.html b/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-rtl.html
new file mode 100644 (file)
index 0000000..65b9d58
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<input type=range list=foo dir=rtl />
+<datalist id=foo>
+    <option>0</option>
+    <option>10</option>
+</datalist>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.txt b/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.txt
new file mode 100644 (file)
index 0000000..f5d2cc7
--- /dev/null
@@ -0,0 +1,3 @@
+  
+  
+  
diff --git a/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html b/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html
new file mode 100644 (file)
index 0000000..e28429a
--- /dev/null
@@ -0,0 +1,28 @@
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText(true);
+</script>
+
+<div style="zoom: 0.7;">
+    <input type=range list=foo style="width: 100px;" />
+    <input type=range list=foo style="-webkit-appearance:slider-vertical; height: 100px; width: 30px" />
+</div>
+
+<div style="zoom: 1.5;">
+    <input type=range list=foo style="width: 100px;" />
+    <input type=range list=foo style="-webkit-appearance:slider-vertical; height: 100px; width: 30px" />
+</div>
+
+<div style="zoom: 2;">
+    <input type=range list=foo style="width: 100px;" />
+    <input type=range list=foo style="-webkit-appearance:slider-vertical; height: 100px; width: 30px" />
+</div>
+
+<datalist id=foo>
+    <option>0</option>
+    <option>10</option>
+    <option>20</option>
+    <option>40</option>
+    <option>80</option>
+    <option>100</option>
+</datalist>
diff --git a/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist.html b/LayoutTests/fast/forms/datalist/input-appearance-range-with-datalist.html
new file mode 100644 (file)
index 0000000..e2b9522
--- /dev/null
@@ -0,0 +1,26 @@
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText(true);
+</script>
+
+<input type=range list=foo />
+<input type=range list=foo style="width: 50px;" />
+<input type=range list=foo style="-webkit-appearance:slider-vertical;" />
+<input type=range list=foo style="-webkit-appearance:slider-vertical; height: 50px;" />
+<datalist id=foo>
+    <option>0</option>
+    <option>10</option>
+    <option>20</option>
+    <option>40</option>
+    <option>80</option>
+    <option>100</option>
+</datalist>
+
+<input type=range list=invalid />
+<datalist id=invalid>
+    <option>-10</option>
+    <option>120</option>
+    <option>50.1</option>
+    <option>Infinity</option>
+    <option>foo</option>
+</datalist>
diff --git a/LayoutTests/platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-expected.png b/LayoutTests/platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-expected.png
new file mode 100644 (file)
index 0000000..25b1824
Binary files /dev/null and b/LayoutTests/platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-expected.png differ
diff --git a/LayoutTests/platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png b/LayoutTests/platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png
new file mode 100644 (file)
index 0000000..b9a5eb2
Binary files /dev/null and b/LayoutTests/platform/chromium-linux/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png differ
diff --git a/LayoutTests/platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png b/LayoutTests/platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png
new file mode 100644 (file)
index 0000000..ad48c70
Binary files /dev/null and b/LayoutTests/platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png differ
diff --git a/LayoutTests/platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png b/LayoutTests/platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png
new file mode 100644 (file)
index 0000000..7a9c091
Binary files /dev/null and b/LayoutTests/platform/chromium-mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png differ
diff --git a/LayoutTests/platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-expected.png b/LayoutTests/platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-expected.png
new file mode 100644 (file)
index 0000000..74f650d
Binary files /dev/null and b/LayoutTests/platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-expected.png differ
diff --git a/LayoutTests/platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png b/LayoutTests/platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png
new file mode 100644 (file)
index 0000000..d1ce0fa
Binary files /dev/null and b/LayoutTests/platform/chromium-win/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png differ
index 8769cd4..d7ebf44 100644 (file)
@@ -3699,3 +3699,7 @@ BUGWK91544 : media/media-continues-playing-after-replace-source.html = PASS TIME
 BUGWK91472 : compositing/reflections/nested-reflection-anchor-point.html = IMAGE
 
 BUGWK91672 WIN : svg/W3C-I18N/tspan-dirRTL-ubEmbed-in-default-context.svg = PASS CRASH
+
+BUG87844 SNOWLEOPARD : fast/forms/datalist/input-appearance-range-with-datalist-rtl.html = IMAGE
+BUG87844 SNOWLEOPARD : fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html = IMAGE
+BUG87844 SNOWLEOPARD : fast/forms/datalist/input-appearance-range-with-datalist.html = IMAGE
index 4981a80..5556966 100644 (file)
@@ -19,7 +19,7 @@ PASS document.getElementById("week").list is document.getElementById("dl1")
 PASS document.getElementById("time").list is document.getElementById("dl1")
 PASS document.getElementById("datetime-local").list is document.getElementById("dl1")
 PASS document.getElementById("number").list is document.getElementById("dl1")
-FAIL document.getElementById("range").list should be [object HTMLDataListElement]. Was null.
+PASS document.getElementById("range").list is document.getElementById("dl1")
 FAIL document.getElementById("color").list should be [object HTMLDataListElement]. Was null.
 PASS document.getElementById("hidden").list is null
 PASS document.getElementById("password").list is null
index fc05893..486b3e9 100644 (file)
@@ -1,3 +1,76 @@
+2012-07-18  Keishi Hattori  <keishi@webkit.org>
+
+        Implement painting slider tick marks
+        https://bugs.webkit.org/show_bug.cgi?id=87844
+
+        Reviewed by Kent Tamura.
+
+        This implements painting slider tick marks for <datalist> support for input type=range.
+        This does not support automatic update when list target changes, and it will be fixed
+        in a follow up patch (Bug 89544).
+
+        Tests: fast/forms/datalist/input-appearance-range-with-datalist-rtl.html
+               fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html
+               fast/forms/datalist/input-appearance-range-with-datalist.html
+
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::sliderThumbElement):
+        (WebCore):
+        * html/HTMLInputElement.h:
+        (HTMLInputElement):
+        * html/InputType.h:
+        (WebCore::InputType::sliderThumbElement):
+        * html/RangeInputType.cpp:
+        (WebCore::RangeInputType::typeMismatchFor): We need HTMLInputElement::isValidValue("foo") to return false.
+        (WebCore):
+        (WebCore::RangeInputType::sliderThumbElement):
+        * html/RangeInputType.h:
+        (RangeInputType):
+        * html/shadow/SliderThumbElement.cpp:
+        (WebCore::RenderSliderContainer::layout): Slider height needs to be increased for the tick marks.
+        * platform/efl/RenderThemeEfl.cpp:
+        (WebCore):
+        (WebCore::RenderThemeEfl::sliderTickSize):
+        (WebCore::RenderThemeEfl::sliderTickOffsetFromTrackCenter):
+        * platform/efl/RenderThemeEfl.h:
+        (RenderThemeEfl):
+        * platform/qt/RenderThemeQt.cpp:
+        (WebCore::RenderThemeQt::sliderTickSize):
+        (WebCore):
+        (WebCore::RenderThemeQt::sliderTickOffsetFromTrackCenter):
+        * platform/qt/RenderThemeQt.h:
+        (RenderThemeQt):
+        * rendering/RenderTheme.cpp:
+        (WebCore):
+        (WebCore::RenderTheme::paintSliderTicks):
+        * rendering/RenderTheme.h:
+        (RenderTheme):
+        * rendering/RenderThemeChromiumCommon.cpp:
+        (WebCore::RenderThemeChromiumCommon::supportsDataListUI):
+        * rendering/RenderThemeChromiumLinux.cpp:
+        (WebCore):
+        (WebCore::RenderThemeChromiumLinux::sliderTickSize): Tick size for horizontal slider. i.e. Width is length along the track.
+        (WebCore::RenderThemeChromiumLinux::sliderTickOffsetFromTrackCenter): Offset from
+        middle of draw rect to draw the ticks. Minus value means above the track.
+        (WebCore::RenderThemeChromiumLinux::paintSliderTrack):
+        * rendering/RenderThemeChromiumLinux.h:
+        (RenderThemeChromiumLinux):
+        * rendering/RenderThemeChromiumWin.cpp:
+        (WebCore):
+        (WebCore::RenderThemeChromiumWin::sliderTickSize):
+        (WebCore::RenderThemeChromiumWin::sliderTickOffsetFromTrackCenter):
+        (WebCore::RenderThemeChromiumWin::paintSliderTrack):
+        (WebCore::RenderThemeChromiumWin::paintSliderThumb):
+        * rendering/RenderThemeChromiumWin.h:
+        (RenderThemeChromiumWin):
+        * rendering/RenderThemeMac.h:
+        (RenderThemeMac):
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::paintSliderTrack):
+        (WebCore):
+        (WebCore::RenderThemeMac::sliderTickSize):
+        (WebCore::RenderThemeMac::sliderTickOffsetFromTrackCenter):
+
 2012-07-18  Shinya Kawanaka  <shinyak@chromium.org>
 
         Element wants to have userAgentShadowRoot()
index 77ea425..a51bf6a 100644 (file)
@@ -183,6 +183,11 @@ HTMLElement* HTMLInputElement::speechButtonElement() const
 }
 #endif
 
+HTMLElement* HTMLInputElement::sliderThumbElement() const
+{
+    return m_inputType->sliderThumbElement();
+}
+
 HTMLElement* HTMLInputElement::placeholderElement() const
 {
     return m_inputType->placeholderElement();
index 2fd43d8..f1cb22b 100644 (file)
@@ -122,6 +122,7 @@ public:
 #if ENABLE(INPUT_SPEECH)
     HTMLElement* speechButtonElement() const;
 #endif
+    HTMLElement* sliderThumbElement() const;
     virtual HTMLElement* placeholderElement() const;
 
     bool checked() const { return m_isChecked; }
index 6c6659a..3e4ff01 100644 (file)
@@ -226,6 +226,7 @@ public:
 #if ENABLE(INPUT_SPEECH)
     virtual HTMLElement* speechButtonElement() const { return 0; }
 #endif
+    virtual HTMLElement* sliderThumbElement() const { return 0; }
     virtual HTMLElement* placeholderElement() const;
 
     // Miscellaneous functions
index 10c7576..6b1f80f 100644 (file)
@@ -96,6 +96,11 @@ void RangeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBe
     element()->setValue(serialize(newValue), eventBehavior);
 }
 
+bool RangeInputType::typeMismatchFor(const String& value) const
+{
+    return !value.isEmpty() && !isfinite(parseToDoubleForNumberType(value));
+}
+
 bool RangeInputType::supportsRequired() const
 {
     return false;
@@ -306,4 +311,9 @@ bool RangeInputType::shouldRespectListAttribute()
     return InputType::themeSupportsDataListUI(this);
 }
 
+HTMLElement* RangeInputType::sliderThumbElement() const
+{
+    return sliderThumbElementOf(element());
+}
+
 } // namespace WebCore
index 0983b3d..3c1e07b 100644 (file)
@@ -47,6 +47,7 @@ private:
     virtual const AtomicString& formControlType() const OVERRIDE;
     virtual double valueAsDouble() const OVERRIDE;
     virtual void setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionCode&) const OVERRIDE;
+    virtual bool typeMismatchFor(const String&) const OVERRIDE;
     virtual bool supportsRequired() const OVERRIDE;
     virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
     virtual bool isSteppable() const OVERRIDE;
@@ -68,6 +69,7 @@ private:
     virtual String fallbackValue() const OVERRIDE;
     virtual String sanitizeValue(const String& proposedValue) const OVERRIDE;
     virtual bool shouldRespectListAttribute() OVERRIDE;
+    virtual HTMLElement* sliderThumbElement() const OVERRIDE;
 };
 
 } // namespace WebCore
index 0186fa5..522c4a4 100644 (file)
@@ -148,19 +148,38 @@ void RenderSliderContainer::layout()
     // Sets the concrete height if the height of the <input> is not fixed or a
     // percentage value because a percentage height value of this box won't be
     // based on the <input> height in such case.
-    Length inputHeight = input->renderer()->style()->height();
-    RenderObject* trackRenderer = node()->firstChild()->renderer();
-    if (!isVertical && input->renderer()->isSlider() && !inputHeight.isFixed() && !inputHeight.isPercent()) {
-        RenderObject* thumbRenderer = input->shadow()->oldestShadowRoot()->firstChild()->firstChild()->firstChild()->renderer();
-        if (thumbRenderer) {
-            style()->setHeight(thumbRenderer->style()->height());
-            if (trackRenderer)
-                trackRenderer->style()->setHeight(thumbRenderer->style()->height());
+    if (input->renderer()->isSlider()) {
+        if (!isVertical) {
+            RenderObject* trackRenderer = node()->firstChild()->renderer();
+            Length inputHeight = input->renderer()->style()->height();
+            if (!inputHeight.isSpecified()) {
+                RenderObject* thumbRenderer = input->sliderThumbElement()->renderer();
+                if (thumbRenderer) {
+                    Length height = thumbRenderer->style()->height();
+#if ENABLE(DATALIST)
+                    if (input && input->list()) {
+                        int offsetFromCenter = theme()->sliderTickOffsetFromTrackCenter();
+                        int trackHeight = 0;
+                        if (offsetFromCenter < 0)
+                            trackHeight = -2 * offsetFromCenter;
+                        else {
+                            int tickLength = theme()->sliderTickSize().height();
+                            trackHeight = 2 * (offsetFromCenter + tickLength);
+                        }
+                        float zoomFactor = style()->effectiveZoom();
+                        if (zoomFactor != 1.0)
+                            trackHeight *= zoomFactor;
+                        height = Length(trackHeight, Fixed);
+                    }
+#endif
+                    style()->setHeight(height);
+                }
+            } else {
+                style()->setHeight(Length(100, Percent));
+                if (trackRenderer)
+                    trackRenderer->style()->setHeight(Length());
+            }
         }
-    } else {
-        style()->setHeight(Length(100, Percent));
-        if (trackRenderer)
-            trackRenderer->style()->setHeight(Length());
     }
 
     RenderDeprecatedFlexibleBox::layout();
index 902341a..1a645dc 100644 (file)
@@ -786,6 +786,20 @@ void RenderThemeEfl::adjustSliderThumbSize(RenderStyle* style, Element*) const
 #endif
 }
 
+#if ENABLE(DATALIST)
+IntSize RenderThemeEfl::sliderTickSize() const
+{
+    // FIXME: We need to set this to the size of one tick mark.
+    return IntSize(0, 0);
+}
+
+int RenderThemeEfl::sliderTickOffsetFromTrackCenter() const
+{
+    // FIXME: We need to set this to the position of the tick marks.
+    return 0;
+}
+#endif
+
 bool RenderThemeEfl::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
 {
     // We've already painted it in paintSliderTrack(), no need to do anything here.
index bbcb4e3..1080844 100644 (file)
@@ -161,6 +161,11 @@ public:
 
     virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
 
+#if ENABLE(DATALIST)
+    virtual IntSize sliderTickSize() const OVERRIDE;
+    virtual int sliderTickOffsetFromTrackCenter() const OVERRIDE;
+#endif
+
     virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
 
     virtual void adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
index 0f00ffc..b744fe0 100644 (file)
@@ -400,6 +400,20 @@ void RenderThemeQt::adjustSliderThumbStyle(StyleResolver* styleResolver, RenderS
     style->setBoxShadow(nullptr);
 }
 
+#if ENABLE(DATALIST)
+IntSize RenderThemeQt::sliderTickSize() const
+{
+    // FIXME: We need to set this to the size of one tick mark.
+    return IntSize(0, 0);
+}
+
+int RenderThemeQt::sliderTickOffsetFromTrackCenter() const
+{
+    // FIXME: We need to set this to the position of the tick marks.
+    return 0;
+}
+#endif
+
 bool RenderThemeQt::paintSearchField(RenderObject* o, const PaintInfo& pi,
                                      const IntRect& r)
 {
index 122edc7..dd48d33 100644 (file)
@@ -82,6 +82,11 @@ public:
 
     virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
 
+#if ENABLE(DATALIST)
+    virtual IntSize sliderTickSize() const OVERRIDE;
+    virtual int sliderTickOffsetFromTrackCenter() const OVERRIDE;
+#endif
+
     virtual double caretBlinkInterval() const;
 
     virtual bool isControlStyled(const RenderStyle*, const BorderData&, const FillLayer&, const Color&) const;
index e68b893..72adbe9 100644 (file)
 #include "RenderInputSpeech.h"
 #endif
 
+#if ENABLE(DATALIST)
+#include "ElementShadow.h"
+#include "HTMLCollection.h"
+#include "HTMLDataListElement.h"
+#include "HTMLOptionElement.h"
+#include "HTMLParserIdioms.h"
+#endif
+
 // The methods in this file are shared by all themes on every platform.
 
 namespace WebCore {
@@ -952,6 +960,76 @@ bool RenderTheme::paintMeter(RenderObject*, const PaintInfo&, const IntRect&)
 
 #endif
 
+#if ENABLE(DATALIST)
+void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
+{
+    HTMLInputElement* input = static_cast<HTMLInputElement*>(o->node()->shadowAncestorNode());
+    if (!input)
+        return;
+
+    HTMLDataListElement* dataList = static_cast<HTMLDataListElement*>(input->list());
+    if (!dataList)
+        return;
+
+    double min = input->minimum();
+    double max = input->maximum();
+    ControlPart part = o->style()->appearance();
+    // We don't support ticks on alternate sliders like MediaVolumeSliders.
+    if (part !=  SliderHorizontalPart && part != SliderVerticalPart)
+        return;
+    bool isHorizontal = part ==  SliderHorizontalPart;
+
+    IntSize thumbSize;
+    RenderObject* thumbRenderer = input->sliderThumbElement()->renderer();
+    if (thumbRenderer) {
+        RenderStyle* thumbStyle = thumbRenderer->style();
+        int thumbWidth = thumbStyle->width().intValue();
+        int thumbHeight = thumbStyle->height().intValue();
+        thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight);
+        thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth);
+    }
+
+    IntSize tickSize = sliderTickSize();
+    float zoomFactor = o->style()->effectiveZoom();
+    FloatRect tickRect;
+    int tickRegionMargin = (thumbSize.width() - tickSize.width()) / 2.0;
+    int tickRegionSideMargin = 0;
+    int tickRegionWidth = 0;
+    if (isHorizontal) {
+        tickRect.setWidth(floor(tickSize.width() * zoomFactor));
+        tickRect.setHeight(floor(tickSize.height() * zoomFactor));
+        tickRect.setY(floor(rect.y() + rect.height() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor));
+        tickRegionSideMargin = rect.x() + tickRegionMargin;
+        tickRegionWidth = rect.width() - tickRegionMargin * 2 - tickSize.width() * zoomFactor;
+    } else {
+        tickRect.setWidth(floor(tickSize.height() * zoomFactor));
+        tickRect.setHeight(floor(tickSize.width() * zoomFactor));
+        tickRect.setX(floor(rect.x() + rect.width() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor));
+        tickRegionSideMargin = rect.y() + tickRegionMargin;
+        tickRegionWidth = rect.height() - tickRegionMargin * 2 - tickSize.width() * zoomFactor;
+    }
+    RefPtr<HTMLCollection> options = dataList->options();
+    GraphicsContextStateSaver stateSaver(*paintInfo.context);
+    paintInfo.context->setFillColor(o->style()->visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
+    for (unsigned i = 0; Node* node = options->item(i); i++) {
+        ASSERT(node->hasTagName(optionTag));
+        HTMLOptionElement* optionElement = static_cast<HTMLOptionElement*>(node);
+        String value = optionElement->value();
+        if (!input->isValidValue(value))
+            continue;
+        double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
+        double tickPosition = (parsedValue - min) / (max - min);
+        if (!o->style()->isLeftToRightDirection())
+            tickPosition = 1.0 - tickPosition;
+        if (isHorizontal)
+            tickRect.setX(floor(tickRegionSideMargin + tickRegionWidth * tickPosition));
+        else
+            tickRect.setY(floor(tickRegionSideMargin + tickRegionWidth * tickPosition));
+        paintInfo.context->fillRect(tickRect);
+    }
+}
+#endif
+
 #if ENABLE(PROGRESS_TAG)
 double RenderTheme::animationRepeatIntervalForProgressBar(RenderProgress*) const
 {
index 5e56b6d..47fcf07 100644 (file)
@@ -213,7 +213,16 @@ public:
     virtual IntSize meterSizeForBounds(const RenderMeter*, const IntRect&) const;
     virtual bool supportsMeter(ControlPart) const;
 #endif
-    
+
+#if ENABLE(DATALIST)    
+    // Returns size of one slider tick mark for a horizontal track.
+    // For vertical tracks we rotate it and use it. i.e. Width is always length along the track.
+    virtual IntSize sliderTickSize() const = 0;
+    // Returns the distance of slider tick origin from the slider track center.
+    virtual int sliderTickOffsetFromTrackCenter() const = 0;
+    void paintSliderTicks(RenderObject*, const PaintInfo&, const IntRect&);
+#endif
+
     virtual bool shouldShowPlaceholderWhenFocused() const { return false; }
     virtual bool shouldHaveSpinButton(HTMLInputElement*) const;
 
index 5739c50..368c2b5 100644 (file)
@@ -32,9 +32,10 @@ namespace WebCore {
 
 bool RenderThemeChromiumCommon::supportsDataListUI(const AtomicString& type)
 {
-    // FIXME: We still need to support email, datetime, date, month, week, time, datetime-local, range, color.
+    // FIXME: We still need to support datetime, date, month, week, time, datetime-local, color.
     return type == InputTypeNames::text() || type == InputTypeNames::search() || type == InputTypeNames::url()
-        || type == InputTypeNames::telephone() || type == InputTypeNames::email() || type == InputTypeNames::number();
+        || type == InputTypeNames::telephone() || type == InputTypeNames::email() || type == InputTypeNames::number()
+        || type == InputTypeNames::range();
 }
 
 }
index 6b7f158..e31312e 100644 (file)
@@ -146,6 +146,18 @@ Color RenderThemeChromiumLinux::platformInactiveSelectionForegroundColor() const
     return m_inactiveSelectionForegroundColor;
 }
 
+#if ENABLE(DATALIST)
+IntSize RenderThemeChromiumLinux::sliderTickSize() const
+{
+    return IntSize(1, 6);
+}
+
+int RenderThemeChromiumLinux::sliderTickOffsetFromTrackCenter() const
+{
+    return -16;
+}
+#endif
+
 void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderStyle* style, Element* element) const
 {
     IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartSliderThumb);
@@ -292,6 +304,11 @@ bool RenderThemeChromiumLinux::paintSliderTrack(RenderObject* o, const PaintInfo
     extraParams.slider.vertical = o->style()->appearance() == SliderVerticalPart;
 
     PlatformSupport::paintThemePart(i.context, PlatformSupport::PartSliderTrack, getWebThemeState(this, o), rect, &extraParams);
+
+#if ENABLE(DATALIST)
+    paintSliderTicks(o, i, rect);
+#endif
+
     return false;
 }
 
index d754082..c641689 100644 (file)
@@ -54,6 +54,10 @@ namespace WebCore {
         virtual Color platformActiveSelectionForegroundColor() const;
         virtual Color platformInactiveSelectionForegroundColor() const;
 
+#if ENABLE(DATALIST)        
+        virtual IntSize sliderTickSize() const OVERRIDE;
+        virtual int sliderTickOffsetFromTrackCenter() const OVERRIDE;
+#endif
         virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
 
         static void setCaretBlinkInterval(double interval);
index e2c41d9..8738e99 100644 (file)
@@ -391,6 +391,18 @@ Color RenderThemeChromiumWin::systemColor(int cssValueId) const
     return Color(GetRValue(color), GetGValue(color), GetBValue(color));
 }
 
+#if ENABLE(DATALIST)
+IntSize RenderThemeChromiumWin::sliderTickSize() const
+{
+    return IntSize(1, 3);
+}
+
+int RenderThemeChromiumWin::sliderTickOffsetFromTrackCenter() const
+{
+    return 11;
+}
+#endif
+
 void RenderThemeChromiumWin::adjustSliderThumbSize(RenderStyle* style, Element* element) const
 {
     // These sizes match what WinXP draws for various menus.
@@ -443,12 +455,26 @@ bool RenderThemeChromiumWin::paintSliderTrack(RenderObject* o, const PaintInfo&
                                   themeData.m_state,
                                   themeData.m_classicState,
                                   painter.drawRect());
+
+#if ENABLE(DATALIST)
+    paintSliderTicks(o, i, r);
+#endif
+
     return false;
 }
 
 bool RenderThemeChromiumWin::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r)
 {
-    return paintSliderTrack(o, i, r);
+    const ThemeData& themeData = getThemeData(o);
+
+    ThemePainter painter(i.context, r);
+    PlatformSupport::paintTrackbar(painter.context(),
+                                   themeData.m_part,
+                                   themeData.m_state,
+                                   themeData.m_classicState,
+                                   painter.drawRect());
+
+    return false;
 }
 
 static int menuListButtonWidth()
index ad9eace..9aea7a5 100644 (file)
@@ -61,6 +61,10 @@ namespace WebCore {
         virtual void systemFont(int propId, FontDescription&) const;
         virtual Color systemColor(int cssValueId) const;
 
+#if ENABLE(DATALIST)        
+        virtual IntSize sliderTickSize() const OVERRIDE;
+        virtual int sliderTickOffsetFromTrackCenter() const OVERRIDE;
+#endif
         virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
 
         // Various paint functions.
index 2f5f80e..02cac53 100644 (file)
@@ -68,7 +68,12 @@ public:
     virtual int minimumMenuListSize(RenderStyle*) const;
 
     virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
-    
+
+#if ENABLE(DATALIST)
+    virtual IntSize sliderTickSize() const OVERRIDE;
+    virtual int sliderTickOffsetFromTrackCenter() const OVERRIDE;
+#endif
+
     virtual int popupInternalPaddingLeft(RenderStyle*) const;
     virtual int popupInternalPaddingRight(RenderStyle*) const;
     virtual int popupInternalPaddingTop(RenderStyle*) const;
index 6ed4abd..80d9ec8 100644 (file)
@@ -1372,6 +1372,10 @@ bool RenderThemeMac::paintSliderTrack(RenderObject* o, const PaintInfo& paintInf
     CGContextRef context = localContext.cgContext();
     CGColorSpaceRef cspace = deviceRGBColorSpaceRef();
 
+#if ENABLE(DATALIST)
+    paintSliderTicks(o, paintInfo, r);
+#endif
+
     GraphicsContextStateSaver stateSaver(*paintInfo.context);
     CGContextClipToRect(context, bounds);
 
@@ -1742,6 +1746,18 @@ static int mediaControllerTheme()
 }
 #endif
 
+#if ENABLE(DATALIST)
+IntSize RenderThemeMac::sliderTickSize() const
+{
+    return IntSize(1, 3);
+}
+
+int RenderThemeMac::sliderTickOffsetFromTrackCenter() const
+{
+    return -9;
+}
+#endif
+
 const int sliderThumbWidth = 15;
 const int sliderThumbHeight = 15;
 const int mediaSliderThumbWidth = 13;