From 284837daa07b29d6a63a748544a90b1f5842ac5c Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 10 Sep 2012 19:10:20 +0200 Subject: Imported WebKit commit 68645295d2e3e09af2c942f092556f06aa5f8b0d (http://svn.webkit.org/repository/webkit/trunk@128073) New snapshot --- .../WebCore/html/shadow/CalendarPickerElement.cpp | 113 +++-------- Source/WebCore/html/shadow/CalendarPickerElement.h | 19 +- Source/WebCore/html/shadow/ContentDistributor.cpp | 6 +- Source/WebCore/html/shadow/ContentDistributor.h | 3 +- Source/WebCore/html/shadow/DateTimeEditElement.cpp | 219 ++++++++------------- Source/WebCore/html/shadow/DateTimeEditElement.h | 25 +-- .../WebCore/html/shadow/DateTimeFieldElement.cpp | 67 ++++++- Source/WebCore/html/shadow/DateTimeFieldElement.h | 22 ++- .../WebCore/html/shadow/DateTimeFieldElements.cpp | 40 ++-- Source/WebCore/html/shadow/DateTimeFieldElements.h | 20 +- .../html/shadow/DateTimeNumericFieldElement.cpp | 10 +- .../html/shadow/DateTimeNumericFieldElement.h | 3 +- .../html/shadow/DateTimeSymbolicFieldElement.cpp | 43 +++- .../html/shadow/DateTimeSymbolicFieldElement.h | 9 +- .../shadow/MediaControlRootElementChromium.cpp | 25 +++ .../html/shadow/MediaControlRootElementChromium.h | 2 + Source/WebCore/html/shadow/SliderThumbElement.cpp | 8 +- .../html/shadow/TextControlInnerElements.cpp | 2 +- 18 files changed, 340 insertions(+), 296 deletions(-) (limited to 'Source/WebCore/html/shadow') 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 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::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("
Loading...
\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 namespace WebCore { class HTMLInputElement; class PagePopup; -class CalendarPickerElement : public HTMLDivElement, public PagePopupClient { +class CalendarPickerElement : public HTMLDivElement, public DateTimeChooserClient { public: static PassRefPtr 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 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 field) appendChild(field); } +void DateTimeEditElement::blurByOwner() +{ + if (DateTimeFieldElement* field = focusedField()) + field->blur(); +} + PassRefPtr DateTimeEditElement::create(Document* document, EditControlOwner& editControlOwner) { RefPtr 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(event)); - } else if (event->isKeyboardEvent()) - handleKeyboardEvent(static_cast(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); + 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 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(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& ampmLabels) - : DateTimeSymbolicFieldElement(document, fieldEventHandler, ampmLabels) +DateTimeAMPMFieldElement::DateTimeAMPMFieldElement(Document* document, FieldOwner& fieldOwner, const Vector& ampmLabels) + : DateTimeSymbolicFieldElement(document, fieldOwner, ampmLabels) { } -PassRefPtr DateTimeAMPMFieldElement::create(Document* document, FieldEventHandler& fieldEventHandler, const Vector& ampmLabels) +PassRefPtr DateTimeAMPMFieldElement::create(Document* document, FieldOwner& fieldOwner, const Vector& ampmLabels) { DEFINE_STATIC_LOCAL(AtomicString, ampmPsuedoId, ("-webkit-datetime-edit-ampm-field")); - RefPtr field = adoptRef(new DateTimeAMPMFieldElement(document, fieldEventHandler, ampmLabels)); + RefPtr 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::create(Document* document, FieldEventHandler& fieldEventHandler, int minimum, int maximum) +PassRefPtr DateTimeHourFieldElement::create(Document* document, FieldOwner& fieldOwner, int minimum, int maximum) { DEFINE_STATIC_LOCAL(AtomicString, hourPsuedoId, ("-webkit-datetime-edit-hour-field")); - RefPtr field = adoptRef(new DateTimeHourFieldElement(document, fieldEventHandler, minimum, maximum)); + RefPtr 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::create(Document* document, FieldEventHandler& fieldEventHandler) +PassRefPtr DateTimeMillisecondFieldElement::create(Document* document, FieldOwner& fieldOwner) { DEFINE_STATIC_LOCAL(AtomicString, millisecondPsuedoId, ("-webkit-datetime-edit-millisecond-field")); - RefPtr field = adoptRef(new DateTimeMillisecondFieldElement(document, fieldEventHandler)); + RefPtr 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::create(Document* document, FieldEventHandler& fieldEventHandler) +PassRefPtr DateTimeMinuteFieldElement::create(Document* document, FieldOwner& fieldOwner) { DEFINE_STATIC_LOCAL(AtomicString, minutePsuedoId, ("-webkit-datetime-edit-minute-field")); - RefPtr field = adoptRef(new DateTimeMinuteFieldElement(document, fieldEventHandler)); + RefPtr 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::create(Document* document, FieldEventHandler& fieldEventHandler) +PassRefPtr DateTimeSecondFieldElement::create(Document* document, FieldOwner& fieldOwner) { DEFINE_STATIC_LOCAL(AtomicString, secondPsuedoId, ("-webkit-datetime-edit-second-field")); - RefPtr field = adoptRef(new DateTimeSecondFieldElement(document, fieldEventHandler)); + RefPtr 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 create(Document*, FieldEventHandler&, const Vector&); + static PassRefPtr create(Document*, FieldOwner&, const Vector&); private: - DateTimeAMPMFieldElement(Document*, FieldEventHandler&, const Vector&); + DateTimeAMPMFieldElement(Document*, FieldOwner&, const Vector&); // DateTimeFieldElement functions. virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL; @@ -57,10 +57,10 @@ class DateTimeHourFieldElement : public DateTimeNumericFieldElement { WTF_MAKE_NONCOPYABLE(DateTimeHourFieldElement); public: - static PassRefPtr create(Document*, FieldEventHandler&, int minimum, int maximum); + static PassRefPtr 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 create(Document*, FieldEventHandler&); + static PassRefPtr 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 create(Document*, FieldEventHandler&); + static PassRefPtr 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 create(Document*, FieldEventHandler&); + static PassRefPtr 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 #include namespace WebCore { -DateTimeSymbolicFieldElement::DateTimeSymbolicFieldElement(Document* document, FieldEventHandler& fieldEventHandler, const Vector& symbols) - : DateTimeFieldElement(document, fieldEventHandler) +static AtomicString makeVisibleEmptyValue(const Vector& 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& symbols) + : DateTimeFieldElement(document, fieldOwner) , m_symbols(symbols) + , m_visibleEmptyValue(makeVisibleEmptyValue(symbols)) , m_selectedIndex(-1) { ASSERT(!symbols.isEmpty()); + setHasCustomCallbacks(); +} + +PassRefPtr DateTimeSymbolicFieldElement::customStyleForRenderer() +{ + FontCachePurgePreventer fontCachePurgePreventer; + RefPtr originalStyle = document()->styleResolver()->styleForElement(this); + RefPtr 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&); + DateTimeSymbolicFieldElement(Document*, FieldOwner&, const Vector&); virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL; private: static const int invalidIndex = -1; + virtual PassRefPtr 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 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 toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document); + m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get(); + panel->appendChild(toggleClosedCaptionsButton.release(), ec, true); + if (ec) + return false; + } + RefPtr 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 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(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 input = static_cast(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); } -- cgit v1.2.1