Diff
Modified: trunk/LayoutTests/ChangeLog (123080 => 123081)
--- trunk/LayoutTests/ChangeLog 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/LayoutTests/ChangeLog 2012-07-19 08:55:06 UTC (rev 123081)
@@ -1,3 +1,15 @@
+2012-07-19 Keishi Hattori <kei...@webkit.org>
+
+ Redraw slider tick marks when datalist changes.
+ https://bugs.webkit.org/show_bug.cgi?id=89544
+
+ Reviewed by Kent Tamura.
+
+ Updating the datalist should redraw the slider tick marks.
+
+ * fast/forms/datalist/update-range-with-datalist-expected.html: Added.
+ * fast/forms/datalist/update-range-with-datalist.html: Added.
+
2012-07-19 Szilard Ledan <szle...@inf.u-szeged.hu>
[Qt] Unreviewed gardening. Remove the platform specific expected after r123066.
Added: trunk/LayoutTests/fast/forms/datalist/update-range-with-datalist-expected.html (0 => 123081)
--- trunk/LayoutTests/fast/forms/datalist/update-range-with-datalist-expected.html (rev 0)
+++ trunk/LayoutTests/fast/forms/datalist/update-range-with-datalist-expected.html 2012-07-19 08:55:06 UTC (rev 123081)
@@ -0,0 +1,77 @@
+<style>
+.test {
+ margin: 0;
+ padding: 10px;
+ width: 300px;
+ height: 60px;
+ float: left;
+}
+</style>
+
+<p>Tests 1-10 should have a tick at 80%. Tests 11 and 12 should have no ticks.</p>
+
+<datalist id="list80">
+ <option>80</option>
+</datalist>
+
+<div class="test">
+ <h4>Test 1: Changing option value</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 2: Changing option attribute</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 3: Changing option text content</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 4: Set datalist</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 5: Set another datalist</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 6: Reassign datalist id</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 7: Reassign datalist in front</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 8: Insert datalist in front</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 9: Insert option</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 10: Remove option</h4>
+ <input type="range" list="list80" />
+</div>
+
+<div class="test">
+ <h4>Test 11: Insert non-datalist in front</h4>
+ <input type="range" />
+</div>
+
+<div class="test">
+ <h4>Test 12: Remove datalist</h4>
+ <input type="range" />
+</div>
+
+<button id="button">Run tests.</button>
Added: trunk/LayoutTests/fast/forms/datalist/update-range-with-datalist.html (0 => 123081)
--- trunk/LayoutTests/fast/forms/datalist/update-range-with-datalist.html (rev 0)
+++ trunk/LayoutTests/fast/forms/datalist/update-range-with-datalist.html 2012-07-19 08:55:06 UTC (rev 123081)
@@ -0,0 +1,219 @@
+<style>
+.test {
+ margin: 0;
+ padding: 10px;
+ width: 300px;
+ height: 60px;
+ float: left;
+}
+</style>
+
+<p>Tests 1-10 should have a tick at 80%. Tests 11 and 12 should have no ticks.</p>
+
+<div class="test">
+ <h4>Test 1: Changing option value</h4>
+ <input type="range" list="list1" />
+ <datalist id="list1">
+ <option id="option1">20</option>
+ </datalist>
+ <script>
+ function test1() {
+ document.getElementById("option1").value = "80";
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 2: Changing option attribute</h4>
+ <input type="range" list="list2" />
+ <datalist id="list2">
+ <option id="option2">20</option>
+ </datalist>
+ <script>
+ function test2() {
+ document.getElementById("option2").setAttribute("value", "80");
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 3: Changing option text content</h4>
+ <input type="range" list="list3" />
+ <datalist id="list3">
+ <option id="option3">20</option>
+ </datalist>
+ <script>
+ function test3() {
+ document.getElementById("option3").textContent = "80";
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 4: Set datalist</h4>
+ <input type="range" id="input4" />
+ <datalist id="list4">
+ <option>80</option>
+ </datalist>
+ <script>
+ function test4() {
+ document.getElementById("input4").setAttribute("list", "list4");
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 5: Set another datalist</h4>
+ <input type="range" id="input5" list="list5-1" />
+ <datalist id="list5-1">
+ <option>20</option>
+ </datalist>
+ <datalist id="list5-2">
+ <option>80</option>
+ </datalist>
+ <script>
+ function test5() {
+ document.getElementById("input5").setAttribute("list", "list5-2");
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 6: Reassign datalist id</h4>
+ <input type="range" list="list6-1" />
+ <datalist id="list6-2">
+ <option>80</option>
+ </datalist>
+ <script>
+ function test6() {
+ document.getElementById("list6-2").id = "list6-1";
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 7: Reassign datalist in front</h4>
+ <input type="range" list="list7-2" />
+ <datalist id="list7-1">
+ <option>80</option>
+ </datalist>
+ <datalist id="list7-2">
+ <option>20</option>
+ </datalist>
+ <script>
+ function test7() {
+ document.getElementById("list7-1").id = "list7-2";
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 8: Insert datalist in front</h4>
+ <input type="range" list="list8-1" />
+ <datalist id="list8-1">
+ <option>20</option>
+ </datalist>
+ <script>
+ function test8() {
+ var e = document.createElement("datalist");
+ e.innerHTML = "<option>80</option>";
+ e.id = "list8-1";
+ var f = document.getElementById("list8-1");
+ f.parentNode.insertBefore(e, f);
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 9: Insert option</h4>
+ <input type="range" list="list9" />
+ <datalist id="list9">
+ </datalist>
+ <script>
+ function test9() {
+ var e = document.createElement("option");
+ e.value = "80";
+ document.getElementById("list9").appendChild(e);
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 10: Remove option</h4>
+ <input type="range" list="list10" />
+ <datalist id="list10">
+ <option id="option10">20</option>
+ <option>80</option>
+ </datalist>
+ <script>
+ function test10() {
+ var e = document.getElementById("option10");
+ e.parentNode.removeChild(e);
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 11: Insert non-datalist in front</h4>
+ <input type="range" list="list11" />
+ <datalist id="list11">
+ <option>20</option>
+ </datalist>
+ <script>
+ function test11() {
+ var e = document.createElement("div");
+ e.id = "list11";
+ var f = document.getElementById("list11");
+ f.parentNode.insertBefore(e, f);
+ };
+ </script>
+</div>
+
+<div class="test">
+ <h4>Test 12: Remove datalist</h4>
+ <input type="range" list="list12" />
+ <datalist id="list12">
+ <option>20</option>
+ </datalist>
+ <script>
+ function test12() {
+ var e = document.getElementById("list12");
+ e.parentNode.removeChild(e);
+ };
+ </script>
+</div>
+
+<button id="button">Run tests.</button>
+
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText(true);
+
+function clickOn(element)
+{
+ var x = element.offsetLeft + element.offsetWidth / 2;
+ var y = element.offsetTop + element.offsetHeight / 2;
+ eventSender.mouseMoveTo(x, y);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+ eventSender.mouseMoveTo(0, 0);
+}
+
+var button = document.getElementById("button");
+button._onclick_ = function() {
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
+ test8();
+ test9();
+ test10();
+ test11();
+ test12();
+};
+if (window.eventSender)
+ clickOn(button);
+</script>
Modified: trunk/Source/WebCore/ChangeLog (123080 => 123081)
--- trunk/Source/WebCore/ChangeLog 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/ChangeLog 2012-07-19 08:55:06 UTC (rev 123081)
@@ -1,3 +1,54 @@
+2012-07-19 Keishi Hattori <kei...@webkit.org>
+
+ Redraw slider tick marks when datalist changes.
+ https://bugs.webkit.org/show_bug.cgi?id=89544
+
+ Reviewed by Kent Tamura.
+
+ Updating the datalist should redraw the slider tick marks. This patch monitors
+ the id target element of the list attribute using ListAttributeTargetObserver
+ and notifies changes to the option element inside of a datalist element.
+
+ Test: fast/forms/datalist/update-range-with-datalist.html
+
+ * html/HTMLDataListElement.cpp:
+ (WebCore::HTMLDataListElement::optionElementChildrenChanged): Called when a child option element's value might have changed.
+ (WebCore):
+ * html/HTMLDataListElement.h:
+ (HTMLDataListElement):
+ * html/HTMLInputElement.cpp:
+ (ListAttributeTargetObserver): Inherits IdTargetObserver.
+ (WebCore):
+ (WebCore::HTMLInputElement::parseAttribute): Observe the form attribute target.
+ (WebCore::HTMLInputElement::insertedInto): Observe the form attribute id target.
+ (WebCore::HTMLInputElement::removedFrom): Remove the observer.
+ (WebCore::HTMLInputElement::resetListAttributeTargetObserver):
+ (WebCore::HTMLInputElement::listAttributeTargetChanged):
+ (WebCore::ListAttributeTargetObserver::create):
+ (WebCore::ListAttributeTargetObserver::ListAttributeTargetObserver):
+ (WebCore::ListAttributeTargetObserver::idTargetChanged):
+ * html/HTMLInputElement.h:
+ (WebCore):
+ (HTMLInputElement):
+ * html/HTMLOptionElement.cpp:
+ (WebCore::HTMLOptionElement::parseAttribute): If the value attribute changed, notify the owner datalist element.
+ (WebCore::HTMLOptionElement::childrenChanged): If the children changed, notify the owner datalist element.
+ (WebCore):
+ (WebCore::HTMLOptionElement::ownerDataListElement): The datalist that the option element is inside of.
+ * html/HTMLOptionElement.h:
+ (WebCore):
+ (HTMLOptionElement):
+ * html/InputType.cpp:
+ (WebCore):
+ (WebCore::InputType::listAttributeTargetChanged):
+ * html/InputType.h:
+ (InputType):
+ * html/RangeInputType.cpp:
+ (WebCore):
+ (WebCore::RangeInputType::listAttributeTargetChanged):
+ * html/RangeInputType.h:
+ (RangeInputType):
+
2012-07-19 Dongwoo Im <dw...@samsung.com>
CodeGeneratorV8.pm : @enabledAtRuntime is not used in GenerateHeader.
Modified: trunk/Source/WebCore/html/HTMLDataListElement.cpp (123080 => 123081)
--- trunk/Source/WebCore/html/HTMLDataListElement.cpp 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/HTMLDataListElement.cpp 2012-07-19 08:55:06 UTC (rev 123081)
@@ -30,11 +30,13 @@
*/
#include "config.h"
-#if ENABLE(DATALIST)
#include "HTMLDataListElement.h"
#include "HTMLNames.h"
+#include "IdTargetObserverRegistry.h"
+#if ENABLE(DATALIST)
+
namespace WebCore {
inline HTMLDataListElement::HTMLDataListElement(const QualifiedName& tagName, Document* document)
@@ -52,5 +54,10 @@
return ensureCachedHTMLCollection(DataListOptions);
}
+void HTMLDataListElement::optionElementChildrenChanged()
+{
+ treeScope()->idTargetObserverRegistry().notifyObservers(getIdAttribute());
+}
+
} // namespace WebCore
#endif // ENABLE(DATALIST)
Modified: trunk/Source/WebCore/html/HTMLDataListElement.h (123080 => 123081)
--- trunk/Source/WebCore/html/HTMLDataListElement.h 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/HTMLDataListElement.h 2012-07-19 08:55:06 UTC (rev 123081)
@@ -45,6 +45,8 @@
PassRefPtr<HTMLCollection> options();
+ void optionElementChildrenChanged();
+
private:
HTMLDataListElement(const QualifiedName&, Document*);
};
Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (123080 => 123081)
--- trunk/Source/WebCore/html/HTMLInputElement.cpp 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp 2012-07-19 08:55:06 UTC (rev 123081)
@@ -45,6 +45,7 @@
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
#include "HTMLParserIdioms.h"
+#include "IdTargetObserver.h"
#include "InputType.h"
#include "KeyboardEvent.h"
#include "LocalizedStrings.h"
@@ -77,6 +78,19 @@
using namespace HTMLNames;
+#if ENABLE(DATALIST)
+class ListAttributeTargetObserver : IdTargetObserver {
+public:
+ static PassOwnPtr<ListAttributeTargetObserver> create(const AtomicString& id, HTMLInputElement*);
+ virtual void idTargetChanged() OVERRIDE;
+
+private:
+ ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*);
+
+ HTMLInputElement* m_element;
+};
+#endif
+
// FIXME: According to HTML4, the length attribute's value can be arbitrarily
// large. However, due to https://bugs.webkit.org/show_bug.cgi?id=14536 things
// get rather sluggish when a text field has a larger number of characters than
@@ -684,9 +698,13 @@
m_inputType->readonlyAttributeChanged();
}
#if ENABLE(DATALIST)
- else if (attribute.name() == listAttr)
+ else if (attribute.name() == listAttr) {
m_hasNonEmptyList = !attribute.isEmpty();
- // FIXME: we need to tell this change to a renderer if the attribute affects the appearance.
+ if (m_hasNonEmptyList) {
+ resetListAttributeTargetObserver();
+ listAttributeTargetChanged();
+ }
+ }
#endif
#if ENABLE(INPUT_SPEECH)
else if (attribute.name() == webkitspeechAttr) {
@@ -1417,6 +1435,9 @@
HTMLTextFormControlElement::insertedInto(insertionPoint);
if (insertionPoint->inDocument() && !form())
addToRadioButtonGroup();
+#if ENABLE(DATALIST)
+ resetListAttributeTargetObserver();
+#endif
return InsertionDone;
}
@@ -1425,6 +1446,10 @@
if (insertionPoint->inDocument() && !form())
removeFromRadioButtonGroup();
HTMLTextFormControlElement::removedFrom(insertionPoint);
+ ASSERT(!inDocument());
+#if ENABLE(DATALIST)
+ resetListAttributeTargetObserver();
+#endif
}
void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
@@ -1497,6 +1522,19 @@
return static_cast<HTMLDataListElement*>(element);
}
+void HTMLInputElement::resetListAttributeTargetObserver()
+{
+ if (inDocument())
+ m_listAttributeTargetObserver = ListAttributeTargetObserver::create(fastGetAttribute(listAttr), this);
+ else
+ m_listAttributeTargetObserver = nullptr;
+}
+
+void HTMLInputElement::listAttributeTargetChanged()
+{
+ m_inputType->listAttributeTargetChanged();
+}
+
#endif // ENABLE(DATALIST)
bool HTMLInputElement::isSteppable() const
@@ -1765,4 +1803,22 @@
setAttribute(widthAttr, String::number(width));
}
+#if ENABLE(DATALIST)
+PassOwnPtr<ListAttributeTargetObserver> ListAttributeTargetObserver::create(const AtomicString& id, HTMLInputElement* element)
+{
+ return adoptPtr(new ListAttributeTargetObserver(id, element));
+}
+
+ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement* element)
+ : IdTargetObserver(element->treeScope()->idTargetObserverRegistry(), id)
+ , m_element(element)
+{
+}
+
+void ListAttributeTargetObserver::idTargetChanged()
+{
+ m_element->listAttributeTargetChanged();
+}
+#endif
+
} // namespace
Modified: trunk/Source/WebCore/html/HTMLInputElement.h (123080 => 123081)
--- trunk/Source/WebCore/html/HTMLInputElement.h 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/HTMLInputElement.h 2012-07-19 08:55:06 UTC (rev 123081)
@@ -39,6 +39,7 @@
class Icon;
class InputType;
class KURL;
+class ListAttributeTargetObserver;
class HTMLInputElement : public HTMLTextFormControlElement, public ImageLoaderClientBase<HTMLInputElement> {
public:
@@ -235,6 +236,7 @@
#if ENABLE(DATALIST)
HTMLElement* list() const;
+ void listAttributeTargetChanged();
#endif
HTMLInputElement* checkedRadioButtonForGroup() const;
@@ -360,9 +362,9 @@
virtual void subtreeHasChanged();
-
#if ENABLE(DATALIST)
HTMLDataListElement* dataList() const;
+ void resetListAttributeTargetObserver();
#endif
void parseMaxLengthAttribute(const Attribute&);
void updateValueIfNeeded();
@@ -395,6 +397,9 @@
bool m_canReceiveDroppedFiles : 1;
bool m_hasTouchEventHandler: 1;
OwnPtr<InputType> m_inputType;
+#if ENABLE(DATALIST)
+ OwnPtr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
+#endif
};
} //namespace
Modified: trunk/Source/WebCore/html/HTMLOptionElement.cpp (123080 => 123081)
--- trunk/Source/WebCore/html/HTMLOptionElement.cpp 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/HTMLOptionElement.cpp 2012-07-19 08:55:06 UTC (rev 123081)
@@ -30,6 +30,7 @@
#include "Attribute.h"
#include "Document.h"
#include "ExceptionCode.h"
+#include "HTMLDataListElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "HTMLSelectElement.h"
@@ -187,6 +188,12 @@
void HTMLOptionElement::parseAttribute(const Attribute& attribute)
{
+#if ENABLE(DATALIST)
+ if (attribute.name() == valueAttr) {
+ if (HTMLDataListElement* dataList = ownerDataListElement())
+ dataList->optionElementChildrenChanged();
+ } else
+#endif
if (attribute.name() == disabledAttr) {
bool oldDisabled = m_disabled;
m_disabled = !attribute.isNull();
@@ -252,11 +259,27 @@
void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
+#if ENABLE(DATALIST)
+ if (HTMLDataListElement* dataList = ownerDataListElement())
+ dataList->optionElementChildrenChanged();
+ else
+#endif
if (HTMLSelectElement* select = ownerSelectElement())
select->optionElementChildrenChanged();
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
+#if ENABLE(DATALIST)
+HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const
+{
+ for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) {
+ if (parent->hasTagName(datalistTag))
+ return static_cast<HTMLDataListElement*>(parent);
+ }
+ return 0;
+}
+#endif
+
HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const
{
ContainerNode* select = parentNode();
Modified: trunk/Source/WebCore/html/HTMLOptionElement.h (123080 => 123081)
--- trunk/Source/WebCore/html/HTMLOptionElement.h 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/HTMLOptionElement.h 2012-07-19 08:55:06 UTC (rev 123081)
@@ -29,6 +29,7 @@
namespace WebCore {
+class HTMLDataListElement;
class HTMLSelectElement;
class HTMLOptionElement : public HTMLElement {
@@ -49,6 +50,9 @@
bool selected();
void setSelected(bool);
+#if ENABLE(DATALIST)
+ HTMLDataListElement* ownerDataListElement() const;
+#endif
HTMLSelectElement* ownerSelectElement() const;
String label() const;
Modified: trunk/Source/WebCore/html/InputType.cpp (123080 => 123081)
--- trunk/Source/WebCore/html/InputType.cpp 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/InputType.cpp 2012-07-19 08:55:06 UTC (rev 123081)
@@ -897,6 +897,12 @@
return String();
}
+#if ENABLE(DATALIST)
+void InputType::listAttributeTargetChanged()
+{
+}
+#endif
+
bool InputType::supportsIndeterminateAppearance() const
{
return false;
Modified: trunk/Source/WebCore/html/InputType.h (123080 => 123081)
--- trunk/Source/WebCore/html/InputType.h 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/InputType.h 2012-07-19 08:55:06 UTC (rev 123081)
@@ -276,6 +276,9 @@
virtual void disabledAttributeChanged();
virtual void readonlyAttributeChanged();
virtual String defaultToolTip() const;
+#if ENABLE(DATALIST)
+ virtual void listAttributeTargetChanged();
+#endif
// Parses the specified string for the type, and return
// the Decimal value for the parsing result if the parsing
Modified: trunk/Source/WebCore/html/RangeInputType.cpp (123080 => 123081)
--- trunk/Source/WebCore/html/RangeInputType.cpp 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/RangeInputType.cpp 2012-07-19 08:55:06 UTC (rev 123081)
@@ -316,4 +316,11 @@
return sliderThumbElementOf(element());
}
+#if ENABLE(DATALIST)
+void RangeInputType::listAttributeTargetChanged()
+{
+ element()->setNeedsStyleRecalc();
+}
+#endif
+
} // namespace WebCore
Modified: trunk/Source/WebCore/html/RangeInputType.h (123080 => 123081)
--- trunk/Source/WebCore/html/RangeInputType.h 2012-07-19 08:24:17 UTC (rev 123080)
+++ trunk/Source/WebCore/html/RangeInputType.h 2012-07-19 08:55:06 UTC (rev 123081)
@@ -70,6 +70,9 @@
virtual String sanitizeValue(const String& proposedValue) const OVERRIDE;
virtual bool shouldRespectListAttribute() OVERRIDE;
virtual HTMLElement* sliderThumbElement() const OVERRIDE;
+#if ENABLE(DATALIST)
+ virtual void listAttributeTargetChanged() OVERRIDE;
+#endif
};
} // namespace WebCore