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 |