diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp | 277 |
1 files changed, 27 insertions, 250 deletions
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp index a19fef2c9e9..57c9fc665a6 100644 --- a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp +++ b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp @@ -27,21 +27,18 @@ #include "config.h" #include "core/html/shadow/TextControlInnerElements.h" -#include "HTMLNames.h" +#include "core/HTMLNames.h" #include "core/dom/Document.h" #include "core/dom/NodeRenderStyle.h" #include "core/events/MouseEvent.h" #include "core/events/TextEvent.h" #include "core/events/TextEventInputType.h" -#include "core/events/ThreadLocalEventNames.h" +#include "core/frame/LocalFrame.h" #include "core/html/HTMLInputElement.h" #include "core/html/shadow/ShadowElementNames.h" #include "core/page/EventHandler.h" -#include "core/frame/Frame.h" #include "core/rendering/RenderTextControlSingleLine.h" #include "core/rendering/RenderView.h" -#include "core/speech/SpeechInput.h" -#include "core/speech/SpeechInputEvent.h" #include "platform/UserGestureIndicator.h" namespace WebCore { @@ -53,9 +50,9 @@ TextControlInnerContainer::TextControlInnerContainer(Document& document) { } -PassRefPtr<TextControlInnerContainer> TextControlInnerContainer::create(Document& document) +PassRefPtrWillBeRawPtr<TextControlInnerContainer> TextControlInnerContainer::create(Document& document) { - RefPtr<TextControlInnerContainer> element = adoptRef(new TextControlInnerContainer(document)); + RefPtrWillBeRawPtr<TextControlInnerContainer> element = adoptRefWillBeNoop(new TextControlInnerContainer(document)); element->setAttribute(idAttr, ShadowElementNames::textFieldContainer()); return element.release(); } @@ -73,9 +70,9 @@ EditingViewPortElement::EditingViewPortElement(Document& document) setHasCustomStyleCallbacks(); } -PassRefPtr<EditingViewPortElement> EditingViewPortElement::create(Document& document) +PassRefPtrWillBeRawPtr<EditingViewPortElement> EditingViewPortElement::create(Document& document) { - RefPtr<EditingViewPortElement> element = adoptRef(new EditingViewPortElement(document)); + RefPtrWillBeRawPtr<EditingViewPortElement> element = adoptRefWillBeNoop(new EditingViewPortElement(document)); element->setAttribute(idAttr, ShadowElementNames::editingViewPort()); return element.release(); } @@ -88,9 +85,6 @@ PassRefPtr<RenderStyle> EditingViewPortElement::customStyleForRenderer() style->inheritFrom(shadowHost()->renderStyle()); style->setFlexGrow(1); - // min-width: 0; is needed for correct shrinking. - // FIXME: Remove this line when https://bugs.webkit.org/show_bug.cgi?id=111790 is fixed. - style->setMinWidth(Length(0, Fixed)); style->setDisplay(BLOCK); style->setDirection(LTR); @@ -104,20 +98,20 @@ PassRefPtr<RenderStyle> EditingViewPortElement::customStyleForRenderer() // --------------------------- -inline TextControlInnerTextElement::TextControlInnerTextElement(Document& document) +inline TextControlInnerEditorElement::TextControlInnerEditorElement(Document& document) : HTMLDivElement(document) { setHasCustomStyleCallbacks(); } -PassRefPtr<TextControlInnerTextElement> TextControlInnerTextElement::create(Document& document) +PassRefPtrWillBeRawPtr<TextControlInnerEditorElement> TextControlInnerEditorElement::create(Document& document) { - RefPtr<TextControlInnerTextElement> element = adoptRef(new TextControlInnerTextElement(document)); + RefPtrWillBeRawPtr<TextControlInnerEditorElement> element = adoptRefWillBeNoop(new TextControlInnerEditorElement(document)); element->setAttribute(idAttr, ShadowElementNames::innerEditor()); return element.release(); } -void TextControlInnerTextElement::defaultEventHandler(Event* event) +void TextControlInnerEditorElement::defaultEventHandler(Event* event) { // FIXME: In the future, we should add a way to have default event listeners. // Then we would add one to the text field's inner div, and we wouldn't need this subclass. @@ -136,18 +130,18 @@ void TextControlInnerTextElement::defaultEventHandler(Event* event) HTMLDivElement::defaultEventHandler(event); } -RenderObject* TextControlInnerTextElement::createRenderer(RenderStyle*) +RenderObject* TextControlInnerEditorElement::createRenderer(RenderStyle*) { return new RenderTextControlInnerBlock(this); } -PassRefPtr<RenderStyle> TextControlInnerTextElement::customStyleForRenderer() +PassRefPtr<RenderStyle> TextControlInnerEditorElement::customStyleForRenderer() { RenderObject* parentRenderer = shadowHost()->renderer(); if (!parentRenderer || !parentRenderer->isTextControl()) return originalStyleForRenderer(); RenderTextControl* textControlRenderer = toRenderTextControl(parentRenderer); - return textControlRenderer->createInnerTextStyle(textControlRenderer->style()); + return textControlRenderer->createInnerEditorStyle(textControlRenderer->style()); } // ---------------------------- @@ -157,21 +151,21 @@ inline SearchFieldDecorationElement::SearchFieldDecorationElement(Document& docu { } -PassRefPtr<SearchFieldDecorationElement> SearchFieldDecorationElement::create(Document& document) +PassRefPtrWillBeRawPtr<SearchFieldDecorationElement> SearchFieldDecorationElement::create(Document& document) { - RefPtr<SearchFieldDecorationElement> element = adoptRef(new SearchFieldDecorationElement(document)); + RefPtrWillBeRawPtr<SearchFieldDecorationElement> element = adoptRefWillBeNoop(new SearchFieldDecorationElement(document)); element->setAttribute(idAttr, ShadowElementNames::searchDecoration()); return element.release(); } -const AtomicString& SearchFieldDecorationElement::pseudo() const +const AtomicString& SearchFieldDecorationElement::shadowPseudoId() const { DEFINE_STATIC_LOCAL(AtomicString, resultsDecorationId, ("-webkit-search-results-decoration", AtomicString::ConstructFromLiteral)); DEFINE_STATIC_LOCAL(AtomicString, decorationId, ("-webkit-search-decoration", AtomicString::ConstructFromLiteral)); Element* host = shadowHost(); if (!host) return resultsDecorationId; - if (host->hasTagName(inputTag)) { + if (isHTMLInputElement(*host)) { if (toHTMLInputElement(host)->maxResults() < 0) return decorationId; return resultsDecorationId; @@ -206,10 +200,10 @@ inline SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(Document& { } -PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document& document) +PassRefPtrWillBeRawPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document& document) { - RefPtr<SearchFieldCancelButtonElement> element = adoptRef(new SearchFieldCancelButtonElement(document)); - element->setPseudo(AtomicString("-webkit-search-cancel-button", AtomicString::ConstructFromLiteral)); + RefPtrWillBeRawPtr<SearchFieldCancelButtonElement> element = adoptRefWillBeNoop(new SearchFieldCancelButtonElement(document)); + element->setShadowPseudoId(AtomicString("-webkit-search-cancel-button", AtomicString::ConstructFromLiteral)); element->setAttribute(idAttr, ShadowElementNames::clearButton()); return element.release(); } @@ -217,8 +211,8 @@ PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::creat void SearchFieldCancelButtonElement::detach(const AttachContext& context) { if (m_capturing) { - if (Frame* frame = document().frame()) - frame->eventHandler().setCapturingMouseEventsNode(0); + if (LocalFrame* frame = document().frame()) + frame->eventHandler().setCapturingMouseEventsNode(nullptr); } HTMLDivElement::detach(context); } @@ -227,136 +221,17 @@ void SearchFieldCancelButtonElement::detach(const AttachContext& context) void SearchFieldCancelButtonElement::defaultEventHandler(Event* event) { // If the element is visible, on mouseup, clear the value, and set selection - RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost())); + RefPtrWillBeRawPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost())); if (!input || input->isDisabledOrReadOnly()) { if (!event->defaultHandled()) HTMLDivElement::defaultEventHandler(event); return; } - if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) { - if (renderer() && renderer()->visibleToHitTesting()) { - if (Frame* frame = document().frame()) { - frame->eventHandler().setCapturingMouseEventsNode(this); - m_capturing = true; - } - } - input->focus(); - input->select(); - event->setDefaultHandled(); - } - if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) { - if (m_capturing) { - if (Frame* frame = document().frame()) { - frame->eventHandler().setCapturingMouseEventsNode(0); - m_capturing = false; - } - if (hovered()) { - String oldValue = input->value(); - input->setValueForUser(""); - input->onSearch(); - event->setDefaultHandled(); - } - } - } - - if (!event->defaultHandled()) - HTMLDivElement::defaultEventHandler(event); -} - -bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents() -{ - const HTMLInputElement* input = toHTMLInputElement(shadowHost()); - if (input && !input->isDisabledOrReadOnly()) - return true; - - return HTMLDivElement::willRespondToMouseClickEvents(); -} - -// ---------------------------- - -#if ENABLE(INPUT_SPEECH) - -inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(Document& document) - : HTMLDivElement(document) - , m_capturing(false) - , m_state(Idle) - , m_listenerId(0) -{ -} - -InputFieldSpeechButtonElement::~InputFieldSpeechButtonElement() -{ - SpeechInput* speech = speechInput(); - if (speech && m_listenerId) { // Could be null when page is unloading. - if (m_state != Idle) - speech->cancelRecognition(m_listenerId); - speech->unregisterListener(m_listenerId); - } -} - -PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(Document& document) -{ - RefPtr<InputFieldSpeechButtonElement> element = adoptRef(new InputFieldSpeechButtonElement(document)); - element->setPseudo(AtomicString("-webkit-input-speech-button", AtomicString::ConstructFromLiteral)); - element->setAttribute(idAttr, ShadowElementNames::speechButton()); - return element.release(); -} - -void InputFieldSpeechButtonElement::defaultEventHandler(Event* event) -{ - // For privacy reasons, only allow clicks directly coming from the user. - if (!UserGestureIndicator::processingUserGesture()) { - HTMLDivElement::defaultEventHandler(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(toHTMLInputElement(shadowHost())); - - if (!input || input->isDisabledOrReadOnly()) { - if (!event->defaultHandled()) - HTMLDivElement::defaultEventHandler(event); - return; - } - // On mouse down, select the text and set focus. - if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) { - if (renderer() && renderer()->visibleToHitTesting()) { - if (Frame* frame = document().frame()) { - frame->eventHandler().setCapturingMouseEventsNode(this); - m_capturing = true; - } - } - RefPtr<InputFieldSpeechButtonElement> holdRefButton(this); - input->focus(); - input->select(); - event->setDefaultHandled(); - } - // On mouse up, release capture cleanly. - if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) { - if (m_capturing && renderer() && renderer()->visibleToHitTesting()) { - if (Frame* frame = document().frame()) { - frame->eventHandler().setCapturingMouseEventsNode(0); - m_capturing = false; - } - } - } - - if (event->type() == EventTypeNames::click && m_listenerId) { - switch (m_state) { - case Idle: - startSpeechInput(); - break; - case Recording: - stopSpeechInput(); - break; - case Recognizing: - // Nothing to do here, we will continue to wait for results. - break; - } + if (event->type() == EventTypeNames::click && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) { + input->setValueForUser(""); + input->onSearch(); event->setDefaultHandled(); } @@ -364,7 +239,7 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event) HTMLDivElement::defaultEventHandler(event); } -bool InputFieldSpeechButtonElement::willRespondToMouseClickEvents() +bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents() { const HTMLInputElement* input = toHTMLInputElement(shadowHost()); if (input && !input->isDisabledOrReadOnly()) @@ -373,102 +248,4 @@ bool InputFieldSpeechButtonElement::willRespondToMouseClickEvents() return HTMLDivElement::willRespondToMouseClickEvents(); } -void InputFieldSpeechButtonElement::setState(SpeechInputState state) -{ - if (m_state != state) { - m_state = state; - shadowHost()->renderer()->repaint(); - } -} - -SpeechInput* InputFieldSpeechButtonElement::speechInput() -{ - return SpeechInput::from(document().page()); -} - -void InputFieldSpeechButtonElement::didCompleteRecording(int) -{ - setState(Recognizing); -} - -void InputFieldSpeechButtonElement::didCompleteRecognition(int) -{ - setState(Idle); -} - -void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputResultArray& results) -{ - m_results = results; - - // 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> input(toHTMLInputElement(shadowHost())); - if (!input || input->isDisabledOrReadOnly()) - return; - - RefPtr<InputFieldSpeechButtonElement> holdRefButton(this); - if (document().domWindow()) { - // Call selectionChanged, causing the element to cache the selection, - // so that the text event inserts the text in this element even if - // focus has moved away from it. - input->selectionChanged(false); - input->dispatchEvent(TextEvent::create(document().domWindow(), results.isEmpty() ? "" : results[0]->utterance(), TextEventInputOther)); - } - - // This event is sent after the text event so the website can perform actions using the input field content immediately. - // It provides alternative recognition hypotheses and notifies that the results come from speech input. - input->dispatchEvent(SpeechInputEvent::create(EventTypeNames::webkitspeechchange, results)); - - // Check before accessing the renderer as the above event could have potentially turned off - // speech in the input element, hence removing this button and renderer from the hierarchy. - if (renderer()) - renderer()->repaint(); -} - -void InputFieldSpeechButtonElement::attach(const AttachContext& context) -{ - ASSERT(!m_listenerId); - if (SpeechInput* input = SpeechInput::from(document().page())) - m_listenerId = input->registerListener(this); - HTMLDivElement::attach(context); -} - -void InputFieldSpeechButtonElement::detach(const AttachContext& context) -{ - if (m_capturing) { - if (Frame* frame = document().frame()) - frame->eventHandler().setCapturingMouseEventsNode(0); - } - - if (m_listenerId) { - if (m_state != Idle) - speechInput()->cancelRecognition(m_listenerId); - speechInput()->unregisterListener(m_listenerId); - m_listenerId = 0; - } - - HTMLDivElement::detach(context); -} - -void InputFieldSpeechButtonElement::startSpeechInput() -{ - if (m_state != Idle) - return; - - RefPtr<HTMLInputElement> input = toHTMLInputElement(shadowHost()); - AtomicString language = input->computeInheritedLanguage(); - String grammar = input->getAttribute(webkitgrammarAttr); - IntRect rect = document().view()->contentsToRootView(pixelSnappedBoundingBox()); - if (speechInput()->startRecognition(m_listenerId, rect, language, grammar, document().securityOrigin())) - setState(Recording); -} - -void InputFieldSpeechButtonElement::stopSpeechInput() -{ - if (m_state == Recording) - speechInput()->stopRecording(m_listenerId); -} -#endif // ENABLE(INPUT_SPEECH) - } |