| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 5 * (http://www.torchmobile.com/) | 5 * (http://www.torchmobile.com/) |
| 6 * Copyright (C) 2009 Adam Barth. All rights reserved. | 6 * Copyright (C) 2009 Adam Barth. All rights reserved. |
| 7 * | 7 * |
| 8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
| 9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
| 10 * are met: | 10 * are met: |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 Member<Document> m_originDocument; | 147 Member<Document> m_originDocument; |
| 148 bool m_replacesCurrentItem; | 148 bool m_replacesCurrentItem; |
| 149 bool m_isLocationChange; | 149 bool m_isLocationChange; |
| 150 RefPtr<UserGestureToken> m_userGestureToken; | 150 RefPtr<UserGestureToken> m_userGestureToken; |
| 151 }; | 151 }; |
| 152 | 152 |
| 153 class ScheduledURLNavigation : public ScheduledNavigation { | 153 class ScheduledURLNavigation : public ScheduledNavigation { |
| 154 protected: | 154 protected: |
| 155 ScheduledURLNavigation(double delay, | 155 ScheduledURLNavigation(double delay, |
| 156 Document* originDocument, | 156 Document* originDocument, |
| 157 const String& url, | 157 const KURL& url, |
| 158 bool replacesCurrentItem, | 158 bool replacesCurrentItem, |
| 159 bool isLocationChange) | 159 bool isLocationChange) |
| 160 : ScheduledNavigation(delay, | 160 : ScheduledNavigation(delay, |
| 161 originDocument, | 161 originDocument, |
| 162 replacesCurrentItem, | 162 replacesCurrentItem, |
| 163 isLocationChange), | 163 isLocationChange), |
| 164 m_url(url), | 164 m_url(url), |
| 165 m_shouldCheckMainWorldContentSecurityPolicy( | 165 m_shouldCheckMainWorldContentSecurityPolicy( |
| 166 CheckContentSecurityPolicy) { | 166 CheckContentSecurityPolicy) { |
| 167 if (ContentSecurityPolicy::shouldBypassMainWorld(originDocument)) { | 167 if (ContentSecurityPolicy::shouldBypassMainWorld(originDocument)) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 178 request.setReplacesCurrentItem(replacesCurrentItem()); | 178 request.setReplacesCurrentItem(replacesCurrentItem()); |
| 179 request.setClientRedirect(ClientRedirectPolicy::ClientRedirect); | 179 request.setClientRedirect(ClientRedirectPolicy::ClientRedirect); |
| 180 | 180 |
| 181 ScheduledNavigationType type = | 181 ScheduledNavigationType type = |
| 182 isLocationChange() ? ScheduledNavigationType::ScheduledLocationChange | 182 isLocationChange() ? ScheduledNavigationType::ScheduledLocationChange |
| 183 : ScheduledNavigationType::ScheduledURLNavigation; | 183 : ScheduledNavigationType::ScheduledURLNavigation; |
| 184 maybeLogScheduledNavigationClobber(type, frame); | 184 maybeLogScheduledNavigationClobber(type, frame); |
| 185 frame->loader().load(request); | 185 frame->loader().load(request); |
| 186 } | 186 } |
| 187 | 187 |
| 188 String url() const { return m_url; } | 188 KURL url() const { return m_url; } |
| 189 | 189 |
| 190 private: | 190 private: |
| 191 String m_url; | 191 KURL m_url; |
| 192 ContentSecurityPolicyDisposition m_shouldCheckMainWorldContentSecurityPolicy; | 192 ContentSecurityPolicyDisposition m_shouldCheckMainWorldContentSecurityPolicy; |
| 193 }; | 193 }; |
| 194 | 194 |
| 195 class ScheduledRedirect final : public ScheduledURLNavigation { | 195 class ScheduledRedirect final : public ScheduledURLNavigation { |
| 196 public: | 196 public: |
| 197 static ScheduledRedirect* create(double delay, | 197 static ScheduledRedirect* create(double delay, |
| 198 Document* originDocument, | 198 Document* originDocument, |
| 199 const String& url, | 199 const KURL& url, |
| 200 bool replacesCurrentItem) { | 200 bool replacesCurrentItem) { |
| 201 return new ScheduledRedirect(delay, originDocument, url, | 201 return new ScheduledRedirect(delay, originDocument, url, |
| 202 replacesCurrentItem); | 202 replacesCurrentItem); |
| 203 } | 203 } |
| 204 | 204 |
| 205 bool shouldStartTimer(LocalFrame* frame) override { | 205 bool shouldStartTimer(LocalFrame* frame) override { |
| 206 return frame->document()->loadEventFinished(); | 206 return frame->document()->loadEventFinished(); |
| 207 } | 207 } |
| 208 | 208 |
| 209 void fire(LocalFrame* frame) override { | 209 void fire(LocalFrame* frame) override { |
| 210 std::unique_ptr<UserGestureIndicator> gestureIndicator = | 210 std::unique_ptr<UserGestureIndicator> gestureIndicator = |
| 211 createUserGestureIndicator(); | 211 createUserGestureIndicator(); |
| 212 FrameLoadRequest request(originDocument(), url(), "_self"); | 212 FrameLoadRequest request(originDocument(), url(), "_self"); |
| 213 request.setReplacesCurrentItem(replacesCurrentItem()); | 213 request.setReplacesCurrentItem(replacesCurrentItem()); |
| 214 if (equalIgnoringFragmentIdentifier(frame->document()->url(), | 214 if (equalIgnoringFragmentIdentifier(frame->document()->url(), |
| 215 request.resourceRequest().url())) { | 215 request.resourceRequest().url())) { |
| 216 request.resourceRequest().setCachePolicy( | 216 request.resourceRequest().setCachePolicy( |
| 217 WebCachePolicy::ValidatingCacheData); | 217 WebCachePolicy::ValidatingCacheData); |
| 218 } | 218 } |
| 219 request.setClientRedirect(ClientRedirectPolicy::ClientRedirect); | 219 request.setClientRedirect(ClientRedirectPolicy::ClientRedirect); |
| 220 maybeLogScheduledNavigationClobber( | 220 maybeLogScheduledNavigationClobber( |
| 221 ScheduledNavigationType::ScheduledRedirect, frame); | 221 ScheduledNavigationType::ScheduledRedirect, frame); |
| 222 frame->loader().load(request); | 222 frame->loader().load(request); |
| 223 } | 223 } |
| 224 | 224 |
| 225 private: | 225 private: |
| 226 ScheduledRedirect(double delay, | 226 ScheduledRedirect(double delay, |
| 227 Document* originDocument, | 227 Document* originDocument, |
| 228 const String& url, | 228 const KURL& url, |
| 229 bool replacesCurrentItem) | 229 bool replacesCurrentItem) |
| 230 : ScheduledURLNavigation(delay, | 230 : ScheduledURLNavigation(delay, |
| 231 originDocument, | 231 originDocument, |
| 232 url, | 232 url, |
| 233 replacesCurrentItem, | 233 replacesCurrentItem, |
| 234 false) { | 234 false) { |
| 235 clearUserGesture(); | 235 clearUserGesture(); |
| 236 } | 236 } |
| 237 }; | 237 }; |
| 238 | 238 |
| 239 class ScheduledLocationChange final : public ScheduledURLNavigation { | 239 class ScheduledLocationChange final : public ScheduledURLNavigation { |
| 240 public: | 240 public: |
| 241 static ScheduledLocationChange* create(Document* originDocument, | 241 static ScheduledLocationChange* create(Document* originDocument, |
| 242 const String& url, | 242 const KURL& url, |
| 243 bool replacesCurrentItem) { | 243 bool replacesCurrentItem) { |
| 244 return new ScheduledLocationChange(originDocument, url, | 244 return new ScheduledLocationChange(originDocument, url, |
| 245 replacesCurrentItem); | 245 replacesCurrentItem); |
| 246 } | 246 } |
| 247 | 247 |
| 248 private: | 248 private: |
| 249 ScheduledLocationChange(Document* originDocument, | 249 ScheduledLocationChange(Document* originDocument, |
| 250 const String& url, | 250 const KURL& url, |
| 251 bool replacesCurrentItem) | 251 bool replacesCurrentItem) |
| 252 : ScheduledURLNavigation(0.0, | 252 : ScheduledURLNavigation(0.0, |
| 253 originDocument, | 253 originDocument, |
| 254 url, | 254 url, |
| 255 replacesCurrentItem, | 255 replacesCurrentItem, |
| 256 !protocolIsJavaScript(url)) {} | 256 !url.protocolIsJavaScript()) {} |
| 257 }; | 257 }; |
| 258 | 258 |
| 259 class ScheduledReload final : public ScheduledNavigation { | 259 class ScheduledReload final : public ScheduledNavigation { |
| 260 public: | 260 public: |
| 261 static ScheduledReload* create() { return new ScheduledReload; } | 261 static ScheduledReload* create() { return new ScheduledReload; } |
| 262 | 262 |
| 263 void fire(LocalFrame* frame) override { | 263 void fire(LocalFrame* frame) override { |
| 264 std::unique_ptr<UserGestureIndicator> gestureIndicator = | 264 std::unique_ptr<UserGestureIndicator> gestureIndicator = |
| 265 createUserGestureIndicator(); | 265 createUserGestureIndicator(); |
| 266 ResourceRequest resourceRequest = frame->loader().resourceRequestForReload( | 266 ResourceRequest resourceRequest = frame->loader().resourceRequestForReload( |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 // to prevent Documents from being reattached during destruction, since it | 374 // to prevent Documents from being reattached during destruction, since it |
| 375 // can cause bugs with security origin confusion. This is primarily intended | 375 // can cause bugs with security origin confusion. This is primarily intended |
| 376 // to block /synchronous/ navigations during things lke | 376 // to block /synchronous/ navigations during things lke |
| 377 // Document::detachLayoutTree(). | 377 // Document::detachLayoutTree(). |
| 378 inline bool NavigationScheduler::shouldScheduleReload() const { | 378 inline bool NavigationScheduler::shouldScheduleReload() const { |
| 379 return m_frame->page() && m_frame->isNavigationAllowed() && | 379 return m_frame->page() && m_frame->isNavigationAllowed() && |
| 380 NavigationDisablerForBeforeUnload::isNavigationAllowed(); | 380 NavigationDisablerForBeforeUnload::isNavigationAllowed(); |
| 381 } | 381 } |
| 382 | 382 |
| 383 inline bool NavigationScheduler::shouldScheduleNavigation( | 383 inline bool NavigationScheduler::shouldScheduleNavigation( |
| 384 const String& url) const { | 384 const KURL& url) const { |
| 385 return m_frame->page() && m_frame->isNavigationAllowed() && | 385 return m_frame->page() && m_frame->isNavigationAllowed() && |
| 386 (protocolIsJavaScript(url) || | 386 (url.protocolIsJavaScript() || |
| 387 NavigationDisablerForBeforeUnload::isNavigationAllowed()); | 387 NavigationDisablerForBeforeUnload::isNavigationAllowed()); |
| 388 } | 388 } |
| 389 | 389 |
| 390 void NavigationScheduler::scheduleRedirect(double delay, const String& url) { | 390 void NavigationScheduler::scheduleRedirect(double delay, const KURL& url) { |
| 391 if (!shouldScheduleNavigation(url)) | 391 if (!shouldScheduleNavigation(url)) |
| 392 return; | 392 return; |
| 393 if (delay < 0 || delay > INT_MAX / 1000) | 393 if (delay < 0 || delay > INT_MAX / 1000) |
| 394 return; | 394 return; |
| 395 if (url.isEmpty()) | 395 if (url.isEmpty()) |
| 396 return; | 396 return; |
| 397 | 397 |
| 398 // We want a new back/forward list item if the refresh timeout is > 1 second. | 398 // We want a new back/forward list item if the refresh timeout is > 1 second. |
| 399 if (!m_redirect || delay <= m_redirect->delay()) { | 399 if (!m_redirect || delay <= m_redirect->delay()) { |
| 400 schedule( | 400 schedule( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 414 // create a new back/forward item. The definition of "during load" is any time | 414 // create a new back/forward item. The definition of "during load" is any time |
| 415 // before all handlers for the load event have been run. See | 415 // before all handlers for the load event have been run. See |
| 416 // https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation | 416 // https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation |
| 417 // for this. | 417 // for this. |
| 418 Frame* parentFrame = targetFrame->tree().parent(); | 418 Frame* parentFrame = targetFrame->tree().parent(); |
| 419 return parentFrame && parentFrame->isLocalFrame() && | 419 return parentFrame && parentFrame->isLocalFrame() && |
| 420 !toLocalFrame(parentFrame)->loader().allAncestorsAreComplete(); | 420 !toLocalFrame(parentFrame)->loader().allAncestorsAreComplete(); |
| 421 } | 421 } |
| 422 | 422 |
| 423 void NavigationScheduler::scheduleLocationChange(Document* originDocument, | 423 void NavigationScheduler::scheduleLocationChange(Document* originDocument, |
| 424 const String& url, | 424 const KURL& url, |
| 425 bool replacesCurrentItem) { | 425 bool replacesCurrentItem) { |
| 426 if (!shouldScheduleNavigation(url)) | 426 if (!shouldScheduleNavigation(url)) |
| 427 return; | 427 return; |
| 428 | 428 |
| 429 replacesCurrentItem = replacesCurrentItem || mustReplaceCurrentItem(m_frame); | 429 replacesCurrentItem = replacesCurrentItem || mustReplaceCurrentItem(m_frame); |
| 430 | 430 |
| 431 // If the URL we're going to navigate to is the same as the current one, | 431 // If the URL we're going to navigate to is the same as the current one, |
| 432 // except for the fragment part, we don't need to schedule the location | 432 // except for the fragment part, we don't need to schedule the location |
| 433 // change. We'll skip this optimization for cross-origin navigations to | 433 // change. We'll skip this optimization for cross-origin navigations to |
| 434 // minimize the navigator's ability to execute timing attacks. | 434 // minimize the navigator's ability to execute timing attacks. |
| 435 if (originDocument->getSecurityOrigin()->canAccess( | 435 if (originDocument->getSecurityOrigin()->canAccess( |
| 436 m_frame->document()->getSecurityOrigin())) { | 436 m_frame->document()->getSecurityOrigin())) { |
| 437 KURL parsedURL(ParsedURLString, url); | 437 if (url.hasFragmentIdentifier() && |
| 438 if (parsedURL.hasFragmentIdentifier() && | 438 equalIgnoringFragmentIdentifier(m_frame->document()->url(), url)) { |
| 439 equalIgnoringFragmentIdentifier(m_frame->document()->url(), | 439 FrameLoadRequest request(originDocument, url, "_self"); |
| 440 parsedURL)) { | |
| 441 FrameLoadRequest request(originDocument, | |
| 442 m_frame->document()->completeURL(url), "_self"); | |
| 443 request.setReplacesCurrentItem(replacesCurrentItem); | 440 request.setReplacesCurrentItem(replacesCurrentItem); |
| 444 if (replacesCurrentItem) | 441 if (replacesCurrentItem) |
| 445 request.setClientRedirect(ClientRedirectPolicy::ClientRedirect); | 442 request.setClientRedirect(ClientRedirectPolicy::ClientRedirect); |
| 446 m_frame->loader().load(request); | 443 m_frame->loader().load(request); |
| 447 return; | 444 return; |
| 448 } | 445 } |
| 449 } | 446 } |
| 450 | 447 |
| 451 schedule(ScheduledLocationChange::create(originDocument, url, | 448 schedule(ScheduledLocationChange::create(originDocument, url, |
| 452 replacesCurrentItem)); | 449 replacesCurrentItem)); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 m_navigateTaskHandle.cancel(); | 541 m_navigateTaskHandle.cancel(); |
| 545 m_redirect.clear(); | 542 m_redirect.clear(); |
| 546 } | 543 } |
| 547 | 544 |
| 548 DEFINE_TRACE(NavigationScheduler) { | 545 DEFINE_TRACE(NavigationScheduler) { |
| 549 visitor->trace(m_frame); | 546 visitor->trace(m_frame); |
| 550 visitor->trace(m_redirect); | 547 visitor->trace(m_redirect); |
| 551 } | 548 } |
| 552 | 549 |
| 553 } // namespace blink | 550 } // namespace blink |
| OLD | NEW |