<!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>[211940] releases/WebKitGTK/webkit-2.14/Source/WebCore</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/211940">211940</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2017-02-09 00:55:52 -0800 (Thu, 09 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/210288">r210288</a> - Correct DOMWindow handling during FrameLoader::clear
https://bugs.webkit.org/show_bug.cgi?id=166357
&lt;rdar://problem/29741862&gt;

Reviewed by Andy Estes.

Make sure that we always clean up the DOM window when clearing Window properties, even if the document will
remain in the page cache. Since 'clearWindowShell' is only used in FrameLoader, divide it's beahvior into
two steps:

1. Rename 'clearWindowShell' to 'clearWIndowShellsNotMatchingDOMWindow' to better describe its function.
Switch to a modern C++ loop. Do not switch to the new DOMWindow here, but detach and clear existing
DOMWindow connections.

2. Add a new method 'setDOMWindowForWindowShell'. Complete switch to the new DOMWindow.

This change allows us to disconnect the old DOMWindow, perform the 'setDocument(nullptr)' operation, and then
connect to the new Window without leaving the loader in an inconsistent state.

* loader/bindings/js/ScriptController.cpp:
(WebCore::clearWindowShellsNotMatchingDOMWindow): Renamed from 'clearWindowShell'
(WebCore::setDOMWindowForWindowShell): Added.
* loader/bindings/js/ScriptController.h:
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::clear): Revise to use the new two-step DOMWindow switch logic.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit214SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit214SourceWebCorebindingsjsScriptControllercpp">releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/ScriptController.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit214SourceWebCorebindingsjsScriptControllerh">releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/ScriptController.h</a></li>
<li><a href="#releasesWebKitGTKwebkit214SourceWebCoreloaderFrameLoadercpp">releases/WebKitGTK/webkit-2.14/Source/WebCore/loader/FrameLoader.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit214SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog (211939 => 211940)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog        2017-02-09 08:55:44 UTC (rev 211939)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog        2017-02-09 08:55:52 UTC (rev 211940)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2016-01-04  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Correct DOMWindow handling during FrameLoader::clear
+        https://bugs.webkit.org/show_bug.cgi?id=166357
+        &lt;rdar://problem/29741862&gt;
+
+        Reviewed by Andy Estes.
+
+        Make sure that we always clean up the DOM window when clearing Window properties, even if the document will
+        remain in the page cache. Since 'clearWindowShell' is only used in FrameLoader, divide it's beahvior into
+        two steps:
+        
+        1. Rename 'clearWindowShell' to 'clearWIndowShellsNotMatchingDOMWindow' to better describe its function.
+        Switch to a modern C++ loop. Do not switch to the new DOMWindow here, but detach and clear existing
+        DOMWindow connections.
+
+        2. Add a new method 'setDOMWindowForWindowShell'. Complete switch to the new DOMWindow.
+
+        This change allows us to disconnect the old DOMWindow, perform the 'setDocument(nullptr)' operation, and then
+        connect to the new Window without leaving the loader in an inconsistent state.
+
+        * loader/bindings/js/ScriptController.cpp:
+        (WebCore::clearWindowShellsNotMatchingDOMWindow): Renamed from 'clearWindowShell'
+        (WebCore::setDOMWindowForWindowShell): Added.
+        * loader/bindings/js/ScriptController.h:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::clear): Revise to use the new two-step DOMWindow switch logic.
+
</ins><span class="cx"> 2016-12-18  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Side effects while restting form elements
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit214SourceWebCorebindingsjsScriptControllercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/ScriptController.cpp (211939 => 211940)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/ScriptController.cpp        2017-02-09 08:55:44 UTC (rev 211939)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/ScriptController.cpp        2017-02-09 08:55:52 UTC (rev 211940)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2006-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -196,7 +196,7 @@
</span><span class="cx">     static_cast&lt;JSVMClientData*&gt;(JSDOMWindow::commonVM().clientData)-&gt;getAllWorlds(worlds);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScriptController::clearWindowShell(DOMWindow* newDOMWindow, bool goingIntoPageCache)
</del><ins>+void ScriptController::clearWindowShellsNotMatchingDOMWindow(DOMWindow* newDOMWindow, bool goingIntoPageCache)
</ins><span class="cx"> {
</span><span class="cx">     if (m_windowShells.isEmpty())
</span><span class="cx">         return;
</span><span class="lines">@@ -203,20 +203,35 @@
</span><span class="cx"> 
</span><span class="cx">     JSLockHolder lock(JSDOMWindowBase::commonVM());
</span><span class="cx"> 
</span><del>-    Vector&lt;JSC::Strong&lt;JSDOMWindowShell&gt;&gt; windowShells = this-&gt;windowShells();
-    for (size_t i = 0; i &lt; windowShells.size(); ++i) {
-        JSDOMWindowShell* windowShell = windowShells[i].get();
-
</del><ins>+    for (auto&amp; windowShell : windowShells()) {
</ins><span class="cx">         if (&amp;windowShell-&gt;window()-&gt;wrapped() == newDOMWindow)
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         // Clear the debugger and console from the current window before setting the new window.
</span><del>-        attachDebugger(windowShell, nullptr);
</del><ins>+        attachDebugger(windowShell.get(), nullptr);
</ins><span class="cx">         windowShell-&gt;window()-&gt;setConsoleClient(nullptr);
</span><ins>+        windowShell-&gt;window()-&gt;willRemoveFromWindowShell();
+    }
</ins><span class="cx"> 
</span><del>-        windowShell-&gt;window()-&gt;willRemoveFromWindowShell();
</del><ins>+    // It's likely that resetting our windows created a lot of garbage, unless
+    // it went in a back/forward cache.
+    if (!goingIntoPageCache)
+        collectGarbageAfterWindowShellDestruction();
+}
+
+void ScriptController::setDOMWindowForWindowShell(DOMWindow* newDOMWindow)
+{
+    if (m_windowShells.isEmpty())
+        return;
+    
+    JSLockHolder lock(JSDOMWindowBase::commonVM());
+    
+    for (auto&amp; windowShell : windowShells()) {
+        if (&amp;windowShell-&gt;window()-&gt;wrapped() == newDOMWindow)
+            continue;
+        
</ins><span class="cx">         windowShell-&gt;setWindow(newDOMWindow);
</span><del>-
</del><ins>+        
</ins><span class="cx">         // An m_cacheableBindingRootObject persists between page navigations
</span><span class="cx">         // so needs to know about the new JSDOMWindow.
</span><span class="cx">         if (m_cacheableBindingRootObject)
</span><span class="lines">@@ -223,16 +238,11 @@
</span><span class="cx">             m_cacheableBindingRootObject-&gt;updateGlobalObject(windowShell-&gt;window());
</span><span class="cx"> 
</span><span class="cx">         if (Page* page = m_frame.page()) {
</span><del>-            attachDebugger(windowShell, page-&gt;debugger());
</del><ins>+            attachDebugger(windowShell.get(), page-&gt;debugger());
</ins><span class="cx">             windowShell-&gt;window()-&gt;setProfileGroup(page-&gt;group().identifier());
</span><span class="cx">             windowShell-&gt;window()-&gt;setConsoleClient(&amp;page-&gt;console());
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-
-    // It's likely that resetting our windows created a lot of garbage, unless
-    // it went in a back/forward cache.
-    if (!goingIntoPageCache)
-        collectGarbageAfterWindowShellDestruction();
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld&amp; world)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit214SourceWebCorebindingsjsScriptControllerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/ScriptController.h (211939 => 211940)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/ScriptController.h        2017-02-09 08:55:44 UTC (rev 211939)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/ScriptController.h        2017-02-09 08:55:52 UTC (rev 211940)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2008 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2008-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2008 Eric Seidel &lt;eric@webkit.org&gt;
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -135,7 +135,8 @@
</span><span class="cx"> 
</span><span class="cx">     const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script
</span><span class="cx"> 
</span><del>-    void clearWindowShell(DOMWindow* newDOMWindow, bool goingIntoPageCache);
</del><ins>+    void clearWindowShellsNotMatchingDOMWindow(DOMWindow*, bool goingIntoPageCache);
+    void setDOMWindowForWindowShell(DOMWindow*);
</ins><span class="cx">     void updateDocument();
</span><span class="cx"> 
</span><span class="cx">     void namedItemAdded(HTMLDocument*, const AtomicString&amp;) { }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit214SourceWebCoreloaderFrameLoadercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/loader/FrameLoader.cpp (211939 => 211940)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.14/Source/WebCore/loader/FrameLoader.cpp        2017-02-09 08:55:44 UTC (rev 211939)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/loader/FrameLoader.cpp        2017-02-09 08:55:52 UTC (rev 211940)
</span><span class="lines">@@ -604,7 +604,7 @@
</span><span class="cx">     if (clearWindowProperties) {
</span><span class="cx">         InspectorInstrumentation::frameWindowDiscarded(&amp;m_frame, m_frame.document()-&gt;domWindow());
</span><span class="cx">         m_frame.document()-&gt;domWindow()-&gt;resetUnlessSuspendedForDocumentSuspension();
</span><del>-        m_frame.script().clearWindowShell(newDocument-&gt;domWindow(), m_frame.document()-&gt;inPageCache());
</del><ins>+        m_frame.script().clearWindowShellsNotMatchingDOMWindow(newDocument-&gt;domWindow(), m_frame.document()-&gt;inPageCache());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_frame.selection().prepareForDestruction();
</span><span class="lines">@@ -622,6 +622,9 @@
</span><span class="cx"> 
</span><span class="cx">     subframeLoader().clear();
</span><span class="cx"> 
</span><ins>+    if (clearWindowProperties)
+        m_frame.script().setDOMWindowForWindowShell(newDocument-&gt;domWindow());
+
</ins><span class="cx">     if (clearScriptObjects)
</span><span class="cx">         m_frame.script().clearScriptObjects();
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>