<!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>[170447] 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/170447">170447</a></dd>
<dt>Author</dt> <dd>cfleizach@apple.com</dd>
<dt>Date</dt> <dd>2014-06-25 16:50:44 -0700 (Wed, 25 Jun 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add an undo group for each dictated utterance in WebKit
https://bugs.webkit.org/show_bug.cgi?id=134086

Reviewed by Enrica Casucci.

Source/WebCore: 
Provide a mechanism for ending the current undo group on a text insertion.
This allows a stream of text, that is normally part of one undo group, to be
broken up so that subsequent undo commands will only undo portions of the text stream.

* WebCore.exp.in:
* WebCore.xcodeproj/project.pbxproj:
* editing/mac/TextUndoInsertionMarkup.h: Added.
* editing/mac/TextUndoInsertionMarkup.mm: Added.
(WebCore::shouldRegisterInsertionUndoGroup):
(WebCore::registerInsertionUndoGrouping):

Source/WebKit/mac: 
* WebView/WebHTMLView.mm:
(-[WebHTMLView validAttributesForMarkedText]):
(-[WebHTMLView insertText:]):

Source/WebKit2: 
* UIProcess/API/mac/WKView.mm:
(-[WKView insertText:replacementRange:]):
(-[WKView validAttributesForMarkedText]):
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::registerInsertionUndoGrouping):
(WebKit::WebPageProxy::insertTextAsync):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::registerInsertionUndoGrouping):
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::registerInsertionUndoGrouping):
* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::insertDictatedTextAsync):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::insertTextAsync):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::insertDictatedTextAsync):

Tools: 
Create a method for creating attributed strings with the undo insertion marker.

* DumpRenderTree/mac/TextInputController.m:
(+[TextInputController isSelectorExcludedFromWebScript:]):
(+[TextInputController webScriptNameForSelector:]):
(-[TextInputController stringWithUndoGroupingInsertion:]):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebViewWebHTMLViewmm">trunk/Source/WebKit/mac/WebView/WebHTMLView.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPImacWKViewmm">trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPageClienth">trunk/Source/WebKit2/UIProcess/PageClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosPageClientImplIOSmm">trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacPageClientImplh">trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacPageClientImplmm">trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacWebPageProxyMacmm">trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagemessagesin">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm">trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreemacTextInputControllerm">trunk/Tools/DumpRenderTree/mac/TextInputController.m</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreeditingmacTextUndoInsertionMarkuph">trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkup.h</a></li>
<li><a href="#trunkSourceWebCoreeditingmacTextUndoInsertionMarkupMach">trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkupMac.h</a></li>
<li><a href="#trunkSourceWebCoreeditingmacTextUndoInsertionMarkupMacmm">trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkupMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebCore/ChangeLog        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2014-06-25  Chris Fleizach  &lt;cfleizach@apple.com&gt;
+
+        Add an undo group for each dictated utterance in WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=134086
+
+        Reviewed by Enrica Casucci.
+
+        Provide a mechanism for ending the current undo group on a text insertion.
+        This allows a stream of text, that is normally part of one undo group, to be
+        broken up so that subsequent undo commands will only undo portions of the text stream.
+
+        * WebCore.exp.in:
+        * WebCore.xcodeproj/project.pbxproj:
+        * editing/mac/TextUndoInsertionMarkup.h: Added.
+        * editing/mac/TextUndoInsertionMarkup.mm: Added.
+        (WebCore::shouldRegisterInsertionUndoGroup):
+        (WebCore::registerInsertionUndoGrouping):
+
</ins><span class="cx"> 2014-06-25  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS]: WK2 Inspector Node Search
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -2427,6 +2427,11 @@
</span><span class="cx"> _wkCreateMemoryStatusPressureCriticalDispatchOnMainQueue
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+__ZN7WebCore32shouldRegisterInsertionUndoGroupEP18NSAttributedString
+__ZN7WebCore44registerInsertionUndoGroupingWithUndoManagerEP13NSUndoManager
+#endif
+
</ins><span class="cx"> #if PLATFORM(MAC) || PLATFORM(IOS_SIMULATOR)
</span><span class="cx"> _wkSetCrashReportApplicationSpecificInformation
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -1037,6 +1037,8 @@
</span><span class="cx">                 293EAE1F1356B2FE0067ACF9 /* RuntimeApplicationChecks.h in Headers */ = {isa = PBXBuildFile; fileRef = 293EAE1E1356B2FE0067ACF9 /* RuntimeApplicationChecks.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 293EAE211356B32E0067ACF9 /* RuntimeApplicationChecks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 293EAE201356B32E0067ACF9 /* RuntimeApplicationChecks.cpp */; };
</span><span class="cx">                 29489FC712C00F0300D83F0F /* AccessibilityScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 29489FC512C00F0300D83F0F /* AccessibilityScrollView.h */; };
</span><ins>+                29498682195341940072D2BD /* TextUndoInsertionMarkup.h in Headers */ = {isa = PBXBuildFile; fileRef = 29498680195341940072D2BD /* TextUndoInsertionMarkup.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                29498683195341940072D2BD /* TextUndoInsertionMarkupMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29498681195341940072D2BD /* TextUndoInsertionMarkupMac.mm */; };
</ins><span class="cx">                 297BE3D516C03C08003316BD /* PlatformSpeechSynthesisUtterance.h in Headers */ = {isa = PBXBuildFile; fileRef = 2527CC9116BF8BA1009DDAC0 /* PlatformSpeechSynthesisUtterance.h */; };
</span><span class="cx">                 297BE3D616C03C0B003316BD /* PlatformSpeechSynthesisVoice.h in Headers */ = {isa = PBXBuildFile; fileRef = 2527CC9216BF90B4009DDAC0 /* PlatformSpeechSynthesisVoice.h */; };
</span><span class="cx">                 297BE3D716C03C0E003316BD /* PlatformSpeechSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */; };
</span><span class="lines">@@ -1064,6 +1066,7 @@
</span><span class="cx">                 29ACB214143E7498006BCA5F /* AccessibilityMockObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29ACB213143E7498006BCA5F /* AccessibilityMockObject.cpp */; };
</span><span class="cx">                 29D7BCF61444AF580070619C /* AccessibilitySpinButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29D7BCF51444AF580070619C /* AccessibilitySpinButton.cpp */; };
</span><span class="cx">                 29D7BCFA1444AF7D0070619C /* AccessibilitySpinButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 29D7BCF91444AF7D0070619C /* AccessibilitySpinButton.h */; };
</span><ins>+                29FAF4B6195AB08900A522DC /* TextUndoInsertionMarkupMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 29FAF4B5195AB08900A522DC /* TextUndoInsertionMarkupMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 2B365C841525119E0091D27B /* RenderSVGEllipse.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B4235A015250F6000DBBCD8 /* RenderSVGEllipse.h */; };
</span><span class="cx">                 2BE8E2C712A589EC00FAD550 /* HTMLMetaCharsetParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BE8E2C612A589EC00FAD550 /* HTMLMetaCharsetParser.h */; };
</span><span class="cx">                 2BE8E2C912A58A0100FAD550 /* HTMLMetaCharsetParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BE8E2C812A58A0100FAD550 /* HTMLMetaCharsetParser.cpp */; };
</span><span class="lines">@@ -7205,8 +7208,8 @@
</span><span class="cx">                 07AB996818DA3C010018771E /* RTCIceServer.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCIceServer.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07AB996D18DA3C740018771E /* RTCConfigurationPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCConfigurationPrivate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07AB996E18DA3C740018771E /* RTCIceServerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCIceServerPrivate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                07AC46FF1952102100EE9723 /* ISOVTTCue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ISOVTTCue.cpp; path = ISOVTTCue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                07AC47001952102100EE9723 /* ISOVTTCue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ISOVTTCue.h; path = ISOVTTCue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><ins>+                07AC46FF1952102100EE9723 /* ISOVTTCue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISOVTTCue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                07AC47001952102100EE9723 /* ISOVTTCue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISOVTTCue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 07B0113E1032242200FBDC33 /* AccessibilityMediaControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityMediaControls.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07B442D4166C70B000556CAD /* InbandTextTrackPrivateAVF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InbandTextTrackPrivateAVF.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07B442D5166C70B000556CAD /* InbandTextTrackPrivateAVF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrackPrivateAVF.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7993,6 +7996,8 @@
</span><span class="cx">                 293EAE1E1356B2FE0067ACF9 /* RuntimeApplicationChecks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeApplicationChecks.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 293EAE201356B32E0067ACF9 /* RuntimeApplicationChecks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeApplicationChecks.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 29489FC512C00F0300D83F0F /* AccessibilityScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityScrollView.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                29498680195341940072D2BD /* TextUndoInsertionMarkup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextUndoInsertionMarkup.h; path = mac/TextUndoInsertionMarkup.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                29498681195341940072D2BD /* TextUndoInsertionMarkupMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TextUndoInsertionMarkupMac.mm; path = mac/TextUndoInsertionMarkupMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 297BE3D916C043D8003316BD /* PlatformSpeechSynthesizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformSpeechSynthesizer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2981CA9D131822EC00D12F2A /* AccessibilityARIAGrid.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityARIAGrid.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2981CA9E131822EC00D12F2A /* AccessibilityARIAGridCell.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityARIAGridCell.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -8041,6 +8046,7 @@
</span><span class="cx">                 29E04A27BED2F81F98E9022B /* JSBeforeUnloadEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBeforeUnloadEvent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformSpeechSynthesizer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 29E4D8E016B0959800C84704 /* PlatformSpeechSynthesizerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformSpeechSynthesizerMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                29FAF4B5195AB08900A522DC /* TextUndoInsertionMarkupMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextUndoInsertionMarkupMac.h; path = mac/TextUndoInsertionMarkupMac.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 2B42359F15250F6000DBBCD8 /* RenderSVGEllipse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGEllipse.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2B4235A015250F6000DBBCD8 /* RenderSVGEllipse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGEllipse.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2BE8E2C612A589EC00FAD550 /* HTMLMetaCharsetParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLMetaCharsetParser.h; path = parser/HTMLMetaCharsetParser.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -17430,6 +17436,7 @@
</span><span class="cx">                                 93309DCC099E64910056E581 /* TextIterator.cpp */,
</span><span class="cx">                                 93309DCD099E64910056E581 /* TextIterator.h */,
</span><span class="cx">                                 9392146818A6D791000EE688 /* TextIteratorBehavior.h */,
</span><ins>+                                29498680195341940072D2BD /* TextUndoInsertionMarkup.h */,
</ins><span class="cx">                                 93309DCA099E64910056E581 /* TypingCommand.cpp */,
</span><span class="cx">                                 93309DCB099E64910056E581 /* TypingCommand.h */,
</span><span class="cx">                                 9B2D8A7814997CCF00ECEF3E /* UndoStep.h */,
</span><span class="lines">@@ -21856,6 +21863,8 @@
</span><span class="cx">                                 4A8C96EA0BE69032004EEFF0 /* FrameSelectionMac.mm */,
</span><span class="cx">                                 CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */,
</span><span class="cx">                                 CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */,
</span><ins>+                                29FAF4B5195AB08900A522DC /* TextUndoInsertionMarkupMac.h */,
+                                29498681195341940072D2BD /* TextUndoInsertionMarkupMac.mm */,
</ins><span class="cx">                         );
</span><span class="cx">                         name = mac;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -26143,6 +26152,7 @@
</span><span class="cx">                                 B2227A690D00BF220071B782 /* SVGPathSegCurvetoCubicSmooth.h in Headers */,
</span><span class="cx">                                 83C1D429178D5AB400141E68 /* SVGPathSegCurvetoCubicSmoothAbs.h in Headers */,
</span><span class="cx">                                 83C1D42A178D5AB400141E68 /* SVGPathSegCurvetoCubicSmoothRel.h in Headers */,
</span><ins>+                                29498682195341940072D2BD /* TextUndoInsertionMarkup.h in Headers */,
</ins><span class="cx">                                 B2227A6D0D00BF220071B782 /* SVGPathSegCurvetoQuadratic.h in Headers */,
</span><span class="cx">                                 83C1D42B178D5AB400141E68 /* SVGPathSegCurvetoQuadraticAbs.h in Headers */,
</span><span class="cx">                                 83C1D42C178D5AB500141E68 /* SVGPathSegCurvetoQuadraticRel.h in Headers */,
</span><span class="lines">@@ -26280,6 +26290,7 @@
</span><span class="cx">                                 93309E1C099E64920056E581 /* TextIterator.h in Headers */,
</span><span class="cx">                                 BCEF45E90E687767001C1287 /* TextMetrics.h in Headers */,
</span><span class="cx">                                 E4D988B417BFD1F60084FB88 /* TextNodeTraversal.h in Headers */,
</span><ins>+                                29FAF4B6195AB08900A522DC /* TextUndoInsertionMarkupMac.h in Headers */,
</ins><span class="cx">                                 1C18DA59181AF6A500C4EF22 /* TextPainter.h in Headers */,
</span><span class="cx">                                 E4C91A0E1802343100A17F6D /* TextPaintStyle.h in Headers */,
</span><span class="cx">                                 930FC68A1072B9280045293E /* TextRenderingMode.h in Headers */,
</span><span class="lines">@@ -29506,6 +29517,7 @@
</span><span class="cx">                                 8419D2AC120D92FC00141F8F /* SVGPathByteStreamSource.cpp in Sources */,
</span><span class="cx">                                 B2227A580D00BF220071B782 /* SVGPathElement.cpp in Sources */,
</span><span class="cx">                                 8476C9EF11DF6A5800555B02 /* SVGPathParser.cpp in Sources */,
</span><ins>+                                29498683195341940072D2BD /* TextUndoInsertionMarkupMac.mm in Sources */,
</ins><span class="cx">                                 B2227A800D00BF220071B782 /* SVGPathSegList.cpp in Sources */,
</span><span class="cx">                                 8476C9E511DF6A0B00555B02 /* SVGPathSegListBuilder.cpp in Sources */,
</span><span class="cx">                                 08FF102012950F5A00F00276 /* SVGPathSegListPropertyTearOff.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingmacTextUndoInsertionMarkuph"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkup.h (0 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkup.h                                (rev 0)
+++ trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkup.h        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/*
+ * Copyright (C) 2014 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. 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 INC. 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.
+ */
+
+#ifndef TextUndoInsertionMarkup_h
+#define TextUndoInsertionMarkup_h
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+#define WTF_USE_INSERTION_UNDO_GROUPING 1
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreeditingmacTextUndoInsertionMarkupMach"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkupMac.h (0 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkupMac.h                                (rev 0)
+++ trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkupMac.h        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+/*
+ * Copyright (C) 2014 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. 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 INC. 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.
+ */
+
+#ifndef TextUndoInsertionMarkupMac_h
+#define TextUndoInsertionMarkupMac_h
+
+#import &lt;WebCore/TextUndoInsertionMarkup.h&gt;
+
+#if USE(INSERTION_UNDO_GROUPING)
+
+#if __has_include(&lt;AppKit/NSTextInputContext_Private.h&gt;)
+#import &lt;AppKit/NSTextInputContext_Private.h&gt;
+#else
+extern &quot;C&quot; NSString *NSTextInsertionUndoableAttributeName;
+#endif
+
+#endif // USE(INSERTION_UNDO_GROUPING)
+
+namespace WebCore {
+    
+#if USE(INSERTION_UNDO_GROUPING)
+bool shouldRegisterInsertionUndoGroup(NSAttributedString*);
+void registerInsertionUndoGroupingWithUndoManager(NSUndoManager*);
+#endif
+    
+} // namespace WebCore
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreeditingmacTextUndoInsertionMarkupMacmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkupMac.mm (0 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkupMac.mm                                (rev 0)
+++ trunk/Source/WebCore/editing/mac/TextUndoInsertionMarkupMac.mm        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+/*
+ * Copyright (C) 2014 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. 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 INC. 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 &quot;config.h&quot;
+#import &quot;TextUndoInsertionMarkupMac.h&quot;
+
+#if __has_include(&lt;Foundation/NSUndoManager_Private.h&gt;)
+#import &lt;Foundation/NSUndoManager_Private.h&gt;
+#else
+@interface NSUndoManager (WebCorePrivate)
+- (void)_processEndOfEventNotification:(id)arg;
+@end
+#endif
+
+namespace WebCore {
+    
+#if USE(INSERTION_UNDO_GROUPING)
+
+bool shouldRegisterInsertionUndoGroup(NSAttributedString* string)
+{
+    return [string attribute:NSTextInsertionUndoableAttributeName atIndex:0 effectiveRange:nil];
+}
+    
+void registerInsertionUndoGroupingWithUndoManager(NSUndoManager* undoManager)
+{
+    if ([undoManager groupingLevel])
+        [undoManager _processEndOfEventNotification:nil];
+}
+    
+#endif
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit/mac/ChangeLog        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2014-06-25  Chris Fleizach  &lt;cfleizach@apple.com&gt;
+
+        Add an undo group for each dictated utterance in WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=134086
+
+        Reviewed by Enrica Casucci.
+
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView validAttributesForMarkedText]):
+        (-[WebHTMLView insertText:]):
+
</ins><span class="cx"> 2014-06-25  Dana Burkart  &lt;dburkart@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add support for 5-tuple versioning.
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebViewWebHTMLViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebView/WebHTMLView.mm (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebView/WebHTMLView.mm        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit/mac/WebView/WebHTMLView.mm        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -113,6 +113,7 @@
</span><span class="cx"> #import &lt;WebCore/StyleProperties.h&gt;
</span><span class="cx"> #import &lt;WebCore/Text.h&gt;
</span><span class="cx"> #import &lt;WebCore/TextAlternativeWithRange.h&gt;
</span><ins>+#import &lt;WebCore/TextUndoInsertionMarkupMac.h&gt;
</ins><span class="cx"> #import &lt;WebCore/WebCoreObjCExtras.h&gt;
</span><span class="cx"> #import &lt;WebCore/WebNSAttributedStringExtras.h&gt;
</span><span class="cx"> #import &lt;WebCore/markup.h&gt;
</span><span class="lines">@@ -6041,6 +6042,9 @@
</span><span class="cx"> #if USE(DICTATION_ALTERNATIVES)
</span><span class="cx">                            NSTextAlternativesAttributeName,
</span><span class="cx"> #endif
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+                           NSTextInsertionUndoableAttributeName,
+#endif
</ins><span class="cx">                            nil];
</span><span class="cx">         // NSText also supports the following attributes, but it's
</span><span class="cx">         // hard to tell which are really required for text input to
</span><span class="lines">@@ -6385,6 +6389,9 @@
</span><span class="cx">     NSString *text;
</span><span class="cx">     NSRange replacementRange = { NSNotFound, 0 };
</span><span class="cx">     bool isFromInputMethod = coreFrame &amp;&amp; coreFrame-&gt;editor().hasComposition();
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+    bool registerUndoGroup = false;
+#endif
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;DictationAlternative&gt; dictationAlternativeLocations;
</span><span class="cx"> #if !PLATFORM(IOS)
</span><span class="lines">@@ -6395,6 +6402,9 @@
</span><span class="cx">         if (!textAlternatives.isEmpty())
</span><span class="cx">             [[self _webView] _getWebCoreDictationAlternatives:dictationAlternativeLocations fromTextAlternatives:textAlternatives];
</span><span class="cx"> #endif
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+        registerUndoGroup = shouldRegisterInsertionUndoGroup(string);
+#endif
</ins><span class="cx">         // FIXME: We ignore most attributes from the string, so for example inserting from Character Palette loses font and glyph variation data.
</span><span class="cx">         // It does not look like any input methods ever use insertText: with attributes other than NSTextInputReplacementRangeAttributeName.
</span><span class="cx">         text = [string string];
</span><span class="lines">@@ -6439,6 +6449,11 @@
</span><span class="cx">             eventHandled = coreFrame-&gt;editor().insertDictatedText(eventText, dictationAlternativeLocations, event);
</span><span class="cx">         else
</span><span class="cx">             eventHandled = coreFrame-&gt;editor().insertText(eventText, event);
</span><ins>+        
+#if USE(INSERTION_UNDO_GROUPING)
+        if (registerUndoGroup)
+            registerInsertionUndoGroupingWithUndoManager([[self _webView] undoManager]);
+#endif
</ins><span class="cx">     } else {
</span><span class="cx">         eventHandled = true;
</span><span class="cx">         coreFrame-&gt;editor().confirmComposition(eventText);
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/ChangeLog        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2014-06-25  Chris Fleizach  &lt;cfleizach@apple.com&gt;
+
+        Add an undo group for each dictated utterance in WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=134086
+
+        Reviewed by Enrica Casucci.
+
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView insertText:replacementRange:]):
+        (-[WKView validAttributesForMarkedText]):
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::registerInsertionUndoGrouping):
+        (WebKit::WebPageProxy::insertTextAsync):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::registerInsertionUndoGrouping):
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::registerInsertionUndoGrouping):
+        * UIProcess/mac/WebPageProxyMac.mm:
+        (WebKit::WebPageProxy::insertDictatedTextAsync):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::insertTextAsync):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::insertDictatedTextAsync):
+
</ins><span class="cx"> 2014-06-25  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS]: WK2 Inspector Node Search
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPImacWKViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -90,6 +90,7 @@
</span><span class="cx"> #import &lt;WebCore/Region.h&gt;
</span><span class="cx"> #import &lt;WebCore/SharedBuffer.h&gt;
</span><span class="cx"> #import &lt;WebCore/TextAlternativeWithRange.h&gt;
</span><ins>+#import &lt;WebCore/TextUndoInsertionMarkupMac.h&gt;
</ins><span class="cx"> #import &lt;WebCore/WebActionDisablingCALayerDelegate.h&gt;
</span><span class="cx"> #import &lt;WebCore/WebCoreCALayerExtras.h&gt;
</span><span class="cx"> #import &lt;WebCore/WebCoreFullScreenPlaceholderView.h&gt;
</span><span class="lines">@@ -1429,10 +1430,14 @@
</span><span class="cx">     NSString *text;
</span><span class="cx">     Vector&lt;TextAlternativeWithRange&gt; dictationAlternatives;
</span><span class="cx"> 
</span><ins>+    bool registerUndoGroup = false;
</ins><span class="cx">     if (isAttributedString) {
</span><span class="cx"> #if USE(DICTATION_ALTERNATIVES)
</span><span class="cx">         collectDictationTextAlternatives(string, dictationAlternatives);
</span><span class="cx"> #endif
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+        registerUndoGroup = shouldRegisterInsertionUndoGroup(string);
+#endif
</ins><span class="cx">         // FIXME: We ignore most attributes from the string, so for example inserting from Character Palette loses font and glyph variation data.
</span><span class="cx">         text = [string string];
</span><span class="cx">     } else
</span><span class="lines">@@ -1456,9 +1461,9 @@
</span><span class="cx">     String eventText = text;
</span><span class="cx">     eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore
</span><span class="cx">     if (!dictationAlternatives.isEmpty())
</span><del>-        _data-&gt;_page-&gt;insertDictatedTextAsync(eventText, replacementRange, dictationAlternatives);
</del><ins>+        _data-&gt;_page-&gt;insertDictatedTextAsync(eventText, replacementRange, dictationAlternatives, registerUndoGroup);
</ins><span class="cx">     else
</span><del>-        _data-&gt;_page-&gt;insertTextAsync(eventText, replacementRange);
</del><ins>+        _data-&gt;_page-&gt;insertTextAsync(eventText, replacementRange, registerUndoGroup);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)selectedRangeWithCompletionHandler:(void(^)(NSRange selectedRange))completionHandlerPtr
</span><span class="lines">@@ -2233,6 +2238,9 @@
</span><span class="cx"> #if USE(DICTATION_ALTERNATIVES)
</span><span class="cx">                            NSTextAlternativesAttributeName,
</span><span class="cx"> #endif
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+                           NSTextInsertionUndoableAttributeName,
+#endif
</ins><span class="cx">                            nil];
</span><span class="cx">         // NSText also supports the following attributes, but it's
</span><span class="cx">         // hard to tell which are really required for text input to
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPageClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/PageClient.h        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> #include &quot;PluginComplexTextInputState.h&quot;
</span><ins>+#include &lt;WebCore/TextUndoInsertionMarkup.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> OBJC_CLASS CALayer;
</span><span class="cx"> 
</span><span class="lines">@@ -242,6 +243,9 @@
</span><span class="cx">     virtual void showDictationAlternativeUI(const WebCore::FloatRect&amp; boundingBoxOfDictatedText, uint64_t dictationContext) = 0;
</span><span class="cx">     virtual Vector&lt;String&gt; dictationAlternatives(uint64_t dictationContext) = 0;
</span><span class="cx"> #endif // USE(DICTATION_ALTERNATIVES)
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+    virtual void registerInsertionUndoGrouping() = 0;
+#endif // USE(INSERTION_UNDO_GROUPING)
</ins><span class="cx"> #endif // USE(APPKIT)
</span><span class="cx"> #endif // PLATFORM(MAC)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -3396,6 +3396,13 @@
</span><span class="cx"> {
</span><span class="cx">     registerEditCommand(WebEditCommandProxy::create(commandID, static_cast&lt;EditAction&gt;(editAction), this), Undo);
</span><span class="cx"> }
</span><ins>+    
+void WebPageProxy::registerInsertionUndoGrouping()
+{
+#if USE(INSERTION_UNDO_GROUPING)
+    m_pageClient.registerInsertionUndoGrouping();
+#endif
+}
</ins><span class="cx"> 
</span><span class="cx"> void WebPageProxy::canUndoRedo(uint32_t action, bool&amp; result)
</span><span class="cx"> {
</span><span class="lines">@@ -4951,12 +4958,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> 
</span><del>-void WebPageProxy::insertTextAsync(const String&amp; text, const EditingRange&amp; replacementRange)
</del><ins>+void WebPageProxy::insertTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, bool registerUndoGroup)
</ins><span class="cx"> {
</span><span class="cx">     if (!isValid())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    process().send(Messages::WebPage::InsertTextAsync(text, replacementRange), m_pageID);
</del><ins>+    process().send(Messages::WebPage::InsertTextAsync(text, replacementRange, registerUndoGroup), m_pageID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::getMarkedRangeAsync(std::function&lt;void (EditingRange, CallbackBase::Error)&gt; callbackFunction)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -472,7 +472,7 @@
</span><span class="cx">     void setAcceleratedCompositingRootLayer(LayerOrView*);
</span><span class="cx">     LayerOrView* acceleratedCompositingRootLayer() const;
</span><span class="cx"> 
</span><del>-    void insertTextAsync(const String&amp; text, const EditingRange&amp; replacementRange);
</del><ins>+    void insertTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, bool registerUndoGroup = false);
</ins><span class="cx">     void getMarkedRangeAsync(std::function&lt;void (EditingRange, CallbackBase::Error)&gt;);
</span><span class="cx">     void getSelectedRangeAsync(std::function&lt;void (EditingRange, CallbackBase::Error)&gt;);
</span><span class="cx">     void characterIndexForPointAsync(const WebCore::IntPoint&amp;, std::function&lt;void (uint64_t, CallbackBase::Error)&gt;);
</span><span class="lines">@@ -481,7 +481,7 @@
</span><span class="cx">     void confirmCompositionAsync();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><del>-    void insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, const Vector&lt;WebCore::TextAlternativeWithRange&gt;&amp; dictationAlternatives);
</del><ins>+    void insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, const Vector&lt;WebCore::TextAlternativeWithRange&gt;&amp; dictationAlternatives, bool registerUndoGroup);
</ins><span class="cx">     void attributedSubstringForCharacterRangeAsync(const EditingRange&amp;, std::function&lt;void (const AttributedString&amp;, const EditingRange&amp;, CallbackBase::Error)&gt;);
</span><span class="cx"> 
</span><span class="cx"> #if !USE(ASYNC_NSTEXTINPUTCLIENT)
</span><span class="lines">@@ -1058,6 +1058,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Undo management
</span><span class="cx">     void registerEditCommandForUndo(uint64_t commandID, uint32_t editAction);
</span><ins>+    void registerInsertionUndoGrouping();
</ins><span class="cx">     void clearAllEditCommands();
</span><span class="cx">     void canUndoRedo(uint32_t action, bool&amp; result);
</span><span class="cx">     void executeUndoRedo(uint32_t action, bool&amp; result);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -210,6 +210,7 @@
</span><span class="cx">     # Undo/Redo messages
</span><span class="cx">     RegisterEditCommandForUndo(uint64_t commandID, uint32_t editAction)
</span><span class="cx">     ClearAllEditCommands()
</span><ins>+    RegisterInsertionUndoGrouping()
</ins><span class="cx">     CanUndoRedo(uint32_t action) -&gt; (bool result)
</span><span class="cx">     ExecuteUndoRedo(uint32_t action) -&gt; (bool result)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosPageClientImplIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -235,6 +235,13 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+void PageClientImpl::registerInsertionUndoGrouping()
+{
+    notImplemented();
+}
+#endif
+
</ins><span class="cx"> void PageClientImpl::clearAllEditCommands()
</span><span class="cx"> {
</span><span class="cx">     notImplemented();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacPageClientImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -154,6 +154,9 @@
</span><span class="cx">     virtual void showDictationAlternativeUI(const WebCore::FloatRect&amp; boundingBoxOfDictatedText, uint64_t dictationContext);
</span><span class="cx">     virtual Vector&lt;String&gt; dictationAlternatives(uint64_t dictationContext);
</span><span class="cx"> #endif
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+    virtual void registerInsertionUndoGrouping() override;
+#endif
</ins><span class="cx"> 
</span><span class="cx">     // Auxiliary Client Creation
</span><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacPageClientImplmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -58,6 +58,7 @@
</span><span class="cx"> #import &lt;WebCore/KeyboardEvent.h&gt;
</span><span class="cx"> #import &lt;WebCore/NotImplemented.h&gt;
</span><span class="cx"> #import &lt;WebCore/SharedBuffer.h&gt;
</span><ins>+#import &lt;WebCore/TextUndoInsertionMarkupMac.h&gt;
</ins><span class="cx"> #import &lt;WebKitSystemInterface.h&gt;
</span><span class="cx"> #import &lt;wtf/text/CString.h&gt;
</span><span class="cx"> #import &lt;wtf/text/WTFString.h&gt;
</span><span class="lines">@@ -360,6 +361,13 @@
</span><span class="cx">         [undoManager setActionName:(NSString *)actionName];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if USE(INSERTION_UNDO_GROUPING)
+void PageClientImpl::registerInsertionUndoGrouping()
+{
+    registerInsertionUndoGroupingWithUndoManager([m_wkView undoManager]);
+}
+#endif
+
</ins><span class="cx"> void PageClientImpl::clearAllEditCommands()
</span><span class="cx"> {
</span><span class="cx">     [[m_wkView undoManager] removeAllActionsWithTarget:m_undoTarget.get()];
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacWebPageProxyMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -300,7 +300,7 @@
</span><span class="cx"> 
</span><span class="cx"> #endif // !USE(ASYNC_NSTEXTINPUTCLIENT)
</span><span class="cx"> 
</span><del>-void WebPageProxy::insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, const Vector&lt;TextAlternativeWithRange&gt;&amp; dictationAlternativesWithRange)
</del><ins>+void WebPageProxy::insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, const Vector&lt;TextAlternativeWithRange&gt;&amp; dictationAlternativesWithRange, bool registerUndoGroup)
</ins><span class="cx"> {
</span><span class="cx"> #if USE(DICTATION_ALTERNATIVES)
</span><span class="cx">     if (!isValid())
</span><span class="lines">@@ -315,13 +315,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (dictationAlternatives.isEmpty()) {
</span><del>-        insertTextAsync(text, replacementRange);
</del><ins>+        insertTextAsync(text, replacementRange, registerUndoGroup);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    process().send(Messages::WebPage::InsertDictatedTextAsync(text, replacementRange, dictationAlternatives), m_pageID);
</del><ins>+    process().send(Messages::WebPage::InsertDictatedTextAsync(text, replacementRange, dictationAlternatives, registerUndoGroup), m_pageID);
</ins><span class="cx"> #else
</span><del>-    insertTextAsync(text, replacementRange);
</del><ins>+    insertTextAsync(text, replacementRange, registerUndoGroup);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -4035,7 +4035,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> 
</span><del>-void WebPage::insertTextAsync(const String&amp; text, const EditingRange&amp; replacementEditingRange)
</del><ins>+void WebPage::insertTextAsync(const String&amp; text, const EditingRange&amp; replacementEditingRange, bool registerUndoGroup)
</ins><span class="cx"> {
</span><span class="cx">     Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
</span><span class="cx"> 
</span><span class="lines">@@ -4044,7 +4044,10 @@
</span><span class="cx">         if (replacementRange)
</span><span class="cx">             frame.selection().setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
</span><span class="cx">     }
</span><del>-
</del><ins>+    
+    if (registerUndoGroup)
+        send(Messages::WebPageProxy::RegisterInsertionUndoGrouping());
+    
</ins><span class="cx">     if (!frame.editor().hasComposition()) {
</span><span class="cx">         // An insertText: might be handled by other responders in the chain if we don't handle it.
</span><span class="cx">         // One example is space bar that results in scrolling down the page.
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -589,7 +589,7 @@
</span><span class="cx">     
</span><span class="cx">     void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String&amp; textInput);
</span><span class="cx"> 
</span><del>-    void insertTextAsync(const String&amp; text, const EditingRange&amp; replacementRange);
</del><ins>+    void insertTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, bool registerUndoGroup = false);
</ins><span class="cx">     void getMarkedRangeAsync(uint64_t callbackID);
</span><span class="cx">     void getSelectedRangeAsync(uint64_t callbackID);
</span><span class="cx">     void characterIndexForPointAsync(const WebCore::IntPoint&amp;, uint64_t callbackID);
</span><span class="lines">@@ -598,7 +598,7 @@
</span><span class="cx">     void confirmCompositionAsync();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><del>-    void insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, const Vector&lt;WebCore::DictationAlternative&gt;&amp; dictationAlternativeLocations);
</del><ins>+    void insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, const Vector&lt;WebCore::DictationAlternative&gt;&amp; dictationAlternativeLocations, bool registerUndoGroup = false);
</ins><span class="cx">     void attributedSubstringForCharacterRangeAsync(const EditingRange&amp;, uint64_t callbackID);
</span><span class="cx"> #if !USE(ASYNC_NSTEXTINPUTCLIENT)
</span><span class="cx">     void insertText(const String&amp; text, const EditingRange&amp; replacementRange, bool&amp; handled, EditorState&amp; newState);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -326,7 +326,7 @@
</span><span class="cx">     ShouldDelayWindowOrderingEvent(WebKit::WebMouseEvent event) -&gt; (bool result)
</span><span class="cx">     AcceptsFirstMouse(int eventNumber, WebKit::WebMouseEvent event) -&gt; (bool result)
</span><span class="cx"> 
</span><del>-    InsertTextAsync(String text, WebKit::EditingRange replacementRange)
</del><ins>+    InsertTextAsync(String text, WebKit::EditingRange replacementRange, bool registerUndoGroup)
</ins><span class="cx">     GetMarkedRangeAsync(uint64_t callbackID)
</span><span class="cx">     GetSelectedRangeAsync(uint64_t callbackID)
</span><span class="cx">     CharacterIndexForPointAsync(WebCore::IntPoint point, uint64_t callbackID);
</span><span class="lines">@@ -335,7 +335,7 @@
</span><span class="cx">     ConfirmCompositionAsync()
</span><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(MAC)
</span><del>-    InsertDictatedTextAsync(String text, WebKit::EditingRange replacementRange, Vector&lt;WebCore::DictationAlternative&gt; dictationAlternatives)
</del><ins>+    InsertDictatedTextAsync(String text, WebKit::EditingRange replacementRange, Vector&lt;WebCore::DictationAlternative&gt; dictationAlternatives, bool registerUndoGroup)
</ins><span class="cx">     AttributedSubstringForCharacterRangeAsync(WebKit::EditingRange range, uint64_t callbackID);
</span><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; !USE(ASYNC_NSTEXTINPUTCLIENT)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -412,7 +412,7 @@
</span><span class="cx"> 
</span><span class="cx"> #endif // !USE(ASYNC_NSTEXTINPUTCLIENT)
</span><span class="cx"> 
</span><del>-void WebPage::insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementEditingRange, const Vector&lt;WebCore::DictationAlternative&gt;&amp; dictationAlternativeLocations)
</del><ins>+void WebPage::insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementEditingRange, const Vector&lt;WebCore::DictationAlternative&gt;&amp; dictationAlternativeLocations, bool registerUndoGroup)
</ins><span class="cx"> {
</span><span class="cx">     Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
</span><span class="cx"> 
</span><span class="lines">@@ -422,6 +422,9 @@
</span><span class="cx">             frame.selection().setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (registerUndoGroup)
+        send(Messages::WebPageProxy::RegisterInsertionUndoGrouping());
+    
</ins><span class="cx">     ASSERT(!frame.editor().hasComposition());
</span><span class="cx">     frame.editor().insertDictatedText(text, dictationAlternativeLocations, nullptr);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Tools/ChangeLog        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2014-06-25  Chris Fleizach  &lt;cfleizach@apple.com&gt;
+
+        Add an undo group for each dictated utterance in WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=134086
+
+        Reviewed by Enrica Casucci.
+
+        Create a method for creating attributed strings with the undo insertion marker.
+
+        * DumpRenderTree/mac/TextInputController.m:
+        (+[TextInputController isSelectorExcludedFromWebScript:]):
+        (+[TextInputController webScriptNameForSelector:]):
+        (-[TextInputController stringWithUndoGroupingInsertion:]):
+
</ins><span class="cx"> 2014-06-25  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Provide javascript aware backtrace script for lldb
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacTextInputControllerm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/TextInputController.m (170446 => 170447)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/TextInputController.m        2014-06-25 23:41:19 UTC (rev 170446)
+++ trunk/Tools/DumpRenderTree/mac/TextInputController.m        2014-06-25 23:50:44 UTC (rev 170447)
</span><span class="lines">@@ -38,6 +38,15 @@
</span><span class="cx"> #define SUPPORT_DICTATION_ALTERNATIVES
</span><span class="cx"> #import &lt;AppKit/NSTextAlternatives.h&gt;
</span><span class="cx"> #endif
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+#define SUPPORT_INSERTION_UNDO_GROUPING
+#if __has_include(&lt;AppKit/NSTextInputContext_Private.h&gt;)
+#import &lt;AppKit/NSTextInputContext_Private.h&gt;
+#else
+extern &quot;C&quot; NSString *NSTextInsertionUndoableAttributeName;
+#endif
+#endif
+
</ins><span class="cx"> #import &lt;WebKit/WebDocument.h&gt;
</span><span class="cx"> #import &lt;WebKit/WebFrame.h&gt;
</span><span class="cx"> #import &lt;WebKit/WebFramePrivate.h&gt;
</span><span class="lines">@@ -232,7 +241,8 @@
</span><span class="cx">             || aSelector == @selector(validAttributesForMarkedText)
</span><span class="cx">             || aSelector == @selector(attributedStringWithString:)
</span><span class="cx">             || aSelector == @selector(setInputMethodHandler:)
</span><del>-            || aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:))
</del><ins>+            || aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:)
+            || aSelector == @selector(stringWithUndoGroupingInsertion:))
</ins><span class="cx">         return NO;
</span><span class="cx">     return YES;
</span><span class="cx"> }
</span><span class="lines">@@ -261,6 +271,8 @@
</span><span class="cx">         return @&quot;setInputMethodHandler&quot;;
</span><span class="cx">     else if (aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:))
</span><span class="cx">         return @&quot;makeDictatedString&quot;;
</span><ins>+    else if (aSelector == @selector(stringWithUndoGroupingInsertion:))
+        return @&quot;makeUndoGroupingInsertionString&quot;;
</ins><span class="cx"> 
</span><span class="cx">     return nil;
</span><span class="cx"> }
</span><span class="lines">@@ -452,6 +464,17 @@
</span><span class="cx">     return [[[NSMutableAttributedString alloc] initWithString:aString] autorelease];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (NSMutableAttributedString*)stringWithUndoGroupingInsertion:(NSString*)aString
+{
+#if defined(SUPPORT_INSERTION_UNDO_GROUPING) &amp;&amp; defined(SUPPORT_DICTATION_ALTERNATIVES)
+    NSMutableAttributedString* attributedString = [self dictatedStringWithPrimaryString:aString alternative:@&quot;test&quot; alternativeOffset:0 alternativeLength:1];
+    [attributedString addAttribute:NSTextInsertionUndoableAttributeName value:@YES range:NSMakeRange(0, [attributedString length])];
+    return attributedString;
+#else
+    return nil;
+#endif
+}
+
</ins><span class="cx"> - (NSMutableAttributedString*)dictatedStringWithPrimaryString:(NSString*)aString alternative:(NSString*)alternative alternativeOffset:(int)offset alternativeLength:(int)length
</span><span class="cx"> {
</span><span class="cx"> #if defined(SUPPORT_DICTATION_ALTERNATIVES)
</span></span></pre>
</div>
</div>

</body>
</html>