Title: [208593] trunk
Revision
208593
Author
[email protected]
Date
2016-11-11 10:38:01 -0800 (Fri, 11 Nov 2016)

Log Message

Composition state should be cleared when changing focus to a non-editable element
https://bugs.webkit.org/show_bug.cgi?id=164595
<rdar://problem/26412551>

Reviewed by Enrica Casucci.

Source/WebCore:

When canceling or confirming a composition, always ensure that the composition node and composition underlines
being tracked are reset, even when there is no current selection. This prevents us from getting into a bad state
where focus has already changed from an element with a pending composition to a different element and the
composition is canceled, but the Editor still maintains its composition node.

Test: editing/input/focus-change-with-marked-text.html

* editing/Editor.cpp:
(WebCore::Editor::setComposition):

Tools:

Adds support for window.textInputController in DumpRenderTree on iOS. So far, only the methods needed for the
new layout test (editing/focus-change-with-marked-text.html) are supported. These are insertText, setMarkedText,
and markedRange.

* DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
* DumpRenderTree/TextInputController.h: Renamed from Tools/DumpRenderTree/mac/TextInputController.h.

Remove the PLATFORM(MAC) guard for defining the TextInputController. Also, move the TextInputController header
out of the /mac platform directory.

* DumpRenderTree/ios/TextInputControllerIOS.m: Added.
(+[TextInputController isSelectorExcludedFromWebScript:]):
(+[TextInputController webScriptNameForSelector:]):
(-[TextInputController initWithWebView:]):
(-[TextInputController markedRange]):
(-[TextInputController insertText:]):
(-[TextInputController setMarkedText:selectedFrom:length:]):

Introduces TextInputControllerIOS.m, which contains an iOS implementation of TextInputController. Only a subset
of the methods available on the Mac version will be available on iOS for now (see above).

* DumpRenderTree/mac/FrameLoadDelegate.mm:

Remove the PLATFORM(MAC) guard for initializing the TextInputController and binding it to the window object.

(-[FrameLoadDelegate didClearWindowObjectInStandardWorldForFrame:]):
* DumpRenderTree/mac/TextInputControllerMac.m: Renamed from Tools/DumpRenderTree/mac/TextInputController.m.
(-[WebHTMLView interpretKeyEvents:]):
(-[WebNSRange initWithNSRange:]):
(-[WebNSRange location]):
(-[WebNSRange length]):
(+[WebNSRange isSelectorExcludedFromWebScript:]):
(+[NSMutableAttributedString isSelectorExcludedFromWebScript:]):
(+[NSMutableAttributedString webScriptNameForSelector:]):
(-[NSMutableAttributedString getLength]):
(-[NSMutableAttributedString ranges]):
(-[NSMutableAttributedString attributeNamesAtIndex:]):
(-[NSMutableAttributedString valueOfAttribute:atIndex:]):
(-[NSMutableAttributedString addAttribute:value:]):
(-[NSMutableAttributedString addAttribute:value:from:length:]):
(-[NSMutableAttributedString addColorAttribute:red:green:blue:alpha:]):
(-[NSMutableAttributedString addColorAttribute:red:green:blue:alpha:from:length:]):
(-[NSMutableAttributedString addFontAttribute:fontName:size:]):
(-[NSMutableAttributedString addFontAttribute:fontName:size:from:length:]):
(+[TextInputController isSelectorExcludedFromWebScript:]):
(+[TextInputController webScriptNameForSelector:]):
(-[TextInputController initWithWebView:]):
(-[TextInputController dealloc]):
(-[TextInputController textInput]):
(-[TextInputController insertText:]):
(-[TextInputController doCommand:]):
(-[TextInputController setMarkedText:selectedFrom:length:]):
(-[TextInputController unmarkText]):
(-[TextInputController hasMarkedText]):
(-[TextInputController conversationIdentifier]):
(-[TextInputController substringFrom:length:]):
(-[TextInputController attributedSubstringFrom:length:]):
(-[TextInputController legacyAttributedString:]):
(-[TextInputController markedRange]):
(-[TextInputController selectedRange]):
(-[TextInputController firstRectForCharactersFrom:length:]):
(-[TextInputController characterIndexForPointX:Y:]):
(-[TextInputController validAttributesForMarkedText]):
(-[TextInputController attributedStringWithString:]):
(-[TextInputController stringWithUndoGroupingInsertion:]):
(-[TextInputController dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:]):
(-[TextInputController setInputMethodHandler:]):
(-[TextInputController interpretKeyEvents:withSender:]):

Fixes miscellaneous style issues.

LayoutTests:

Adds a new layout test to ensure that when changing focus from an element with pending composition text to
another element, the composition is committed and there should not still be a pending composition.

* editing/input/focus-change-with-marked-text-expected.txt: Added.
* editing/input/focus-change-with-marked-text.html: Added.
* platform/ios-simulator-wk2/TestExpectations:
* platform/mac/TestExpectations:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (208592 => 208593)


--- trunk/LayoutTests/ChangeLog	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/LayoutTests/ChangeLog	2016-11-11 18:38:01 UTC (rev 208593)
@@ -1,3 +1,19 @@
+2016-11-11  Wenson Hsieh  <[email protected]>
+
+        Composition state should be cleared when changing focus to a non-editable element
+        https://bugs.webkit.org/show_bug.cgi?id=164595
+        <rdar://problem/26412551>
+
+        Reviewed by Enrica Casucci.
+
+        Adds a new layout test to ensure that when changing focus from an element with pending composition text to
+        another element, the composition is committed and there should not still be a pending composition.
+
+        * editing/input/focus-change-with-marked-text-expected.txt: Added.
+        * editing/input/focus-change-with-marked-text.html: Added.
+        * platform/ios-simulator-wk2/TestExpectations:
+        * platform/mac/TestExpectations:
+
 2016-11-11  Manuel Rego Casasnovas  <[email protected]>
 
         [css-grid] ASSERTION FAILED: !m_gridIsDirty in WebCore::RenderGrid::gridRowCount

Added: trunk/LayoutTests/editing/input/focus-change-with-marked-text-expected.txt (0 => 208593)


--- trunk/LayoutTests/editing/input/focus-change-with-marked-text-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/input/focus-change-with-marked-text-expected.txt	2016-11-11 18:38:01 UTC (rev 208593)
@@ -0,0 +1,4 @@
+  
+The text field's value is: "abc"
+Is there marked text? false
+

Added: trunk/LayoutTests/editing/input/focus-change-with-marked-text.html (0 => 208593)


--- trunk/LayoutTests/editing/input/focus-change-with-marked-text.html	                        (rev 0)
+++ trunk/LayoutTests/editing/input/focus-change-with-marked-text.html	2016-11-11 18:38:01 UTC (rev 208593)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<body>
+    <input id="input" contenteditable></input>
+    <select id="select"><option></option></select>
+    <div id="output"></div>
+    <script type="text/_javascript_">
+        let write = s => output.innerHTML += `${s}<br>`;
+        input.focus();
+
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            textInputController.setMarkedText("a", 1, 0);
+            textInputController.setMarkedText("ab", 2, 0);
+            textInputController.setMarkedText("abc", 3, 0);
+            select.focus();
+            textInputController.insertText(null);
+            write(`The text field's value is: "${input.value}"`);
+            write(`Is there marked text? ${!!textInputController.markedRange()}`);
+        } else {
+            write(`To manually test, insert some marked text in the left text field without committing it, then focus
+                the right select menu. The composition text should be committed, and the composition should no longer
+                be highlighted.`);
+        }
+    </script>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations (208592 => 208593)


--- trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations	2016-11-11 18:38:01 UTC (rev 208593)
@@ -937,6 +937,7 @@
 editing/execCommand/toggle-unlink-mac.html [ Failure ]
 editing/execCommand/unlink.html [ Failure ]
 editing/input/editable-container-with-word-wrap-normal.html [ Failure ]
+editing/input/focus-change-with-marked-text.html [ Failure ]
 editing/input/option-page-up-down.html [ Failure ]
 editing/input/password-echo-passnode.html [ Failure ]
 editing/input/password-echo-passnode2.html [ Failure ]

Modified: trunk/LayoutTests/platform/mac/TestExpectations (208592 => 208593)


--- trunk/LayoutTests/platform/mac/TestExpectations	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2016-11-11 18:38:01 UTC (rev 208593)
@@ -426,6 +426,9 @@
 
 # --- Editing ---
 
+# The codepath for canceling marked text differs on Mac
+editing/input/focus-change-with-marked-text.html [ Failure ]
+
 # Mac does not have global selections.
 editing/pasteboard/paste-global-selection.html
 

Modified: trunk/Source/WebCore/ChangeLog (208592 => 208593)


--- trunk/Source/WebCore/ChangeLog	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/Source/WebCore/ChangeLog	2016-11-11 18:38:01 UTC (rev 208593)
@@ -1,3 +1,21 @@
+2016-11-11  Wenson Hsieh  <[email protected]>
+
+        Composition state should be cleared when changing focus to a non-editable element
+        https://bugs.webkit.org/show_bug.cgi?id=164595
+        <rdar://problem/26412551>
+
+        Reviewed by Enrica Casucci.
+
+        When canceling or confirming a composition, always ensure that the composition node and composition underlines
+        being tracked are reset, even when there is no current selection. This prevents us from getting into a bad state
+        where focus has already changed from an element with a pending composition to a different element and the
+        composition is canceled, but the Editor still maintains its composition node.
+
+        Test: editing/input/focus-change-with-marked-text.html
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::setComposition):
+
 2016-11-11  Dave Hyatt  <[email protected]>
 
         [CSS Parser] Support -webkit-svg-shadow

Modified: trunk/Source/WebCore/editing/Editor.cpp (208592 => 208593)


--- trunk/Source/WebCore/editing/Editor.cpp	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/Source/WebCore/editing/Editor.cpp	2016-11-11 18:38:01 UTC (rev 208593)
@@ -1676,6 +1676,9 @@
     else
         selectComposition();
 
+    m_compositionNode = nullptr;
+    m_customCompositionUnderlines.clear();
+
     if (m_frame.selection().isNone()) {
         setIgnoreCompositionSelectionChange(false);
         return;
@@ -1687,9 +1690,6 @@
     if (mode != CancelComposition)
         TypingCommand::deleteSelection(document(), 0, TypingCommand::TextCompositionPending);
 
-    m_compositionNode = nullptr;
-    m_customCompositionUnderlines.clear();
-
     insertTextForConfirmedComposition(text);
 
     if (auto* target = document().focusedElement())

Modified: trunk/Tools/ChangeLog (208592 => 208593)


--- trunk/Tools/ChangeLog	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/Tools/ChangeLog	2016-11-11 18:38:01 UTC (rev 208593)
@@ -1,3 +1,82 @@
+2016-11-11  Wenson Hsieh  <[email protected]>
+
+        Composition state should be cleared when changing focus to a non-editable element
+        https://bugs.webkit.org/show_bug.cgi?id=164595
+        <rdar://problem/26412551>
+
+        Reviewed by Enrica Casucci.
+
+        Adds support for window.textInputController in DumpRenderTree on iOS. So far, only the methods needed for the
+        new layout test (editing/focus-change-with-marked-text.html) are supported. These are insertText, setMarkedText,
+        and markedRange.
+
+        * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+        * DumpRenderTree/TextInputController.h: Renamed from Tools/DumpRenderTree/mac/TextInputController.h.
+
+        Remove the PLATFORM(MAC) guard for defining the TextInputController. Also, move the TextInputController header
+        out of the /mac platform directory.
+
+        * DumpRenderTree/ios/TextInputControllerIOS.m: Added.
+        (+[TextInputController isSelectorExcludedFromWebScript:]):
+        (+[TextInputController webScriptNameForSelector:]):
+        (-[TextInputController initWithWebView:]):
+        (-[TextInputController markedRange]):
+        (-[TextInputController insertText:]):
+        (-[TextInputController setMarkedText:selectedFrom:length:]):
+
+        Introduces TextInputControllerIOS.m, which contains an iOS implementation of TextInputController. Only a subset
+        of the methods available on the Mac version will be available on iOS for now (see above).
+
+        * DumpRenderTree/mac/FrameLoadDelegate.mm:
+
+        Remove the PLATFORM(MAC) guard for initializing the TextInputController and binding it to the window object.
+
+        (-[FrameLoadDelegate didClearWindowObjectInStandardWorldForFrame:]):
+        * DumpRenderTree/mac/TextInputControllerMac.m: Renamed from Tools/DumpRenderTree/mac/TextInputController.m.
+        (-[WebHTMLView interpretKeyEvents:]):
+        (-[WebNSRange initWithNSRange:]):
+        (-[WebNSRange location]):
+        (-[WebNSRange length]):
+        (+[WebNSRange isSelectorExcludedFromWebScript:]):
+        (+[NSMutableAttributedString isSelectorExcludedFromWebScript:]):
+        (+[NSMutableAttributedString webScriptNameForSelector:]):
+        (-[NSMutableAttributedString getLength]):
+        (-[NSMutableAttributedString ranges]):
+        (-[NSMutableAttributedString attributeNamesAtIndex:]):
+        (-[NSMutableAttributedString valueOfAttribute:atIndex:]):
+        (-[NSMutableAttributedString addAttribute:value:]):
+        (-[NSMutableAttributedString addAttribute:value:from:length:]):
+        (-[NSMutableAttributedString addColorAttribute:red:green:blue:alpha:]):
+        (-[NSMutableAttributedString addColorAttribute:red:green:blue:alpha:from:length:]):
+        (-[NSMutableAttributedString addFontAttribute:fontName:size:]):
+        (-[NSMutableAttributedString addFontAttribute:fontName:size:from:length:]):
+        (+[TextInputController isSelectorExcludedFromWebScript:]):
+        (+[TextInputController webScriptNameForSelector:]):
+        (-[TextInputController initWithWebView:]):
+        (-[TextInputController dealloc]):
+        (-[TextInputController textInput]):
+        (-[TextInputController insertText:]):
+        (-[TextInputController doCommand:]):
+        (-[TextInputController setMarkedText:selectedFrom:length:]):
+        (-[TextInputController unmarkText]):
+        (-[TextInputController hasMarkedText]):
+        (-[TextInputController conversationIdentifier]):
+        (-[TextInputController substringFrom:length:]):
+        (-[TextInputController attributedSubstringFrom:length:]):
+        (-[TextInputController legacyAttributedString:]):
+        (-[TextInputController markedRange]):
+        (-[TextInputController selectedRange]):
+        (-[TextInputController firstRectForCharactersFrom:length:]):
+        (-[TextInputController characterIndexForPointX:Y:]):
+        (-[TextInputController validAttributesForMarkedText]):
+        (-[TextInputController attributedStringWithString:]):
+        (-[TextInputController stringWithUndoGroupingInsertion:]):
+        (-[TextInputController dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:]):
+        (-[TextInputController setInputMethodHandler:]):
+        (-[TextInputController interpretKeyEvents:withSender:]):
+
+        Fixes miscellaneous style issues.
+
 2016-11-11  Philippe Normand  <[email protected]>
 
         [GTK][JHbuild] bump libnice version in openwebrtc.modules

Modified: trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj (208592 => 208593)


--- trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj	2016-11-11 18:38:01 UTC (rev 208593)
@@ -125,7 +125,7 @@
 		BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B250C9B015C00114369 /* WorkQueueItemMac.mm */; };
 		BCA18B320C9B01B400114369 /* ObjCController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B300C9B01B400114369 /* ObjCController.m */; };
 		BCA18B390C9B021900114369 /* AppleScriptController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B370C9B021900114369 /* AppleScriptController.m */; };
-		BCA18B490C9B02C400114369 /* TextInputController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B480C9B02C400114369 /* TextInputController.m */; };
+		BCA18B490C9B02C400114369 /* TextInputControllerMac.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B480C9B02C400114369 /* TextInputControllerMac.m */; };
 		BCA18B620C9B08C200114369 /* EditingDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B580C9B08C200114369 /* EditingDelegate.mm */; };
 		BCA18B640C9B08C200114369 /* FrameLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */; };
 		BCA18B660C9B08C200114369 /* PolicyDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */; };
@@ -150,6 +150,7 @@
 		C23EA2081BC9F05100C980B7 /* FontWithFeatures.otf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = C23EA2061BC9EABA00C980B7 /* FontWithFeatures.otf */; };
 		C23EA2091BC9F05100C980B7 /* FontWithFeatures.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = C23EA2071BC9EABA00C980B7 /* FontWithFeatures.ttf */; };
 		E1B7816511AF31B7007E1BC2 /* MockGeolocationProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */; };
+		F4D423611DD5048200678290 /* TextInputControllerIOS.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D4235F1DD5045300678290 /* TextInputControllerIOS.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -374,8 +375,7 @@
 		BCA18B300C9B01B400114369 /* ObjCController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ObjCController.m; path = mac/ObjCController.m; sourceTree = "<group>"; };
 		BCA18B360C9B021900114369 /* AppleScriptController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleScriptController.h; path = mac/AppleScriptController.h; sourceTree = "<group>"; };
 		BCA18B370C9B021900114369 /* AppleScriptController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = AppleScriptController.m; path = mac/AppleScriptController.m; sourceTree = "<group>"; };
-		BCA18B3A0C9B024900114369 /* TextInputController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextInputController.h; path = mac/TextInputController.h; sourceTree = "<group>"; };
-		BCA18B480C9B02C400114369 /* TextInputController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = TextInputController.m; path = mac/TextInputController.m; sourceTree = "<group>"; };
+		BCA18B480C9B02C400114369 /* TextInputControllerMac.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = TextInputControllerMac.m; path = mac/TextInputControllerMac.m; sourceTree = "<group>"; };
 		BCA18B570C9B08C200114369 /* EditingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = EditingDelegate.h; path = mac/EditingDelegate.h; sourceTree = "<group>"; };
 		BCA18B580C9B08C200114369 /* EditingDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = EditingDelegate.mm; path = mac/EditingDelegate.mm; sourceTree = "<group>"; };
 		BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FrameLoadDelegate.h; path = mac/FrameLoadDelegate.h; sourceTree = "<group>"; };
@@ -421,6 +421,8 @@
 		C23EA2071BC9EABA00C980B7 /* FontWithFeatures.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = FontWithFeatures.ttf; path = fonts/FontWithFeatures.ttf; sourceTree = "<group>"; };
 		E1B7808511AF1643007E1BC2 /* MockGeolocationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MockGeolocationProvider.h; path = mac/MockGeolocationProvider.h; sourceTree = "<group>"; };
 		E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MockGeolocationProvider.mm; path = mac/MockGeolocationProvider.mm; sourceTree = "<group>"; };
+		F4D4235F1DD5045300678290 /* TextInputControllerIOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TextInputControllerIOS.m; path = ios/TextInputControllerIOS.m; sourceTree = "<group>"; };
+		F4D423601DD5046900678290 /* TextInputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextInputController.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -586,6 +588,8 @@
 		1422A2690AF6F45200E1A883 /* Controllers */ = {
 			isa = PBXGroup;
 			children = (
+				F4D4235E1DD4F9A400678290 /* ios */,
+				F4D4235D1DD4F99900678290 /* mac */,
 				A134E53718905F4C00901D06 /* AccessibilityCommonMac.h */,
 				BC0E26140E2DA4C6001B6BC3 /* AccessibilityCommonMac.mm */,
 				BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */,
@@ -617,11 +621,10 @@
 				BCA18B6E0C9B08DB00114369 /* NavigationController.m */,
 				BCA18B2F0C9B01B400114369 /* ObjCController.h */,
 				BCA18B300C9B01B400114369 /* ObjCController.m */,
+				F4D423601DD5046900678290 /* TextInputController.h */,
 				BC0131D80C9772010087317D /* TestRunner.cpp */,
 				BC0131D90C9772010087317D /* TestRunner.h */,
 				BCA18B220C9B014B00114369 /* TestRunnerMac.mm */,
-				BCA18B3A0C9B024900114369 /* TextInputController.h */,
-				BCA18B480C9B02C400114369 /* TextInputController.m */,
 			);
 			name = Controllers;
 			sourceTree = "<group>";
@@ -821,6 +824,22 @@
 			name = PixelDump;
 			sourceTree = "<group>";
 		};
+		F4D4235D1DD4F99900678290 /* mac */ = {
+			isa = PBXGroup;
+			children = (
+				BCA18B480C9B02C400114369 /* TextInputControllerMac.m */,
+			);
+			name = mac;
+			sourceTree = "<group>";
+		};
+		F4D4235E1DD4F9A400678290 /* ios */ = {
+			isa = PBXGroup;
+			children = (
+				F4D4235F1DD5045300678290 /* TextInputControllerIOS.m */,
+			);
+			name = ios;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
@@ -1114,6 +1133,7 @@
 				BCA18B800C9B08F100114369 /* ObjCPluginFunction.m in Sources */,
 				8465E2C70FFA8DF2003B8342 /* PixelDumpSupport.cpp in Sources */,
 				BCB284CD0CFA83C8007E533E /* PixelDumpSupportCG.cpp in Sources */,
+				F4D423611DD5048200678290 /* TextInputControllerIOS.m in Sources */,
 				A1158D59189274360088C17B /* PixelDumpSupportIOS.mm in Sources */,
 				BCB284D60CFA83D1007E533E /* PixelDumpSupportMac.mm in Sources */,
 				BCA18B660C9B08C200114369 /* PolicyDelegate.mm in Sources */,
@@ -1120,7 +1140,7 @@
 				BCA18B680C9B08C200114369 /* ResourceLoadDelegate.mm in Sources */,
 				BC0131DA0C9772010087317D /* TestRunner.cpp in Sources */,
 				BCA18B240C9B014B00114369 /* TestRunnerMac.mm in Sources */,
-				BCA18B490C9B02C400114369 /* TextInputController.m in Sources */,
+				BCA18B490C9B02C400114369 /* TextInputControllerMac.m in Sources */,
 				BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */,
 				0F18E6EC1D6B9C070027E547 /* UIScriptContext.cpp in Sources */,
 				0F18E6ED1D6B9C070027E547 /* UIScriptController.cpp in Sources */,

Copied: trunk/Tools/DumpRenderTree/TextInputController.h (from rev 208592, trunk/Tools/DumpRenderTree/mac/TextInputController.h) (0 => 208593)


--- trunk/Tools/DumpRenderTree/TextInputController.h	                        (rev 0)
+++ trunk/Tools/DumpRenderTree/TextInputController.h	2016-11-11 18:38:01 UTC (rev 208593)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2005, 2016 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class WebView;
+@class WebHTMLView;
+@class WebScriptObject;
+
+@interface TextInputController : NSObject {
+    WebView *webView;
+    WebHTMLView *inputMethodView;
+    WebScriptObject *inputMethodHandler;    
+}
+- (id)initWithWebView:(WebView *)view;
+@end

Added: trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m (0 => 208593)


--- trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m	                        (rev 0)
+++ trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m	2016-11-11 18:38:01 UTC (rev 208593)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "TextInputController.h"
+
+#if PLATFORM(IOS)
+
+// FIXME: <rdar://problem/5106287> Only partial support for TextInputController has been implemented on iOS so far. We need to finish the implementation
+// here to bring it up to parity with the Mac version (see TextInputControllerMac.m), and then reenable skipped iOS tests that use TextInputController.
+
+#import <WebKit/WebFramePrivate.h>
+#import <WebKit/WebKit.h>
+
+@implementation TextInputController
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+    if (aSelector == @selector(insertText:)
+        || aSelector == @selector(setMarkedText:selectedFrom:length:)
+        || aSelector == @selector(markedRange))
+        return NO;
+
+    return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+    if (aSelector == @selector(insertText:))
+        return @"insertText";
+    if (aSelector == @selector(setMarkedText:selectedFrom:length:))
+        return @"setMarkedText";
+    if (aSelector == @selector(markedRange))
+        return @"markedRange";
+
+    return nil;
+}
+
+- (id)initWithWebView:(WebView *)wv
+{
+    if (self = [super init]) {
+        webView = wv;
+        inputMethodView = nil;
+        inputMethodHandler = nil;
+    }
+
+    return self;
+}
+
+- (NSArray *)markedRange
+{
+    DOMRange *range = [[webView mainFrame] markedTextDOMRange];
+    if (!range)
+        return nil;
+
+    return [NSArray arrayWithObjects:@([range startOffset]), @([range endOffset]), nil];
+}
+
+- (void)insertText:(NSString *)text
+{
+    [[webView mainFrame] confirmMarkedText:text];
+}
+
+- (void)setMarkedText:(NSString *)text selectedFrom:(NSInteger)selectionStart length:(NSInteger)selectionLength
+{
+    if (selectionStart == -1)
+        selectionStart = NSNotFound;
+
+    [[webView mainFrame] setMarkedText:text selectedRange:NSMakeRange(selectionStart, selectionLength)];
+}
+
+@end
+
+#endif

Modified: trunk/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm (208592 => 208593)


--- trunk/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm	2016-11-11 18:38:01 UTC (rev 208593)
@@ -302,9 +302,7 @@
 
     // Make Old-Style controllers
 
-#if !PLATFORM(IOS)
     WebView *webView = [frame webView];
-#endif
     WebScriptObject *obj = [frame windowObject];
 #if !PLATFORM(IOS)
     AppleScriptController *asc = [[AppleScriptController alloc] initWithWebView:webView];
@@ -330,12 +328,9 @@
     [obj setValue:pluginFunction forKey:@"objCPluginFunction"];
     [pluginFunction release];
 
-#if !PLATFORM(IOS)
-// FIXME: <rdar://problem/5106287> DumpRenderTree: fix TextInputController to work with iOS and re-enable tests
     TextInputController *tic = [[TextInputController alloc] initWithWebView:webView];
     [obj setValue:tic forKey:@"textInputController"];
     [tic release];
-#endif
 }
 
 - (void)didClearWindowObjectForFrame:(WebFrame *)frame inIsolatedWorld:(WebScriptWorld *)world

Deleted: trunk/Tools/DumpRenderTree/mac/TextInputController.h (208592 => 208593)


--- trunk/Tools/DumpRenderTree/mac/TextInputController.h	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/Tools/DumpRenderTree/mac/TextInputController.h	2016-11-11 18:38:01 UTC (rev 208593)
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer. 
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution. 
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import <Foundation/Foundation.h>
-
-#if PLATFORM(MAC)
-// FIXME: <rdar://problem/5106287> DumpRenderTree: fix TextInputController to work with iOS and re-enable tests
-
-@class WebView;
-@class WebHTMLView;
-@class WebScriptObject;
-
-@interface TextInputController : NSObject
-{
-    WebView *webView;
-    WebHTMLView *inputMethodView;
-    WebScriptObject *inputMethodHandler;    
-}
-- (id)initWithWebView:(WebView *)view;
-@end
-
-#endif

Deleted: trunk/Tools/DumpRenderTree/mac/TextInputController.m (208592 => 208593)


--- trunk/Tools/DumpRenderTree/mac/TextInputController.m	2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/Tools/DumpRenderTree/mac/TextInputController.m	2016-11-11 18:38:01 UTC (rev 208593)
@@ -1,551 +0,0 @@
-/*
- * Copyright (C) 2005, 2007 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer. 
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution. 
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-#import "TextInputController.h"
-
-#if PLATFORM(MAC)
-// FIXME: <rdar://problem/5106287> DumpRenderTree: fix TextInputController to work with iOS and re-enable tests
-
-#import "DumpRenderTreeMac.h"
-#import <AppKit/NSInputManager.h>
-#import <AppKit/NSTextAlternatives.h>
-
-#define SUPPORT_INSERTION_UNDO_GROUPING
-#if __has_include(<AppKit/NSTextInputContext_Private.h>)
-#import <AppKit/NSTextInputContext_Private.h>
-#else
-NSString *NSTextInsertionUndoableAttributeName;
-#endif
-
-#import <WebKit/WebDocument.h>
-#import <WebKit/WebFrame.h>
-#import <WebKit/WebFramePrivate.h>
-#import <WebKit/WebFrameView.h>
-#import <WebKit/WebHTMLViewPrivate.h>
-#import <WebKit/WebScriptObject.h>
-#import <WebKit/WebTypesInternal.h>
-#import <WebKit/WebView.h>
-#import <wtf/mac/AppKitCompatibilityDeclarations.h>
-
-@interface TextInputController (DumpRenderTreeInputMethodHandler)
-- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender;
-@end
-
-@interface WebHTMLView (DumpRenderTreeInputMethodHandler)
-- (void)interpretKeyEvents:(NSArray *)eventArray;
-@end
-
-@interface WebHTMLView (WebKitSecretsTextInputControllerIsAwareOf)
-- (WebFrame *)_frame;
-- (NSAttributedString *)_attributedStringFromDOMRange:(DOMRange *)range;
-@end
-
-@implementation WebHTMLView (DumpRenderTreeInputMethodHandler)
-- (void)interpretKeyEvents:(NSArray *)eventArray
-{
-    WebScriptObject *obj = [[self _frame] windowObject];
-    TextInputController *tic = [obj valueForKey:@"textInputController"];
-    if (![tic interpretKeyEvents:eventArray withSender:self])
-        [super interpretKeyEvents:eventArray];
-}
-@end
-
-@interface WebNSRange : NSObject {
-@private
-    NSRange _range;
-}
-- (id)initWithNSRange:(NSRange)range;
-- (unsigned)location;
-- (unsigned)length;
-@end
-
-@implementation WebNSRange
-
-- (id)initWithNSRange:(NSRange)range
-{
-    self = [super init];
-    if (!self)
-        return self;
-
-    _range = range;
-    return self;
-}
-
-- (unsigned)location
-{
-    return _range.location;
-}
-
-- (unsigned)length
-{
-    return _range.length;
-}
-
-+ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
-{
-    return !(selector == @selector(location) || selector == @selector(length));
-}
-
-@end
-
-@implementation NSMutableAttributedString (TextInputController)
-
-+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
-{
-    if (aSelector == @selector(string)
-            || aSelector == @selector(getLength)
-            || aSelector == @selector(ranges)
-            || aSelector == @selector(attributeNamesAtIndex:)
-            || aSelector == @selector(valueOfAttribute:atIndex:)
-            || aSelector == @selector(addAttribute:value:)
-            || aSelector == @selector(addAttribute:value:from:length:)
-            || aSelector == @selector(addColorAttribute:red:green:blue:alpha:)
-            || aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:)
-            || aSelector == @selector(addFontAttribute:fontName:size:)
-            || aSelector == @selector(addFontAttribute:fontName:size:from:length:))
-        return NO;
-    return YES;
-}
-
-+ (NSString *)webScriptNameForSelector:(SEL)aSelector
-{
-    if (aSelector == @selector(getLength))
-        return @"length";
-    if (aSelector == @selector(ranges))
-        return @"ranges";
-    if (aSelector == @selector(attributeNamesAtIndex:))
-        return @"getAttributeNamesAtIndex";
-    if (aSelector == @selector(valueOfAttribute:atIndex:))
-        return @"getAttributeValueAtIndex";
-    if (aSelector == @selector(addAttribute:value:))
-        return @"addAttribute";
-    if (aSelector == @selector(addAttribute:value:from:length:))
-        return @"addAttributeForRange";
-    if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:))
-        return @"addColorAttribute";
-    if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:))
-        return @"addColorAttributeForRange";
-    if (aSelector == @selector(addFontAttribute:fontName:size:))
-        return @"addFontAttribute";
-    if (aSelector == @selector(addFontAttribute:fontName:size:from:length:))
-        return @"addFontAttributeForRange";
-
-    return nil;
-}
-
-- (int)getLength
-{
-    return (int)[self length];
-}
-
-- (NSArray *)ranges
-{
-    NSMutableArray *array = [NSMutableArray array];
-    [self enumerateAttributesInRange:NSMakeRange(0, [self length]) options:0 usingBlock:^(NSDictionary *attributes, NSRange range, BOOL *stop) {
-        WebNSRange *webRange = [[WebNSRange alloc] initWithNSRange:range];
-        [array addObject:webRange];
-        [webRange release];
-    }];
-    return array;
-}
-
-- (NSArray *)attributeNamesAtIndex:(int)index
-{
-    NSDictionary *attributes = [self attributesAtIndex:(unsigned)index effectiveRange:nil];
-    return [attributes allKeys];
-}
-
-- (id)valueOfAttribute:(NSString *)attrName atIndex:(int)index
-{
-    return [self attribute:attrName atIndex:(unsigned)index effectiveRange:nil];
-}
-
-- (void)addAttribute:(NSString *)attrName value:(id)value
-{
-    [self addAttribute:attrName value:value range:NSMakeRange(0, [self length])];
-}
-
-- (void)addAttribute:(NSString *)attrName value:(id)value from:(int)from length:(int)length
-{
-    [self addAttribute:attrName value:value range:NSMakeRange((unsigned)from, (unsigned)length)];
-}
-
-- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
-{
-    [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange(0, [self length])];
-}
-
-- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha from:(int)from length:(int)length
-{
-    [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange((unsigned)from, (unsigned)length)];
-}
-
-- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize
-{
-    [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange(0, [self length])];
-}
-
-- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize from:(int)from length:(int)length
-{
-    [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange((unsigned)from, (unsigned)length)];
-}
-
-@end
-
-@implementation TextInputController
-
-+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
-{
-    if (aSelector == @selector(insertText:)
-            || aSelector == @selector(doCommand:)
-            || aSelector == @selector(setMarkedText:selectedFrom:length:)
-            || aSelector == @selector(unmarkText)
-            || aSelector == @selector(hasMarkedText)
-            || aSelector == @selector(conversationIdentifier)
-            || aSelector == @selector(substringFrom:length:)
-            || aSelector == @selector(attributedSubstringFrom:length:)
-            || aSelector == @selector(legacyAttributedString:)
-            || aSelector == @selector(markedRange)
-            || aSelector == @selector(selectedRange)
-            || aSelector == @selector(firstRectForCharactersFrom:length:)
-            || aSelector == @selector(characterIndexForPointX:Y:)
-            || aSelector == @selector(validAttributesForMarkedText)
-            || aSelector == @selector(attributedStringWithString:)
-            || aSelector == @selector(setInputMethodHandler:)
-            || aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:)
-            || aSelector == @selector(stringWithUndoGroupingInsertion:))
-        return NO;
-    return YES;
-}
-
-+ (NSString *)webScriptNameForSelector:(SEL)aSelector
-{
-    if (aSelector == @selector(insertText:))
-        return @"insertText";
-    else if (aSelector == @selector(doCommand:))
-        return @"doCommand";
-    else if (aSelector == @selector(setMarkedText:selectedFrom:length:))
-        return @"setMarkedText";
-    else if (aSelector == @selector(substringFrom:length:))
-        return @"substringFromRange";
-    else if (aSelector == @selector(attributedSubstringFrom:length:))
-        return @"attributedSubstringFromRange";
-    else if (aSelector == @selector(legacyAttributedString:))
-        return @"legacyAttributedString";
-    else if (aSelector == @selector(firstRectForCharactersFrom:length:))
-        return @"firstRectForCharacterRange";
-    else if (aSelector == @selector(characterIndexForPointX:Y:))
-        return @"characterIndexForPoint";
-    else if (aSelector == @selector(attributedStringWithString:))
-        return @"makeAttributedString"; // just a factory method, doesn't call into NSTextInput
-    else if (aSelector == @selector(setInputMethodHandler:))
-        return @"setInputMethodHandler";
-    else if (aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:))
-        return @"makeDictatedString";
-    else if (aSelector == @selector(stringWithUndoGroupingInsertion:))
-        return @"makeUndoGroupingInsertionString";
-
-    return nil;
-}
-
-- (id)initWithWebView:(WebView *)wv
-{
-    self = [super init];
-    webView = wv;
-    inputMethodView = nil;
-    inputMethodHandler = nil;
-    return self;
-}
-
-- (void)dealloc
-{
-    [inputMethodHandler release];
-    inputMethodHandler = nil;
-    
-    [super dealloc];
-}
-
-- (NSObject <NSTextInput> *)textInput
-{
-    NSView <NSTextInput> *view = inputMethodView ? inputMethodView : (id)[[[webView mainFrame] frameView] documentView];
-    return [view conformsToProtocol:@protocol(NSTextInput)] ? view : nil;
-}
-
-- (void)insertText:(id)aString
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput)
-        [textInput insertText:aString];
-}
-
-- (void)doCommand:(NSString *)aCommand
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput)
-        [textInput doCommandBySelector:NSSelectorFromString(aCommand)];
-}
-
-- (void)setMarkedText:(NSString *)aString selectedFrom:(int)from length:(int)length
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
- 
-    if (textInput)
-        [textInput setMarkedText:aString selectedRange:NSMakeRange(from, length)];
-}
-
-- (void)unmarkText
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput)
-        [textInput unmarkText];
-}
-
-- (BOOL)hasMarkedText
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput)
-        return [textInput hasMarkedText];
-
-    return FALSE;
-}
-
-- (long)conversationIdentifier
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput)
-        return [textInput conversationIdentifier];
-
-    return 0;
-}
-
-- (NSString *)substringFrom:(int)from length:(int)length
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput)
-        return [[textInput attributedSubstringFromRange:NSMakeRange(from, length)] string];
-    
-    return @"";
-}
-
-- (NSMutableAttributedString *)attributedSubstringFrom:(int)from length:(int)length
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    NSMutableAttributedString *ret = [[[NSMutableAttributedString alloc] init] autorelease];
-
-    if (textInput)
-        [ret setAttributedString:[textInput attributedSubstringFromRange:NSMakeRange(from, length)]];
-    
-    return ret;
-}
-
-- (NSMutableAttributedString *)legacyAttributedString:(DOMRange*)range
-{
-    NSMutableAttributedString *string = [[[NSMutableAttributedString alloc] init] autorelease];
-    id documentView = [[[webView mainFrame] frameView] documentView];
-    if (![documentView isKindOfClass:[WebHTMLView class]])
-        return string;
-
-    [string setAttributedString:[(WebHTMLView *)documentView _attributedStringFromDOMRange:range]];
-    return string;
-}
-
-- (NSArray *)markedRange
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput) {
-        NSRange range = [textInput markedRange];
-        return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
-    }
-
-    return nil;
-}
-
-- (NSArray *)selectedRange
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput) {
-        NSRange range = [textInput selectedRange];
-        return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
-    }
-
-    return nil;
-}
-  
-
-- (NSArray *)firstRectForCharactersFrom:(int)from length:(int)length
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput) {
-        NSRect rect = [textInput firstRectForCharacterRange:NSMakeRange(from, length)];
-        if (rect.origin.x || rect.origin.y || rect.size.width || rect.size.height) {
-            rect.origin = [[webView window] convertScreenToBase:rect.origin];
-            rect = [webView convertRect:rect fromView:nil];
-        }
-        return [NSArray arrayWithObjects:
-                    [NSNumber numberWithFloat:rect.origin.x],
-                    [NSNumber numberWithFloat:rect.origin.y],
-                    [NSNumber numberWithFloat:rect.size.width],
-                    [NSNumber numberWithFloat:rect.size.height],
-                    nil];
-    }
-
-    return nil;
-}
-
-- (NSInteger)characterIndexForPointX:(float)x Y:(float)y
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput) {
-        NSPoint point = NSMakePoint(x, y);
-        point = [webView convertPoint:point toView:nil];
-        point = [[webView window] convertBaseToScreen:point];
-        NSInteger index = [textInput characterIndexForPoint:point];
-        if (index == NSNotFound)
-            return -1;
-
-        return index;
-    }
-
-    return 0;
-}
-
-- (NSArray *)validAttributesForMarkedText
-{
-    NSObject <NSTextInput> *textInput = [self textInput];
-
-    if (textInput)
-        return [textInput validAttributesForMarkedText];
-
-    return nil;
-}
-
-- (NSMutableAttributedString *)attributedStringWithString:(NSString *)aString
-{
-    return [[[NSMutableAttributedString alloc] initWithString:aString] autorelease];
-}
-
-- (NSMutableAttributedString*)stringWithUndoGroupingInsertion:(NSString*)aString
-{
-#if defined(SUPPORT_INSERTION_UNDO_GROUPING)
-    NSMutableAttributedString* attributedString = [self dictatedStringWithPrimaryString:aString alternative:@"test" alternativeOffset:0 alternativeLength:1];
-    [attributedString addAttribute:NSTextInsertionUndoableAttributeName value:@YES range:NSMakeRange(0, [attributedString length])];
-    return attributedString;
-#else
-    return nil;
-#endif
-}
-
-- (NSMutableAttributedString*)dictatedStringWithPrimaryString:(NSString*)aString alternative:(NSString*)alternative alternativeOffset:(int)offset alternativeLength:(int)length
-{
-    NSMutableAttributedString* dictatedString = [self attributedStringWithString:aString];
-    NSRange rangeWithAlternative = NSMakeRange((NSUInteger)offset, (NSUInteger)length);
-    NSString* subStringWithAlternative = [aString substringWithRange:rangeWithAlternative];
-    if (!subStringWithAlternative)
-        return nil;
-
-    NSTextAlternatives* alternativeObject = [[[NSTextAlternatives alloc] initWithPrimaryString:subStringWithAlternative alternativeStrings:[NSArray arrayWithObject:alternative]] autorelease];
-    if (!alternativeObject)
-        return nil;
-
-    [dictatedString addAttribute:NSTextAlternativesAttributeName value:alternativeObject range:rangeWithAlternative];
-
-    return dictatedString;
-}
-
-- (void)setInputMethodHandler:(WebScriptObject *)handler
-{
-    if (inputMethodHandler == handler)
-        return;
-    [handler retain];
-    [inputMethodHandler release];
-    inputMethodHandler = handler;
-}
-
-- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender
-{
-    if (!inputMethodHandler)
-        return NO;
-    
-    inputMethodView = sender;
-    
-    NSEvent *event = [eventArray objectAtIndex:0];
-    unsigned modifierFlags = [event modifierFlags]; 
-    NSMutableArray *modifiers = [[NSMutableArray alloc] init];
-    if (modifierFlags & NSEventModifierFlagCapsLock)
-        [modifiers addObject:@"NSAlphaShiftKeyMask"];
-    if (modifierFlags & NSEventModifierFlagShift)
-        [modifiers addObject:@"NSShiftKeyMask"];
-    if (modifierFlags & NSEventModifierFlagControl)
-        [modifiers addObject:@"NSControlKeyMask"];
-    if (modifierFlags & NSEventModifierFlagOption)
-        [modifiers addObject:@"NSAlternateKeyMask"];
-    if (modifierFlags & NSEventModifierFlagCommand)
-        [modifiers addObject:@"NSCommandKeyMask"];
-    if (modifierFlags & NSEventModifierFlagNumericPad)
-        [modifiers addObject:@"NSNumericPadKeyMask"];
-    if (modifierFlags & NSEventModifierFlagHelp)
-        [modifiers addObject:@"NSHelpKeyMask"];
-    if (modifierFlags & NSEventModifierFlagFunction)
-        [modifiers addObject:@"NSFunctionKeyMask"];
-    
-    WebScriptObject* eventParam = [inputMethodHandler evaluateWebScript:@"new Object();"];
-    [eventParam setValue:[event characters] forKey:@"characters"];
-    [eventParam setValue:[event charactersIgnoringModifiers] forKey:@"charactersIgnoringModifiers"];
-    [eventParam setValue:[NSNumber numberWithBool:[event isARepeat]] forKey:@"isARepeat"];
-    [eventParam setValue:[NSNumber numberWithUnsignedShort:[event keyCode]] forKey:@"keyCode"];
-    [eventParam setValue:modifiers forKey:@"modifierFlags"];
-
-    [modifiers release];
-    
-    id result = [inputMethodHandler callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:inputMethodHandler, eventParam, nil]];
-    if (![result respondsToSelector:@selector(boolValue)] || ![result boolValue]) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wundeclared-selector"
-        [sender doCommandBySelector:@selector(noop:)]; // AppKit sends noop: if the ime does not handle an event
-#pragma clang diagnostic pop
-    }
-
-    inputMethodView = nil;
-    return YES;
-}
-
-@end
-
-#endif // !PLATFORM(IOS)

Copied: trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m (from rev 208592, trunk/Tools/DumpRenderTree/mac/TextInputController.m) (0 => 208593)


--- trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m	                        (rev 0)
+++ trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m	2016-11-11 18:38:01 UTC (rev 208593)
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2005, 2007, 2016 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "TextInputController.h"
+
+#if PLATFORM(MAC)
+
+#import "DumpRenderTreeMac.h"
+#import <AppKit/NSInputManager.h>
+#import <AppKit/NSTextAlternatives.h>
+
+#define SUPPORT_INSERTION_UNDO_GROUPING
+#if __has_include(<AppKit/NSTextInputContext_Private.h>)
+#import <AppKit/NSTextInputContext_Private.h>
+#else
+NSString *NSTextInsertionUndoableAttributeName;
+#endif
+
+#import <WebKit/WebDocument.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebFramePrivate.h>
+#import <WebKit/WebFrameView.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebScriptObject.h>
+#import <WebKit/WebTypesInternal.h>
+#import <WebKit/WebView.h>
+#import <wtf/mac/AppKitCompatibilityDeclarations.h>
+
+@interface TextInputController (DumpRenderTreeInputMethodHandler)
+- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender;
+@end
+
+@interface WebHTMLView (DumpRenderTreeInputMethodHandler)
+- (void)interpretKeyEvents:(NSArray *)eventArray;
+@end
+
+@interface WebHTMLView (WebKitSecretsTextInputControllerIsAwareOf)
+- (WebFrame *)_frame;
+- (NSAttributedString *)_attributedStringFromDOMRange:(DOMRange *)range;
+@end
+
+@implementation WebHTMLView (DumpRenderTreeInputMethodHandler)
+- (void)interpretKeyEvents:(NSArray *)eventArray
+{
+    WebScriptObject *obj = [[self _frame] windowObject];
+    TextInputController *tic = [obj valueForKey:@"textInputController"];
+    if (![tic interpretKeyEvents:eventArray withSender:self])
+        [super interpretKeyEvents:eventArray];
+}
+@end
+
+@interface WebNSRange : NSObject {
+@private
+    NSRange _range;
+}
+- (id)initWithNSRange:(NSRange)range;
+- (unsigned)location;
+- (unsigned)length;
+@end
+
+@implementation WebNSRange
+
+- (id)initWithNSRange:(NSRange)range
+{
+    self = [super init];
+    if (!self)
+        return self;
+
+    _range = range;
+    return self;
+}
+
+- (unsigned)location
+{
+    return _range.location;
+}
+
+- (unsigned)length
+{
+    return _range.length;
+}
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
+{
+    return !(selector == @selector(location) || selector == @selector(length));
+}
+
+@end
+
+@implementation NSMutableAttributedString (TextInputController)
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+    if (aSelector == @selector(string)
+        || aSelector == @selector(getLength)
+        || aSelector == @selector(ranges)
+        || aSelector == @selector(attributeNamesAtIndex:)
+        || aSelector == @selector(valueOfAttribute:atIndex:)
+        || aSelector == @selector(addAttribute:value:)
+        || aSelector == @selector(addAttribute:value:from:length:)
+        || aSelector == @selector(addColorAttribute:red:green:blue:alpha:)
+        || aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:)
+        || aSelector == @selector(addFontAttribute:fontName:size:)
+        || aSelector == @selector(addFontAttribute:fontName:size:from:length:))
+        return NO;
+    return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+    if (aSelector == @selector(getLength))
+        return @"length";
+    if (aSelector == @selector(ranges))
+        return @"ranges";
+    if (aSelector == @selector(attributeNamesAtIndex:))
+        return @"getAttributeNamesAtIndex";
+    if (aSelector == @selector(valueOfAttribute:atIndex:))
+        return @"getAttributeValueAtIndex";
+    if (aSelector == @selector(addAttribute:value:))
+        return @"addAttribute";
+    if (aSelector == @selector(addAttribute:value:from:length:))
+        return @"addAttributeForRange";
+    if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:))
+        return @"addColorAttribute";
+    if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:))
+        return @"addColorAttributeForRange";
+    if (aSelector == @selector(addFontAttribute:fontName:size:))
+        return @"addFontAttribute";
+    if (aSelector == @selector(addFontAttribute:fontName:size:from:length:))
+        return @"addFontAttributeForRange";
+
+    return nil;
+}
+
+- (int)getLength
+{
+    return (int)[self length];
+}
+
+- (NSArray *)ranges
+{
+    NSMutableArray *array = [NSMutableArray array];
+    [self enumerateAttributesInRange:NSMakeRange(0, [self length]) options:0 usingBlock:^(NSDictionary *attributes, NSRange range, BOOL *stop) {
+        WebNSRange *webRange = [[WebNSRange alloc] initWithNSRange:range];
+        [array addObject:webRange];
+        [webRange release];
+    }];
+    return array;
+}
+
+- (NSArray *)attributeNamesAtIndex:(int)index
+{
+    NSDictionary *attributes = [self attributesAtIndex:(unsigned)index effectiveRange:nil];
+    return [attributes allKeys];
+}
+
+- (id)valueOfAttribute:(NSString *)attrName atIndex:(int)index
+{
+    return [self attribute:attrName atIndex:(unsigned)index effectiveRange:nil];
+}
+
+- (void)addAttribute:(NSString *)attrName value:(id)value
+{
+    [self addAttribute:attrName value:value range:NSMakeRange(0, [self length])];
+}
+
+- (void)addAttribute:(NSString *)attrName value:(id)value from:(int)from length:(int)length
+{
+    [self addAttribute:attrName value:value range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
+{
+    [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange(0, [self length])];
+}
+
+- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha from:(int)from length:(int)length
+{
+    [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize
+{
+    [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange(0, [self length])];
+}
+
+- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize from:(int)from length:(int)length
+{
+    [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+@end
+
+@implementation TextInputController
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+    if (aSelector == @selector(insertText:)
+        || aSelector == @selector(doCommand:)
+        || aSelector == @selector(setMarkedText:selectedFrom:length:)
+        || aSelector == @selector(unmarkText)
+        || aSelector == @selector(hasMarkedText)
+        || aSelector == @selector(conversationIdentifier)
+        || aSelector == @selector(substringFrom:length:)
+        || aSelector == @selector(attributedSubstringFrom:length:)
+        || aSelector == @selector(legacyAttributedString:)
+        || aSelector == @selector(markedRange)
+        || aSelector == @selector(selectedRange)
+        || aSelector == @selector(firstRectForCharactersFrom:length:)
+        || aSelector == @selector(characterIndexForPointX:Y:)
+        || aSelector == @selector(validAttributesForMarkedText)
+        || aSelector == @selector(attributedStringWithString:)
+        || aSelector == @selector(setInputMethodHandler:)
+        || aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:)
+        || aSelector == @selector(stringWithUndoGroupingInsertion:))
+        return NO;
+    return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+    if (aSelector == @selector(insertText:))
+        return @"insertText";
+    if (aSelector == @selector(doCommand:))
+        return @"doCommand";
+    if (aSelector == @selector(setMarkedText:selectedFrom:length:))
+        return @"setMarkedText";
+    if (aSelector == @selector(substringFrom:length:))
+        return @"substringFromRange";
+    if (aSelector == @selector(attributedSubstringFrom:length:))
+        return @"attributedSubstringFromRange";
+    if (aSelector == @selector(legacyAttributedString:))
+        return @"legacyAttributedString";
+    if (aSelector == @selector(firstRectForCharactersFrom:length:))
+        return @"firstRectForCharacterRange";
+    if (aSelector == @selector(characterIndexForPointX:Y:))
+        return @"characterIndexForPoint";
+    if (aSelector == @selector(attributedStringWithString:))
+        return @"makeAttributedString"; // just a factory method, doesn't call into NSTextInput
+    if (aSelector == @selector(setInputMethodHandler:))
+        return @"setInputMethodHandler";
+    if (aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:))
+        return @"makeDictatedString";
+    if (aSelector == @selector(stringWithUndoGroupingInsertion:))
+        return @"makeUndoGroupingInsertionString";
+
+    return nil;
+}
+
+- (id)initWithWebView:(WebView *)wv
+{
+    self = [super init];
+    webView = wv;
+    inputMethodView = nil;
+    inputMethodHandler = nil;
+    return self;
+}
+
+- (void)dealloc
+{
+    [inputMethodHandler release];
+    inputMethodHandler = nil;
+    
+    [super dealloc];
+}
+
+- (NSObject <NSTextInput> *)textInput
+{
+    NSView <NSTextInput> *view = inputMethodView ? inputMethodView : (id)[[[webView mainFrame] frameView] documentView];
+    return [view conformsToProtocol:@protocol(NSTextInput)] ? view : nil;
+}
+
+- (void)insertText:(id)aString
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput)
+        [textInput insertText:aString];
+}
+
+- (void)doCommand:(NSString *)aCommand
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput)
+        [textInput doCommandBySelector:NSSelectorFromString(aCommand)];
+}
+
+- (void)setMarkedText:(NSString *)aString selectedFrom:(int)from length:(int)length
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput)
+        [textInput setMarkedText:aString selectedRange:NSMakeRange(from, length)];
+}
+
+- (void)unmarkText
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput)
+        [textInput unmarkText];
+}
+
+- (BOOL)hasMarkedText
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput)
+        return [textInput hasMarkedText];
+
+    return FALSE;
+}
+
+- (long)conversationIdentifier
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput)
+        return [textInput conversationIdentifier];
+
+    return 0;
+}
+
+- (NSString *)substringFrom:(int)from length:(int)length
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput)
+        return [[textInput attributedSubstringFromRange:NSMakeRange(from, length)] string];
+    
+    return @"";
+}
+
+- (NSMutableAttributedString *)attributedSubstringFrom:(int)from length:(int)length
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    NSMutableAttributedString *ret = [[[NSMutableAttributedString alloc] init] autorelease];
+
+    if (textInput)
+        [ret setAttributedString:[textInput attributedSubstringFromRange:NSMakeRange(from, length)]];
+    
+    return ret;
+}
+
+- (NSMutableAttributedString *)legacyAttributedString:(DOMRange*)range
+{
+    NSMutableAttributedString *string = [[[NSMutableAttributedString alloc] init] autorelease];
+    id documentView = [[[webView mainFrame] frameView] documentView];
+    if (![documentView isKindOfClass:[WebHTMLView class]])
+        return string;
+
+    [string setAttributedString:[(WebHTMLView *)documentView _attributedStringFromDOMRange:range]];
+    return string;
+}
+
+- (NSArray *)markedRange
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput) {
+        NSRange range = [textInput markedRange];
+        return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
+    }
+
+    return nil;
+}
+
+- (NSArray *)selectedRange
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput) {
+        NSRange range = [textInput selectedRange];
+        return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
+    }
+
+    return nil;
+}
+
+- (NSArray *)firstRectForCharactersFrom:(int)from length:(int)length
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput) {
+        NSRect rect = [textInput firstRectForCharacterRange:NSMakeRange(from, length)];
+        if (rect.origin.x || rect.origin.y || rect.size.width || rect.size.height) {
+            rect.origin = [[webView window] convertScreenToBase:rect.origin];
+            rect = [webView convertRect:rect fromView:nil];
+        }
+        return [NSArray arrayWithObjects:
+            [NSNumber numberWithFloat:rect.origin.x],
+            [NSNumber numberWithFloat:rect.origin.y],
+            [NSNumber numberWithFloat:rect.size.width],
+            [NSNumber numberWithFloat:rect.size.height],
+            nil];
+    }
+
+    return nil;
+}
+
+- (NSInteger)characterIndexForPointX:(float)x Y:(float)y
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput) {
+        NSPoint point = NSMakePoint(x, y);
+        point = [webView convertPoint:point toView:nil];
+        point = [[webView window] convertBaseToScreen:point];
+        NSInteger index = [textInput characterIndexForPoint:point];
+        if (index == NSNotFound)
+            return -1;
+
+        return index;
+    }
+
+    return 0;
+}
+
+- (NSArray *)validAttributesForMarkedText
+{
+    NSObject <NSTextInput> *textInput = [self textInput];
+
+    if (textInput)
+        return [textInput validAttributesForMarkedText];
+
+    return nil;
+}
+
+- (NSMutableAttributedString *)attributedStringWithString:(NSString *)aString
+{
+    return [[[NSMutableAttributedString alloc] initWithString:aString] autorelease];
+}
+
+- (NSMutableAttributedString*)stringWithUndoGroupingInsertion:(NSString*)aString
+{
+#if defined(SUPPORT_INSERTION_UNDO_GROUPING)
+    NSMutableAttributedString* attributedString = [self dictatedStringWithPrimaryString:aString alternative:@"test" alternativeOffset:0 alternativeLength:1];
+    [attributedString addAttribute:NSTextInsertionUndoableAttributeName value:@YES range:NSMakeRange(0, [attributedString length])];
+    return attributedString;
+#else
+    return nil;
+#endif
+}
+
+- (NSMutableAttributedString*)dictatedStringWithPrimaryString:(NSString*)aString alternative:(NSString*)alternative alternativeOffset:(int)offset alternativeLength:(int)length
+{
+    NSMutableAttributedString* dictatedString = [self attributedStringWithString:aString];
+    NSRange rangeWithAlternative = NSMakeRange((NSUInteger)offset, (NSUInteger)length);
+    NSString* subStringWithAlternative = [aString substringWithRange:rangeWithAlternative];
+    if (!subStringWithAlternative)
+        return nil;
+
+    NSTextAlternatives* alternativeObject = [[[NSTextAlternatives alloc] initWithPrimaryString:subStringWithAlternative alternativeStrings:[NSArray arrayWithObject:alternative]] autorelease];
+    if (!alternativeObject)
+        return nil;
+
+    [dictatedString addAttribute:NSTextAlternativesAttributeName value:alternativeObject range:rangeWithAlternative];
+
+    return dictatedString;
+}
+
+- (void)setInputMethodHandler:(WebScriptObject *)handler
+{
+    if (inputMethodHandler == handler)
+        return;
+    [handler retain];
+    [inputMethodHandler release];
+    inputMethodHandler = handler;
+}
+
+- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender
+{
+    if (!inputMethodHandler)
+        return NO;
+    
+    inputMethodView = sender;
+    
+    NSEvent *event = [eventArray objectAtIndex:0];
+    unsigned modifierFlags = [event modifierFlags]; 
+    NSMutableArray *modifiers = [[NSMutableArray alloc] init];
+    if (modifierFlags & NSEventModifierFlagCapsLock)
+        [modifiers addObject:@"NSAlphaShiftKeyMask"];
+    if (modifierFlags & NSEventModifierFlagShift)
+        [modifiers addObject:@"NSShiftKeyMask"];
+    if (modifierFlags & NSEventModifierFlagControl)
+        [modifiers addObject:@"NSControlKeyMask"];
+    if (modifierFlags & NSEventModifierFlagOption)
+        [modifiers addObject:@"NSAlternateKeyMask"];
+    if (modifierFlags & NSEventModifierFlagCommand)
+        [modifiers addObject:@"NSCommandKeyMask"];
+    if (modifierFlags & NSEventModifierFlagNumericPad)
+        [modifiers addObject:@"NSNumericPadKeyMask"];
+    if (modifierFlags & NSEventModifierFlagHelp)
+        [modifiers addObject:@"NSHelpKeyMask"];
+    if (modifierFlags & NSEventModifierFlagFunction)
+        [modifiers addObject:@"NSFunctionKeyMask"];
+    
+    WebScriptObject* eventParam = [inputMethodHandler evaluateWebScript:@"new Object();"];
+    [eventParam setValue:[event characters] forKey:@"characters"];
+    [eventParam setValue:[event charactersIgnoringModifiers] forKey:@"charactersIgnoringModifiers"];
+    [eventParam setValue:[NSNumber numberWithBool:[event isARepeat]] forKey:@"isARepeat"];
+    [eventParam setValue:[NSNumber numberWithUnsignedShort:[event keyCode]] forKey:@"keyCode"];
+    [eventParam setValue:modifiers forKey:@"modifierFlags"];
+
+    [modifiers release];
+    
+    id result = [inputMethodHandler callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:inputMethodHandler, eventParam, nil]];
+    if (![result respondsToSelector:@selector(boolValue)] || ![result boolValue]) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
+        [sender doCommandBySelector:@selector(noop:)]; // AppKit sends noop: if the ime does not handle an event
+#pragma clang diagnostic pop
+    }
+
+    inputMethodView = nil;
+    return YES;
+}
+
+@end
+
+#endif // !PLATFORM(IOS)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to