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 |