<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[208593] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/208593">208593</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2016-11-11 10:38:01 -0800 (Fri, 11 Nov 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>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:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2TestExpectations">trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformmacTestExpectations">trunk/LayoutTests/platform/mac/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorcpp">trunk/Source/WebCore/editing/Editor.cpp</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreeDumpRenderTreexcodeprojprojectpbxproj">trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsDumpRenderTreemacFrameLoadDelegatemm">trunk/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestseditinginputfocuschangewithmarkedtextexpectedtxt">trunk/LayoutTests/editing/input/focus-change-with-marked-text-expected.txt</a></li>
<li><a href="#trunkLayoutTestseditinginputfocuschangewithmarkedtexthtml">trunk/LayoutTests/editing/input/focus-change-with-marked-text.html</a></li>
<li><a href="#trunkToolsDumpRenderTreeTextInputControllerh">trunk/Tools/DumpRenderTree/TextInputController.h</a></li>
<li><a href="#trunkToolsDumpRenderTreeiosTextInputControllerIOSm">trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m</a></li>
<li><a href="#trunkToolsDumpRenderTreemacTextInputControllerMacm">trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkToolsDumpRenderTreemacTextInputControllerh">trunk/Tools/DumpRenderTree/mac/TextInputController.h</a></li>
<li><a href="#trunkToolsDumpRenderTreemacTextInputControllerm">trunk/Tools/DumpRenderTree/mac/TextInputController.m</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/LayoutTests/ChangeLog        2016-11-11 18:38:01 UTC (rev 208593)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-11-11 Wenson Hsieh <wenson_hsieh@apple.com>
+
+ 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:
+
</ins><span class="cx"> 2016-11-11 Manuel Rego Casasnovas <rego@igalia.com>
</span><span class="cx">
</span><span class="cx"> [css-grid] ASSERTION FAILED: !m_gridIsDirty in WebCore::RenderGrid::gridRowCount
</span></span></pre></div>
<a id="trunkLayoutTestseditinginputfocuschangewithmarkedtextexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/editing/input/focus-change-with-marked-text-expected.txt (0 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+
+The text field's value is: "abc"
+Is there marked text? false
+
</ins></span></pre></div>
<a id="trunkLayoutTestseditinginputfocuschangewithmarkedtexthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/editing/input/focus-change-with-marked-text.html (0 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+<!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>
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -937,6 +937,7 @@
</span><span class="cx"> editing/execCommand/toggle-unlink-mac.html [ Failure ]
</span><span class="cx"> editing/execCommand/unlink.html [ Failure ]
</span><span class="cx"> editing/input/editable-container-with-word-wrap-normal.html [ Failure ]
</span><ins>+editing/input/focus-change-with-marked-text.html [ Failure ]
</ins><span class="cx"> editing/input/option-page-up-down.html [ Failure ]
</span><span class="cx"> editing/input/password-echo-passnode.html [ Failure ]
</span><span class="cx"> editing/input/password-echo-passnode2.html [ Failure ]
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/TestExpectations (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -426,6 +426,9 @@
</span><span class="cx">
</span><span class="cx"> # --- Editing ---
</span><span class="cx">
</span><ins>+# The codepath for canceling marked text differs on Mac
+editing/input/focus-change-with-marked-text.html [ Failure ]
+
</ins><span class="cx"> # Mac does not have global selections.
</span><span class="cx"> editing/pasteboard/paste-global-selection.html
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2016-11-11 Wenson Hsieh <wenson_hsieh@apple.com>
+
+ 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):
+
</ins><span class="cx"> 2016-11-11 Dave Hyatt <hyatt@apple.com>
</span><span class="cx">
</span><span class="cx"> [CSS Parser] Support -webkit-svg-shadow
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1676,6 +1676,9 @@
</span><span class="cx"> else
</span><span class="cx"> selectComposition();
</span><span class="cx">
</span><ins>+ m_compositionNode = nullptr;
+ m_customCompositionUnderlines.clear();
+
</ins><span class="cx"> if (m_frame.selection().isNone()) {
</span><span class="cx"> setIgnoreCompositionSelectionChange(false);
</span><span class="cx"> return;
</span><span class="lines">@@ -1687,9 +1690,6 @@
</span><span class="cx"> if (mode != CancelComposition)
</span><span class="cx"> TypingCommand::deleteSelection(document(), 0, TypingCommand::TextCompositionPending);
</span><span class="cx">
</span><del>- m_compositionNode = nullptr;
- m_customCompositionUnderlines.clear();
-
</del><span class="cx"> insertTextForConfirmedComposition(text);
</span><span class="cx">
</span><span class="cx"> if (auto* target = document().focusedElement())
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-11-11 18:21:20 UTC (rev 208592)
+++ trunk/Tools/ChangeLog        2016-11-11 18:38:01 UTC (rev 208593)
</span><span class="lines">@@ -1,3 +1,82 @@
</span><ins>+2016-11-11 Wenson Hsieh <wenson_hsieh@apple.com>
+
+ 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.
+
</ins><span class="cx"> 2016-11-11 Philippe Normand <pnormand@igalia.com>
</span><span class="cx">
</span><span class="cx"> [GTK][JHbuild] bump libnice version in openwebrtc.modules
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeDumpRenderTreexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -125,7 +125,7 @@
</span><span class="cx">                 BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B250C9B015C00114369 /* WorkQueueItemMac.mm */; };
</span><span class="cx">                 BCA18B320C9B01B400114369 /* ObjCController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B300C9B01B400114369 /* ObjCController.m */; };
</span><span class="cx">                 BCA18B390C9B021900114369 /* AppleScriptController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B370C9B021900114369 /* AppleScriptController.m */; };
</span><del>-                BCA18B490C9B02C400114369 /* TextInputController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B480C9B02C400114369 /* TextInputController.m */; };
</del><ins>+                BCA18B490C9B02C400114369 /* TextInputControllerMac.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B480C9B02C400114369 /* TextInputControllerMac.m */; };
</ins><span class="cx">                 BCA18B620C9B08C200114369 /* EditingDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B580C9B08C200114369 /* EditingDelegate.mm */; };
</span><span class="cx">                 BCA18B640C9B08C200114369 /* FrameLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */; };
</span><span class="cx">                 BCA18B660C9B08C200114369 /* PolicyDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */; };
</span><span class="lines">@@ -150,6 +150,7 @@
</span><span class="cx">                 C23EA2081BC9F05100C980B7 /* FontWithFeatures.otf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = C23EA2061BC9EABA00C980B7 /* FontWithFeatures.otf */; };
</span><span class="cx">                 C23EA2091BC9F05100C980B7 /* FontWithFeatures.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = C23EA2071BC9EABA00C980B7 /* FontWithFeatures.ttf */; };
</span><span class="cx">                 E1B7816511AF31B7007E1BC2 /* MockGeolocationProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */; };
</span><ins>+                F4D423611DD5048200678290 /* TextInputControllerIOS.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D4235F1DD5045300678290 /* TextInputControllerIOS.m */; };
</ins><span class="cx"> /* End PBXBuildFile section */
</span><span class="cx">
</span><span class="cx"> /* Begin PBXContainerItemProxy section */
</span><span class="lines">@@ -374,8 +375,7 @@
</span><span class="cx">                 BCA18B300C9B01B400114369 /* ObjCController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ObjCController.m; path = mac/ObjCController.m; sourceTree = "<group>"; };
</span><span class="cx">                 BCA18B360C9B021900114369 /* AppleScriptController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleScriptController.h; path = mac/AppleScriptController.h; sourceTree = "<group>"; };
</span><span class="cx">                 BCA18B370C9B021900114369 /* AppleScriptController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = AppleScriptController.m; path = mac/AppleScriptController.m; sourceTree = "<group>"; };
</span><del>-                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>"; };
</del><ins>+                BCA18B480C9B02C400114369 /* TextInputControllerMac.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = TextInputControllerMac.m; path = mac/TextInputControllerMac.m; sourceTree = "<group>"; };
</ins><span class="cx">                 BCA18B570C9B08C200114369 /* EditingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = EditingDelegate.h; path = mac/EditingDelegate.h; sourceTree = "<group>"; };
</span><span class="cx">                 BCA18B580C9B08C200114369 /* EditingDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = EditingDelegate.mm; path = mac/EditingDelegate.mm; sourceTree = "<group>"; };
</span><span class="cx">                 BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FrameLoadDelegate.h; path = mac/FrameLoadDelegate.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -421,6 +421,8 @@
</span><span class="cx">                 C23EA2071BC9EABA00C980B7 /* FontWithFeatures.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = FontWithFeatures.ttf; path = fonts/FontWithFeatures.ttf; sourceTree = "<group>"; };
</span><span class="cx">                 E1B7808511AF1643007E1BC2 /* MockGeolocationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MockGeolocationProvider.h; path = mac/MockGeolocationProvider.h; sourceTree = "<group>"; };
</span><span class="cx">                 E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MockGeolocationProvider.mm; path = mac/MockGeolocationProvider.mm; sourceTree = "<group>"; };
</span><ins>+                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>"; };
</ins><span class="cx"> /* End PBXFileReference section */
</span><span class="cx">
</span><span class="cx"> /* Begin PBXFrameworksBuildPhase section */
</span><span class="lines">@@ -586,6 +588,8 @@
</span><span class="cx">                 1422A2690AF6F45200E1A883 /* Controllers */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                F4D4235E1DD4F9A400678290 /* ios */,
+                                F4D4235D1DD4F99900678290 /* mac */,
</ins><span class="cx">                                 A134E53718905F4C00901D06 /* AccessibilityCommonMac.h */,
</span><span class="cx">                                 BC0E26140E2DA4C6001B6BC3 /* AccessibilityCommonMac.mm */,
</span><span class="cx">                                 BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */,
</span><span class="lines">@@ -617,11 +621,10 @@
</span><span class="cx">                                 BCA18B6E0C9B08DB00114369 /* NavigationController.m */,
</span><span class="cx">                                 BCA18B2F0C9B01B400114369 /* ObjCController.h */,
</span><span class="cx">                                 BCA18B300C9B01B400114369 /* ObjCController.m */,
</span><ins>+                                F4D423601DD5046900678290 /* TextInputController.h */,
</ins><span class="cx">                                 BC0131D80C9772010087317D /* TestRunner.cpp */,
</span><span class="cx">                                 BC0131D90C9772010087317D /* TestRunner.h */,
</span><span class="cx">                                 BCA18B220C9B014B00114369 /* TestRunnerMac.mm */,
</span><del>-                                BCA18B3A0C9B024900114369 /* TextInputController.h */,
-                                BCA18B480C9B02C400114369 /* TextInputController.m */,
</del><span class="cx">                         );
</span><span class="cx">                         name = Controllers;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -821,6 +824,22 @@
</span><span class="cx">                         name = PixelDump;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="cx">                 };
</span><ins>+                F4D4235D1DD4F99900678290 /* mac */ = {
+                        isa = PBXGroup;
+                        children = (
+                                BCA18B480C9B02C400114369 /* TextInputControllerMac.m */,
+                        );
+                        name = mac;
+                        sourceTree = "<group>";
+                };
+                F4D4235E1DD4F9A400678290 /* ios */ = {
+                        isa = PBXGroup;
+                        children = (
+                                F4D4235F1DD5045300678290 /* TextInputControllerIOS.m */,
+                        );
+                        name = ios;
+                        sourceTree = "<group>";
+                };
</ins><span class="cx"> /* End PBXGroup section */
</span><span class="cx">
</span><span class="cx"> /* Begin PBXHeadersBuildPhase section */
</span><span class="lines">@@ -1114,6 +1133,7 @@
</span><span class="cx">                                 BCA18B800C9B08F100114369 /* ObjCPluginFunction.m in Sources */,
</span><span class="cx">                                 8465E2C70FFA8DF2003B8342 /* PixelDumpSupport.cpp in Sources */,
</span><span class="cx">                                 BCB284CD0CFA83C8007E533E /* PixelDumpSupportCG.cpp in Sources */,
</span><ins>+                                F4D423611DD5048200678290 /* TextInputControllerIOS.m in Sources */,
</ins><span class="cx">                                 A1158D59189274360088C17B /* PixelDumpSupportIOS.mm in Sources */,
</span><span class="cx">                                 BCB284D60CFA83D1007E533E /* PixelDumpSupportMac.mm in Sources */,
</span><span class="cx">                                 BCA18B660C9B08C200114369 /* PolicyDelegate.mm in Sources */,
</span><span class="lines">@@ -1120,7 +1140,7 @@
</span><span class="cx">                                 BCA18B680C9B08C200114369 /* ResourceLoadDelegate.mm in Sources */,
</span><span class="cx">                                 BC0131DA0C9772010087317D /* TestRunner.cpp in Sources */,
</span><span class="cx">                                 BCA18B240C9B014B00114369 /* TestRunnerMac.mm in Sources */,
</span><del>-                                BCA18B490C9B02C400114369 /* TextInputController.m in Sources */,
</del><ins>+                                BCA18B490C9B02C400114369 /* TextInputControllerMac.m in Sources */,
</ins><span class="cx">                                 BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */,
</span><span class="cx">                                 0F18E6EC1D6B9C070027E547 /* UIScriptContext.cpp in Sources */,
</span><span class="cx">                                 0F18E6ED1D6B9C070027E547 /* UIScriptController.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeTextInputControllerhfromrev208592trunkToolsDumpRenderTreemacTextInputControllerh"></a>
<div class="copfile"><h4>Copied: trunk/Tools/DumpRenderTree/TextInputController.h (from rev 208592, trunk/Tools/DumpRenderTree/mac/TextInputController.h) (0 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/TextInputController.h         (rev 0)
+++ trunk/Tools/DumpRenderTree/TextInputController.h        2016-11-11 18:38:01 UTC (rev 208593)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/*
+ * 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
</ins></span></pre></div>
<a id="trunkToolsDumpRenderTreeiosTextInputControllerIOSm"></a>
<div class="addfile"><h4>Added: trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m (0 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m         (rev 0)
+++ trunk/Tools/DumpRenderTree/ios/TextInputControllerIOS.m        2016-11-11 18:38:01 UTC (rev 208593)
</span><span class="lines">@@ -0,0 +1,96 @@
</span><ins>+/*
+ * 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
</ins></span></pre></div>
<a id="trunkToolsDumpRenderTreemacFrameLoadDelegatemm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -302,9 +302,7 @@
</span><span class="cx">
</span><span class="cx"> // Make Old-Style controllers
</span><span class="cx">
</span><del>-#if !PLATFORM(IOS)
</del><span class="cx"> WebView *webView = [frame webView];
</span><del>-#endif
</del><span class="cx"> WebScriptObject *obj = [frame windowObject];
</span><span class="cx"> #if !PLATFORM(IOS)
</span><span class="cx"> AppleScriptController *asc = [[AppleScriptController alloc] initWithWebView:webView];
</span><span class="lines">@@ -330,12 +328,9 @@
</span><span class="cx"> [obj setValue:pluginFunction forKey:@"objCPluginFunction"];
</span><span class="cx"> [pluginFunction release];
</span><span class="cx">
</span><del>-#if !PLATFORM(IOS)
-// FIXME: <rdar://problem/5106287> DumpRenderTree: fix TextInputController to work with iOS and re-enable tests
</del><span class="cx"> TextInputController *tic = [[TextInputController alloc] initWithWebView:webView];
</span><span class="cx"> [obj setValue:tic forKey:@"textInputController"];
</span><span class="cx"> [tic release];
</span><del>-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> - (void)didClearWindowObjectForFrame:(WebFrame *)frame inIsolatedWorld:(WebScriptWorld *)world
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacTextInputControllerh"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/DumpRenderTree/mac/TextInputController.h (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,47 +0,0 @@
</span><del>-/*
- * 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
</del></span></pre></div>
<a id="trunkToolsDumpRenderTreemacTextInputControllerm"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/DumpRenderTree/mac/TextInputController.m (208592 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,551 +0,0 @@
</span><del>-/*
- * 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)
</del></span></pre></div>
<a id="trunkToolsDumpRenderTreemacTextInputControllerMacmfromrev208592trunkToolsDumpRenderTreemacTextInputControllerm"></a>
<div class="copfile"><h4>Copied: trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m (from rev 208592, trunk/Tools/DumpRenderTree/mac/TextInputController.m) (0 => 208593)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m         (rev 0)
+++ trunk/Tools/DumpRenderTree/mac/TextInputControllerMac.m        2016-11-11 18:38:01 UTC (rev 208593)
</span><span class="lines">@@ -0,0 +1,549 @@
</span><ins>+/*
+ * 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)
</ins></span></pre>
</div>
</div>
</body>
</html>