summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering/TextControlInnerElements.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/TextControlInnerElements.cpp')
-rw-r--r--Source/WebCore/rendering/TextControlInnerElements.cpp45
1 files changed, 30 insertions, 15 deletions
diff --git a/Source/WebCore/rendering/TextControlInnerElements.cpp b/Source/WebCore/rendering/TextControlInnerElements.cpp
index 7b1b36f..1162999 100644
--- a/Source/WebCore/rendering/TextControlInnerElements.cpp
+++ b/Source/WebCore/rendering/TextControlInnerElements.cpp
@@ -77,7 +77,6 @@ VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& po
TextControlInnerElement::TextControlInnerElement(Document* document, HTMLElement* shadowParent)
: HTMLDivElement(divTag, document)
- , m_shadowParent(shadowParent)
{
setShadowHost(shadowParent);
}
@@ -220,7 +219,7 @@ void SearchFieldCancelButtonElement::detach()
void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
{
// If the element is visible, on mouseup, clear the value, and set selection
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ RefPtr<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()) {
@@ -233,13 +232,12 @@ void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
event->setDefaultHandled();
}
if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
- if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
+ if (m_capturing) {
if (Frame* frame = document()->frame()) {
frame->eventHandler()->setCapturingMouseEventsNode(0);
m_capturing = false;
}
if (hovered()) {
- RefPtr<HTMLInputElement> protector(input);
String oldValue = input->value();
input->setValue("");
if (!oldValue.isEmpty()) {
@@ -272,6 +270,18 @@ PassRefPtr<SpinButtonElement> SpinButtonElement::create(HTMLElement* shadowParen
return adoptRef(new SpinButtonElement(shadowParent));
}
+void SpinButtonElement::detach()
+{
+ stopRepeatingTimer();
+ if (m_capturing) {
+ if (Frame* frame = document()->frame()) {
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ m_capturing = false;
+ }
+ }
+ TextControlInnerElement::detach();
+}
+
void SpinButtonElement::defaultEventHandler(Event* event)
{
if (!event->isMouseEvent()) {
@@ -287,7 +297,7 @@ void SpinButtonElement::defaultEventHandler(Event* event)
return;
}
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
if (input->disabled() || input->isReadOnlyFormControl()) {
if (!event->defaultHandled())
HTMLDivElement::defaultEventHandler(event);
@@ -298,12 +308,18 @@ void SpinButtonElement::defaultEventHandler(Event* event)
IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
if (mouseEvent->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
if (box->borderBoxRect().contains(local)) {
- RefPtr<Node> protector(input);
+ // The following functions of HTMLInputElement may run JavaScript
+ // code which detaches this shadow node. We need to take a reference
+ // and check renderer() after such function calls.
+ RefPtr<Node> protector(this);
input->focus();
input->select();
- input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
+ if (renderer()) {
+ input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
+ if (renderer())
+ startRepeatingTimer();
+ }
event->setDefaultHandled();
- startRepeatingTimer();
}
} else if (mouseEvent->type() == eventNames().mouseupEvent && mouseEvent->button() == LeftButton)
stopRepeatingTimer();
@@ -404,8 +420,12 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
return;
}
+ // 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> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
+
// 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()) {
@@ -413,10 +433,6 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
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);
RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
input->focus();
input->select();
@@ -483,11 +499,10 @@ void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputR
{
m_results = results;
- 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);
+ RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
input->setValue(results.isEmpty() ? "" : results[0]->utterance());
input->dispatchEvent(SpeechInputEvent::create(eventNames().webkitspeechchangeEvent, results));