summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/shadow
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-09-10 19:10:20 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-09-10 19:10:20 +0200
commit284837daa07b29d6a63a748544a90b1f5842ac5c (patch)
treeecd258180bde91fe741e0cfd2638beb3c6da7e8e /Source/WebCore/html/shadow
parent2e2ba8ff45915f40ed3e014101269c175f2a89a0 (diff)
downloadqtwebkit-284837daa07b29d6a63a748544a90b1f5842ac5c.tar.gz
Imported WebKit commit 68645295d2e3e09af2c942f092556f06aa5f8b0d (http://svn.webkit.org/repository/webkit/trunk@128073)
New snapshot
Diffstat (limited to 'Source/WebCore/html/shadow')
-rw-r--r--Source/WebCore/html/shadow/CalendarPickerElement.cpp113
-rw-r--r--Source/WebCore/html/shadow/CalendarPickerElement.h19
-rw-r--r--Source/WebCore/html/shadow/ContentDistributor.cpp6
-rw-r--r--Source/WebCore/html/shadow/ContentDistributor.h3
-rw-r--r--Source/WebCore/html/shadow/DateTimeEditElement.cpp219
-rw-r--r--Source/WebCore/html/shadow/DateTimeEditElement.h25
-rw-r--r--Source/WebCore/html/shadow/DateTimeFieldElement.cpp67
-rw-r--r--Source/WebCore/html/shadow/DateTimeFieldElement.h22
-rw-r--r--Source/WebCore/html/shadow/DateTimeFieldElements.cpp40
-rw-r--r--Source/WebCore/html/shadow/DateTimeFieldElements.h20
-rw-r--r--Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp10
-rw-r--r--Source/WebCore/html/shadow/DateTimeNumericFieldElement.h3
-rw-r--r--Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp43
-rw-r--r--Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h9
-rw-r--r--Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp25
-rw-r--r--Source/WebCore/html/shadow/MediaControlRootElementChromium.h2
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.cpp8
-rw-r--r--Source/WebCore/html/shadow/TextControlInnerElements.cpp2
18 files changed, 340 insertions, 296 deletions
diff --git a/Source/WebCore/html/shadow/CalendarPickerElement.cpp b/Source/WebCore/html/shadow/CalendarPickerElement.cpp
index f3244de6b..28d78d1d5 100644
--- a/Source/WebCore/html/shadow/CalendarPickerElement.cpp
+++ b/Source/WebCore/html/shadow/CalendarPickerElement.cpp
@@ -33,22 +33,13 @@
#if ENABLE(CALENDAR_PICKER)
-#include "CalendarPicker.h"
#include "Chrome.h"
#include "ChromeClient.h"
-#include "DateComponents.h"
#include "Event.h"
#include "FrameView.h"
#include "HTMLInputElement.h"
-#include "HTMLNames.h"
-#include "Language.h"
-#include "LocalizedDate.h"
-#include "LocalizedStrings.h"
#include "Page.h"
-#include "PickerCommon.h"
#include "RenderDetailsMarker.h"
-#include "RenderTheme.h"
-#include <wtf/text/StringBuilder.h>
using namespace WTF::Unicode;
@@ -58,7 +49,7 @@ using namespace HTMLNames;
inline CalendarPickerElement::CalendarPickerElement(Document* document)
: HTMLDivElement(divTag, document)
- , m_popup(0)
+ , m_chooser(nullptr)
{
setShadowPseudoId("-webkit-calendar-picker-indicator");
}
@@ -71,7 +62,7 @@ PassRefPtr<CalendarPickerElement> CalendarPickerElement::create(Document* docume
CalendarPickerElement::~CalendarPickerElement()
{
closePopup();
- ASSERT(!m_popup);
+ ASSERT(!m_chooser);
}
RenderObject* CalendarPickerElement::createRenderer(RenderArena* arena, RenderStyle*)
@@ -114,9 +105,19 @@ bool CalendarPickerElement::willRespondToMouseClickEvents()
return HTMLDivElement::willRespondToMouseClickEvents();
}
+void CalendarPickerElement::didChooseValue(const String& value)
+{
+ hostInput()->setValue(value, DispatchChangeEvent);
+}
+
+void CalendarPickerElement::didEndChooser()
+{
+ m_chooser.clear();
+}
+
void CalendarPickerElement::openPopup()
{
- if (m_popup)
+ if (m_chooser)
return;
if (!document()->page())
return;
@@ -125,20 +126,29 @@ void CalendarPickerElement::openPopup()
return;
if (!document()->view())
return;
- IntRect elementRectInRootView = document()->view()->contentsToRootView(hostInput()->getPixelSnappedRect());
- m_popup = chrome->client()->openPagePopup(this, elementRectInRootView);
+
+ HTMLInputElement* input = hostInput();
+ DateTimeChooserParameters parameters;
+ parameters.type = input->type();
+ parameters.minimum = input->minimum();
+ parameters.maximum = input->maximum();
+ parameters.required = input->required();
+ Decimal step;
+ if (hostInput()->getAllowedValueStep(&step))
+ parameters.step = 1.0;
+ else
+ parameters.step = step.toDouble();
+ parameters.anchorRectInRootView = document()->view()->contentsToRootView(hostInput()->pixelSnappedBoundingBox());
+ parameters.currentValue = input->value();
+ // FIXME: parameters.suggestionValues and suggestionLabels will be used when we support datalist.
+ m_chooser = chrome->client()->openDateTimeChooser(this, parameters);
}
void CalendarPickerElement::closePopup()
{
- if (!m_popup)
- return;
- if (!document()->page())
+ if (!m_chooser)
return;
- Chrome* chrome = document()->page()->chrome();
- if (!chrome)
- return;
- chrome->client()->closePagePopup(m_popup);
+ m_chooser->endChooser();
}
void CalendarPickerElement::detach()
@@ -147,67 +157,6 @@ void CalendarPickerElement::detach()
HTMLDivElement::detach();
}
-IntSize CalendarPickerElement::contentSize()
-{
- return IntSize(0, 0);
-}
-
-void CalendarPickerElement::writeDocument(DocumentWriter& writer)
-{
- HTMLInputElement* input = hostInput();
- DateComponents date;
- date.setMillisecondsSinceEpochForDate(input->minimum());
- String minString = date.toString();
- date.setMillisecondsSinceEpochForDate(input->maximum());
- String maxString = date.toString();
- Decimal step;
- String stepString = input->fastGetAttribute(stepAttr);
- if (stepString.isEmpty() || !input->getAllowedValueStep(&step))
- stepString = "1";
-
- addString("<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", writer);
- writer.addData(pickerCommonCss, sizeof(pickerCommonCss));
- writer.addData(calendarPickerCss, sizeof(calendarPickerCss));
- if (document()->page()) {
- CString extraStyle = document()->page()->theme()->extraCalendarPickerStyleSheet();
- if (extraStyle.length())
- writer.addData(extraStyle.data(), extraStyle.length());
- }
- addString("</style></head><body><div id=main>Loading...</div><script>\n"
- "window.dialogArguments = {\n", writer);
- addProperty("min", minString, writer);
- addProperty("max", maxString, writer);
- addProperty("step", stepString, writer);
- addProperty("required", input->required(), writer);
- addProperty("currentValue", input->value(), writer);
- addProperty("locale", defaultLanguage(), writer);
- addProperty("todayLabel", calendarTodayText(), writer);
- addProperty("clearLabel", calendarClearText(), writer);
- addProperty("weekStartDay", firstDayOfWeek(), writer);
- addProperty("monthLabels", monthLabels(), writer);
- addProperty("dayLabels", weekDayShortLabels(), writer);
- Direction dir = direction(monthLabels()[0][0]);
- addProperty("isRTL", dir == RightToLeft || dir == RightToLeftArabic, writer);
- addString("}\n", writer);
-
- writer.addData(pickerCommonJs, sizeof(pickerCommonJs));
- writer.addData(calendarPickerJs, sizeof(calendarPickerJs));
- addString("</script></body>\n", writer);
-}
-
-void CalendarPickerElement::setValueAndClosePopup(int numValue, const String& stringValue)
-{
- ASSERT(m_popup);
- closePopup();
- if (numValue >= 0)
- hostInput()->setValue(stringValue, DispatchChangeEvent);
-}
-
-void CalendarPickerElement::didClosePopup()
-{
- m_popup = 0;
-}
-
}
#endif
diff --git a/Source/WebCore/html/shadow/CalendarPickerElement.h b/Source/WebCore/html/shadow/CalendarPickerElement.h
index cbf213fc5..f90347864 100644
--- a/Source/WebCore/html/shadow/CalendarPickerElement.h
+++ b/Source/WebCore/html/shadow/CalendarPickerElement.h
@@ -32,15 +32,18 @@
#define CalendarPickerElement_h
#if ENABLE(CALENDAR_PICKER)
+
+#include "DateTimeChooser.h"
+#include "DateTimeChooserClient.h"
#include "HTMLDivElement.h"
-#include "PagePopupClient.h"
+#include <wtf/OwnPtr.h>
namespace WebCore {
class HTMLInputElement;
class PagePopup;
-class CalendarPickerElement : public HTMLDivElement, public PagePopupClient {
+class CalendarPickerElement : public HTMLDivElement, public DateTimeChooserClient {
public:
static PassRefPtr<CalendarPickerElement> create(Document*);
virtual ~CalendarPickerElement();
@@ -48,21 +51,19 @@ public:
void closePopup();
virtual bool willRespondToMouseClickEvents() OVERRIDE;
+ // DateTimeChooserClient implementation.
+ virtual void didChooseValue(const String&) OVERRIDE;
+ virtual void didEndChooser() OVERRIDE;
+
private:
CalendarPickerElement(Document*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
virtual void detach() OVERRIDE;
- // PagePopupClient functions:
- virtual IntSize contentSize() OVERRIDE;
- virtual void writeDocument(DocumentWriter&) OVERRIDE;
- virtual void setValueAndClosePopup(int, const String&) OVERRIDE;
- virtual void didClosePopup() OVERRIDE;
-
HTMLInputElement* hostInput();
- PagePopup* m_popup;
+ OwnPtr<DateTimeChooser> m_chooser;
};
}
diff --git a/Source/WebCore/html/shadow/ContentDistributor.cpp b/Source/WebCore/html/shadow/ContentDistributor.cpp
index 324a5d0ed..b3c8eb0e4 100644
--- a/Source/WebCore/html/shadow/ContentDistributor.cpp
+++ b/Source/WebCore/html/shadow/ContentDistributor.cpp
@@ -71,7 +71,7 @@ void ContentDistributor::distribute(Element* host)
if (point->doesSelectFromHostChildren())
distributeSelectionsTo(point, pool);
else if (older && !older->assignedTo()) {
- distributeShadowChildrenTo(point, older);
+ distributeNodeChildrenTo(point, older);
older->setAssignedTo(point);
}
}
@@ -126,10 +126,10 @@ void ContentDistributor::distributeSelectionsTo(InsertionPoint* insertionPoint,
insertionPoint->setDistribution(distribution);
}
-void ContentDistributor::distributeShadowChildrenTo(InsertionPoint* insertionPoint, ShadowRoot* root)
+void ContentDistributor::distributeNodeChildrenTo(InsertionPoint* insertionPoint, ContainerNode* containerNode)
{
ContentDistribution distribution;
- for (Node* node = root->firstChild(); node; node = node->nextSibling()) {
+ for (Node* node = containerNode->firstChild(); node; node = node->nextSibling()) {
distribution.append(node);
m_nodeToInsertionPoint.add(node, insertionPoint);
}
diff --git a/Source/WebCore/html/shadow/ContentDistributor.h b/Source/WebCore/html/shadow/ContentDistributor.h
index 214e54fce..08cb543f8 100644
--- a/Source/WebCore/html/shadow/ContentDistributor.h
+++ b/Source/WebCore/html/shadow/ContentDistributor.h
@@ -38,6 +38,7 @@
namespace WebCore {
+class ContainerNode;
class Element;
class InsertionPoint;
class Node;
@@ -69,7 +70,7 @@ public:
bool needsInvalidation() const { return m_validity != Invalidated; }
void distributeSelectionsTo(InsertionPoint*, ContentDistribution& pool);
- void distributeShadowChildrenTo(InsertionPoint*, ShadowRoot*);
+ void distributeNodeChildrenTo(InsertionPoint*, ContainerNode*);
void invalidateDistributionIn(ContentDistribution*);
private:
diff --git a/Source/WebCore/html/shadow/DateTimeEditElement.cpp b/Source/WebCore/html/shadow/DateTimeEditElement.cpp
index 44a1c2b0a..7ee8216c7 100644
--- a/Source/WebCore/html/shadow/DateTimeEditElement.cpp
+++ b/Source/WebCore/html/shadow/DateTimeEditElement.cpp
@@ -195,7 +195,6 @@ DateTimeEditElement::DateTimeEditElement(Document* document, EditControlOwner& e
: HTMLDivElement(divTag, document)
, m_editControlOwner(&editControlOwner)
, m_spinButton(0)
- , m_focusFieldIndex(invalidFieldIndex)
{
DEFINE_STATIC_LOCAL(AtomicString, dateTimeEditPseudoId, ("-webkit-datetime-edit"));
setShadowPseudoId(dateTimeEditPseudoId);
@@ -218,12 +217,30 @@ void DateTimeEditElement::addField(PassRefPtr<DateTimeFieldElement> field)
appendChild(field);
}
+void DateTimeEditElement::blurByOwner()
+{
+ if (DateTimeFieldElement* field = focusedField())
+ field->blur();
+}
+
PassRefPtr<DateTimeEditElement> DateTimeEditElement::create(Document* document, EditControlOwner& editControlOwner)
{
RefPtr<DateTimeEditElement> container = adoptRef(new DateTimeEditElement(document, editControlOwner));
return container.release();
}
+void DateTimeEditElement::didBlurFromField()
+{
+ if (m_editControlOwner)
+ m_editControlOwner->didBlurFromControl();
+}
+
+void DateTimeEditElement::didFocusOnField()
+{
+ if (m_editControlOwner)
+ m_editControlOwner->didFocusOnControl();
+}
+
void DateTimeEditElement::disabledStateChanged()
{
updateUIState();
@@ -234,73 +251,42 @@ DateTimeFieldElement* DateTimeEditElement::fieldAt(size_t fieldIndex) const
return fieldIndex < m_fields.size() ? m_fields[fieldIndex] : 0;
}
-void DateTimeEditElement::focusAndSelectSpinButtonOwner()
+size_t DateTimeEditElement::fieldIndexOf(const DateTimeFieldElement& field) const
{
- if (!m_editControlOwner)
- return;
- m_editControlOwner->focusAndSelectEditControlOwner();
+ for (size_t fieldIndex = 0; fieldIndex < m_fields.size(); ++fieldIndex) {
+ if (m_fields[fieldIndex] == &field)
+ return fieldIndex;
+ }
+ return invalidFieldIndex;
}
-void DateTimeEditElement::focusFieldAt(size_t newFocusFieldIndex)
+void DateTimeEditElement::focusAndSelectSpinButtonOwner()
{
- if (m_focusFieldIndex == newFocusFieldIndex)
- return;
-
- DateTimeFieldElement* const newFocusField = fieldAt(newFocusFieldIndex);
- if (newFocusField && newFocusField->isReadOnly())
+ if (focusedFieldIndex() != invalidFieldIndex)
return;
- DateTimeFieldElement* const currentFocusField = fieldAt(m_focusFieldIndex);
-
- if (currentFocusField)
- currentFocusField->setFocus(false);
-
- if (!newFocusField) {
- m_focusFieldIndex = invalidFieldIndex;
- return;
- }
-
- m_focusFieldIndex = newFocusFieldIndex;
- newFocusField->setFocus(true);
+ if (DateTimeFieldElement* field = fieldAt(0))
+ field->focus();
}
-void DateTimeEditElement::handleKeyboardEvent(KeyboardEvent* keyboardEvent)
+void DateTimeEditElement::focusByOwner()
{
- if (isDisabled() || isReadOnly())
- return;
-
- if (!fieldAt(m_focusFieldIndex))
- return;
-
- if (keyboardEvent->type() != eventNames().keydownEvent)
- return;
-
- const String& keyIdentifier = keyboardEvent->keyIdentifier();
-
- if (keyIdentifier == "Left") {
- keyboardEvent->setDefaultHandled();
- const size_t fieldIndex = previousFieldIndex();
- if (fieldAt(fieldIndex))
- focusFieldAt(fieldIndex);
- return;
- }
+ if (DateTimeFieldElement* field = fieldAt(0))
+ field->focus();
+}
- if (keyIdentifier == "Right") {
- keyboardEvent->setDefaultHandled();
- const size_t fieldIndex = nextFieldIndex();
- if (fieldAt(fieldIndex))
- focusFieldAt(fieldIndex);
- return;
- }
+DateTimeFieldElement* DateTimeEditElement::focusedField() const
+{
+ return fieldAt(focusedFieldIndex());
+}
- if (keyIdentifier == "U+0009") {
- const size_t fieldIndex = keyboardEvent->getModifierState("Shift") ? previousFieldIndex() : nextFieldIndex();
- if (fieldAt(fieldIndex)) {
- keyboardEvent->setDefaultHandled();
- focusFieldAt(fieldIndex);
- return;
- }
+size_t DateTimeEditElement::focusedFieldIndex() const
+{
+ for (size_t fieldIndex = 0; fieldIndex < m_fields.size(); ++fieldIndex) {
+ if (m_fields[fieldIndex]->focused())
+ return fieldIndex;
}
+ return invalidFieldIndex;
}
void DateTimeEditElement::fieldValueChanged()
@@ -309,30 +295,34 @@ void DateTimeEditElement::fieldValueChanged()
m_editControlOwner->editControlValueChanged();
}
-void DateTimeEditElement::focusOnNextField()
+bool DateTimeEditElement::focusOnNextField(const DateTimeFieldElement& field)
{
- if (m_focusFieldIndex != invalidFieldIndex)
- focusFieldAt(nextFieldIndex());
+ const size_t startFieldIndex = fieldIndexOf(field);
+ if (startFieldIndex == invalidFieldIndex)
+ return false;
+ for (size_t fieldIndex = startFieldIndex + 1; fieldIndex < m_fields.size(); ++fieldIndex) {
+ if (!m_fields[fieldIndex]->isReadOnly()) {
+ m_fields[fieldIndex]->focus();
+ return true;
+ }
+ }
+ return false;
}
-void DateTimeEditElement::handleMouseEvent(MouseEvent* mouseEvent)
+bool DateTimeEditElement::focusOnPreviousField(const DateTimeFieldElement& field)
{
- if (isDisabled() || isReadOnly())
- return;
-
- if (mouseEvent->type() != eventNames().mousedownEvent || mouseEvent->button() != LeftButton)
- return;
-
- Node* const relatedTarget = mouseEvent->target()->toNode();
- for (size_t fieldIndex = 0; fieldIndex < m_fields.size(); ++fieldIndex) {
- if (m_fields[fieldIndex] == relatedTarget) {
- mouseEvent->setDefaultHandled();
- focusFieldAt(fieldIndex);
- if (m_editControlOwner)
- m_editControlOwner->editControlMouseFocus();
- break;
+ const size_t startFieldIndex = fieldIndexOf(field);
+ if (startFieldIndex == invalidFieldIndex)
+ return false;
+ size_t fieldIndex = startFieldIndex;
+ while (fieldIndex > 0) {
+ --fieldIndex;
+ if (!m_fields[fieldIndex]->isReadOnly()) {
+ m_fields[fieldIndex]->focus();
+ return true;
}
}
+ return false;
}
bool DateTimeEditElement::isDisabled() const
@@ -347,10 +337,9 @@ bool DateTimeEditElement::isReadOnly() const
void DateTimeEditElement::layout(const StepRange& stepRange, const DateComponents& dateValue)
{
- size_t focusFieldIndex = m_focusFieldIndex;
- DateTimeFieldElement* const focusField = fieldAt(m_focusFieldIndex);
- const AtomicString focusFieldId = focusField ? focusField->shadowPseudoId() : nullAtom;
- focusFieldAt(invalidFieldIndex);
+ size_t focusedFieldIndex = this->focusedFieldIndex();
+ DateTimeFieldElement* const focusedField = fieldAt(focusedFieldIndex);
+ const AtomicString focusedFieldId = focusedField ? focusedField->shadowPseudoId() : nullAtom;
DateTimeEditBuilder builder(*this, stepRange, dateValue);
const String dateTimeFormat = builder.needSecondField() ? localizedTimeFormatText() : localizedShortTimeFormatText();
@@ -361,37 +350,16 @@ void DateTimeEditElement::layout(const StepRange& stepRange, const DateComponent
m_spinButton = spinButton.get();
appendChild(spinButton);
- if (focusFieldIndex != invalidFieldIndex) {
+ if (focusedFieldIndex != invalidFieldIndex) {
for (size_t fieldIndex = 0; fieldIndex < m_fields.size(); ++fieldIndex) {
- if (m_fields[fieldIndex]->shadowPseudoId() == focusFieldId) {
- focusFieldIndex = fieldIndex;
+ if (m_fields[fieldIndex]->shadowPseudoId() == focusedFieldId) {
+ focusedFieldIndex = fieldIndex;
break;
}
}
- focusFieldAt(std::min(focusFieldIndex, m_fields.size() - 1));
- }
-}
-
-size_t DateTimeEditElement::nextFieldIndex() const
-{
- ASSERT(m_focusFieldIndex != invalidFieldIndex);
- for (size_t fieldIndex = m_focusFieldIndex + 1; fieldIndex < m_fields.size(); ++fieldIndex) {
- if (!m_fields[fieldIndex]->isReadOnly())
- return fieldIndex;
- }
- return m_fields.size();
-}
-
-size_t DateTimeEditElement::previousFieldIndex() const
-{
- ASSERT(m_focusFieldIndex != invalidFieldIndex);
- size_t fieldIndex = m_focusFieldIndex;
- while (fieldIndex > 0) {
- --fieldIndex;
- if (!m_fields[fieldIndex]->isReadOnly())
- return fieldIndex;
+ if (DateTimeFieldElement* field = fieldAt(std::min(focusedFieldIndex, m_fields.size() - 1)))
+ field->focus();
}
- return invalidFieldIndex;
}
void DateTimeEditElement::readOnlyStateChanged()
@@ -403,42 +371,26 @@ void DateTimeEditElement::resetLayout()
{
m_fields.shrink(0);
m_spinButton = 0;
- m_focusFieldIndex = invalidFieldIndex;
removeChildren();
}
void DateTimeEditElement::defaultEventHandler(Event* event)
{
- if (event->type() == eventNames().focusEvent) {
- if (!isDisabled() && !isReadOnly() && m_focusFieldIndex == invalidFieldIndex)
- focusFieldAt(0);
- return;
- }
-
- if (event->type() == eventNames().blurEvent) {
- focusFieldAt(invalidFieldIndex);
- return;
+ // In case of control owner forward event to control, e.g. DOM
+ // dispatchEvent method.
+ if (DateTimeFieldElement* field = focusedField()) {
+ field->defaultEventHandler(event);
+ if (event->defaultHandled())
+ return;
}
- if (event->isMouseEvent()) {
- handleMouseEvent(static_cast<MouseEvent*>(event));
- } else if (event->isKeyboardEvent())
- handleKeyboardEvent(static_cast<KeyboardEvent*>(event));
-
- if (event->defaultHandled())
- return;
-
- DateTimeFieldElement* const focusField = fieldAt(m_focusFieldIndex);
- if (!focusField)
- return;
-
if (m_spinButton) {
m_spinButton->forwardEvent(event);
if (event->defaultHandled())
return;
}
- focusField->defaultEventHandler(event);
+ HTMLDivElement::defaultEventHandler(event);
}
void DateTimeEditElement::setValueAsDate(const StepRange& stepRange, const DateComponents& date)
@@ -465,26 +417,27 @@ bool DateTimeEditElement::shouldSpinButtonRespondToWheelEvents()
if (!shouldSpinButtonRespondToMouseEvents())
return false;
- return !m_editControlOwner || m_editControlOwner->isEditControlOwnerFocused();
+ return focusedFieldIndex() != invalidFieldIndex;
}
void DateTimeEditElement::spinButtonStepDown()
{
- if (DateTimeFieldElement* const focusField = fieldAt(m_focusFieldIndex))
- focusField->stepDown();
+ if (DateTimeFieldElement* const field = focusedField())
+ field->stepDown();
}
void DateTimeEditElement::spinButtonStepUp()
{
- if (DateTimeFieldElement* const focusField = fieldAt(m_focusFieldIndex))
- focusField->stepUp();
+ if (DateTimeFieldElement* const field = focusedField())
+ field->stepUp();
}
void DateTimeEditElement::updateUIState()
{
if (isDisabled() || isReadOnly()) {
m_spinButton->releaseCapture();
- focusFieldAt(invalidFieldIndex);
+ if (DateTimeFieldElement* field = focusedField())
+ field->blur();
}
}
diff --git a/Source/WebCore/html/shadow/DateTimeEditElement.h b/Source/WebCore/html/shadow/DateTimeEditElement.h
index 4767368f4..10c466487 100644
--- a/Source/WebCore/html/shadow/DateTimeEditElement.h
+++ b/Source/WebCore/html/shadow/DateTimeEditElement.h
@@ -42,7 +42,7 @@ class StepRange;
// representing date and time, such as
// - Year, Month, Day Of Month
// - Hour, Minute, Second, Millisecond, AM/PM
-class DateTimeEditElement : public HTMLDivElement, public DateTimeFieldElement::FieldEventHandler, private SpinButtonElement::SpinButtonOwner {
+class DateTimeEditElement : public HTMLDivElement, public DateTimeFieldElement::FieldOwner, private SpinButtonElement::SpinButtonOwner {
WTF_MAKE_NONCOPYABLE(DateTimeEditElement);
public:
@@ -51,11 +51,10 @@ public:
class EditControlOwner {
public:
virtual ~EditControlOwner();
- virtual void focusAndSelectEditControlOwner() = 0;
- virtual void editControlMouseFocus() = 0;
+ virtual void didBlurFromControl() = 0;
+ virtual void didFocusOnControl() = 0;
virtual void editControlValueChanged() = 0;
virtual bool isEditControlOwnerDisabled() const = 0;
- virtual bool isEditControlOwnerFocused() const = 0;
virtual bool isEditControlOwnerReadOnly() const = 0;
};
@@ -63,8 +62,10 @@ public:
virtual ~DateTimeEditElement();
void addField(PassRefPtr<DateTimeFieldElement>);
+ void blurByOwner();
virtual void defaultEventHandler(Event*) OVERRIDE;
void disabledStateChanged();
+ void focusByOwner();
void readOnlyStateChanged();
void removeEditControlOwner() { m_editControlOwner = 0; }
void resetLayout();
@@ -89,19 +90,20 @@ private:
DateTimeEditElement(Document*, EditControlOwner&);
DateTimeFieldElement* fieldAt(size_t) const;
- void focusFieldAt(size_t);
- void handleKeyboardEvent(KeyboardEvent*);
- void handleMouseEvent(MouseEvent*);
+ size_t fieldIndexOf(const DateTimeFieldElement&) const;
+ DateTimeFieldElement* focusedField() const;
+ size_t focusedFieldIndex() const;
bool isDisabled() const;
bool isReadOnly() const;
void layout(const StepRange&, const DateComponents&);
- size_t nextFieldIndex() const;
- size_t previousFieldIndex() const;
void updateUIState();
- // DateTimeFieldElement::FieldEventHandler functions.
+ // DateTimeFieldElement::FieldOwner functions.
+ virtual void didBlurFromField() OVERRIDE FINAL;
+ virtual void didFocusOnField() OVERRIDE FINAL;
virtual void fieldValueChanged() OVERRIDE FINAL;
- virtual void focusOnNextField() OVERRIDE FINAL;
+ virtual bool focusOnNextField(const DateTimeFieldElement&) OVERRIDE FINAL;
+ virtual bool focusOnPreviousField(const DateTimeFieldElement&) OVERRIDE FINAL;
// SpinButtonElement::SpinButtonOwner functions.
virtual void focusAndSelectSpinButtonOwner() OVERRIDE FINAL;
@@ -113,7 +115,6 @@ private:
Vector<DateTimeFieldElement*, maximumNumberOfFields> m_fields;
EditControlOwner* m_editControlOwner;
SpinButtonElement* m_spinButton;
- size_t m_focusFieldIndex;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/shadow/DateTimeFieldElement.cpp b/Source/WebCore/html/shadow/DateTimeFieldElement.cpp
index 702e4900c..b62467d4b 100644
--- a/Source/WebCore/html/shadow/DateTimeFieldElement.cpp
+++ b/Source/WebCore/html/shadow/DateTimeFieldElement.cpp
@@ -30,24 +30,31 @@
#include "DateComponents.h"
#include "HTMLNames.h"
#include "KeyboardEvent.h"
+#include "RenderObject.h"
#include "Text.h"
namespace WebCore {
using namespace HTMLNames;
-DateTimeFieldElement::FieldEventHandler::~FieldEventHandler()
+DateTimeFieldElement::FieldOwner::~FieldOwner()
{
}
-DateTimeFieldElement::DateTimeFieldElement(Document* document, FieldEventHandler& fieldEventHandler)
+DateTimeFieldElement::DateTimeFieldElement(Document* document, FieldOwner& fieldOwner)
: HTMLElement(spanTag, document)
- , m_fieldEventHandler(&fieldEventHandler)
+ , m_fieldOwner(&fieldOwner)
{
}
void DateTimeFieldElement::defaultEventHandler(Event* event)
{
+ if (event->type() == eventNames().blurEvent)
+ didBlur();
+
+ if (event->type() == eventNames().focusEvent)
+ didFocus();
+
if (event->isKeyboardEvent()) {
KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(event);
handleKeyboardEvent(keyboardEvent);
@@ -74,23 +81,52 @@ void DateTimeFieldElement::defaultKeyboardEventHandler(KeyboardEvent* keyboardEv
return;
}
+ if (keyIdentifier == "Left") {
+ if (!m_fieldOwner)
+ return;
+ if (isRTL() ? m_fieldOwner->focusOnNextField(*this) : m_fieldOwner->focusOnPreviousField(*this))
+ keyboardEvent->setDefaultHandled();
+ return;
+ }
+
+ if (keyIdentifier == "Right") {
+ if (!m_fieldOwner)
+ return;
+ if (isRTL() ? m_fieldOwner->focusOnPreviousField(*this) : m_fieldOwner->focusOnNextField(*this))
+ keyboardEvent->setDefaultHandled();
+ return;
+ }
+
if (keyIdentifier == "Up") {
keyboardEvent->setDefaultHandled();
stepUp();
return;
}
- if (keyIdentifier == "U+0008") {
+ if (keyIdentifier == "U+0008" || keyIdentifier == "U+007F") {
keyboardEvent->setDefaultHandled();
setEmptyValue(DateComponents(), DispatchEvent);
return;
}
}
+void DateTimeFieldElement::didBlur()
+{
+ if (m_fieldOwner)
+ m_fieldOwner->didBlurFromField();
+}
+
+void DateTimeFieldElement::didFocus()
+{
+ if (m_fieldOwner)
+ m_fieldOwner->didFocusOnField();
+}
+
void DateTimeFieldElement::focusOnNextField()
{
- if (m_fieldEventHandler)
- m_fieldEventHandler->focusOnNextField();
+ if (!m_fieldOwner)
+ return;
+ m_fieldOwner->focusOnNextField(*this);
}
void DateTimeFieldElement::initialize(const AtomicString& shadowPseudoId)
@@ -99,11 +135,21 @@ void DateTimeFieldElement::initialize(const AtomicString& shadowPseudoId)
appendChild(Text::create(document(), visibleValue()));
}
+bool DateTimeFieldElement::isFocusable() const
+{
+ return !isReadOnly();
+}
+
bool DateTimeFieldElement::isReadOnly() const
{
return fastHasAttribute(readonlyAttr);
}
+bool DateTimeFieldElement::isRTL() const
+{
+ return renderer() && renderer()->style()->direction() == RTL;
+}
+
void DateTimeFieldElement::setReadOnly()
{
// Set HTML attribute readonly to change apperance.
@@ -111,6 +157,11 @@ void DateTimeFieldElement::setReadOnly()
setNeedsStyleRecalc();
}
+bool DateTimeFieldElement::supportsFocus() const
+{
+ return true;
+}
+
void DateTimeFieldElement::updateVisibleValue(EventBehavior eventBehavior)
{
Text* const textNode = toText(firstChild());
@@ -122,8 +173,8 @@ void DateTimeFieldElement::updateVisibleValue(EventBehavior eventBehavior)
textNode->replaceWholeText(newVisibleValue, ASSERT_NO_EXCEPTION);
- if (eventBehavior == DispatchEvent && m_fieldEventHandler)
- m_fieldEventHandler->fieldValueChanged();
+ if (eventBehavior == DispatchEvent && m_fieldOwner)
+ m_fieldOwner->fieldValueChanged();
}
double DateTimeFieldElement::valueAsDouble() const
diff --git a/Source/WebCore/html/shadow/DateTimeFieldElement.h b/Source/WebCore/html/shadow/DateTimeFieldElement.h
index 066b61ffa..0a9bee010 100644
--- a/Source/WebCore/html/shadow/DateTimeFieldElement.h
+++ b/Source/WebCore/html/shadow/DateTimeFieldElement.h
@@ -44,19 +44,22 @@ public:
DispatchEvent,
};
- // FieldEventHandler implementer must call removeEventHandler when
+ // FieldOwner implementer must call removeEventHandler when
// it doesn't handle event, e.g. at destruction.
- class FieldEventHandler {
+ class FieldOwner {
public:
- virtual ~FieldEventHandler();
+ virtual ~FieldOwner();
+ virtual void didBlurFromField() = 0;
+ virtual void didFocusOnField() = 0;
virtual void fieldValueChanged() = 0;
- virtual void focusOnNextField() = 0;
+ virtual bool focusOnNextField(const DateTimeFieldElement&) = 0;
+ virtual bool focusOnPreviousField(const DateTimeFieldElement&) = 0;
};
virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool hasValue() const = 0;
bool isReadOnly() const;
- void removeEventHandler() { m_fieldEventHandler = 0; }
+ void removeEventHandler() { m_fieldOwner = 0; }
void setReadOnly();
virtual void setEmptyValue(const DateComponents& dateForReadOnlyField, EventBehavior = DispatchNoEvent) = 0;
virtual void setValueAsDate(const DateComponents&) = 0;
@@ -69,7 +72,9 @@ public:
virtual String visibleValue() const = 0;
protected:
- DateTimeFieldElement(Document*, FieldEventHandler&);
+ DateTimeFieldElement(Document*, FieldOwner&);
+ virtual void didBlur();
+ virtual void didFocus();
void focusOnNextField();
virtual void handleKeyboardEvent(KeyboardEvent*) = 0;
void initialize(const AtomicString&);
@@ -78,8 +83,11 @@ protected:
private:
void defaultKeyboardEventHandler(KeyboardEvent*);
+ virtual bool isFocusable() const OVERRIDE FINAL;
+ bool isRTL() const;
+ virtual bool supportsFocus() const OVERRIDE FINAL;
- FieldEventHandler* m_fieldEventHandler;
+ FieldOwner* m_fieldOwner;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/shadow/DateTimeFieldElements.cpp b/Source/WebCore/html/shadow/DateTimeFieldElements.cpp
index 1ff7fa5c7..d8bc849fd 100644
--- a/Source/WebCore/html/shadow/DateTimeFieldElements.cpp
+++ b/Source/WebCore/html/shadow/DateTimeFieldElements.cpp
@@ -32,15 +32,15 @@
namespace WebCore {
-DateTimeAMPMFieldElement::DateTimeAMPMFieldElement(Document* document, FieldEventHandler& fieldEventHandler, const Vector<String>& ampmLabels)
- : DateTimeSymbolicFieldElement(document, fieldEventHandler, ampmLabels)
+DateTimeAMPMFieldElement::DateTimeAMPMFieldElement(Document* document, FieldOwner& fieldOwner, const Vector<String>& ampmLabels)
+ : DateTimeSymbolicFieldElement(document, fieldOwner, ampmLabels)
{
}
-PassRefPtr<DateTimeAMPMFieldElement> DateTimeAMPMFieldElement::create(Document* document, FieldEventHandler& fieldEventHandler, const Vector<String>& ampmLabels)
+PassRefPtr<DateTimeAMPMFieldElement> DateTimeAMPMFieldElement::create(Document* document, FieldOwner& fieldOwner, const Vector<String>& ampmLabels)
{
DEFINE_STATIC_LOCAL(AtomicString, ampmPsuedoId, ("-webkit-datetime-edit-ampm-field"));
- RefPtr<DateTimeAMPMFieldElement> field = adoptRef(new DateTimeAMPMFieldElement(document, fieldEventHandler, ampmLabels));
+ RefPtr<DateTimeAMPMFieldElement> field = adoptRef(new DateTimeAMPMFieldElement(document, fieldOwner, ampmLabels));
field->initialize(ampmPsuedoId);
return field.release();
}
@@ -57,17 +57,17 @@ double DateTimeAMPMFieldElement::unitInMillisecond() const
// ----------------------------
-DateTimeHourFieldElement::DateTimeHourFieldElement(Document* document, FieldEventHandler& fieldEventHandler, int minimum, int maximum)
- : DateTimeNumericFieldElement(document, fieldEventHandler, minimum, maximum)
+DateTimeHourFieldElement::DateTimeHourFieldElement(Document* document, FieldOwner& fieldOwner, int minimum, int maximum)
+ : DateTimeNumericFieldElement(document, fieldOwner, minimum, maximum)
, m_alignment(maximum + maximum % 2)
{
ASSERT((!minimum && (maximum == 11 || maximum == 23)) || (minimum == 1 && (maximum == 12 || maximum == 24)));
}
-PassRefPtr<DateTimeHourFieldElement> DateTimeHourFieldElement::create(Document* document, FieldEventHandler& fieldEventHandler, int minimum, int maximum)
+PassRefPtr<DateTimeHourFieldElement> DateTimeHourFieldElement::create(Document* document, FieldOwner& fieldOwner, int minimum, int maximum)
{
DEFINE_STATIC_LOCAL(AtomicString, hourPsuedoId, ("-webkit-datetime-edit-hour-field"));
- RefPtr<DateTimeHourFieldElement> field = adoptRef(new DateTimeHourFieldElement(document, fieldEventHandler, minimum, maximum));
+ RefPtr<DateTimeHourFieldElement> field = adoptRef(new DateTimeHourFieldElement(document, fieldOwner, minimum, maximum));
field->initialize(hourPsuedoId);
return field.release();
}
@@ -95,15 +95,15 @@ int DateTimeHourFieldElement::valueAsInteger() const
// ----------------------------
-DateTimeMillisecondFieldElement::DateTimeMillisecondFieldElement(Document* document, FieldEventHandler& fieldEventHandler)
- : DateTimeNumericFieldElement(document, fieldEventHandler, 0, 999)
+DateTimeMillisecondFieldElement::DateTimeMillisecondFieldElement(Document* document, FieldOwner& fieldOwner)
+ : DateTimeNumericFieldElement(document, fieldOwner, 0, 999)
{
}
-PassRefPtr<DateTimeMillisecondFieldElement> DateTimeMillisecondFieldElement::create(Document* document, FieldEventHandler& fieldEventHandler)
+PassRefPtr<DateTimeMillisecondFieldElement> DateTimeMillisecondFieldElement::create(Document* document, FieldOwner& fieldOwner)
{
DEFINE_STATIC_LOCAL(AtomicString, millisecondPsuedoId, ("-webkit-datetime-edit-millisecond-field"));
- RefPtr<DateTimeMillisecondFieldElement> field = adoptRef(new DateTimeMillisecondFieldElement(document, fieldEventHandler));
+ RefPtr<DateTimeMillisecondFieldElement> field = adoptRef(new DateTimeMillisecondFieldElement(document, fieldOwner));
field->initialize(millisecondPsuedoId);
return field.release();
}
@@ -120,15 +120,15 @@ double DateTimeMillisecondFieldElement::unitInMillisecond() const
// ----------------------------
-DateTimeMinuteFieldElement::DateTimeMinuteFieldElement(Document* document, FieldEventHandler& fieldEventHandler)
- : DateTimeNumericFieldElement(document, fieldEventHandler, 0, 59)
+DateTimeMinuteFieldElement::DateTimeMinuteFieldElement(Document* document, FieldOwner& fieldOwner)
+ : DateTimeNumericFieldElement(document, fieldOwner, 0, 59)
{
}
-PassRefPtr<DateTimeMinuteFieldElement> DateTimeMinuteFieldElement::create(Document* document, FieldEventHandler& fieldEventHandler)
+PassRefPtr<DateTimeMinuteFieldElement> DateTimeMinuteFieldElement::create(Document* document, FieldOwner& fieldOwner)
{
DEFINE_STATIC_LOCAL(AtomicString, minutePsuedoId, ("-webkit-datetime-edit-minute-field"));
- RefPtr<DateTimeMinuteFieldElement> field = adoptRef(new DateTimeMinuteFieldElement(document, fieldEventHandler));
+ RefPtr<DateTimeMinuteFieldElement> field = adoptRef(new DateTimeMinuteFieldElement(document, fieldOwner));
field->initialize(minutePsuedoId);
return field.release();
}
@@ -145,15 +145,15 @@ double DateTimeMinuteFieldElement::unitInMillisecond() const
// ----------------------------
-DateTimeSecondFieldElement::DateTimeSecondFieldElement(Document* document, FieldEventHandler& fieldEventHandler)
- : DateTimeNumericFieldElement(document, fieldEventHandler, 0, 59)
+DateTimeSecondFieldElement::DateTimeSecondFieldElement(Document* document, FieldOwner& fieldOwner)
+ : DateTimeNumericFieldElement(document, fieldOwner, 0, 59)
{
}
-PassRefPtr<DateTimeSecondFieldElement> DateTimeSecondFieldElement::create(Document* document, FieldEventHandler& fieldEventHandler)
+PassRefPtr<DateTimeSecondFieldElement> DateTimeSecondFieldElement::create(Document* document, FieldOwner& fieldOwner)
{
DEFINE_STATIC_LOCAL(AtomicString, secondPsuedoId, ("-webkit-datetime-edit-second-field"));
- RefPtr<DateTimeSecondFieldElement> field = adoptRef(new DateTimeSecondFieldElement(document, fieldEventHandler));
+ RefPtr<DateTimeSecondFieldElement> field = adoptRef(new DateTimeSecondFieldElement(document, fieldOwner));
field->initialize(secondPsuedoId);
return field.release();
}
diff --git a/Source/WebCore/html/shadow/DateTimeFieldElements.h b/Source/WebCore/html/shadow/DateTimeFieldElements.h
index 57bc1efa5..d7f4d9538 100644
--- a/Source/WebCore/html/shadow/DateTimeFieldElements.h
+++ b/Source/WebCore/html/shadow/DateTimeFieldElements.h
@@ -36,10 +36,10 @@ class DateTimeAMPMFieldElement : public DateTimeSymbolicFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeAMPMFieldElement);
public:
- static PassRefPtr<DateTimeAMPMFieldElement> create(Document*, FieldEventHandler&, const Vector<String>&);
+ static PassRefPtr<DateTimeAMPMFieldElement> create(Document*, FieldOwner&, const Vector<String>&);
private:
- DateTimeAMPMFieldElement(Document*, FieldEventHandler&, const Vector<String>&);
+ DateTimeAMPMFieldElement(Document*, FieldOwner&, const Vector<String>&);
// DateTimeFieldElement functions.
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
@@ -57,10 +57,10 @@ class DateTimeHourFieldElement : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeHourFieldElement);
public:
- static PassRefPtr<DateTimeHourFieldElement> create(Document*, FieldEventHandler&, int minimum, int maximum);
+ static PassRefPtr<DateTimeHourFieldElement> create(Document*, FieldOwner&, int minimum, int maximum);
private:
- DateTimeHourFieldElement(Document*, FieldEventHandler&, int minimum, int maximum);
+ DateTimeHourFieldElement(Document*, FieldOwner&, int minimum, int maximum);
// DateTimeFieldElement functions.
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
@@ -75,10 +75,10 @@ class DateTimeMillisecondFieldElement : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeMillisecondFieldElement);
public:
- static PassRefPtr<DateTimeMillisecondFieldElement> create(Document*, FieldEventHandler&);
+ static PassRefPtr<DateTimeMillisecondFieldElement> create(Document*, FieldOwner&);
private:
- DateTimeMillisecondFieldElement(Document*, FieldEventHandler&);
+ DateTimeMillisecondFieldElement(Document*, FieldOwner&);
// DateTimeFieldElement functions.
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
@@ -89,10 +89,10 @@ class DateTimeMinuteFieldElement : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeMinuteFieldElement);
public:
- static PassRefPtr<DateTimeMinuteFieldElement> create(Document*, FieldEventHandler&);
+ static PassRefPtr<DateTimeMinuteFieldElement> create(Document*, FieldOwner&);
private:
- DateTimeMinuteFieldElement(Document*, FieldEventHandler&);
+ DateTimeMinuteFieldElement(Document*, FieldOwner&);
// DateTimeFieldElement functions.
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
@@ -103,10 +103,10 @@ class DateTimeSecondFieldElement : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeSecondFieldElement);
public:
- static PassRefPtr<DateTimeSecondFieldElement> create(Document*, FieldEventHandler&);
+ static PassRefPtr<DateTimeSecondFieldElement> create(Document*, FieldOwner&);
private:
- DateTimeSecondFieldElement(Document*, FieldEventHandler&);
+ DateTimeSecondFieldElement(Document*, FieldOwner&);
// DateTimeFieldElement functions.
virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
diff --git a/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp b/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp
index d522e1579..bf80af942 100644
--- a/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp
+++ b/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp
@@ -63,8 +63,8 @@ int DateTimeNumericFieldElement::Range::clampValue(int value) const
return std::min(std::max(value, minimum), maximum);
}
-DateTimeNumericFieldElement::DateTimeNumericFieldElement(Document* document, FieldEventHandler& fieldEventHandler, int minimum, int maximum)
- : DateTimeFieldElement(document, fieldEventHandler)
+DateTimeNumericFieldElement::DateTimeNumericFieldElement(Document* document, FieldOwner& fieldOwner, int minimum, int maximum)
+ : DateTimeFieldElement(document, fieldOwner)
, m_lastDigitCharTime(0)
, m_range(minimum, maximum)
, m_value(0)
@@ -72,6 +72,12 @@ DateTimeNumericFieldElement::DateTimeNumericFieldElement(Document* document, Fie
{
}
+void DateTimeNumericFieldElement::didBlur()
+{
+ m_lastDigitCharTime = 0;
+ DateTimeFieldElement::didBlur();
+}
+
void DateTimeNumericFieldElement::handleKeyboardEvent(KeyboardEvent* keyboardEvent)
{
if (isReadOnly())
diff --git a/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h b/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h
index 7cb398250..283e60672 100644
--- a/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h
+++ b/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h
@@ -50,7 +50,7 @@ protected:
int minimum;
};
- DateTimeNumericFieldElement(Document*, FieldEventHandler&, int minimum, int maximum);
+ DateTimeNumericFieldElement(Document*, FieldOwner&, int minimum, int maximum);
int clampValue(int value) const { return m_range.clampValue(value); }
const Range& range() const { return m_range; }
@@ -63,6 +63,7 @@ protected:
private:
// DateTimeFieldElement functions.
+ virtual void didBlur() OVERRIDE FINAL;
virtual void handleKeyboardEvent(KeyboardEvent*) OVERRIDE FINAL;
virtual void setEmptyValue(const DateComponents& dateForReadOnlyField, EventBehavior) OVERRIDE FINAL;
virtual void stepDown() OVERRIDE FINAL;
diff --git a/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp b/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp
index 08eb52229..beadca974 100644
--- a/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp
+++ b/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp
@@ -27,17 +27,49 @@
#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
#include "DateTimeSymbolicFieldElement.h"
+#include "FontCache.h"
#include "KeyboardEvent.h"
+#include "RenderStyle.h"
+#include "StyleResolver.h"
+#include "TextBreakIterator.h"
+#include "TextRun.h"
+#include <wtf/text/StringBuilder.h>
#include <wtf/unicode/Unicode.h>
namespace WebCore {
-DateTimeSymbolicFieldElement::DateTimeSymbolicFieldElement(Document* document, FieldEventHandler& fieldEventHandler, const Vector<String>& symbols)
- : DateTimeFieldElement(document, fieldEventHandler)
+static AtomicString makeVisibleEmptyValue(const Vector<String>& symbols)
+{
+ unsigned maximumLength = 0;
+ for (unsigned index = 0; index < symbols.size(); ++index)
+ maximumLength = std::max(maximumLength, numGraphemeClusters(symbols[index]));
+ StringBuilder builder;
+ builder.reserveCapacity(maximumLength);
+ for (unsigned length = 0; length < maximumLength; ++length)
+ builder.append('-');
+ return builder.toAtomicString();
+}
+
+DateTimeSymbolicFieldElement::DateTimeSymbolicFieldElement(Document* document, FieldOwner& fieldOwner, const Vector<String>& symbols)
+ : DateTimeFieldElement(document, fieldOwner)
, m_symbols(symbols)
+ , m_visibleEmptyValue(makeVisibleEmptyValue(symbols))
, m_selectedIndex(-1)
{
ASSERT(!symbols.isEmpty());
+ setHasCustomCallbacks();
+}
+
+PassRefPtr<RenderStyle> DateTimeSymbolicFieldElement::customStyleForRenderer()
+{
+ FontCachePurgePreventer fontCachePurgePreventer;
+ RefPtr<RenderStyle> originalStyle = document()->styleResolver()->styleForElement(this);
+ RefPtr<RenderStyle> style = RenderStyle::clone(originalStyle.get());
+ float maxiumWidth = style->font().width(visibleEmptyValue());
+ for (unsigned index = 0; index < m_symbols.size(); ++index)
+ maxiumWidth = std::max(maxiumWidth, style->font().width(m_symbols[index]));
+ style->setWidth(Length(maxiumWidth, Fixed));
+ return style.release();
}
void DateTimeSymbolicFieldElement::handleKeyboardEvent(KeyboardEvent* keyboardEvent)
@@ -98,9 +130,14 @@ int DateTimeSymbolicFieldElement::valueAsInteger() const
return m_selectedIndex;
}
+String DateTimeSymbolicFieldElement::visibleEmptyValue() const
+{
+ return m_visibleEmptyValue;
+}
+
String DateTimeSymbolicFieldElement::visibleValue() const
{
- return hasValue() ? m_symbols[m_selectedIndex] : "--";
+ return hasValue() ? m_symbols[m_selectedIndex] : visibleEmptyValue();
}
} // namespace WebCore
diff --git a/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h b/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h
index 8329dd114..b21a8e4f3 100644
--- a/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h
+++ b/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h
@@ -37,12 +37,15 @@ class DateTimeSymbolicFieldElement : public DateTimeFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeSymbolicFieldElement);
protected:
- DateTimeSymbolicFieldElement(Document*, FieldEventHandler&, const Vector<String>&);
+ DateTimeSymbolicFieldElement(Document*, FieldOwner&, const Vector<String>&);
virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
private:
static const int invalidIndex = -1;
+ virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE FINAL;
+ String visibleEmptyValue() const;
+
// DateTimeFieldElement functions.
virtual void handleKeyboardEvent(KeyboardEvent*) OVERRIDE FINAL;
virtual bool hasValue() const OVERRIDE FINAL;
@@ -54,6 +57,10 @@ private:
virtual String visibleValue() const OVERRIDE FINAL;
const Vector<String> m_symbols;
+
+ // We use AtomicString to share visible empty value among multiple
+ // DateTimeEditElements in the page.
+ const AtomicString m_visibleEmptyValue;
int m_selectedIndex;
};
diff --git a/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp b/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp
index 62f9e8599..6b3913bb6 100644
--- a/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp
+++ b/Source/WebCore/html/shadow/MediaControlRootElementChromium.cpp
@@ -84,6 +84,7 @@ MediaControlRootElementChromium::MediaControlRootElementChromium(Document* docum
, m_timeline(0)
, m_panelMuteButton(0)
, m_volumeSlider(0)
+ , m_toggleClosedCaptionsButton(0)
, m_fullscreenButton(0)
, m_panel(0)
, m_enclosure(0)
@@ -164,6 +165,14 @@ bool MediaControlRootElementChromium::initializeControls(Document* document)
if (ec)
return false;
+ if (document->page()->theme()->supportsClosedCaptioning()) {
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document);
+ m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
+ panel->appendChild(toggleClosedCaptionsButton.release(), ec, true);
+ if (ec)
+ return false;
+ }
+
RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(document, this);
m_fullscreenButton = fullscreenButton.get();
panel->appendChild(fullscreenButton.release(), ec, true);
@@ -201,6 +210,8 @@ void MediaControlRootElementChromium::setMediaController(MediaControllerInterfac
m_panelMuteButton->setMediaController(controller);
if (m_volumeSlider)
m_volumeSlider->setMediaController(controller);
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->setMediaController(controller);
if (m_fullscreenButton)
m_fullscreenButton->setMediaController(controller);
if (m_panel)
@@ -265,6 +276,13 @@ void MediaControlRootElementChromium::reset()
}
}
+ if (m_toggleClosedCaptionsButton) {
+ if (m_mediaController->hasClosedCaptions())
+ m_toggleClosedCaptionsButton->show();
+ else
+ m_toggleClosedCaptionsButton->hide();
+ }
+
if (m_mediaController->supportsFullscreen() && m_mediaController->hasVideo())
m_fullscreenButton->show();
else
@@ -332,6 +350,8 @@ void MediaControlRootElementChromium::reportedError()
m_panelMuteButton->hide();
m_volumeSlider->hide();
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->hide();
m_fullscreenButton->hide();
}
@@ -417,6 +437,8 @@ void MediaControlRootElementChromium::stopHideFullscreenControlsTimer()
void MediaControlRootElementChromium::changedClosedCaptionsVisibility()
{
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->updateDisplayType();
}
void MediaControlRootElementChromium::changedMute()
@@ -465,6 +487,9 @@ void MediaControlRootElementChromium::createTextTrackDisplay()
RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document());
m_textDisplayContainer = textDisplayContainer.get();
+ if (m_mediaController)
+ m_textDisplayContainer->setMediaController(m_mediaController);
+
// Insert it before the first controller element so it always displays behind the controls.
insertBefore(textDisplayContainer.release(), m_enclosure, ASSERT_NO_EXCEPTION, true);
}
diff --git a/Source/WebCore/html/shadow/MediaControlRootElementChromium.h b/Source/WebCore/html/shadow/MediaControlRootElementChromium.h
index a827f1116..8c2061233 100644
--- a/Source/WebCore/html/shadow/MediaControlRootElementChromium.h
+++ b/Source/WebCore/html/shadow/MediaControlRootElementChromium.h
@@ -44,6 +44,7 @@ class MediaControlCurrentTimeDisplayElement;
class MediaControlTimeRemainingDisplayElement;
class MediaControlTimelineElement;
class MediaControlVolumeSliderElement;
+class MediaControlToggleClosedCaptionsButtonElement;
class MediaControlFullscreenButtonElement;
class MediaControlTimeDisplayElement;
class MediaControlTimelineContainerElement;
@@ -146,6 +147,7 @@ private:
MediaControlTimelineElement* m_timeline;
MediaControlPanelMuteButtonElement* m_panelMuteButton;
MediaControlVolumeSliderElement* m_volumeSlider;
+ MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
MediaControlFullscreenButtonElement* m_fullscreenButton;
MediaControlPanelElement* m_panel;
MediaControlPanelEnclosureElement* m_enclosure;
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp
index 155e3d2de..d8bbd2bbb 100644
--- a/Source/WebCore/html/shadow/SliderThumbElement.cpp
+++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp
@@ -272,13 +272,15 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point)
IntRect inputBoundingBox = input->renderer()->absoluteBoundingBoxRectIgnoringTransforms();
if (isVertical) {
trackSize = trackElement->renderBox()->contentHeight();
- position = offset.y() - renderBox()->height() / 2 - trackBoundingBox.y() + inputBoundingBox.y();
+ position = offset.y() - renderBox()->height() / 2 - trackBoundingBox.y() + inputBoundingBox.y() - renderBox()->marginBottom();
currentPosition = absoluteThumbOrigin.y() - absoluteSliderContentOrigin.y();
} else {
trackSize = trackElement->renderBox()->contentWidth();
position = offset.x() - renderBox()->width() / 2 - trackBoundingBox.x() + inputBoundingBox.x();
- if (!isLeftToRightDirection)
- position += renderBox()->width();
+ if (isLeftToRightDirection)
+ position -= renderBox()->marginLeft();
+ else
+ position += renderBox()->width() - renderBox()->marginRight();
currentPosition = absoluteThumbOrigin.x() - absoluteSliderContentOrigin.x();
}
position = max<LayoutUnit>(0, min(position, trackSize));
diff --git a/Source/WebCore/html/shadow/TextControlInnerElements.cpp b/Source/WebCore/html/shadow/TextControlInnerElements.cpp
index 116b67869..fdc25355d 100644
--- a/Source/WebCore/html/shadow/TextControlInnerElements.cpp
+++ b/Source/WebCore/html/shadow/TextControlInnerElements.cpp
@@ -425,7 +425,7 @@ void InputFieldSpeechButtonElement::startSpeechInput()
RefPtr<HTMLInputElement> input = static_cast<HTMLInputElement*>(shadowHost());
AtomicString language = input->computeInheritedLanguage();
String grammar = input->getAttribute(webkitgrammarAttr);
- IntRect rect = document()->view()->contentsToRootView(getPixelSnappedRect());
+ IntRect rect = document()->view()->contentsToRootView(pixelSnappedBoundingBox());
if (speechInput()->startRecognition(m_listenerId, rect, language, grammar, document()->securityOrigin()))
setState(Recording);
}