summaryrefslogtreecommitdiffstats
path: root/WebCore/loader/FrameLoader.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-12-15 10:12:09 +0000
committerSteve Block <steveblock@google.com>2009-12-17 17:41:10 +0000
commit643ca7872b450ea4efacab6188849e5aac2ba161 (patch)
tree6982576c228bcd1a7efe98afed544d840751094c /WebCore/loader/FrameLoader.cpp
parentd026980fde6eb3b01c1fe49441174e89cd1be298 (diff)
downloadexternal_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.zip
external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.tar.gz
external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.tar.bz2
Merge webkit.org at r51976 : Initial merge by git.
Change-Id: Ib0e7e2f0fb4bee5a186610272edf3186f0986b43
Diffstat (limited to 'WebCore/loader/FrameLoader.cpp')
-rw-r--r--WebCore/loader/FrameLoader.cpp425
1 files changed, 249 insertions, 176 deletions
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index 98b8e61..22399b0 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -203,6 +203,7 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
, m_didPerformFirstNavigation(false)
, m_loadingFromCachedPage(false)
, m_suppressOpenerInNewFrame(false)
+ , m_sandboxFlags(SandboxAll)
#ifndef NDEBUG
, m_didDispatchDidCommitLoad(false)
#endif
@@ -235,6 +236,9 @@ void FrameLoader::init()
m_frame->document()->cancelParsing();
m_creatingInitialEmptyDocument = false;
m_didCallImplicitClose = true;
+
+ // Propagate sandbox attributes to this Frameloader and its descendants.
+ updateSandboxFlags();
}
void FrameLoader::setDefersLoading(bool defers)
@@ -452,6 +456,9 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F
if (u.isEmpty())
return;
+ if (isSandboxed(SandboxForms))
+ return;
+
if (protocolIsJavaScript(u)) {
m_isExecutingJavaScriptFormAction = true;
m_frame->script()->executeIfJavaScriptURL(u, false, false);
@@ -530,7 +537,10 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic
if (m_frame->domWindow()) {
if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide)
m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document());
+<<<<<<< HEAD:WebCore/loader/FrameLoader.cpp
#ifndef ANDROID_PAGE_CACHE_UNLOAD
+=======
+>>>>>>> webkit.org at r51976:WebCore/loader/FrameLoader.cpp
if (!m_frame->document()->inPageCache())
#endif
m_frame->domWindow()->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), m_frame->domWindow()->document());
@@ -624,8 +634,8 @@ KURL FrameLoader::iconURL()
KURL url;
url.setProtocol(m_URL.protocol());
url.setHost(m_URL.host());
- if (int port = m_URL.port())
- url.setPort(port);
+ if (m_URL.hasPort())
+ url.setPort(m_URL.port());
url.setPath("/favicon.ico");
return url;
}
@@ -759,7 +769,7 @@ void FrameLoader::receivedFirstData()
begin(m_workingURL, false);
dispatchDidCommitLoad();
- dispatchWindowObjectAvailable();
+ dispatchDidClearWindowObjectsInAllWorlds();
if (m_documentLoader) {
String ptitle = m_documentLoader->title();
@@ -848,7 +858,7 @@ void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin)
m_frame->domWindow()->setSecurityOrigin(document->securityOrigin());
if (dispatch)
- dispatchWindowObjectAvailable();
+ dispatchDidClearWindowObjectsInAllWorlds();
updateFirstPartyForCookies();
@@ -1285,14 +1295,18 @@ bool FrameLoader::requestObject(RenderPart* renderer, const String& url, const A
if (!settings || !settings->arePluginsEnabled() ||
(!settings->isJavaEnabled() && MIMETypeRegistry::isJavaAppletMIMEType(mimeType)))
return false;
+ if (isSandboxed(SandboxPlugins))
+ return false;
return loadPlugin(renderer, completedURL, mimeType, paramNames, paramValues, useFallback);
}
ASSERT(renderer->node()->hasTagName(objectTag) || renderer->node()->hasTagName(embedTag));
HTMLPlugInElement* element = static_cast<HTMLPlugInElement*>(renderer->node());
-
- // FIXME: OK to always make a new frame? When does the old frame get removed?
- return loadSubframe(element, completedURL, frameName, m_outgoingReferrer);
+
+ // If the plug-in element already contains a subframe, requestFrame will re-use it. Otherwise,
+ // it will create a new frame and set it as the RenderPart's widget, causing what was previously
+ // in the widget to be torn down.
+ return requestFrame(element, completedURL, frameName);
}
bool FrameLoader::shouldUsePlugin(const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback)
@@ -1730,52 +1744,70 @@ void FrameLoader::setFirstPartyForCookies(const KURL& url)
child->loader()->setFirstPartyForCookies(url);
}
-class HashChangeEventTask : public ScriptExecutionContext::Task {
-public:
- static PassRefPtr<HashChangeEventTask> create(PassRefPtr<Document> document)
- {
- return adoptRef(new HashChangeEventTask(document));
- }
-
- virtual void performTask(ScriptExecutionContext* context)
- {
- ASSERT_UNUSED(context, context->isDocument());
- m_document->dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false));
- }
-
-private:
- HashChangeEventTask(PassRefPtr<Document> document)
- : m_document(document)
- {
- ASSERT(m_document);
- }
-
- RefPtr<Document> m_document;
-};
-
// This does the same kind of work that didOpenURL does, except it relies on the fact
// that a higher level already checked that the URLs match and the scrolling is the right thing to do.
-void FrameLoader::scrollToAnchor(const KURL& url)
-{
- ASSERT(equalIgnoringFragmentIdentifier(url, m_URL));
- if (equalIgnoringFragmentIdentifier(url, m_URL) && !equalIgnoringNullity(url.fragmentIdentifier(), m_URL.fragmentIdentifier())) {
- Document* currentDocument = frame()->document();
- currentDocument->postTask(HashChangeEventTask::create(currentDocument));
+void FrameLoader::loadInSameDocument(const KURL& url, SerializedScriptValue* stateObject, bool isNewNavigation)
+{
+ // If we have a state object, we cannot also be a new navigation.
+ ASSERT(!stateObject || (stateObject && !isNewNavigation));
+
+ // Update the data source's request with the new URL to fake the URL change
+ m_frame->document()->setURL(url);
+ documentLoader()->replaceRequestURLForSameDocumentNavigation(url);
+ if (isNewNavigation && !shouldTreatURLAsSameAsCurrent(url) && !stateObject) {
+ // NB: must happen after replaceRequestURLForSameDocumentNavigation(), since we add
+ // based on the current request. Must also happen before we openURL and displace the
+ // scroll position, since adding the BF item will save away scroll state.
+
+ // NB2: If we were loading a long, slow doc, and the user anchor nav'ed before
+ // it was done, currItem is now set the that slow doc, and prevItem is whatever was
+ // before it. Adding the b/f item will bump the slow doc down to prevItem, even
+ // though its load is not yet done. I think this all works out OK, for one because
+ // we have already saved away the scroll and doc state for the long slow load,
+ // but it's not an obvious case.
+
+ history()->updateBackForwardListForFragmentScroll();
}
+ bool hashChange = equalIgnoringFragmentIdentifier(url, m_URL) && url.fragmentIdentifier() != m_URL.fragmentIdentifier();
m_URL = url;
- history()->updateForAnchorScroll();
+ history()->updateForSameDocumentNavigation();
// If we were in the autoscroll/panScroll mode we want to stop it before following the link to the anchor
- m_frame->eventHandler()->stopAutoscrollTimer();
- started();
- if (FrameView* view = m_frame->view())
- view->scrollToFragment(m_URL);
-
+ if (hashChange)
+ m_frame->eventHandler()->stopAutoscrollTimer();
+
// It's important to model this as a load that starts and immediately finishes.
// Otherwise, the parent frame may think we never finished loading.
+ started();
+
+ if (hashChange) {
+ if (FrameView* view = m_frame->view())
+ view->scrollToFragment(m_URL);
+ }
+
m_isComplete = false;
checkCompleted();
+
+ if (isNewNavigation) {
+ // This will clear previousItem from the rest of the frame tree that didn't
+ // doing any loading. We need to make a pass on this now, since for anchor nav
+ // we'll not go through a real load and reach Completed state.
+ checkLoadComplete();
+ }
+
+ if (stateObject) {
+ m_frame->document()->statePopped(stateObject);
+ m_client->dispatchDidPopStateWithinPage();
+ }
+
+ if (hashChange) {
+ m_frame->document()->dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false));
+ m_client->dispatchDidChangeLocationWithinPage();
+ }
+
+ // FrameLoaderClient::didFinishLoad() tells the internal load delegate the load finished with no error
+ m_client->didFinishLoad();
}
bool FrameLoader::isComplete() const
@@ -2256,6 +2288,10 @@ bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const
if (m_frame == targetFrame)
return true;
+ // A sandboxed frame can only navigate itself and its descendants.
+ if (isSandboxed(SandboxNavigation) && !targetFrame->tree()->isDescendantOf(m_frame))
+ return false;
+
// Let a frame navigate the top-level window that contains it. This is
// important to allow because it lets a site "frame-bust" (escape from a
// frame created by another web site).
@@ -2957,8 +2993,8 @@ void FrameLoader::checkLoadCompleteForThisFrame()
// delegate callback.
if (pdl == m_provisionalDocumentLoader)
clearProvisionalLoad();
- else if (m_provisionalDocumentLoader) {
- KURL unreachableURL = m_provisionalDocumentLoader->unreachableURL();
+ else if (activeDocumentLoader()) {
+ KURL unreachableURL = activeDocumentLoader()->unreachableURL();
if (!unreachableURL.isEmpty() && unreachableURL == pdl->request().url())
shouldReset = false;
}
@@ -3339,10 +3375,16 @@ unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& requ
ResourceRequest initialRequest = request;
initialRequest.setTimeoutInterval(10);
+ // Use the original request's cache policy for two reasons:
+ // 1. For POST requests, we mutate the cache policy for the main resource,
+ // but we do not want this to apply to subresources
+ // 2. Delegates that modify the cache policy using willSendRequest: should
+ // not affect any other resources. Such changes need to be done
+ // per request.
if (initialRequest.isConditional())
initialRequest.setCachePolicy(ReloadIgnoringCacheData);
else
- initialRequest.setCachePolicy(documentLoader()->request().cachePolicy());
+ initialRequest.setCachePolicy(originalRequest().cachePolicy());
if (!referrer.isEmpty())
initialRequest.setHTTPReferrer(referrer);
@@ -3423,12 +3465,12 @@ void FrameLoader::callContinueFragmentScrollAfterNavigationPolicy(void* argument
void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
{
- bool isRedirect = m_quickRedirectComing || policyChecker()->loadType() == FrameLoadTypeRedirectWithLockedBackForwardList;
m_quickRedirectComing = false;
if (!shouldContinue)
return;
+<<<<<<< HEAD:WebCore/loader/FrameLoader.cpp
KURL url = request.url();
m_documentLoader->replaceRequestURLForAnchorScroll(url);
@@ -3464,6 +3506,10 @@ void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequ
m_client->dispatchDidChangeLocationWithinPage();
m_client->didFinishLoad();
+=======
+ bool isRedirect = m_quickRedirectComing || policyChecker()->loadType() == FrameLoadTypeRedirectWithLockedBackForwardList;
+ loadInSameDocument(request.url(), 0, !isRedirect);
+>>>>>>> webkit.org at r51976:WebCore/loader/FrameLoader.cpp
}
bool FrameLoader::shouldScrollToAnchor(bool isFormSubmission, FrameLoadType loadType, const KURL& url)
@@ -3738,14 +3784,51 @@ Frame* FrameLoader::findFrameForNavigation(const AtomicString& name)
return frame;
}
-// Loads content into this frame, as specified by history item
+void FrameLoader::navigateWithinDocument(HistoryItem* item)
+{
+ ASSERT(!item->document() || item->document() == m_frame->document());
+
+ // Save user view state to the current history item here since we don't do a normal load.
+ // FIXME: Does form state need to be saved here too?
+ history()->saveScrollPositionAndViewStateToItem(history()->currentItem());
+ if (FrameView* view = m_frame->view())
+ view->setWasScrolledByUser(false);
+
+ history()->setCurrentItem(item);
+
+ // loadInSameDocument() actually changes the URL and notifies load delegates of a "fake" load
+ loadInSameDocument(item->url(), item->stateObject(), false);
+
+ // Restore user view state from the current history item here since we don't do a normal load.
+ // Even though we just manually set the current history item, this ASSERT verifies nothing
+ // inside of loadInSameDocument() caused it to change.
+ ASSERT(history()->currentItem() == item);
+ history()->restoreScrollPositionAndViewState();
+}
+
// FIXME: This function should really be split into a couple pieces, some of
// which should be methods of HistoryController and some of which should be
// methods of FrameLoader.
-void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType)
+void FrameLoader::navigateToDifferentDocument(HistoryItem* item, FrameLoadType loadType)
{
- if (!m_frame->page())
- return;
+ // Remember this item so we can traverse any child items as child frames load
+ history()->setProvisionalItem(item);
+
+ // Check if we'll be using the page cache. We only use the page cache
+ // if one exists and it is less than _backForwardCacheExpirationInterval
+ // seconds old. If the cache is expired it gets flushed here.
+ if (RefPtr<CachedPage> cachedPage = pageCache()->get(item)) {
+ // FIXME: 1800 should not be hardcoded, it should come from
+ // WebKitBackForwardCacheExpirationIntervalKey in WebKit.
+ // Or we should remove WebKitBackForwardCacheExpirationIntervalKey.
+ if (currentTime() - cachedPage->timeStamp() <= 1800) {
+ loadWithDocumentLoader(cachedPage->documentLoader(), loadType, 0);
+ return;
+ }
+
+ LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", history()->provisionalItem()->url().string().ascii().data());
+ pageCache()->remove(item);
+ }
KURL itemURL = item->url();
KURL itemOriginalURL = item->originalURL();
@@ -3754,138 +3837,96 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType)
currentURL = documentLoader()->url();
RefPtr<FormData> formData = item->formData();
- // Are we navigating to an anchor within the page?
- // Note if we have child frames we do a real reload, since the child frames might not
- // match our current frame structure, or they might not have the right content. We could
- // check for all that as an additional optimization.
- // We also do not do anchor-style navigation if we're posting a form or navigating from
- // a page that was resulted from a form post.
- bool shouldScroll = !formData && !(history()->currentItem() && history()->currentItem()->formData()) && history()->urlsMatchItem(item);
+ bool addedExtraFields = false;
+ ResourceRequest request(itemURL);
-#if ENABLE(WML)
- // All WML decks should go through the real load mechanism, not the scroll-to-anchor code
- if (frameContainsWMLContent(m_frame))
- shouldScroll = false;
-#endif
-
- if (shouldScroll) {
- // Must do this maintenance here, since we don't go through a real page reload
- history()->saveScrollPositionAndViewStateToItem(history()->currentItem());
-
- if (FrameView* view = m_frame->view())
- view->setWasScrolledByUser(false);
-
- history()->setCurrentItem(item);
-
- // FIXME: Form state might need to be saved here too.
-
- // We always call scrollToAnchor here, even if the URL doesn't have an
- // anchor fragment. This is so we'll keep the WebCore Frame's URL up-to-date.
- scrollToAnchor(item->url());
+ if (!item->referrer().isNull())
+ request.setHTTPReferrer(item->referrer());
- // must do this maintenance here, since we don't go through a real page reload
- history()->restoreScrollPositionAndViewState();
+ // If this was a repost that failed the page cache, we might try to repost the form.
+ NavigationAction action;
+ if (formData) {
+ formData->generateFiles(m_frame->page()->chrome()->client());
+
+ request.setHTTPMethod("POST");
+ request.setHTTPBody(formData);
+ request.setHTTPContentType(item->formContentType());
+ RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer());
+ addHTTPOriginIfNeeded(request, securityOrigin->toString());
+
+ // Make sure to add extra fields to the request after the Origin header is added for the FormData case.
+ // See https://bugs.webkit.org/show_bug.cgi?id=22194 for more discussion.
+ addExtraFieldsToRequest(request, m_loadType, true, formData);
+ addedExtraFields = true;
- // Fake the URL change by updating the data source's request. This will no longer
- // be necessary if we do the better fix described above.
- documentLoader()->replaceRequestURLForAnchorScroll(itemURL);
-
- m_client->dispatchDidChangeLocationWithinPage();
+ // FIXME: Slight hack to test if the NSURL cache contains the page we're going to.
+ // We want to know this before talking to the policy delegate, since it affects whether
+ // we show the DoYouReallyWantToRepost nag.
+ //
+ // This trick has a small bug (3123893) where we might find a cache hit, but then
+ // have the item vanish when we try to use it in the ensuing nav. This should be
+ // extremely rare, but in that case the user will get an error on the navigation.
- // FrameLoaderClient::didFinishLoad() tells the internal load delegate the load finished with no error
- m_client->didFinishLoad();
+ if (ResourceHandle::willLoadFromCache(request, m_frame))
+ action = NavigationAction(itemURL, loadType, false);
+ else {
+ request.setCachePolicy(ReloadIgnoringCacheData);
+ action = NavigationAction(itemURL, NavigationTypeFormResubmitted);
+ }
} else {
- // Remember this item so we can traverse any child items as child frames load
- history()->setProvisionalItem(item);
-
- bool inPageCache = false;
-
- // Check if we'll be using the page cache. We only use the page cache
- // if one exists and it is less than _backForwardCacheExpirationInterval
- // seconds old. If the cache is expired it gets flushed here.
- if (RefPtr<CachedPage> cachedPage = pageCache()->get(item)) {
- double interval = currentTime() - cachedPage->timeStamp();
-
- // FIXME: 1800 should not be hardcoded, it should come from
- // WebKitBackForwardCacheExpirationIntervalKey in WebKit.
- // Or we should remove WebKitBackForwardCacheExpirationIntervalKey.
- if (interval <= 1800) {
- loadWithDocumentLoader(cachedPage->documentLoader(), loadType, 0);
- inPageCache = true;
- } else {
- LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", history()->provisionalItem()->url().string().ascii().data());
- pageCache()->remove(item);
- }
+ switch (loadType) {
+ case FrameLoadTypeReload:
+ case FrameLoadTypeReloadFromOrigin:
+ request.setCachePolicy(ReloadIgnoringCacheData);
+ break;
+ case FrameLoadTypeBack:
+ case FrameLoadTypeBackWMLDeckNotAccessible:
+ case FrameLoadTypeForward:
+ case FrameLoadTypeIndexedBackForward:
+ if (!itemURL.protocolIs("https"))
+ request.setCachePolicy(ReturnCacheDataElseLoad);
+ break;
+ case FrameLoadTypeStandard:
+ case FrameLoadTypeRedirectWithLockedBackForwardList:
+ break;
+ case FrameLoadTypeSame:
+ default:
+ ASSERT_NOT_REACHED();
}
-
- if (!inPageCache) {
- bool addedExtraFields = false;
- ResourceRequest request(itemURL);
- if (!item->referrer().isNull())
- request.setHTTPReferrer(item->referrer());
-
- // If this was a repost that failed the page cache, we might try to repost the form.
- NavigationAction action;
- if (formData) {
-
- formData->generateFiles(m_frame->page()->chrome()->client());
+ action = NavigationAction(itemOriginalURL, loadType, false);
+ }
+
+ if (!addedExtraFields)
+ addExtraFieldsToRequest(request, m_loadType, true, formData);
- request.setHTTPMethod("POST");
- request.setHTTPBody(formData);
- request.setHTTPContentType(item->formContentType());
- RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer());
- addHTTPOriginIfNeeded(request, securityOrigin->toString());
-
- // Make sure to add extra fields to the request after the Origin header is added for the FormData case.
- // See https://bugs.webkit.org/show_bug.cgi?id=22194 for more discussion.
- addExtraFieldsToRequest(request, m_loadType, true, formData);
- addedExtraFields = true;
-
- // FIXME: Slight hack to test if the NSURL cache contains the page we're going to.
- // We want to know this before talking to the policy delegate, since it affects whether
- // we show the DoYouReallyWantToRepost nag.
- //
- // This trick has a small bug (3123893) where we might find a cache hit, but then
- // have the item vanish when we try to use it in the ensuing nav. This should be
- // extremely rare, but in that case the user will get an error on the navigation.
-
- if (ResourceHandle::willLoadFromCache(request, m_frame))
- action = NavigationAction(itemURL, loadType, false);
- else {
- request.setCachePolicy(ReloadIgnoringCacheData);
- action = NavigationAction(itemURL, NavigationTypeFormResubmitted);
- }
- } else {
- switch (loadType) {
- case FrameLoadTypeReload:
- case FrameLoadTypeReloadFromOrigin:
- request.setCachePolicy(ReloadIgnoringCacheData);
- break;
- case FrameLoadTypeBack:
- case FrameLoadTypeBackWMLDeckNotAccessible:
- case FrameLoadTypeForward:
- case FrameLoadTypeIndexedBackForward:
- if (itemURL.protocol() != "https")
- request.setCachePolicy(ReturnCacheDataElseLoad);
- break;
- case FrameLoadTypeStandard:
- case FrameLoadTypeRedirectWithLockedBackForwardList:
- break;
- case FrameLoadTypeSame:
- default:
- ASSERT_NOT_REACHED();
- }
+ loadWithNavigationAction(request, action, false, loadType, 0);
+}
- action = NavigationAction(itemOriginalURL, loadType, false);
- }
-
- if (!addedExtraFields)
- addExtraFieldsToRequest(request, m_loadType, true, formData);
+// Loads content into this frame, as specified by history item
+void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType)
+{
+ // We do same-document navigation in the following cases:
+ // - The HistoryItem has a history state object
+ // - Navigating to an anchor within the page, with no form data stored on the target item or the current history entry,
+ // and the URLs in the frame tree match the history item for fragment scrolling.
+ bool sameDocumentNavigation = (!item->formData() && !(history()->currentItem() && history()->currentItem()->formData()) && history()->urlsMatchItem(item)) || item->document() == m_frame->document();
- loadWithNavigationAction(request, action, false, loadType, 0);
- }
- }
+#if ENABLE(WML)
+ // All WML decks should go through the real load mechanism, not the scroll-to-anchor code
+ // FIXME: Why do WML decks have this different behavior?
+ // Are WML decks incompatible with HTML5 pushState/replaceState which require inter-document history navigations?
+ // Should this new API be disabled for WML pages, or does WML need to update their mechanism to act like normal loads?
+ // If scroll-to-anchor navigations were broken for WML and required them to have different loading behavior, then
+ // state object loads are certainly also broken for them.
+ if (frameContainsWMLContent(m_frame))
+ sameDocumentNavigation = false;
+#endif
+
+ if (sameDocumentNavigation)
+ navigateWithinDocument(item);
+ else
+ navigateToDifferentDocument(item, loadType);
}
void FrameLoader::setMainDocumentError(DocumentLoader* loader, const ResourceError& error)
@@ -3955,15 +3996,28 @@ void FrameLoader::dispatchDocumentElementAvailable()
m_client->documentElementAvailable();
}
-void FrameLoader::dispatchWindowObjectAvailable()
+void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
{
- // FIXME: should this be isolated-worlds-aware?
- if (!m_frame->script()->isEnabled() || !m_frame->script()->existingWindowShell(mainThreadNormalWorld()))
+ if (!m_frame->script()->isEnabled())
return;
- m_client->windowObjectCleared();
+ Vector<DOMWrapperWorld*> worlds;
+ ScriptController::getAllWorlds(worlds);
+ for (size_t i = 0; i < worlds.size(); ++i)
+ dispatchDidClearWindowObjectInWorld(worlds[i]);
+}
+
+void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
+{
+ if (!m_frame->script()->isEnabled() || !m_frame->script()->existingWindowShell(world))
+ return;
+
+ m_client->dispatchDidClearWindowObjectInWorld(world);
#if ENABLE(INSPECTOR)
+ if (world != mainThreadNormalWorld())
+ return;
+
if (Page* page = m_frame->page()) {
if (InspectorController* inspector = page->inspectorController())
inspector->inspectedWindowScriptObjectCleared(m_frame);
@@ -3973,6 +4027,25 @@ void FrameLoader::dispatchWindowObjectAvailable()
#endif
}
+void FrameLoader::updateSandboxFlags()
+{
+ SandboxFlags flags = SandboxNone;
+ if (Frame* parentFrame = m_frame->tree()->parent())
+ flags |= parentFrame->loader()->sandboxFlags();
+ if (HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement())
+ flags |= ownerElement->sandboxFlags();
+
+ if (m_sandboxFlags == flags)
+ return;
+
+ m_sandboxFlags = flags;
+
+ m_frame->document()->updateSandboxFlags();
+
+ for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
+ child->loader()->updateSandboxFlags();
+ }
+
PassRefPtr<Widget> FrameLoader::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const HashMap<String, String>& args)
{
String baseURLString;