<!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>[210638] branches/safari-603-branch</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/210638">210638</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2017-01-12 08:44:58 -0800 (Thu, 12 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/210432">r210432</a>. rdar://problem/29633667</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari603branchLayoutTestsChangeLog">branches/safari-603-branch/LayoutTests/ChangeLog</a></li>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorcountmarklineboxesexpectedtxt">branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-lineboxes-expected.txt</a></li>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorcountmarklineboxeshtml">branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-lineboxes.html</a></li>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorcountmarksimplelinesexpectedtxt">branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-simple-lines-expected.txt</a></li>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorcountmarksimplelineshtml">branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-simple-lines.html</a></li>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorcountmatchesinformexpectedtxt">branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-form-expected.txt</a></li>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorcountmatchesinformhtml">branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-form.html</a></li>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorcountmatchesinframeshtml">branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-frames.html</a></li>
<li><a href="#branchessafari603branchLayoutTestsfasttextmarkmatchesbrokenlinerenderinghtml">branches/safari-603-branch/LayoutTests/fast/text/mark-matches-broken-line-rendering.html</a></li>
<li><a href="#branchessafari603branchLayoutTestsfasttextmarkmatchesoverflowcliphtml">branches/safari-603-branch/LayoutTests/fast/text/mark-matches-overflow-clip.html</a></li>
<li><a href="#branchessafari603branchLayoutTestsfasttextmarkmatchesrenderingsimplelinesexpectedhtml">branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering-simple-lines-expected.html</a></li>
<li><a href="#branchessafari603branchLayoutTestsfasttextmarkmatchesrenderingsimplelineshtml">branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering-simple-lines.html</a></li>
<li><a href="#branchessafari603branchLayoutTestsfasttextmarkmatchesrenderinghtml">branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering.html</a></li>
<li><a href="#branchessafari603branchSourceWebCoreChangeLog">branches/safari-603-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceWebCoreeditingEditorcpp">branches/safari-603-branch/Source/WebCore/editing/Editor.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCoreeditingEditorh">branches/safari-603-branch/Source/WebCore/editing/Editor.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreeditingEditorCommandcpp">branches/safari-603-branch/Source/WebCore/editing/EditorCommand.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCoreeditingFindOptionsh">branches/safari-603-branch/Source/WebCore/editing/FindOptions.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreeditingTextIteratorcpp">branches/safari-603-branch/Source/WebCore/editing/TextIterator.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCoreeditingTextIteratorBehaviorh">branches/safari-603-branch/Source/WebCore/editing/TextIteratorBehavior.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorepageDOMWindowcpp">branches/safari-603-branch/Source/WebCore/page/DOMWindow.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCoretestingInternalscpp">branches/safari-603-branch/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCoretestingInternalsh">branches/safari-603-branch/Source/WebCore/testing/Internals.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoretestingInternalsidl">branches/safari-603-branch/Source/WebCore/testing/Internals.idl</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorfindstringonflattreeexpectedtxt">branches/safari-603-branch/LayoutTests/editing/text-iterator/find-string-on-flat-tree-expected.txt</a></li>
<li><a href="#branchessafari603branchLayoutTestseditingtextiteratorfindstringonflattreehtml">branches/safari-603-branch/LayoutTests/editing/text-iterator/find-string-on-flat-tree.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari603branchLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/ChangeLog (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/ChangeLog        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/ChangeLog        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2017-01-12  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
+        Merge r210432. rdar://problem/29633667
+
+    2017-01-05  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+            Finding text doesn't work across shadow boundary
+            https://bugs.webkit.org/show_bug.cgi?id=158503
+
+            Reviewed by Antti Koivisto.
+
+            Updated the existing tests per changes to use an array of find options instead of raw bit mask,
+            and added a regression test for finding text by traversing flat tree along with testing
+            window.find and execCommand('FindString', false, ~) not walking across shadow boundaries.
+
+            * editing/text-iterator/count-mark-lineboxes-expected.txt:
+            * editing/text-iterator/count-mark-lineboxes.html:
+            * editing/text-iterator/count-mark-simple-lines-expected.txt:
+            * editing/text-iterator/count-mark-simple-lines.html:
+            * editing/text-iterator/count-matches-in-form-expected.txt:
+            * editing/text-iterator/count-matches-in-form.html:
+            * editing/text-iterator/count-matches-in-frames.html:
+            * editing/text-iterator/find-string-on-flat-tree-expected.txt: Added.
+            * editing/text-iterator/find-string-on-flat-tree.html: Added.
+            * fast/text/mark-matches-broken-line-rendering.html:
+            * fast/text/mark-matches-overflow-clip.html:
+            * fast/text/mark-matches-rendering-simple-lines-expected.html:
+            * fast/text/mark-matches-rendering-simple-lines.html:
+            * fast/text/mark-matches-rendering.html:
+
</ins><span class="cx"> 2017-01-06  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Merge r210377.
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorcountmarklineboxesexpectedtxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-lineboxes-expected.txt (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-lineboxes-expected.txt        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-lineboxes-expected.txt        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -1,8 +1,8 @@
</span><del>-PASS internals.countMatchesForText('Catilina', 23, 'mark') is 3
</del><ins>+PASS internals.countMatchesForText('Catilina', findOptions, 'mark') is 3
</ins><span class="cx"> PASS internals.markerCountForNode(text, 'all') is 3
</span><del>-PASS internals.countMatchesForText('Roma', 23, 'mark') is 3
</del><ins>+PASS internals.countMatchesForText('Roma', findOptions, 'mark') is 3
</ins><span class="cx"> PASS internals.markerCountForNode(text, 'all') is 6
</span><del>-PASS internals.countMatchesForText('uid', 23, 'mark') is 2
</del><ins>+PASS internals.countMatchesForText('uid', findOptions, 'mark') is 2
</ins><span class="cx"> PASS internals.markerCountForNode(text, 'all') is 8
</span><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorcountmarklineboxeshtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-lineboxes.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-lineboxes.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-lineboxes.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -49,11 +49,12 @@
</span><span class="cx"> &lt;/p&gt;
</span><span class="cx"> &lt;script&gt;
</span><span class="cx"> var text = document.getElementById('test').firstChild;
</span><del>-shouldBe(&quot;internals.countMatchesForText('Catilina', 23, 'mark')&quot;, &quot;3&quot;);
</del><ins>+var findOptions = ['CaseInsensitive', 'AtWordStarts', 'TreatMedialCapitalAsWordStart', 'WrapAround'];
+shouldBe(&quot;internals.countMatchesForText('Catilina', findOptions, 'mark')&quot;, &quot;3&quot;);
</ins><span class="cx"> shouldBe(&quot;internals.markerCountForNode(text, 'all')&quot;, &quot;3&quot;);
</span><del>-shouldBe(&quot;internals.countMatchesForText('Roma', 23, 'mark')&quot;, &quot;3&quot;);
</del><ins>+shouldBe(&quot;internals.countMatchesForText('Roma', findOptions, 'mark')&quot;, &quot;3&quot;);
</ins><span class="cx"> shouldBe(&quot;internals.markerCountForNode(text, 'all')&quot;, &quot;6&quot;);
</span><del>-shouldBe(&quot;internals.countMatchesForText('uid', 23, 'mark')&quot;, &quot;2&quot;);
</del><ins>+shouldBe(&quot;internals.countMatchesForText('uid', findOptions, 'mark')&quot;, &quot;2&quot;);
</ins><span class="cx"> shouldBe(&quot;internals.markerCountForNode(text, 'all')&quot;, &quot;8&quot;);
</span><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorcountmarksimplelinesexpectedtxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-simple-lines-expected.txt (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-simple-lines-expected.txt        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-simple-lines-expected.txt        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -1,8 +1,8 @@
</span><del>-PASS internals.countMatchesForText('Catilina', 23, 'mark') is 3
</del><ins>+PASS internals.countMatchesForText('Catilina', findOptions, 'mark') is 3
</ins><span class="cx"> PASS internals.markerCountForNode(text, 'all') is 3
</span><del>-PASS internals.countMatchesForText('Roma', 23, 'mark') is 3
</del><ins>+PASS internals.countMatchesForText('Roma', findOptions, 'mark') is 3
</ins><span class="cx"> PASS internals.markerCountForNode(text, 'all') is 6
</span><del>-PASS internals.countMatchesForText('uid', 23, 'mark') is 2
</del><ins>+PASS internals.countMatchesForText('uid', findOptions, 'mark') is 2
</ins><span class="cx"> PASS internals.markerCountForNode(text, 'all') is 8
</span><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorcountmarksimplelineshtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-simple-lines.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-simple-lines.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/count-mark-simple-lines.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -46,11 +46,12 @@
</span><span class="cx"> &lt;/p&gt;
</span><span class="cx"> &lt;script&gt;
</span><span class="cx"> var text = document.getElementById('test').firstChild;
</span><del>-shouldBe(&quot;internals.countMatchesForText('Catilina', 23, 'mark')&quot;, &quot;3&quot;);
</del><ins>+var findOptions = ['CaseInsensitive', 'AtWordStarts', 'TreatMedialCapitalAsWordStart', 'WrapAround'];
+shouldBe(&quot;internals.countMatchesForText('Catilina', findOptions, 'mark')&quot;, &quot;3&quot;);
</ins><span class="cx"> shouldBe(&quot;internals.markerCountForNode(text, 'all')&quot;, &quot;3&quot;);
</span><del>-shouldBe(&quot;internals.countMatchesForText('Roma', 23, 'mark')&quot;, &quot;3&quot;);
</del><ins>+shouldBe(&quot;internals.countMatchesForText('Roma', findOptions, 'mark')&quot;, &quot;3&quot;);
</ins><span class="cx"> shouldBe(&quot;internals.markerCountForNode(text, 'all')&quot;, &quot;6&quot;);
</span><del>-shouldBe(&quot;internals.countMatchesForText('uid', 23, 'mark')&quot;, &quot;2&quot;);
</del><ins>+shouldBe(&quot;internals.countMatchesForText('uid', findOptions, 'mark')&quot;, &quot;2&quot;);
</ins><span class="cx"> shouldBe(&quot;internals.markerCountForNode(text, 'all')&quot;, &quot;8&quot;);
</span><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorcountmatchesinformexpectedtxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-form-expected.txt (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-form-expected.txt        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-form-expected.txt        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-PASS internals.countMatchesForText('rule', 23, '') is 1
</del><ins>+PASS internals.countMatchesForText('rule', ['CaseInsensitive', 'AtWordStarts', 'TreatMedialCapitalAsWordStart', 'WrapAround'], '') is 1
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorcountmatchesinformhtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-form.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-form.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-form.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -3,6 +3,6 @@
</span><span class="cx"> &lt;body&gt;
</span><span class="cx"> &lt;fieldset&gt;&lt;input value=&quot;rule&quot;&gt;&lt;/fieldset&gt;
</span><span class="cx"> &lt;script&gt;
</span><del>-shouldBe(&quot;internals.countMatchesForText('rule', 23, '')&quot;, &quot;1&quot;);
</del><ins>+shouldBe(&quot;internals.countMatchesForText('rule', ['CaseInsensitive', 'AtWordStarts', 'TreatMedialCapitalAsWordStart', 'WrapAround'], '')&quot;, &quot;1&quot;);
</ins><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorcountmatchesinframeshtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-frames.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-frames.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/count-matches-in-frames.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> 
</span><span class="cx">     frame.contentDocument.body.innerHTML = findString;
</span><span class="cx"> 
</span><del>-    assert_equals(internals.countFindMatches(findString, 0, ''), shouldFindInFrame ? 2 : 1);
</del><ins>+    assert_equals(internals.countFindMatches(findString, [], ''), shouldFindInFrame ? 2 : 1);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> test(function () {
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorfindstringonflattreeexpectedtxt"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/LayoutTests/editing/text-iterator/find-string-on-flat-tree-expected.txt (0 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/find-string-on-flat-tree-expected.txt                                (rev 0)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/find-string-on-flat-tree-expected.txt        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -0,0 +1,83 @@
</span><ins>+This tests finding across shadow boundaries using the flat tree.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS clearSelection(); document.execCommand('FindString', null, 'in-document'); selectedText() is '(#test-content, 0) 0 to 11'
+PASS clearSelection(); window.find('in-document'); selectedText() is '(#test-content, 0) 0 to 11'
+PASS rangeText(internals.rangeOfString('in-document', null, ['DoNotTraverseFlatTree'])) is '(#test-content, 0) 0 to 11'
+PASS rangeText(internals.rangeOfString('in-document', null, [])) is '(#test-content, 0) 0 to 11'
+PASS clearSelection(); document.execCommand('FindString', null, 'in-shadow'); selectedText() is null
+PASS clearSelection(); window.find('in-shadow'); selectedText() is null
+PASS rangeText(internals.rangeOfString('in-shadow', null, ['DoNotTraverseFlatTree'])) is null
+PASS rangeText(internals.rangeOfString('in-shadow', null, [])) is '(#shadow-root, 0) 0 to 9'
+PASS clearSelection(); document.execCommand('FindString', null, 'unslotted'); selectedText() is null
+PASS clearSelection(); window.find('unslotted'); selectedText() is null
+PASS rangeText(internals.rangeOfString('unslotted', null, ['DoNotTraverseFlatTree'])) is null
+PASS rangeText(internals.rangeOfString('unslotted', null, [])) is null
+PASS clearSelection(); document.execCommand('FindString', null, 'slotted'); selectedText() is '(#slotted-element, 0) 0 to 7'
+PASS clearSelection(); window.find('slotted'); selectedText() is '(#slotted-element, 0) 0 to 7'
+PASS rangeText(internals.rangeOfString('slotted', null, ['DoNotTraverseFlatTree'])) is '(#slotted-element, 0) 0 to 7'
+PASS rangeText(internals.rangeOfString('slotted', null, [])) is '(#slotted-element, 0) 0 to 7'
+PASS clearSelection(); document.execCommand('FindString', null, 'slotted in-document'); selectedText() is '((#slotted-element, 0), 0) to ((#test-content, 2), 12)'
+PASS clearSelection(); window.find('slotted in-document'); selectedText() is '((#slotted-element, 0), 0) to ((#test-content, 2), 12)'
+PASS rangeText(internals.rangeOfString('slotted in-document', null, ['DoNotTraverseFlatTree'])) is '((#slotted-element, 0), 0) to ((#test-content, 2), 12)'
+PASS rangeText(internals.rangeOfString('slotted in-document', null, [])) is null
+PASS clearSelection(); document.execCommand('FindString', null, 'in-shadow in-document'); selectedText() is null
+PASS clearSelection(); window.find('in-shadow in-document'); selectedText() is null
+PASS rangeText(internals.rangeOfString('in-shadow in-document', null, ['DoNotTraverseFlatTree'])) is null
+PASS rangeText(internals.rangeOfString('in-shadow in-document', null, [])) is null /* Can't return a range across shadow boundary */
+PASS setSelection(testContent, 1); document.execCommand('FindString', null, 'in-document'); selectedText() is '(#test-content, 2) 1 to 12'
+PASS setSelection(testContent, 1); window.find('in-document'); selectedText() is '(#test-content, 2) 1 to 12'
+PASS rangeText(internals.rangeOfString('in-document', range(testContent, 1), ['DoNotTraverseFlatTree'])) is '(#test-content, 2) 1 to 12'
+PASS rangeText(internals.rangeOfString('in-document', range(testContent, 1), [])) is '(#test-content, 2) 1 to 12'
+PASS setSelection(shadowRoot, 0); document.execCommand('FindString', null, 'in-document'); selectedText() is '(#test-content, 2) 1 to 12'
+PASS setSelection(shadowRoot, 0); window.find('in-document'); selectedText() is '(#test-content, 2) 1 to 12'
+PASS rangeText(internals.rangeOfString('in-document', range(shadowRoot, 0), ['DoNotTraverseFlatTree'])) is '(#test-content, 2) 1 to 12'
+PASS rangeText(internals.rangeOfString('in-document', range(shadowRoot, 0), [])) is '(#test-content, 2) 1 to 12'
+PASS setSelection(shadowRoot, 0); document.execCommand('FindString', null, 'in-shadow'); selectedText() is '#test-content 1 to 1'
+PASS setSelection(shadowRoot, 0); window.find('in-shadow'); selectedText() is '#test-content 1 to 1'
+PASS rangeText(internals.rangeOfString('in-shadow', range(shadowRoot, 0), ['DoNotTraverseFlatTree'])) is '(#shadow-root, 0) 0 to 9'
+PASS rangeText(internals.rangeOfString('in-shadow', range(shadowRoot, 0), [])) is '(#shadow-root, 0) 0 to 9'
+PASS setSelection(shadowRoot, 0); document.execCommand('FindString', null, 'slotted'); selectedText() is '(#slotted-element, 0) 0 to 7' /* Wrapped around */
+PASS setSelection(shadowRoot, 0); window.find('slotted'); selectedText() is '#test-content 1 to 1'
+PASS setSelection(shadowRoot, 0); window.find('slotted', /* caseSensitive */ true, /* backwards */ false, /* wrap */ true); selectedText() is '(#slotted-element, 0) 0 to 7'
+PASS rangeText(internals.rangeOfString('slotted', range(shadowRoot, 0), ['DoNotTraverseFlatTree'])) is null
+PASS rangeText(internals.rangeOfString('slotted', range(shadowRoot, 0), [])) is '(#slotted-element, 0) 0 to 7'
+PASS setSelection(shadowRoot, 1); document.execCommand('FindString', null, 'slotted'); selectedText() is '(#slotted-element, 0) 0 to 7' /* Wrapped around */
+PASS setSelection(shadowRoot, 1); window.find('slotted'); selectedText() is '#test-content 1 to 1'
+PASS setSelection(shadowRoot, 1); window.find('slotted', /* caseSensitive */ true, /* backwards */ false, /* wrap */ true); selectedText() is '(#slotted-element, 0) 0 to 7'
+PASS rangeText(internals.rangeOfString('slotted', range(shadowRoot, 1), ['DoNotTraverseFlatTree'])) is null
+PASS rangeText(internals.rangeOfString('slotted', range(shadowRoot, 1), [])) is '(#slotted-element, 0) 0 to 7'
+PASS setSelection(shadowRoot, 1); document.execCommand('FindString', null, 'in-shadow'); selectedText() is '#test-content 1 to 1'
+PASS setSelection(shadowRoot, 1); window.find('in-shadow'); selectedText() is '#test-content 1 to 1'
+PASS rangeText(internals.rangeOfString('in-shadow', range(shadowRoot, 1), ['DoNotTraverseFlatTree'])) is '(#shadow-root, 2) 1 to 10'
+PASS rangeText(internals.rangeOfString('in-shadow', range(shadowRoot, 1), [])) is '(#shadow-root, 2) 1 to 10'
+PASS setSelection(shadowRoot, 1); document.execCommand('FindString', null, 'in-document'); selectedText() is '(#test-content, 2) 1 to 12'
+PASS setSelection(shadowRoot, 1); window.find('in-document'); selectedText() is '(#test-content, 2) 1 to 12'
+PASS rangeText(internals.rangeOfString('in-document', range(shadowRoot, 1), ['DoNotTraverseFlatTree'])) is '(#test-content, 2) 1 to 12'
+PASS rangeText(internals.rangeOfString('in-document', range(shadowRoot, 1), [])) is '(#test-content, 2) 1 to 12'
+PASS setSelection(shadowRoot, 1); document.execCommand('FindString', null, 'in-slot'); selectedText() is '#test-content 1 to 1'
+PASS setSelection(shadowRoot, 1); window.find('in-slot'); selectedText() is '#test-content 1 to 1'
+PASS rangeText(internals.rangeOfString('in-slot', range(shadowRoot, 1), ['DoNotTraverseFlatTree'])) is null
+PASS rangeText(internals.rangeOfString('in-slot', range(shadowRoot, 1), [])) is null
+PASS clearSelection(); document.execCommand('FindString', null, 'in-user-agent-shadow'); selectedText() is null
+PASS clearSelection(); window.find('in-user-agent-shadow'); selectedText() is null
+PASS rangeText(internals.rangeOfString('in-user-agent-shadow', null, ['DoNotTraverseFlatTree'])) is null
+PASS rangeText(internals.rangeOfString('in-user-agent-shadow', null, [])) is null
+PASS setSelection(userAgentShadowRoot, 0); document.execCommand('FindString', null, 'in-user-agent-shadow'); selectedText() is '#test-content 3 to 3'
+PASS setSelection(userAgentShadowRoot, 0); window.find('in-user-agent-shadow'); selectedText() is '#test-content 3 to 3'
+PASS rangeText(internals.rangeOfString('in-user-agent-shadow', range(userAgentShadowRoot, 0), ['DoNotTraverseFlatTree'])) is '(#user-agent-shadow-root, 0) 0 to 20'
+PASS rangeText(internals.rangeOfString('in-user-agent-shadow', range(userAgentShadowRoot, 0), [])) is '(#user-agent-shadow-root, 0) 0 to 20'
+PASS clearSelection(); internals.countFindMatches('in-document', ['DoNotTraverseFlatTree']) is 2
+PASS internals.countFindMatches('in-document', []) is 2
+PASS internals.countFindMatches('in-shadow', ['DoNotTraverseFlatTree']) is 0
+PASS internals.countFindMatches('in-shadow', []) is 2
+PASS internals.countFindMatches('in-', ['DoNotTraverseFlatTree']) is 2
+PASS internals.countFindMatches('in-', []) is 4
+PASS internals.countFindMatches('in-shadow in-document', ['DoNotTraverseFlatTree']) is 0
+PASS internals.countFindMatches('in-shadow in-document', []) is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+in-document slotted in-document
</ins></span></pre></div>
<a id="branchessafari603branchLayoutTestseditingtextiteratorfindstringonflattreehtml"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/LayoutTests/editing/text-iterator/find-string-on-flat-tree.html (0 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/editing/text-iterator/find-string-on-flat-tree.html                                (rev 0)
+++ branches/safari-603-branch/LayoutTests/editing/text-iterator/find-string-on-flat-tree.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -0,0 +1,169 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+&lt;div id=&quot;test-content&quot;&gt;in-document &lt;span id=&quot;host&quot;&gt;unslotted &lt;b id=&quot;slotted-element&quot; slot=&quot;named-slot&quot;&gt;slotted&lt;/b&gt; unslotted&lt;/span&gt; in-document&lt;span id=&quot;user-agent-host&quot;&gt;&lt;/span&gt;&lt;/div&gt;
+&lt;script src=&quot;../../resources/js-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+
+description('This tests finding across shadow boundaries using the flat tree.');
+
+var testContent = document.getElementById('test-content');
+var shadowHost = document.getElementById('host');
+var shadowRoot = shadowHost.attachShadow({mode: 'closed'});
+shadowRoot.innerHTML = 'in-shadow &lt;slot name=&quot;named-slot&quot;&gt;in-slot&lt;/slot&gt; in-shadow';
+shadowRoot.id = 'shadow-root';
+
+if (!window.internals)
+    testFailed('This test requires internals');
+else {
+    var userAgentShadowHost = document.getElementById('user-agent-host');
+    var userAgentShadowRoot = internals.ensureUserAgentShadowRoot(userAgentShadowHost);
+    userAgentShadowRoot.innerHTML = 'in-user-agent-shadow';
+    userAgentShadowRoot.id = 'user-agent-shadow-root';
+
+    // Hide console so that we don't end up finding text in the log itself.
+    document.getElementById('console').style.display = 'none';
+
+    function nodeLabel(node)
+    {
+        if (node.nodeType != Node.TEXT_NODE)
+            return '#' + node.id;
+        let offset = 0;
+        for (let child = node.previousSibling; child; child = child.previousSibling)
+            offset++;
+        return `(#${node.parentNode.id}, ${offset})`;
+    }
+
+    function rangeText(range)
+    {
+        if (!range)
+            return null;
+        if (range.startContainer == range.endContainer)
+            return `${nodeLabel(range.startContainer)} ${range.startOffset} to ${range.endOffset}`;
+        return `(${nodeLabel(range.startContainer)}, ${range.startOffset}) to (${nodeLabel(range.endContainer)}, ${range.endOffset})`;
+    }
+
+    function clearSelection()
+    {
+        getSelection().removeAllRanges();
+    }
+
+    function selectedText(range)
+    {
+        if (!getSelection().rangeCount)
+            return null;
+        return rangeText(getSelection().getRangeAt(0));
+    }
+
+    function setSelection(node, offset)
+    {
+        getSelection().setPosition(node, offset);
+    }
+
+    function range(node, offset)
+    {
+        let range = new Range;
+        range.setStart(node, offset);
+        return range;
+    }
+
+    shouldBe(&quot;clearSelection(); document.execCommand('FindString', null, 'in-document'); selectedText()&quot;, &quot;'(#test-content, 0) 0 to 11'&quot;);
+    shouldBe(&quot;clearSelection(); window.find('in-document'); selectedText()&quot;, &quot;'(#test-content, 0) 0 to 11'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-document', null, ['DoNotTraverseFlatTree']))&quot;, &quot;'(#test-content, 0) 0 to 11'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-document', null, []))&quot;, &quot;'(#test-content, 0) 0 to 11'&quot;);
+
+    shouldBe(&quot;clearSelection(); document.execCommand('FindString', null, 'in-shadow'); selectedText()&quot;, &quot;null&quot;);
+    shouldBe(&quot;clearSelection(); window.find('in-shadow'); selectedText()&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-shadow', null, ['DoNotTraverseFlatTree']))&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-shadow', null, []))&quot;, &quot;'(#shadow-root, 0) 0 to 9'&quot;);
+
+    shouldBe(&quot;clearSelection(); document.execCommand('FindString', null, 'unslotted'); selectedText()&quot;, &quot;null&quot;);
+    shouldBe(&quot;clearSelection(); window.find('unslotted'); selectedText()&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('unslotted', null, ['DoNotTraverseFlatTree']))&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('unslotted', null, []))&quot;, &quot;null&quot;);
+
+    shouldBe(&quot;clearSelection(); document.execCommand('FindString', null, 'slotted'); selectedText()&quot;, &quot;'(#slotted-element, 0) 0 to 7'&quot;);
+    shouldBe(&quot;clearSelection(); window.find('slotted'); selectedText()&quot;, &quot;'(#slotted-element, 0) 0 to 7'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('slotted', null, ['DoNotTraverseFlatTree']))&quot;, &quot;'(#slotted-element, 0) 0 to 7'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('slotted', null, []))&quot;, &quot;'(#slotted-element, 0) 0 to 7'&quot;);
+
+    shouldBe(&quot;clearSelection(); document.execCommand('FindString', null, 'slotted in-document'); selectedText()&quot;, &quot;'((#slotted-element, 0), 0) to ((#test-content, 2), 12)'&quot;);
+    shouldBe(&quot;clearSelection(); window.find('slotted in-document'); selectedText()&quot;, &quot;'((#slotted-element, 0), 0) to ((#test-content, 2), 12)'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('slotted in-document', null, ['DoNotTraverseFlatTree']))&quot;, &quot;'((#slotted-element, 0), 0) to ((#test-content, 2), 12)'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('slotted in-document', null, []))&quot;, &quot;null&quot;);
+
+    shouldBe(&quot;clearSelection(); document.execCommand('FindString', null, 'in-shadow in-document'); selectedText()&quot;, &quot;null&quot;);
+    shouldBe(&quot;clearSelection(); window.find('in-shadow in-document'); selectedText()&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-shadow in-document', null, ['DoNotTraverseFlatTree']))&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-shadow in-document', null, []))&quot;, &quot;null /* Can't return a range across shadow boundary */&quot;);
+
+    shouldBe(&quot;setSelection(testContent, 1); document.execCommand('FindString', null, 'in-document'); selectedText()&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;setSelection(testContent, 1); window.find('in-document'); selectedText()&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-document', range(testContent, 1), ['DoNotTraverseFlatTree']))&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-document', range(testContent, 1), []))&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+
+    shouldBe(&quot;setSelection(shadowRoot, 0); document.execCommand('FindString', null, 'in-document'); selectedText()&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 0); window.find('in-document'); selectedText()&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-document', range(shadowRoot, 0), ['DoNotTraverseFlatTree']))&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-document', range(shadowRoot, 0), []))&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+
+    shouldBe(&quot;setSelection(shadowRoot, 0); document.execCommand('FindString', null, 'in-shadow'); selectedText()&quot;, &quot;'#test-content 1 to 1'&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 0); window.find('in-shadow'); selectedText()&quot;, &quot;'#test-content 1 to 1'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-shadow', range(shadowRoot, 0), ['DoNotTraverseFlatTree']))&quot;, &quot;'(#shadow-root, 0) 0 to 9'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-shadow', range(shadowRoot, 0), []))&quot;, &quot;'(#shadow-root, 0) 0 to 9'&quot;);
+
+    shouldBe(&quot;setSelection(shadowRoot, 0); document.execCommand('FindString', null, 'slotted'); selectedText()&quot;, &quot;'(#slotted-element, 0) 0 to 7' /* Wrapped around */&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 0); window.find('slotted'); selectedText()&quot;, &quot;'#test-content 1 to 1'&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 0); window.find('slotted', /* caseSensitive */ true, /* backwards */ false, /* wrap */ true); selectedText()&quot;, &quot;'(#slotted-element, 0) 0 to 7'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('slotted', range(shadowRoot, 0), ['DoNotTraverseFlatTree']))&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('slotted', range(shadowRoot, 0), []))&quot;, &quot;'(#slotted-element, 0) 0 to 7'&quot;);
+
+    shouldBe(&quot;setSelection(shadowRoot, 1); document.execCommand('FindString', null, 'slotted'); selectedText()&quot;, &quot;'(#slotted-element, 0) 0 to 7' /* Wrapped around */&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 1); window.find('slotted'); selectedText()&quot;, &quot;'#test-content 1 to 1'&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 1); window.find('slotted', /* caseSensitive */ true, /* backwards */ false, /* wrap */ true); selectedText()&quot;, &quot;'(#slotted-element, 0) 0 to 7'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('slotted', range(shadowRoot, 1), ['DoNotTraverseFlatTree']))&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('slotted', range(shadowRoot, 1), []))&quot;, &quot;'(#slotted-element, 0) 0 to 7'&quot;);
+
+    shouldBe(&quot;setSelection(shadowRoot, 1); document.execCommand('FindString', null, 'in-shadow'); selectedText()&quot;, &quot;'#test-content 1 to 1'&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 1); window.find('in-shadow'); selectedText()&quot;, &quot;'#test-content 1 to 1'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-shadow', range(shadowRoot, 1), ['DoNotTraverseFlatTree']))&quot;, &quot;'(#shadow-root, 2) 1 to 10'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-shadow', range(shadowRoot, 1), []))&quot;, &quot;'(#shadow-root, 2) 1 to 10'&quot;);
+
+    shouldBe(&quot;setSelection(shadowRoot, 1); document.execCommand('FindString', null, 'in-document'); selectedText()&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 1); window.find('in-document'); selectedText()&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-document', range(shadowRoot, 1), ['DoNotTraverseFlatTree']))&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-document', range(shadowRoot, 1), []))&quot;, &quot;'(#test-content, 2) 1 to 12'&quot;);
+
+    shouldBe(&quot;setSelection(shadowRoot, 1); document.execCommand('FindString', null, 'in-slot'); selectedText()&quot;, &quot;'#test-content 1 to 1'&quot;);
+    shouldBe(&quot;setSelection(shadowRoot, 1); window.find('in-slot'); selectedText()&quot;, &quot;'#test-content 1 to 1'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-slot', range(shadowRoot, 1), ['DoNotTraverseFlatTree']))&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-slot', range(shadowRoot, 1), []))&quot;, &quot;null&quot;);
+
+    shouldBe(&quot;clearSelection(); document.execCommand('FindString', null, 'in-user-agent-shadow'); selectedText()&quot;, &quot;null&quot;);
+    shouldBe(&quot;clearSelection(); window.find('in-user-agent-shadow'); selectedText()&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-user-agent-shadow', null, ['DoNotTraverseFlatTree']))&quot;, &quot;null&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-user-agent-shadow', null, []))&quot;, &quot;null&quot;);
+
+    shouldBe(&quot;setSelection(userAgentShadowRoot, 0); document.execCommand('FindString', null, 'in-user-agent-shadow'); selectedText()&quot;, &quot;'#test-content 3 to 3'&quot;);
+    shouldBe(&quot;setSelection(userAgentShadowRoot, 0); window.find('in-user-agent-shadow'); selectedText()&quot;, &quot;'#test-content 3 to 3'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-user-agent-shadow', range(userAgentShadowRoot, 0), ['DoNotTraverseFlatTree']))&quot;, &quot;'(#user-agent-shadow-root, 0) 0 to 20'&quot;);
+    shouldBe(&quot;rangeText(internals.rangeOfString('in-user-agent-shadow', range(userAgentShadowRoot, 0), []))&quot;, &quot;'(#user-agent-shadow-root, 0) 0 to 20'&quot;);
+
+    shouldBe(&quot;clearSelection(); internals.countFindMatches('in-document', ['DoNotTraverseFlatTree'])&quot;, &quot;2&quot;);
+    shouldBe(&quot;internals.countFindMatches('in-document', [])&quot;, &quot;2&quot;);
+
+    shouldBe(&quot;internals.countFindMatches('in-shadow', ['DoNotTraverseFlatTree'])&quot;, &quot;0&quot;);
+    shouldBe(&quot;internals.countFindMatches('in-shadow', [])&quot;, &quot;2&quot;);
+
+    shouldBe(&quot;internals.countFindMatches('in-', ['DoNotTraverseFlatTree'])&quot;, &quot;2&quot;);
+    shouldBe(&quot;internals.countFindMatches('in-', [])&quot;, &quot;4&quot;);
+
+    shouldBe(&quot;internals.countFindMatches('in-shadow in-document', ['DoNotTraverseFlatTree'])&quot;, &quot;0&quot;);
+    shouldBe(&quot;internals.countFindMatches('in-shadow in-document', [])&quot;, &quot;0&quot;);
+
+    document.getElementById('console').style.display = null;
+}
+
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="branchessafari603branchLayoutTestsfasttextmarkmatchesbrokenlinerenderinghtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/fast/text/mark-matches-broken-line-rendering.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/fast/text/mark-matches-broken-line-rendering.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/fast/text/mark-matches-broken-line-rendering.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -11,6 +11,6 @@
</span><span class="cx"> &lt;script&gt;
</span><span class="cx"> if (window.internals) {
</span><span class="cx">     internals.setMarkedTextMatchesAreHighlighted(true);
</span><del>-    internals.countMatchesForText(&quot;Quo usque tandem abutere, Catilina, patientia nostra?&quot;, 0, &quot;mark&quot;);
</del><ins>+    internals.countMatchesForText(&quot;Quo usque tandem abutere, Catilina, patientia nostra?&quot;, [], &quot;mark&quot;);
</ins><span class="cx"> }
</span><span class="cx"> &lt;/script&gt;
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestsfasttextmarkmatchesoverflowcliphtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/fast/text/mark-matches-overflow-clip.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/fast/text/mark-matches-overflow-clip.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/fast/text/mark-matches-overflow-clip.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -17,7 +17,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     testRunner.dumpAsText();
</span><del>-    internals.countMatchesForText(&quot;tandem&quot;, 0, &quot;mark&quot;);
</del><ins>+    internals.countMatchesForText(&quot;tandem&quot;, [], &quot;mark&quot;);
</ins><span class="cx">     
</span><span class="cx">     var markedNode = document.getElementsByTagName(&quot;span&quot;)[0].firstChild;
</span><span class="cx">     document.write(internals.dumpMarkerRects(&quot;TextMatch&quot;));
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestsfasttextmarkmatchesrenderingsimplelinesexpectedhtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering-simple-lines-expected.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering-simple-lines-expected.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering-simple-lines-expected.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -8,6 +8,6 @@
</span><span class="cx"> &lt;script&gt;
</span><span class="cx"> if (window.internals) {
</span><span class="cx">     internals.setMarkedTextMatchesAreHighlighted(true);
</span><del>-    internals.countMatchesForText(&quot;ti&quot;, 0, &quot;mark&quot;);
</del><ins>+    internals.countMatchesForText(&quot;ti&quot;, [], &quot;mark&quot;);
</ins><span class="cx"> }
</span><span class="cx"> &lt;/script&gt;
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestsfasttextmarkmatchesrenderingsimplelineshtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering-simple-lines.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering-simple-lines.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering-simple-lines.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -4,6 +4,6 @@
</span><span class="cx"> &lt;script&gt;
</span><span class="cx"> if (window.internals) {
</span><span class="cx">     internals.setMarkedTextMatchesAreHighlighted(true);
</span><del>-    internals.countMatchesForText(&quot;ti&quot;, 0, &quot;mark&quot;);
</del><ins>+    internals.countMatchesForText(&quot;ti&quot;, [], &quot;mark&quot;);
</ins><span class="cx"> }
</span><span class="cx"> &lt;/script&gt;
</span></span></pre></div>
<a id="branchessafari603branchLayoutTestsfasttextmarkmatchesrenderinghtml"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering.html (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering.html        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/LayoutTests/fast/text/mark-matches-rendering.html        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -4,6 +4,6 @@
</span><span class="cx"> &lt;script&gt;
</span><span class="cx"> if (window.internals) {
</span><span class="cx">     internals.setMarkedTextMatchesAreHighlighted(true);
</span><del>-    internals.countMatchesForText(&quot;Quo usque tandem abutere, Catilina, patientia nostra?&quot;, 0, &quot;mark&quot;);
</del><ins>+    internals.countMatchesForText(&quot;Quo usque tandem abutere, Catilina, patientia nostra?&quot;, [], &quot;mark&quot;);
</ins><span class="cx"> }
</span><span class="cx"> &lt;/script&gt;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ChangeLog        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -1,5 +1,60 @@
</span><span class="cx"> 2017-01-12  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210432. rdar://problem/29633667
+
+    2017-01-05  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+            Finding text doesn't work across shadow boundary
+            https://bugs.webkit.org/show_bug.cgi?id=158503
+
+            Reviewed by Antti Koivisto.
+
+            Added a new TextIterator behavior flag, TextIteratorTraversesFlatTree, which makes TextIterator traverse
+            the flat tree instead of the DOM tree, and made this behavior default in findPlainText.
+
+            Also added a new find options flag, DoNotTraverseFlatTree, to suppress this behavior in window.find(~)
+            and execCommand('FindString', false, ~) as they should not be able to peek information inside shadow trees.
+            Unfortunately these APIs have been deprecated in the standards so there is no specification to follow.
+
+            For now, we don't support finding a word or a keyword across a shadow boundary as this would require
+            making rangeOfString and other related functions return a Range-like object that can cross shadow boundaries.
+
+            Also added internals.rangeOfString to test Editor::rangeOfString, and replaced the bit-flag arguments
+            to internals.countMatchesForText and internals.countFindMatches by an array of strings for better portability.
+
+            Test: editing/text-iterator/find-string-on-flat-tree.html
+
+            * editing/Editor.cpp:
+            (WebCore::Editor::rangeOfString): Use the modern containingShadowRoot instead of nonBoundaryShadowTreeRootNode
+            since the start container can be a shadow root, which nonBoundaryShadowTreeRootNode asserts not be the case.
+            * editing/Editor.h:
+            * editing/EditorCommand.cpp:
+            (WebCore::executeFindString): Don't traverse across shadow boundaries.
+            * editing/FindOptions.h: Added DoNotTraverseFlatTree.
+            * editing/TextIterator.cpp:
+            (WebCore::assignedAuthorSlot): Added.
+            (WebCore::authorShadowRoot): Added.
+            (WebCore::firstChildInFlatTreeIgnoringUserAgentShadow): Added.
+            (WebCore::nextSiblingInFlatTreeIgnoringUserAgentShadow): Added.
+            (WebCore::firstChild): Added. Traverses the flat tree when TextIteratorTraversesFlatTree is set.
+            (WebCore::nextSibling): Ditto.
+            (WebCore::parentNodeOrShadowHost): Ditto.
+            (WebCore::TextIterator::advance): Don't set m_handledChildren to true when the current node has display: contents.
+            (WebCore::findPlainText): Use TextIteratorTraversesFlatTree unless DoNotTraverseFlatTree is set.
+            * editing/TextIteratorBehavior.h: Added TextIteratorTraversesFlatTree.
+            * page/DOMWindow.cpp:
+            (WebCore::DOMWindow::find): Don't traverse across shadow boundaries.
+            * testing/Internals.cpp:
+            (WebCore::parseFindOptions): Added.
+            (WebCore::Internals::rangeOfString): Added.
+            (WebCore::Internals::countMatchesForText): Replaced the find options by an array of strings instead of a bit mask.
+            (WebCore::Internals::countFindMatches): Ditto.
+            * testing/Internals.h:
+            * testing/Internals.idl: Added rangeOfString, and replaced find options bit-flag in countMatchesForText and
+            countFindMatches by an array of strings so that the tests themselves don't rely on a specific value of each bit flag.
+
+2017-01-12  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r210131. rdar://problem/29633667
</span><span class="cx"> 
</span><span class="cx">     2016-12-23  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/editing/Editor.cpp (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/editing/Editor.cpp        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/editing/Editor.cpp        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -3132,7 +3132,7 @@
</span><span class="cx">             searchRange-&gt;setEnd(startInReferenceRange ? referenceRange-&gt;endPosition() : referenceRange-&gt;startPosition());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    RefPtr&lt;Node&gt; shadowTreeRoot = referenceRange ? referenceRange-&gt;startContainer().nonBoundaryShadowTreeRootNode() : nullptr;
</del><ins>+    RefPtr&lt;ShadowRoot&gt; shadowTreeRoot = referenceRange ? referenceRange-&gt;startContainer().containingShadowRoot() : nullptr;
</ins><span class="cx">     if (shadowTreeRoot) {
</span><span class="cx">         if (forward)
</span><span class="cx">             searchRange-&gt;setEnd(*shadowTreeRoot, shadowTreeRoot-&gt;countChildNodes());
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreeditingEditorh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/editing/Editor.h (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/editing/Editor.h        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/editing/Editor.h        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -378,7 +378,7 @@
</span><span class="cx">     String selectedTextForDataTransfer() const;
</span><span class="cx">     WEBCORE_EXPORT bool findString(const String&amp;, FindOptions);
</span><span class="cx"> 
</span><del>-    RefPtr&lt;Range&gt; rangeOfString(const String&amp;, Range*, FindOptions);
</del><ins>+    WEBCORE_EXPORT RefPtr&lt;Range&gt; rangeOfString(const String&amp;, Range*, FindOptions);
</ins><span class="cx"> 
</span><span class="cx">     const VisibleSelection&amp; mark() const; // Mark, to be used as emacs uses it.
</span><span class="cx">     void setMark(const VisibleSelection&amp;);
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreeditingEditorCommandcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/editing/EditorCommand.cpp (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/editing/EditorCommand.cpp        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/editing/EditorCommand.cpp        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -377,7 +377,7 @@
</span><span class="cx"> 
</span><span class="cx"> static bool executeFindString(Frame&amp; frame, Event*, EditorCommandSource, const String&amp; value)
</span><span class="cx"> {
</span><del>-    return frame.editor().findString(value, CaseInsensitive | WrapAround);
</del><ins>+    return frame.editor().findString(value, CaseInsensitive | WrapAround | DoNotTraverseFlatTree);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static bool executeFontName(Frame&amp; frame, Event*, EditorCommandSource source, const String&amp; value)
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreeditingFindOptionsh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/editing/FindOptions.h (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/editing/FindOptions.h        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/editing/FindOptions.h        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -37,9 +37,10 @@
</span><span class="cx">     WrapAround = 1 &lt;&lt; 4,
</span><span class="cx">     StartInSelection = 1 &lt;&lt; 5,
</span><span class="cx">     DoNotRevealSelection = 1 &lt;&lt; 6,
</span><del>-    AtWordEnds = 1 &lt;&lt; 7
</del><ins>+    AtWordEnds = 1 &lt;&lt; 7,
+    DoNotTraverseFlatTree = 1 &lt;&lt; 8,
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-typedef unsigned char FindOptions;
</del><ins>+typedef unsigned short FindOptions;
</ins><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreeditingTextIteratorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/editing/TextIterator.cpp (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/editing/TextIterator.cpp        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/editing/TextIterator.cpp        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -381,6 +381,69 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static HTMLSlotElement* assignedAuthorSlot(Node&amp; node)
+{
+    auto* slot = node.assignedSlot();
+    if (!slot || slot-&gt;containingShadowRoot()-&gt;mode() == ShadowRootMode::UserAgent)
+        return nullptr;
+    return slot;
+}
+
+static ShadowRoot* authorShadowRoot(Node&amp; node)
+{
+    auto* shadowRoot = node.shadowRoot();
+    if (!shadowRoot || shadowRoot-&gt;mode() == ShadowRootMode::UserAgent)
+        return nullptr;
+    return shadowRoot;
+}
+
+// FIXME: Use ComposedTreeIterator instead. These functions are more expensive because they might do O(n) work.
+static inline Node* firstChildInFlatTreeIgnoringUserAgentShadow(Node&amp; node)
+{
+    if (auto* shadowRoot = authorShadowRoot(node))
+        return shadowRoot-&gt;firstChild();
+    if (is&lt;HTMLSlotElement&gt;(node)) {
+        if (auto* assignedNodes = downcast&lt;HTMLSlotElement&gt;(node).assignedNodes())
+            return assignedNodes-&gt;at(0);
+    }
+    return node.firstChild();
+}
+
+static inline Node* nextSiblingInFlatTreeIgnoringUserAgentShadow(Node&amp; node)
+{
+    if (auto* slot = assignedAuthorSlot(node)) {
+        auto* assignedNodes = slot-&gt;assignedNodes();
+        ASSERT(assignedNodes);
+        auto nodeIndex = assignedNodes-&gt;find(&amp;node);
+        ASSERT(nodeIndex != notFound);
+        if (assignedNodes-&gt;size() &gt; nodeIndex + 1)
+            return assignedNodes-&gt;at(nodeIndex + 1);
+        return nullptr;
+    }
+    return node.nextSibling();
+}
+
+static inline Node* firstChild(TextIteratorBehavior options, Node&amp; node)
+{
+    if (UNLIKELY(options &amp; TextIteratorTraversesFlatTree))
+        return firstChildInFlatTreeIgnoringUserAgentShadow(node);
+    return node.firstChild();
+}
+
+static inline Node* nextSibling(TextIteratorBehavior options, Node&amp; node)
+{
+    if (UNLIKELY(options &amp; TextIteratorTraversesFlatTree))
+        return nextSiblingInFlatTreeIgnoringUserAgentShadow(node);
+    return node.nextSibling();
+}
+
+static inline Node* parentNodeOrShadowHost(TextIteratorBehavior options, Node&amp; node)
+{
+    if (UNLIKELY(options &amp; TextIteratorTraversesFlatTree))
+        return node.parentInComposedTree();
+    return node.parentOrShadowHostNode();
+}
+
</ins><span class="cx"> void TextIterator::advance()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!atEnd());
</span><span class="lines">@@ -430,7 +493,7 @@
</span><span class="cx">         auto* renderer = m_node-&gt;renderer();
</span><span class="cx">         if (!renderer) {
</span><span class="cx">             m_handledNode = true;
</span><del>-            m_handledChildren = true;
</del><ins>+            m_handledChildren = !((m_behavior &amp; TextIteratorTraversesFlatTree) &amp;&amp; is&lt;Element&gt;(*m_node) &amp;&amp; downcast&lt;Element&gt;(*m_node).hasDisplayContents());
</ins><span class="cx">         } else {
</span><span class="cx">             // handle current node according to its type
</span><span class="cx">             if (!m_handledNode) {
</span><span class="lines">@@ -447,13 +510,13 @@
</span><span class="cx"> 
</span><span class="cx">         // find a new current node to handle in depth-first manner,
</span><span class="cx">         // calling exitNode() as we come back thru a parent node
</span><del>-        Node* next = m_handledChildren ? nullptr : m_node-&gt;firstChild();
</del><ins>+        Node* next = m_handledChildren ? nullptr : firstChild(m_behavior, *m_node);
</ins><span class="cx">         m_offset = 0;
</span><span class="cx">         if (!next) {
</span><del>-            next = m_node-&gt;nextSibling();
</del><ins>+            next = nextSibling(m_behavior, *m_node);
</ins><span class="cx">             if (!next) {
</span><span class="cx">                 bool pastEnd = NodeTraversal::next(*m_node) == m_pastEndNode;
</span><del>-                Node* parentNode = m_node-&gt;parentOrShadowHostNode();
</del><ins>+                Node* parentNode = parentNodeOrShadowHost(m_behavior, *m_node);
</ins><span class="cx">                 while (!next &amp;&amp; parentNode) {
</span><span class="cx">                     if ((pastEnd &amp;&amp; parentNode == m_endContainer) || m_endContainer-&gt;isDescendantOf(*parentNode))
</span><span class="cx">                         return;
</span><span class="lines">@@ -461,7 +524,7 @@
</span><span class="cx">                     Node* exitedNode = m_node;
</span><span class="cx">                     m_node = parentNode;
</span><span class="cx">                     m_fullyClippedStack.pop();
</span><del>-                    parentNode = m_node-&gt;parentOrShadowHostNode();
</del><ins>+                    parentNode = parentNodeOrShadowHost(m_behavior, *m_node);
</ins><span class="cx">                     if (haveRenderer)
</span><span class="cx">                         exitNode(exitedNode);
</span><span class="cx">                     if (m_positionNode) {
</span><span class="lines">@@ -469,7 +532,7 @@
</span><span class="cx">                         m_handledChildren = true;
</span><span class="cx">                         return;
</span><span class="cx">                     }
</span><del>-                    next = m_node-&gt;nextSibling();
</del><ins>+                    next = nextSibling(m_behavior, *m_node);
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             m_fullyClippedStack.pop();            
</span><span class="lines">@@ -2640,6 +2703,8 @@
</span><span class="cx"> 
</span><span class="cx">     bool searchForward = !(options &amp; Backwards);
</span><span class="cx">     TextIteratorBehavior iteratorOptions = TextIteratorEntersTextControls | TextIteratorClipsToFrameAncestors;
</span><ins>+    if (!(options &amp; DoNotTraverseFlatTree))
+        iteratorOptions |= TextIteratorTraversesFlatTree;
</ins><span class="cx"> 
</span><span class="cx">     CharacterIterator findIterator(range, iteratorOptions);
</span><span class="cx">     auto result = findPlainTextOffset(buffer, findIterator, searchForward);
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreeditingTextIteratorBehaviorh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/editing/TextIteratorBehavior.h (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/editing/TextIteratorBehavior.h        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/editing/TextIteratorBehavior.h        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -57,6 +57,8 @@
</span><span class="cx">     // Makes visiblity test take into account the visibility of the frame.
</span><span class="cx">     // FIXME: This should probably be always on unless TextIteratorIgnoresStyleVisibility is set.
</span><span class="cx">     TextIteratorClipsToFrameAncestors = 1 &lt;&lt; 8,
</span><ins>+
+    TextIteratorTraversesFlatTree = 1 &lt;&lt; 9,
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> typedef unsigned short TextIteratorBehavior;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorepageDOMWindowcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/page/DOMWindow.cpp (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/page/DOMWindow.cpp        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/page/DOMWindow.cpp        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -1207,7 +1207,7 @@
</span><span class="cx"> 
</span><span class="cx">     // FIXME (13016): Support wholeWord, searchInFrames and showDialog.    
</span><span class="cx">     FindOptions options = (backwards ? Backwards : 0) | (caseSensitive ? 0 : CaseInsensitive) | (wrap ? WrapAround : 0);
</span><del>-    return m_frame-&gt;editor().findString(string, options);
</del><ins>+    return m_frame-&gt;editor().findString(string, options | DoNotTraverseFlatTree);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool DOMWindow::offscreenBuffering() const
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/testing/Internals.cpp (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/testing/Internals.cpp        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/testing/Internals.cpp        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -1822,23 +1822,76 @@
</span><span class="cx">     document-&gt;frame()-&gt;editor().toggleOverwriteModeEnabled();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-unsigned Internals::countMatchesForText(const String&amp; text, unsigned findOptions, const String&amp; markMatches)
</del><ins>+static ExceptionOr&lt;FindOptions&gt; parseFindOptions(const Vector&lt;String&gt;&amp; optionList)
</ins><span class="cx"> {
</span><ins>+    const struct {
+        const char* name;
+        FindOptionFlag value;
+    } flagList[] = {
+        {&quot;CaseInsensitive&quot;, CaseInsensitive},
+        {&quot;AtWordStarts&quot;, AtWordStarts},
+        {&quot;TreatMedialCapitalAsWordStart&quot;, TreatMedialCapitalAsWordStart},
+        {&quot;Backwards&quot;, Backwards},
+        {&quot;WrapAround&quot;, WrapAround},
+        {&quot;StartInSelection&quot;, StartInSelection},
+        {&quot;DoNotRevealSelection&quot;, DoNotRevealSelection},
+        {&quot;AtWordEnds&quot;, AtWordEnds},
+        {&quot;DoNotTraverseFlatTree&quot;, DoNotTraverseFlatTree},
+    };
+    FindOptions result = 0;
+    for (auto&amp; option : optionList) {
+        bool found = false;
+        for (auto&amp; flag : flagList) {
+            if (flag.name == option) {
+                result |= flag.value;
+                found = true;
+                break;
+            }
+        }
+        if (!found)
+            return Exception { SYNTAX_ERR };
+    }
+    return result;
+}
+
+ExceptionOr&lt;RefPtr&lt;Range&gt;&gt; Internals::rangeOfString(const String&amp; text, RefPtr&lt;Range&gt;&amp;&amp; referenceRange, const Vector&lt;String&gt;&amp; findOptions)
+{
</ins><span class="cx">     Document* document = contextDocument();
</span><span class="cx">     if (!document || !document-&gt;frame())
</span><del>-        return 0;
</del><ins>+        return Exception { INVALID_ACCESS_ERR };
</ins><span class="cx"> 
</span><ins>+    auto parsedOptions = parseFindOptions(findOptions);
+    if (parsedOptions.hasException())
+        return parsedOptions.releaseException();
+
+    return document-&gt;frame()-&gt;editor().rangeOfString(text, referenceRange.get(), parsedOptions.releaseReturnValue());
+}
+
+ExceptionOr&lt;unsigned&gt; Internals::countMatchesForText(const String&amp; text, const Vector&lt;String&gt;&amp; findOptions, const String&amp; markMatches)
+{
+    Document* document = contextDocument();
+    if (!document || !document-&gt;frame())
+        return Exception { INVALID_ACCESS_ERR };
+
+    auto parsedOptions = parseFindOptions(findOptions);
+    if (parsedOptions.hasException())
+        return parsedOptions.releaseException();
+
</ins><span class="cx">     bool mark = markMatches == &quot;mark&quot;;
</span><del>-    return document-&gt;frame()-&gt;editor().countMatchesForText(text, nullptr, findOptions, 1000, mark, nullptr);
</del><ins>+    return document-&gt;frame()-&gt;editor().countMatchesForText(text, nullptr, parsedOptions.releaseReturnValue(), 1000, mark, nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-unsigned Internals::countFindMatches(const String&amp; text, unsigned findOptions)
</del><ins>+ExceptionOr&lt;unsigned&gt; Internals::countFindMatches(const String&amp; text, const Vector&lt;String&gt;&amp; findOptions)
</ins><span class="cx"> {
</span><span class="cx">     Document* document = contextDocument();
</span><span class="cx">     if (!document || !document-&gt;page())
</span><del>-        return 0;
</del><ins>+        return Exception { INVALID_ACCESS_ERR };
</ins><span class="cx"> 
</span><del>-    return document-&gt;page()-&gt;countFindMatches(text, findOptions, 1000);
</del><ins>+    auto parsedOptions = parseFindOptions(findOptions);
+    if (parsedOptions.hasException())
+        return parsedOptions.releaseException();
+
+    return document-&gt;page()-&gt;countFindMatches(text, parsedOptions.releaseReturnValue(), 1000);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned Internals::numberOfLiveNodes() const
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoretestingInternalsh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/testing/Internals.h (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/testing/Internals.h        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/testing/Internals.h        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -237,8 +237,9 @@
</span><span class="cx">     bool isOverwriteModeEnabled();
</span><span class="cx">     void toggleOverwriteModeEnabled();
</span><span class="cx"> 
</span><del>-    unsigned countMatchesForText(const String&amp;, unsigned findOptions, const String&amp; markMatches);
-    unsigned countFindMatches(const String&amp;, unsigned findOptions);
</del><ins>+    ExceptionOr&lt;RefPtr&lt;Range&gt;&gt; rangeOfString(const String&amp;, RefPtr&lt;Range&gt;&amp;&amp;, const Vector&lt;String&gt;&amp; findOptions);
+    ExceptionOr&lt;unsigned&gt; countMatchesForText(const String&amp;, const Vector&lt;String&gt;&amp; findOptions, const String&amp; markMatches);
+    ExceptionOr&lt;unsigned&gt; countFindMatches(const String&amp;, const Vector&lt;String&gt;&amp; findOptions);
</ins><span class="cx"> 
</span><span class="cx">     unsigned numberOfScrollableAreas();
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoretestingInternalsidl"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/testing/Internals.idl (210637 => 210638)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/testing/Internals.idl        2017-01-12 16:44:49 UTC (rev 210637)
+++ branches/safari-603-branch/Source/WebCore/testing/Internals.idl        2017-01-12 16:44:58 UTC (rev 210638)
</span><span class="lines">@@ -178,9 +178,11 @@
</span><span class="cx">     void setEditingValue(HTMLInputElement inputElement, DOMString value);
</span><span class="cx">     void setAutofilled(HTMLInputElement inputElement, boolean enabled);
</span><span class="cx">     void setShowAutoFillButton(HTMLInputElement inputElement, AutoFillButtonType autoFillButtonType);
</span><del>-    unsigned long countMatchesForText(DOMString text, unsigned long findOptions, DOMString markMatches);
-    unsigned long countFindMatches(DOMString text, unsigned long findOptions);
</del><span class="cx"> 
</span><ins>+    [MayThrowException] Range? rangeOfString(DOMString text, Range? referenceRange, sequence&lt;DOMString&gt; findOptions);
+    [MayThrowException] unsigned long countMatchesForText(DOMString text, sequence&lt;DOMString&gt; findOptions, DOMString markMatches);
+    [MayThrowException] unsigned long countFindMatches(DOMString text, sequence&lt;DOMString&gt; findOptions);
+
</ins><span class="cx">     [MayThrowException] DOMString autofillFieldName(Element formControlElement);
</span><span class="cx"> 
</span><span class="cx">     [MayThrowException] void paintControlTints();
</span></span></pre>
</div>
</div>

</body>
</html>