Defer ScriptExecutionContext::Task's in Document when page loading is deferred.
[WebKit-https.git] / Source / WebCore / page / PageGroupLoadDeferrer.cpp
index 292b4cd..e85d40e 100644 (file)
 #include "config.h"
 #include "PageGroupLoadDeferrer.h"
 
-#include "AsyncScriptRunner.h"
+#include "Document.h"
 #include "DocumentParser.h"
 #include "Frame.h"
 #include "Page.h"
 #include "PageGroup.h"
+#include "ScriptRunner.h"
 #include <wtf/HashSet.h>
 
 namespace WebCore {
@@ -39,8 +40,18 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
     HashSet<Page*>::const_iterator end = pages.end();
     for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
         Page* otherPage = *it;
-        if ((deferSelf || otherPage != page) && !otherPage->defersLoading())
-            m_deferredFrames.append(otherPage->mainFrame());
+        if ((deferSelf || otherPage != page)) {
+            if (!otherPage->defersLoading()) {
+                m_deferredFrames.append(otherPage->mainFrame());
+
+                // This code is not logically part of load deferring, but we do not want JS code executed beneath modal
+                // windows or sheets, which is exactly when PageGroupLoadDeferrer is used.
+                // NOTE: if PageGroupLoadDeferrer is ever used for tasks other than showing a modal window or sheet,
+                // the constructor will need to take a ActiveDOMObject::ReasonForSuspension.
+                for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext())
+                    frame->document()->suspendScheduledTasks();
+            }
+        }
     }
 
     size_t count = m_deferredFrames.size();
@@ -52,8 +63,12 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
 PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
 {
     for (size_t i = 0; i < m_deferredFrames.size(); ++i) {
-        if (Page* page = m_deferredFrames[i]->page())
+        if (Page* page = m_deferredFrames[i]->page()) {
             page->setDefersLoading(false);
+
+            for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
+                frame->document()->resumeScheduledTasks();
+        }
     }
 }