| 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. (http://www.t
orchmobile.com/) | 4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
| 5 * Copyright (C) 2009 Adam Barth. All rights reserved. | 5 * Copyright (C) 2009 Adam Barth. All rights reserved. |
| 6 * | 6 * |
| 7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
| 8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
| 9 * are met: | 9 * are met: |
| 10 * | 10 * |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 scheduledNavigationClobberHistogram.count(value); | 89 scheduledNavigationClobberHistogram.count(value); |
| 90 | 90 |
| 91 DEFINE_STATIC_LOCAL(CustomCountHistogram, scheduledClobberAbortTimeHistogram
, ("Navigation.Scheduled.MaybeCausedAbort.Time", 1, 10000, 50)); | 91 DEFINE_STATIC_LOCAL(CustomCountHistogram, scheduledClobberAbortTimeHistogram
, ("Navigation.Scheduled.MaybeCausedAbort.Time", 1, 10000, 50)); |
| 92 double navigationStart = frame->loader().provisionalDocumentLoader()->timing
().navigationStart(); | 92 double navigationStart = frame->loader().provisionalDocumentLoader()->timing
().navigationStart(); |
| 93 if (navigationStart) | 93 if (navigationStart) |
| 94 scheduledClobberAbortTimeHistogram.count(monotonicallyIncreasingTime() -
navigationStart); | 94 scheduledClobberAbortTimeHistogram.count(monotonicallyIncreasingTime() -
navigationStart); |
| 95 } | 95 } |
| 96 | 96 |
| 97 } // namespace | 97 } // namespace |
| 98 | 98 |
| 99 unsigned NavigationDisablerForBeforeUnload::s_navigationDisableCount = 0; | 99 unsigned NavigationDisablerForUnload::s_navigationDisableCount = 0; |
| 100 unsigned NavigationCounterForUnload::s_inUnloadHandler = 0; | |
| 101 | 100 |
| 102 class ScheduledNavigation : public GarbageCollectedFinalized<ScheduledNavigation
> { | 101 class ScheduledNavigation : public GarbageCollectedFinalized<ScheduledNavigation
> { |
| 103 WTF_MAKE_NONCOPYABLE(ScheduledNavigation); | 102 WTF_MAKE_NONCOPYABLE(ScheduledNavigation); |
| 104 public: | 103 public: |
| 105 ScheduledNavigation(double delay, Document* originDocument, bool replacesCur
rentItem, bool isLocationChange) | 104 ScheduledNavigation(double delay, Document* originDocument, bool replacesCur
rentItem, bool isLocationChange) |
| 106 : m_delay(delay) | 105 : m_delay(delay) |
| 107 , m_originDocument(originDocument) | 106 , m_originDocument(originDocument) |
| 108 , m_replacesCurrentItem(replacesCurrentItem) | 107 , m_replacesCurrentItem(replacesCurrentItem) |
| 109 , m_isLocationChange(isLocationChange) | 108 , m_isLocationChange(isLocationChange) |
| 110 , m_wasUserGesture(UserGestureIndicator::processingUserGesture()) | 109 , m_wasUserGesture(UserGestureIndicator::processingUserGesture()) |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 } | 319 } |
| 321 | 320 |
| 322 bool NavigationScheduler::isNavigationScheduledWithin(double interval) const | 321 bool NavigationScheduler::isNavigationScheduledWithin(double interval) const |
| 323 { | 322 { |
| 324 return m_redirect && m_redirect->delay() <= interval; | 323 return m_redirect && m_redirect->delay() <= interval; |
| 325 } | 324 } |
| 326 | 325 |
| 327 // TODO(dcheng): There are really two different load blocking concepts at work | 326 // TODO(dcheng): There are really two different load blocking concepts at work |
| 328 // here and they have been incorrectly tangled together. | 327 // here and they have been incorrectly tangled together. |
| 329 // | 328 // |
| 330 // 1. NavigationDisablerForBeforeUnload is for blocking navigation scheduling | 329 // 1. NavigationDisablerForUnload is for blocking navigation scheduling during |
| 331 // during a beforeunload event. Scheduled navigations during beforeunload | 330 // a beforeunload or unload events. Scheduled navigations during |
| 332 // would make it possible to get trapped in an endless loop of beforeunload | 331 // beforeunload would make it possible to get trapped in an endless loop of |
| 333 // dialogs. | 332 // beforeunload dialogs. Scheduled navigations during the unload handler |
| 333 // makes is possible to cancel a navigation that was initiated right before |
| 334 // it commits. |
| 334 // | 335 // |
| 335 // Checking Frame::isNavigationAllowed() doesn't make sense in this context: | 336 // Checking Frame::isNavigationAllowed() doesn't make sense in this context: |
| 336 // NavigationScheduler is always cleared when a new load commits, so it's | 337 // NavigationScheduler is always cleared when a new load commits, so it's |
| 337 // impossible for a scheduled navigation to clobber a navigation that just | 338 // impossible for a scheduled navigation to clobber a navigation that just |
| 338 // committed. | 339 // committed. |
| 339 // | 340 // |
| 340 // 2. FrameNavigationDisabler / LocalFrame::isNavigationAllowed() are intended | 341 // 2. FrameNavigationDisabler / LocalFrame::isNavigationAllowed() are intended |
| 341 // to prevent Documents from being reattached during destruction, since it | 342 // to prevent Documents from being reattached during destruction, since it |
| 342 // can cause bugs with security origin confusion. This is primarily intended | 343 // can cause bugs with security origin confusion. This is primarily intended |
| 343 // to block /synchronous/ navigations during things lke Document::detachLayou
tTree(). | 344 // to block /synchronous/ navigations during things lke Document::detachLayou
tTree(). |
| 344 inline bool NavigationScheduler::shouldScheduleReload() const | 345 inline bool NavigationScheduler::shouldScheduleReload() const |
| 345 { | 346 { |
| 346 return m_frame->page() && m_frame->isNavigationAllowed() && NavigationDisabl
erForBeforeUnload::isNavigationAllowed(); | 347 return m_frame->page() && m_frame->isNavigationAllowed() && NavigationDisabl
erForUnload::isNavigationAllowed(); |
| 347 } | 348 } |
| 348 | 349 |
| 349 inline bool NavigationScheduler::shouldScheduleNavigation(const String& url) con
st | 350 inline bool NavigationScheduler::shouldScheduleNavigation(const String& url) con
st |
| 350 { | 351 { |
| 351 return m_frame->page() && m_frame->isNavigationAllowed() && (protocolIsJavaS
cript(url) || NavigationDisablerForBeforeUnload::isNavigationAllowed()); | 352 return m_frame->page() && m_frame->isNavigationAllowed() && (protocolIsJavaS
cript(url) || NavigationDisablerForUnload::isNavigationAllowed()); |
| 352 } | 353 } |
| 353 | 354 |
| 354 void NavigationScheduler::scheduleRedirect(double delay, const String& url) | 355 void NavigationScheduler::scheduleRedirect(double delay, const String& url) |
| 355 { | 356 { |
| 356 if (!shouldScheduleNavigation(url)) | 357 if (!shouldScheduleNavigation(url)) |
| 357 return; | 358 return; |
| 358 if (delay < 0 || delay > INT_MAX / 1000) | 359 if (delay < 0 || delay > INT_MAX / 1000) |
| 359 return; | 360 return; |
| 360 if (url.isEmpty()) | 361 if (url.isEmpty()) |
| 361 return; | 362 return; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 386 | 387 |
| 387 replacesCurrentItem = replacesCurrentItem || mustReplaceCurrentItem(m_frame)
; | 388 replacesCurrentItem = replacesCurrentItem || mustReplaceCurrentItem(m_frame)
; |
| 388 | 389 |
| 389 // If the URL we're going to navigate to is the same as the current one, exc
ept for the | 390 // If the URL we're going to navigate to is the same as the current one, exc
ept for the |
| 390 // fragment part, we don't need to schedule the location change. We'll skip
this | 391 // fragment part, we don't need to schedule the location change. We'll skip
this |
| 391 // optimization for cross-origin navigations to minimize the navigator's abi
lity to | 392 // optimization for cross-origin navigations to minimize the navigator's abi
lity to |
| 392 // execute timing attacks. | 393 // execute timing attacks. |
| 393 if (originDocument->getSecurityOrigin()->canAccess(m_frame->document()->getS
ecurityOrigin())) { | 394 if (originDocument->getSecurityOrigin()->canAccess(m_frame->document()->getS
ecurityOrigin())) { |
| 394 KURL parsedURL(ParsedURLString, url); | 395 KURL parsedURL(ParsedURLString, url); |
| 395 if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier
(m_frame->document()->url(), parsedURL)) { | 396 if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier
(m_frame->document()->url(), parsedURL)) { |
| 396 if (NavigationCounterForUnload::inUnloadHandler()) | |
| 397 Deprecation::countDeprecation(m_frame, UseCounter::UnloadHandler
_Navigation); | |
| 398 | 397 |
| 399 FrameLoadRequest request(originDocument, m_frame->document()->comple
teURL(url), "_self"); | 398 FrameLoadRequest request(originDocument, m_frame->document()->comple
teURL(url), "_self"); |
| 400 request.setReplacesCurrentItem(replacesCurrentItem); | 399 request.setReplacesCurrentItem(replacesCurrentItem); |
| 401 if (replacesCurrentItem) | 400 if (replacesCurrentItem) |
| 402 request.setClientRedirect(ClientRedirectPolicy::ClientRedirect); | 401 request.setClientRedirect(ClientRedirectPolicy::ClientRedirect); |
| 403 m_frame->loader().load(request); | 402 m_frame->loader().load(request); |
| 404 return; | 403 return; |
| 405 } | 404 } |
| 406 } | 405 } |
| 407 | 406 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 m_redirect.clear(); | 493 m_redirect.clear(); |
| 495 } | 494 } |
| 496 | 495 |
| 497 DEFINE_TRACE(NavigationScheduler) | 496 DEFINE_TRACE(NavigationScheduler) |
| 498 { | 497 { |
| 499 visitor->trace(m_frame); | 498 visitor->trace(m_frame); |
| 500 visitor->trace(m_redirect); | 499 visitor->trace(m_redirect); |
| 501 } | 500 } |
| 502 | 501 |
| 503 } // namespace blink | 502 } // namespace blink |
| OLD | NEW |