| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "web/WebViewImpl.h" | 31 #include "web/WebViewImpl.h" |
| 32 | 32 |
| 33 #include "core/CSSValueKeywords.h" | 33 #include "core/CSSValueKeywords.h" |
| 34 #include "core/HTMLNames.h" | 34 #include "core/HTMLNames.h" |
| 35 #include "core/InputTypeNames.h" | |
| 36 #include "core/clipboard/DataObject.h" | 35 #include "core/clipboard/DataObject.h" |
| 37 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
| 38 #include "core/dom/Fullscreen.h" | 37 #include "core/dom/Fullscreen.h" |
| 39 #include "core/dom/LayoutTreeBuilderTraversal.h" | 38 #include "core/dom/LayoutTreeBuilderTraversal.h" |
| 40 #include "core/dom/Text.h" | 39 #include "core/dom/Text.h" |
| 41 #include "core/editing/EditingUtilities.h" | 40 #include "core/editing/EditingUtilities.h" |
| 42 #include "core/editing/Editor.h" | 41 #include "core/editing/Editor.h" |
| 43 #include "core/editing/FrameSelection.h" | 42 #include "core/editing/FrameSelection.h" |
| 44 #include "core/editing/InputMethodController.h" | 43 #include "core/editing/InputMethodController.h" |
| 45 #include "core/editing/iterators/TextIterator.h" | 44 #include "core/editing/iterators/TextIterator.h" |
| 46 #include "core/editing/markers/DocumentMarkerController.h" | 45 #include "core/editing/markers/DocumentMarkerController.h" |
| 47 #include "core/editing/serializers/HTMLInterchange.h" | 46 #include "core/editing/serializers/HTMLInterchange.h" |
| 48 #include "core/editing/serializers/Serialization.h" | 47 #include "core/editing/serializers/Serialization.h" |
| 49 #include "core/events/KeyboardEvent.h" | 48 #include "core/events/KeyboardEvent.h" |
| 50 #include "core/events/UIEventWithKeyState.h" | 49 #include "core/events/UIEventWithKeyState.h" |
| 51 #include "core/events/WheelEvent.h" | 50 #include "core/events/WheelEvent.h" |
| 52 #include "core/fetch/UniqueIdentifier.h" | 51 #include "core/fetch/UniqueIdentifier.h" |
| 53 #include "core/frame/EventHandlerRegistry.h" | 52 #include "core/frame/EventHandlerRegistry.h" |
| 54 #include "core/frame/FrameHost.h" | 53 #include "core/frame/FrameHost.h" |
| 55 #include "core/frame/FrameView.h" | 54 #include "core/frame/FrameView.h" |
| 56 #include "core/frame/LocalFrame.h" | 55 #include "core/frame/LocalFrame.h" |
| 57 #include "core/frame/PageScaleConstraintsSet.h" | 56 #include "core/frame/PageScaleConstraintsSet.h" |
| 58 #include "core/frame/RemoteFrame.h" | 57 #include "core/frame/RemoteFrame.h" |
| 59 #include "core/frame/Settings.h" | 58 #include "core/frame/Settings.h" |
| 60 #include "core/frame/SmartClip.h" | 59 #include "core/frame/SmartClip.h" |
| 61 #include "core/frame/TopControls.h" | 60 #include "core/frame/TopControls.h" |
| 62 #include "core/frame/UseCounter.h" | 61 #include "core/frame/UseCounter.h" |
| 63 #include "core/frame/VisualViewport.h" | 62 #include "core/frame/VisualViewport.h" |
| 64 #include "core/html/HTMLInputElement.h" | |
| 65 #include "core/html/HTMLMediaElement.h" | 63 #include "core/html/HTMLMediaElement.h" |
| 66 #include "core/html/HTMLPlugInElement.h" | 64 #include "core/html/HTMLPlugInElement.h" |
| 67 #include "core/html/HTMLTextAreaElement.h" | 65 #include "core/html/HTMLTextAreaElement.h" |
| 68 #include "core/input/EventHandler.h" | 66 #include "core/input/EventHandler.h" |
| 69 #include "core/input/TouchActionUtil.h" | 67 #include "core/input/TouchActionUtil.h" |
| 70 #include "core/layout/LayoutPart.h" | 68 #include "core/layout/LayoutPart.h" |
| 71 #include "core/layout/TextAutosizer.h" | 69 #include "core/layout/TextAutosizer.h" |
| 72 #include "core/layout/api/LayoutViewItem.h" | 70 #include "core/layout/api/LayoutViewItem.h" |
| 73 #include "core/layout/compositing/PaintLayerCompositor.h" | 71 #include "core/layout/compositing/PaintLayerCompositor.h" |
| 74 #include "core/loader/FrameLoadRequest.h" | 72 #include "core/loader/FrameLoadRequest.h" |
| (...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2534 focused->selection().rootEditableElementOrDocumentElement(); | 2532 focused->selection().rootEditableElementOrDocumentElement(); |
| 2535 DCHECK(editable); | 2533 DCHECK(editable); |
| 2536 | 2534 |
| 2537 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 2535 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
| 2538 // needs to be audited. See http://crbug.com/590369 for more details. | 2536 // needs to be audited. See http://crbug.com/590369 for more details. |
| 2539 editable->document().updateStyleAndLayoutIgnorePendingStylesheets(); | 2537 editable->document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 2540 | 2538 |
| 2541 return PlainTextRange::create(*editable, range); | 2539 return PlainTextRange::create(*editable, range); |
| 2542 } | 2540 } |
| 2543 | 2541 |
| 2544 // TODO(ekaramad):This method is almost duplicated in WebFrameWidgetImpl as | |
| 2545 // well. This code needs to be refactored (http://crbug.com/629721). | |
| 2546 WebTextInputInfo WebViewImpl::textInputInfo() { | 2542 WebTextInputInfo WebViewImpl::textInputInfo() { |
| 2547 WebTextInputInfo info; | |
| 2548 | |
| 2549 LocalFrame* focused = focusedLocalFrameInWidget(); | 2543 LocalFrame* focused = focusedLocalFrameInWidget(); |
| 2550 if (!focused) | 2544 if (!focused) |
| 2551 return info; | 2545 return WebTextInputInfo(); |
| 2546 return focused->inputMethodController().textInputInfo(); |
| 2547 } |
| 2552 | 2548 |
| 2553 FrameSelection& selection = focused->selection(); | 2549 WebTextInputType WebViewImpl::textInputType() { |
| 2554 if (!selection.isAvailable()) { | 2550 LocalFrame* focused = focusedLocalFrameInWidget(); |
| 2555 // plugins/mouse-capture-inside-shadow.html reaches here. | 2551 if (!focused) |
| 2556 return info; | 2552 return WebTextInputTypeNone; |
| 2557 } | 2553 return focused->inputMethodController().textInputType(); |
| 2558 Element* element = selection.selection().rootEditableElement(); | |
| 2559 if (!element) | |
| 2560 return info; | |
| 2561 | |
| 2562 info.inputMode = inputModeOfFocusedElement(); | |
| 2563 | |
| 2564 info.type = textInputType(); | |
| 2565 info.flags = textInputFlags(); | |
| 2566 if (info.type == WebTextInputTypeNone) | |
| 2567 return info; | |
| 2568 | |
| 2569 if (!focused->editor().canEdit()) | |
| 2570 return info; | |
| 2571 | |
| 2572 // TODO(dglazkov): The use of updateStyleAndLayoutIgnorePendingStylesheets | |
| 2573 // needs to be audited. see http://crbug.com/590369 for more details. | |
| 2574 focused->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 2575 | |
| 2576 DocumentLifecycle::DisallowTransitionScope disallowTransition( | |
| 2577 focused->document()->lifecycle()); | |
| 2578 | |
| 2579 // Emits an object replacement character for each replaced element so that | |
| 2580 // it is exposed to IME and thus could be deleted by IME on android. | |
| 2581 info.value = plainText(EphemeralRange::rangeOfContents(*element), | |
| 2582 TextIteratorEmitsObjectReplacementCharacter); | |
| 2583 | |
| 2584 if (info.value.isEmpty()) | |
| 2585 return info; | |
| 2586 | |
| 2587 EphemeralRange firstRange = firstEphemeralRangeOf(selection.selection()); | |
| 2588 if (firstRange.isNotNull()) { | |
| 2589 PlainTextRange plainTextRange(PlainTextRange::create(*element, firstRange)); | |
| 2590 if (plainTextRange.isNotNull()) { | |
| 2591 info.selectionStart = plainTextRange.start(); | |
| 2592 info.selectionEnd = plainTextRange.end(); | |
| 2593 } | |
| 2594 } | |
| 2595 | |
| 2596 EphemeralRange range = | |
| 2597 focused->inputMethodController().compositionEphemeralRange(); | |
| 2598 if (range.isNotNull()) { | |
| 2599 PlainTextRange plainTextRange(PlainTextRange::create(*element, range)); | |
| 2600 if (plainTextRange.isNotNull()) { | |
| 2601 info.compositionStart = plainTextRange.start(); | |
| 2602 info.compositionEnd = plainTextRange.end(); | |
| 2603 } | |
| 2604 } | |
| 2605 | |
| 2606 return info; | |
| 2607 } | 2554 } |
| 2608 | 2555 |
| 2609 // TODO(ekaramad):This method is almost duplicated in WebFrameWidgetImpl as | 2556 // TODO(ekaramad):This method is almost duplicated in WebFrameWidgetImpl as |
| 2610 // well. This code needs to be refactored (http://crbug.com/629721). | |
| 2611 WebTextInputType WebViewImpl::textInputType() { | |
| 2612 LocalFrame* focusedFrame = focusedLocalFrameInWidget(); | |
| 2613 if (!focusedFrame) | |
| 2614 return WebTextInputTypeNone; | |
| 2615 | |
| 2616 if (!focusedFrame->selection().isAvailable()) { | |
| 2617 // "mouse-capture-inside-shadow.html" reaches here. | |
| 2618 return WebTextInputTypeNone; | |
| 2619 } | |
| 2620 | |
| 2621 // It's important to preserve the equivalence of textInputInfo().type and | |
| 2622 // textInputType(), so perform the same rootEditableElement() existence check | |
| 2623 // here for consistency. | |
| 2624 if (!focusedFrame->selection().selection().rootEditableElement()) | |
| 2625 return WebTextInputTypeNone; | |
| 2626 | |
| 2627 Document* document = focusedFrame->document(); | |
| 2628 if (!document) | |
| 2629 return WebTextInputTypeNone; | |
| 2630 | |
| 2631 Element* element = document->focusedElement(); | |
| 2632 if (!element) | |
| 2633 return WebTextInputTypeNone; | |
| 2634 | |
| 2635 if (isHTMLInputElement(*element)) { | |
| 2636 HTMLInputElement& input = toHTMLInputElement(*element); | |
| 2637 const AtomicString& type = input.type(); | |
| 2638 | |
| 2639 if (input.isDisabledOrReadOnly()) | |
| 2640 return WebTextInputTypeNone; | |
| 2641 | |
| 2642 if (type == InputTypeNames::password) | |
| 2643 return WebTextInputTypePassword; | |
| 2644 if (type == InputTypeNames::search) | |
| 2645 return WebTextInputTypeSearch; | |
| 2646 if (type == InputTypeNames::email) | |
| 2647 return WebTextInputTypeEmail; | |
| 2648 if (type == InputTypeNames::number) | |
| 2649 return WebTextInputTypeNumber; | |
| 2650 if (type == InputTypeNames::tel) | |
| 2651 return WebTextInputTypeTelephone; | |
| 2652 if (type == InputTypeNames::url) | |
| 2653 return WebTextInputTypeURL; | |
| 2654 if (type == InputTypeNames::text) | |
| 2655 return WebTextInputTypeText; | |
| 2656 | |
| 2657 return WebTextInputTypeNone; | |
| 2658 } | |
| 2659 | |
| 2660 if (isHTMLTextAreaElement(*element)) { | |
| 2661 if (toHTMLTextAreaElement(*element).isDisabledOrReadOnly()) | |
| 2662 return WebTextInputTypeNone; | |
| 2663 return WebTextInputTypeTextArea; | |
| 2664 } | |
| 2665 | |
| 2666 if (element->isHTMLElement()) { | |
| 2667 if (toHTMLElement(element)->isDateTimeFieldElement()) | |
| 2668 return WebTextInputTypeDateTimeField; | |
| 2669 } | |
| 2670 | |
| 2671 document->updateStyleAndLayoutTree(); | |
| 2672 if (hasEditableStyle(*element)) | |
| 2673 return WebTextInputTypeContentEditable; | |
| 2674 | |
| 2675 return WebTextInputTypeNone; | |
| 2676 } | |
| 2677 | |
| 2678 // TODO(ekaramad):This method is almost duplicated in WebFrameWidgetImpl as | |
| 2679 // well. This code needs to be refactored (http://crbug.com/629721). | |
| 2680 int WebViewImpl::textInputFlags() { | |
| 2681 Element* element = focusedElement(); | |
| 2682 if (!element) | |
| 2683 return WebTextInputFlagNone; | |
| 2684 | |
| 2685 DEFINE_STATIC_LOCAL(AtomicString, autocompleteString, ("autocomplete")); | |
| 2686 DEFINE_STATIC_LOCAL(AtomicString, autocorrectString, ("autocorrect")); | |
| 2687 int flags = 0; | |
| 2688 | |
| 2689 const AtomicString& autocomplete = element->getAttribute(autocompleteString); | |
| 2690 if (autocomplete == "on") | |
| 2691 flags |= WebTextInputFlagAutocompleteOn; | |
| 2692 else if (autocomplete == "off") | |
| 2693 flags |= WebTextInputFlagAutocompleteOff; | |
| 2694 | |
| 2695 const AtomicString& autocorrect = element->getAttribute(autocorrectString); | |
| 2696 if (autocorrect == "on") | |
| 2697 flags |= WebTextInputFlagAutocorrectOn; | |
| 2698 else if (autocorrect == "off") | |
| 2699 flags |= WebTextInputFlagAutocorrectOff; | |
| 2700 | |
| 2701 SpellcheckAttributeState spellcheck = element->spellcheckAttributeState(); | |
| 2702 if (spellcheck == SpellcheckAttributeTrue) | |
| 2703 flags |= WebTextInputFlagSpellcheckOn; | |
| 2704 else if (spellcheck == SpellcheckAttributeFalse) | |
| 2705 flags |= WebTextInputFlagSpellcheckOff; | |
| 2706 | |
| 2707 if (isHTMLTextFormControlElement(element)) { | |
| 2708 HTMLTextFormControlElement* formElement = | |
| 2709 static_cast<HTMLTextFormControlElement*>(element); | |
| 2710 if (formElement->supportsAutocapitalize()) { | |
| 2711 DEFINE_STATIC_LOCAL(const AtomicString, none, ("none")); | |
| 2712 DEFINE_STATIC_LOCAL(const AtomicString, characters, ("characters")); | |
| 2713 DEFINE_STATIC_LOCAL(const AtomicString, words, ("words")); | |
| 2714 DEFINE_STATIC_LOCAL(const AtomicString, sentences, ("sentences")); | |
| 2715 | |
| 2716 const AtomicString& autocapitalize = formElement->autocapitalize(); | |
| 2717 if (autocapitalize == none) | |
| 2718 flags |= WebTextInputFlagAutocapitalizeNone; | |
| 2719 else if (autocapitalize == characters) | |
| 2720 flags |= WebTextInputFlagAutocapitalizeCharacters; | |
| 2721 else if (autocapitalize == words) | |
| 2722 flags |= WebTextInputFlagAutocapitalizeWords; | |
| 2723 else if (autocapitalize == sentences) | |
| 2724 flags |= WebTextInputFlagAutocapitalizeSentences; | |
| 2725 else | |
| 2726 NOTREACHED(); | |
| 2727 } | |
| 2728 } | |
| 2729 | |
| 2730 return flags; | |
| 2731 } | |
| 2732 | |
| 2733 WebString WebViewImpl::inputModeOfFocusedElement() { | |
| 2734 if (!RuntimeEnabledFeatures::inputModeAttributeEnabled()) | |
| 2735 return WebString(); | |
| 2736 | |
| 2737 Element* element = focusedElement(); | |
| 2738 if (!element) | |
| 2739 return WebString(); | |
| 2740 | |
| 2741 if (isHTMLInputElement(*element)) { | |
| 2742 const HTMLInputElement& input = toHTMLInputElement(*element); | |
| 2743 if (input.supportsInputModeAttribute()) | |
| 2744 return input.fastGetAttribute(HTMLNames::inputmodeAttr).lower(); | |
| 2745 return WebString(); | |
| 2746 } | |
| 2747 if (isHTMLTextAreaElement(*element)) { | |
| 2748 const HTMLTextAreaElement& textarea = toHTMLTextAreaElement(*element); | |
| 2749 return textarea.fastGetAttribute(HTMLNames::inputmodeAttr).lower(); | |
| 2750 } | |
| 2751 | |
| 2752 return WebString(); | |
| 2753 } | |
| 2754 | |
| 2755 // TODO(ekaramad):This method is almost duplicated in WebFrameWidgetImpl as | |
| 2756 // well. This code needs to be refactored (http://crbug.com/629721). | 2557 // well. This code needs to be refactored (http://crbug.com/629721). |
| 2757 bool WebViewImpl::selectionBounds(WebRect& anchor, WebRect& focus) const { | 2558 bool WebViewImpl::selectionBounds(WebRect& anchor, WebRect& focus) const { |
| 2758 const Frame* frame = focusedCoreFrame(); | 2559 const Frame* frame = focusedCoreFrame(); |
| 2759 if (!frame || !frame->isLocalFrame()) | 2560 if (!frame || !frame->isLocalFrame()) |
| 2760 return false; | 2561 return false; |
| 2761 | 2562 |
| 2762 const LocalFrame* localFrame = toLocalFrame(frame); | 2563 const LocalFrame* localFrame = toLocalFrame(frame); |
| 2763 if (!localFrame) | 2564 if (!localFrame) |
| 2764 return false; | 2565 return false; |
| 2765 FrameSelection& selection = localFrame->selection(); | 2566 FrameSelection& selection = localFrame->selection(); |
| (...skipping 1981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4747 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) | 4548 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) |
| 4748 return nullptr; | 4549 return nullptr; |
| 4749 return focusedFrame; | 4550 return focusedFrame; |
| 4750 } | 4551 } |
| 4751 | 4552 |
| 4752 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { | 4553 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { |
| 4753 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; | 4554 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; |
| 4754 } | 4555 } |
| 4755 | 4556 |
| 4756 } // namespace blink | 4557 } // namespace blink |
| OLD | NEW |