Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1149)

Side by Side Diff: third_party/WebKit/Source/core/editing/InputMethodController.cpp

Issue 2417643002: Move text input mode/info/type into InputMethodController (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "core/editing/InputMethodController.h" 27 #include "core/editing/InputMethodController.h"
28 28
29 #include "core/InputTypeNames.h"
29 #include "core/dom/Document.h" 30 #include "core/dom/Document.h"
30 #include "core/dom/Element.h" 31 #include "core/dom/Element.h"
31 #include "core/dom/Text.h" 32 #include "core/dom/Text.h"
32 #include "core/editing/EditingUtilities.h" 33 #include "core/editing/EditingUtilities.h"
33 #include "core/editing/Editor.h" 34 #include "core/editing/Editor.h"
34 #include "core/editing/commands/TypingCommand.h" 35 #include "core/editing/commands/TypingCommand.h"
35 #include "core/editing/markers/DocumentMarkerController.h" 36 #include "core/editing/markers/DocumentMarkerController.h"
36 #include "core/events/CompositionEvent.h" 37 #include "core/events/CompositionEvent.h"
37 #include "core/frame/LocalFrame.h" 38 #include "core/frame/LocalFrame.h"
39 #include "core/html/HTMLInputElement.h"
38 #include "core/html/HTMLTextAreaElement.h" 40 #include "core/html/HTMLTextAreaElement.h"
39 #include "core/input/EventHandler.h" 41 #include "core/input/EventHandler.h"
40 #include "core/layout/LayoutObject.h" 42 #include "core/layout/LayoutObject.h"
41 #include "core/layout/LayoutTheme.h" 43 #include "core/layout/LayoutTheme.h"
42 #include "core/page/ChromeClient.h" 44 #include "core/page/ChromeClient.h"
43 45
44 namespace blink { 46 namespace blink {
45 47
46 namespace { 48 namespace {
47 49
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 } while (frame().selection().start() == frame().selection().end() && 863 } while (frame().selection().start() == frame().selection().end() &&
862 before <= static_cast<int>(selectionOffsets.start())); 864 before <= static_cast<int>(selectionOffsets.start()));
863 // TODO(chongz): Find a way to distinguish Forward and Backward. 865 // TODO(chongz): Find a way to distinguish Forward and Backward.
864 dispatchBeforeInputEditorCommand( 866 dispatchBeforeInputEditorCommand(
865 m_frame->document()->focusedElement(), 867 m_frame->document()->focusedElement(),
866 InputEvent::InputType::DeleteContentBackward, 868 InputEvent::InputType::DeleteContentBackward,
867 new RangeVector(1, m_frame->selection().firstRange())); 869 new RangeVector(1, m_frame->selection().firstRange()));
868 TypingCommand::deleteSelection(*frame().document()); 870 TypingCommand::deleteSelection(*frame().document());
869 } 871 }
870 872
873 WebTextInputInfo InputMethodController::textInputInfo() const {
874 WebTextInputInfo info;
875 if (!frame().document())
876 return info;
877
878 if (!frame().selection().isAvailable()) {
879 // plugins/mouse-capture-inside-shadow.html reaches here.
880 return info;
881 }
882 Element* element = frame().selection().rootEditableElement();
883 if (!element)
884 return info;
885
886 info.inputMode = inputModeOfFocusedElement();
887 info.type = textInputType();
888 info.flags = textInputFlags();
889 if (info.type == WebTextInputTypeNone)
890 return info;
891
892 if (!frame().editor().canEdit())
893 return info;
894
895 // TODO(dglazkov): The use of updateStyleAndLayoutIgnorePendingStylesheets
896 // needs to be audited. see http://crbug.com/590369 for more details.
897 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
898
899 DocumentLifecycle::DisallowTransitionScope disallowTransition(
900 frame().document()->lifecycle());
901
902 // Emits an object replacement character for each replaced element so that
903 // it is exposed to IME and thus could be deleted by IME on android.
904 info.value = plainText(EphemeralRange::rangeOfContents(*element),
905 TextIteratorEmitsObjectReplacementCharacter);
906
907 if (info.value.isEmpty())
908 return info;
909
910 EphemeralRange firstRange =
911 firstEphemeralRangeOf(frame().selection().selection());
912 if (firstRange.isNotNull()) {
913 PlainTextRange plainTextRange(PlainTextRange::create(*element, firstRange));
914 if (plainTextRange.isNotNull()) {
915 info.selectionStart = plainTextRange.start();
916 info.selectionEnd = plainTextRange.end();
917 }
918 }
919
920 EphemeralRange range = compositionEphemeralRange();
921 if (range.isNotNull()) {
922 PlainTextRange plainTextRange(PlainTextRange::create(*element, range));
923 if (plainTextRange.isNotNull()) {
924 info.compositionStart = plainTextRange.start();
925 info.compositionEnd = plainTextRange.end();
926 }
927 }
928
929 return info;
930 }
931
932 int InputMethodController::textInputFlags() const {
933 Element* element = frame().document()->focusedElement();
934 if (!element)
935 return WebTextInputFlagNone;
936
937 DEFINE_STATIC_LOCAL(AtomicString, autocompleteString, ("autocomplete"));
938 DEFINE_STATIC_LOCAL(AtomicString, autocorrectString, ("autocorrect"));
939 int flags = 0;
940
941 const AtomicString& autocomplete = element->getAttribute(autocompleteString);
942 if (autocomplete == "on")
943 flags |= WebTextInputFlagAutocompleteOn;
944 else if (autocomplete == "off")
945 flags |= WebTextInputFlagAutocompleteOff;
946
947 const AtomicString& autocorrect = element->getAttribute(autocorrectString);
948 if (autocorrect == "on")
949 flags |= WebTextInputFlagAutocorrectOn;
950 else if (autocorrect == "off")
951 flags |= WebTextInputFlagAutocorrectOff;
952
953 SpellcheckAttributeState spellcheck = element->spellcheckAttributeState();
954 if (spellcheck == SpellcheckAttributeTrue)
955 flags |= WebTextInputFlagSpellcheckOn;
956 else if (spellcheck == SpellcheckAttributeFalse)
957 flags |= WebTextInputFlagSpellcheckOff;
958
959 if (isHTMLTextFormControlElement(element)) {
960 HTMLTextFormControlElement* formElement =
961 static_cast<HTMLTextFormControlElement*>(element);
962 if (formElement->supportsAutocapitalize()) {
963 DEFINE_STATIC_LOCAL(const AtomicString, none, ("none"));
964 DEFINE_STATIC_LOCAL(const AtomicString, characters, ("characters"));
965 DEFINE_STATIC_LOCAL(const AtomicString, words, ("words"));
966 DEFINE_STATIC_LOCAL(const AtomicString, sentences, ("sentences"));
967
968 const AtomicString& autocapitalize = formElement->autocapitalize();
969 if (autocapitalize == none)
970 flags |= WebTextInputFlagAutocapitalizeNone;
971 else if (autocapitalize == characters)
972 flags |= WebTextInputFlagAutocapitalizeCharacters;
973 else if (autocapitalize == words)
974 flags |= WebTextInputFlagAutocapitalizeWords;
975 else if (autocapitalize == sentences)
976 flags |= WebTextInputFlagAutocapitalizeSentences;
977 else
978 NOTREACHED();
979 }
980 }
981
982 return flags;
983 }
984
985 WebString InputMethodController::inputModeOfFocusedElement() const {
986 if (!RuntimeEnabledFeatures::inputModeAttributeEnabled())
987 return WebString();
988
989 Element* element = frame().document()->focusedElement();
990 if (!element)
991 return WebString();
992
993 if (isHTMLInputElement(*element)) {
994 const HTMLInputElement& input = toHTMLInputElement(*element);
995 if (input.supportsInputModeAttribute())
996 return input.fastGetAttribute(HTMLNames::inputmodeAttr).lower();
997 return WebString();
998 }
999 if (isHTMLTextAreaElement(*element)) {
1000 const HTMLTextAreaElement& textarea = toHTMLTextAreaElement(*element);
1001 return textarea.fastGetAttribute(HTMLNames::inputmodeAttr).lower();
1002 }
1003
1004 return WebString();
1005 }
1006
1007 WebTextInputType InputMethodController::textInputType() const {
1008 if (!frame().selection().isAvailable()) {
1009 // "mouse-capture-inside-shadow.html" reaches here.
1010 return WebTextInputTypeNone;
1011 }
1012
1013 // It's important to preserve the equivalence of textInputInfo().type and
1014 // textInputType(), so perform the same rootEditableElement() existence check
1015 // here for consistency.
1016 if (!frame().selection().selection().rootEditableElement())
1017 return WebTextInputTypeNone;
1018
1019 Document* document = frame().document();
1020 if (!document)
1021 return WebTextInputTypeNone;
1022
1023 Element* element = document->focusedElement();
1024 if (!element)
1025 return WebTextInputTypeNone;
1026
1027 if (isHTMLInputElement(*element)) {
1028 HTMLInputElement& input = toHTMLInputElement(*element);
1029 const AtomicString& type = input.type();
1030
1031 if (input.isDisabledOrReadOnly())
1032 return WebTextInputTypeNone;
1033
1034 if (type == InputTypeNames::password)
1035 return WebTextInputTypePassword;
1036 if (type == InputTypeNames::search)
1037 return WebTextInputTypeSearch;
1038 if (type == InputTypeNames::email)
1039 return WebTextInputTypeEmail;
1040 if (type == InputTypeNames::number)
1041 return WebTextInputTypeNumber;
1042 if (type == InputTypeNames::tel)
1043 return WebTextInputTypeTelephone;
1044 if (type == InputTypeNames::url)
1045 return WebTextInputTypeURL;
1046 if (type == InputTypeNames::text)
1047 return WebTextInputTypeText;
1048
1049 return WebTextInputTypeNone;
1050 }
1051
1052 if (isHTMLTextAreaElement(*element)) {
1053 if (toHTMLTextAreaElement(*element).isDisabledOrReadOnly())
1054 return WebTextInputTypeNone;
1055 return WebTextInputTypeTextArea;
1056 }
1057
1058 if (element->isHTMLElement()) {
1059 if (toHTMLElement(element)->isDateTimeFieldElement())
1060 return WebTextInputTypeDateTimeField;
1061 }
1062
1063 document->updateStyleAndLayoutTree();
1064 if (hasEditableStyle(*element))
1065 return WebTextInputTypeContentEditable;
1066
1067 return WebTextInputTypeNone;
1068 }
1069
871 DEFINE_TRACE(InputMethodController) { 1070 DEFINE_TRACE(InputMethodController) {
872 visitor->trace(m_frame); 1071 visitor->trace(m_frame);
873 visitor->trace(m_compositionRange); 1072 visitor->trace(m_compositionRange);
874 } 1073 }
875 1074
876 } // namespace blink 1075 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698