summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/TextControlInnerElements.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/TextControlInnerElements.cpp')
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp97
1 files changed, 90 insertions, 7 deletions
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index 36e30af..24e1d74 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -36,8 +36,10 @@
#include "HTMLNames.h"
#include "HTMLTextAreaElement.h"
#include "MouseEvent.h"
+#include "Page.h"
#include "RenderLayer.h"
#include "RenderTextControlSingleLine.h"
+#include "SpeechInput.h"
namespace WebCore {
@@ -246,7 +248,7 @@ void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
inline SpinButtonElement::SpinButtonElement(Node* shadowParent)
: TextControlInnerElement(shadowParent->document(), shadowParent)
, m_capturing(false)
- , m_onUpButton(false)
+ , m_upDownState(Indeterminate)
{
}
@@ -278,12 +280,19 @@ void SpinButtonElement::defaultEventHandler(Event* event)
}
HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ if (input->disabled() || input->isReadOnlyFormControl()) {
+ if (!event->defaultHandled())
+ HTMLDivElement::defaultEventHandler(event);
+ return;
+ }
+
IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
if (event->type() == eventNames().clickEvent) {
if (box->borderBoxRect().contains(local)) {
+ RefPtr<Node> protector(input);
input->focus();
input->select();
- if (local.y() < box->y() + box->height() / 2)
+ if (local.y() < box->height() / 2)
input->stepUpFromRenderer(1);
else
input->stepUpFromRenderer(-1);
@@ -297,9 +306,9 @@ void SpinButtonElement::defaultEventHandler(Event* event)
m_capturing = true;
}
}
- bool oldOnUpButton = m_onUpButton;
- m_onUpButton = local.y() < box->y() + box->height() / 2;
- if (m_onUpButton != oldOnUpButton)
+ UpDownState oldUpDownState = m_upDownState;
+ m_upDownState = local.y() < box->height() / 2 ? Up : Down;
+ if (m_upDownState != oldUpDownState)
renderer()->repaint();
} else {
if (m_capturing) {
@@ -315,12 +324,21 @@ void SpinButtonElement::defaultEventHandler(Event* event)
HTMLDivElement::defaultEventHandler(event);
}
+void SpinButtonElement::setHovered(bool flag)
+{
+ if (!hovered() && flag)
+ m_upDownState = Indeterminate;
+ TextControlInnerElement::setHovered(flag);
+}
+
+
// ----------------------------
#if ENABLE(INPUT_SPEECH)
inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(Document* document)
: TextControlInnerElement(document)
+ , m_capturing(false)
{
}
@@ -331,8 +349,73 @@ PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(
void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
{
- // FIXME: Start speech recognition here.
- HTMLDivElement::defaultEventHandler(event);
+ // On mouse down, select the text and set focus.
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+ if (renderer() && renderer()->visibleToHitTesting()) {
+ if (Frame* frame = document()->frame()) {
+ frame->eventHandler()->setCapturingMouseEventsNode(this);
+ m_capturing = true;
+ }
+ }
+ // The call to focus() below dispatches a focus event, and an event handler in the page might
+ // remove the input element from DOM. To make sure it remains valid until we finish our work
+ // here, we take a temporary reference.
+ RefPtr<HTMLInputElement> holdRef(input);
+ input->focus();
+ input->select();
+ event->setDefaultHandled();
+ }
+ // On mouse up, start speech recognition.
+ if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+ if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
+ if (Frame* frame = document()->frame()) {
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ m_capturing = false;
+ }
+ if (hovered()) {
+ speechInput()->startRecognition();
+ event->setDefaultHandled();
+ }
+ }
+ }
+
+ if (!event->defaultHandled())
+ HTMLDivElement::defaultEventHandler(event);
+}
+
+SpeechInput* InputFieldSpeechButtonElement::speechInput()
+{
+ if (!m_speechInput)
+ m_speechInput.set(new SpeechInput(document()->page()->speechInputClient(), this));
+ return m_speechInput.get();
+}
+
+void InputFieldSpeechButtonElement::recordingComplete()
+{
+ // FIXME: Add UI feedback here to indicate that audio recording stopped and recognition is
+ // in progress.
+}
+
+void InputFieldSpeechButtonElement::setRecognitionResult(const String& result)
+{
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ // The call to setValue() below dispatches an event, and an event handler in the page might
+ // remove the input element from DOM. To make sure it remains valid until we finish our work
+ // here, we take a temporary reference.
+ RefPtr<HTMLInputElement> holdRef(input);
+ input->setValue(result);
+ input->dispatchFormControlChangeEvent();
+ renderer()->repaint();
+}
+
+void InputFieldSpeechButtonElement::detach()
+{
+ if (m_capturing) {
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ }
+ TextControlInnerElement::detach();
}
#endif // ENABLE(INPUT_SPEECH)