Commit 8b2606e4 authored by andersca's avatar andersca
Browse files

Reviewed by Darin.

        <rdar://problem/5267992>
        Make sure an alert doesn't allow loading to continue inside a script.
        
        Make sure to defer all loads where it's possible for a second main loop to be running.
        
        * page/Chrome.cpp:
        (WebCore::Chrome::runModal):
        (WebCore::Chrome::runBeforeUnloadConfirmPanel):
        (WebCore::Chrome::runJavaScriptAlert):
        (WebCore::Chrome::runJavaScriptConfirm):
        (WebCore::Chrome::runJavaScriptPrompt):
        (WebCore::PageGroupLoadDeferrer::PageGroupLoadDeferrer):
        (WebCore::PageGroupLoadDeferrer::~PageGroupLoadDeferrer):
        
        * platform/network/cf/ResourceHandleCFNet.cpp:
        (WebCore::ResourceHandle::setDefersLoading):
        Implement this.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@23510 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 534741b0
2007-06-13 Anders Carlsson <andersca@apple.com>
Reviewed by Darin.
<rdar://problem/5267992>
Make sure an alert doesn't allow loading to continue inside a script.
Make sure to defer all loads where it's possible for a second main loop to be running.
* page/Chrome.cpp:
(WebCore::Chrome::runModal):
(WebCore::Chrome::runBeforeUnloadConfirmPanel):
(WebCore::Chrome::runJavaScriptAlert):
(WebCore::Chrome::runJavaScriptConfirm):
(WebCore::Chrome::runJavaScriptPrompt):
(WebCore::PageGroupLoadDeferrer::PageGroupLoadDeferrer):
(WebCore::PageGroupLoadDeferrer::~PageGroupLoadDeferrer):
* platform/network/cf/ResourceHandleCFNet.cpp:
(WebCore::ResourceHandle::setDefersLoading):
Implement this.
2007-06-13 Alp Toker <alp.toker@collabora.co.uk>
 
Reviewed by Rob.
......@@ -33,6 +33,14 @@
namespace WebCore {
class PageGroupLoadDeferrer : Noncopyable {
public:
PageGroupLoadDeferrer(Page*, bool deferSelf);
~PageGroupLoadDeferrer();
private:
Vector<Page*, 16> m_deferredPages;
};
Chrome::Chrome(Page* page, ChromeClient* client)
: m_page(page)
, m_client(client)
......@@ -119,27 +127,12 @@ void Chrome::runModal() const
return;
}
// Defer callbacks in all the other pages in this group, so we don't try to run JavaScript
// Defer callbacks in all the other pages in this group, so we don't try to run JavaScript
// in a way that could interact with this view.
Vector<Page*> pagesToDefer;
if (const HashSet<Page*>* group = m_page->frameNamespace()) {
HashSet<Page*>::const_iterator end = group->end();
for (HashSet<Page*>::const_iterator it = group->begin(); it != end; ++it) {
Page* otherPage = *it;
if (otherPage != m_page && !otherPage->defersLoading())
pagesToDefer.append(otherPage);
}
}
size_t count = pagesToDefer.size();
for (size_t i = 0; i < count; ++i)
pagesToDefer[i]->setDefersLoading(true);
PageGroupLoadDeferrer deferrer(m_page, false);
// Go run the modal event loop.
m_client->runModal();
// Restore loading for any views that we shut down.
for (size_t i = 0; i < count; ++i)
pagesToDefer[i]->setDefersLoading(false);
}
void Chrome::setToolbarsVisible(bool b) const
......@@ -200,6 +193,10 @@ bool Chrome::canRunBeforeUnloadConfirmPanel()
bool Chrome::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
{
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
return m_client->runBeforeUnloadConfirmPanel(message, frame);
}
......@@ -210,14 +207,23 @@ void Chrome::closeWindowSoon()
void Chrome::runJavaScriptAlert(Frame* frame, const String& message)
{
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
ASSERT(frame);
String text = message;
text.replace('\\', frame->backslashAsCurrencySymbol());
m_client->runJavaScriptAlert(frame, text);
}
bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
{
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
ASSERT(frame);
String text = message;
text.replace('\\', frame->backslashAsCurrencySymbol());
......@@ -227,6 +233,10 @@ bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultValue, String& result)
{
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
ASSERT(frame);
String promptText = prompt;
promptText.replace('\\', frame->backslashAsCurrencySymbol());
......@@ -252,6 +262,10 @@ void Chrome::setStatusbarText(Frame* frame, const String& status)
bool Chrome::shouldInterruptJavaScript()
{
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
return m_client->shouldInterruptJavaScript();
}
......@@ -275,5 +289,27 @@ void Chrome::updateBackingStore()
m_client->updateBackingStore();
}
PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
{
if (const HashSet<Page*>* group = page->frameNamespace()) {
HashSet<Page*>::const_iterator end = group->end();
for (HashSet<Page*>::const_iterator it = group->begin(); it != end; ++it) {
Page* otherPage = *it;
if ((deferSelf || otherPage != page) && !otherPage->defersLoading())
m_deferredPages.append(otherPage);
}
}
size_t count = m_deferredPages.size();
for (size_t i = 0; i < count; ++i)
m_deferredPages[i]->setDefersLoading(true);
}
PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
{
size_t count = m_deferredPages.size();
for (size_t i = 0; i < count; ++i)
m_deferredPages[i]->setDefersLoading(false);
}
} // namespace WebCore
......@@ -399,4 +399,12 @@ void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
allowsAnyHTTPSCertificateHosts().add(host.lower());
}
void ResourceHandle::setDefersLoading(bool defers)
{
if (defers)
CFURLConnectionHalt(d->m_connection.get());
else
CFURLConnectionResume(d->m_connection.get());
}
} // namespace WebCore
......@@ -103,7 +103,6 @@ void Frame::setNeedsReapplyStyles() { notImplemented(); }
String FrameLoader::overrideMediaType()const { notImplemented(); return String(); }
bool ResourceHandle::loadsBlocked() { return false; }
void ResourceHandle::setDefersLoading(bool) { }
// CRITFIXME: See if any of the following are actually implemented in OpenSource and copy the impls to internal
bool DocumentLoader::getResponseModifiedHeader(String&) const { notImplemented(); return false; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment