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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 , m_haveToldClient(false) | 106 , m_haveToldClient(false) |
107 { | 107 { |
108 } | 108 } |
109 | 109 |
110 virtual void fire(Frame* frame) | 110 virtual void fire(Frame* frame) |
111 { | 111 { |
112 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); | 112 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); |
113 FrameLoadRequest request(m_securityOrigin.get(), ResourceRequest(KURL(Pa
rsedURLString, m_url), m_referrer), "_self"); | 113 FrameLoadRequest request(m_securityOrigin.get(), ResourceRequest(KURL(Pa
rsedURLString, m_url), m_referrer), "_self"); |
114 request.setLockBackForwardList(lockBackForwardList()); | 114 request.setLockBackForwardList(lockBackForwardList()); |
115 request.setClientRedirect(true); | 115 request.setClientRedirect(true); |
116 frame->loader()->load(request); | 116 frame->loader().load(request); |
117 } | 117 } |
118 | 118 |
119 virtual void didStartTimer(Frame* frame, Timer<NavigationScheduler>* timer) | 119 virtual void didStartTimer(Frame* frame, Timer<NavigationScheduler>* timer) |
120 { | 120 { |
121 if (m_haveToldClient) | 121 if (m_haveToldClient) |
122 return; | 122 return; |
123 m_haveToldClient = true; | 123 m_haveToldClient = true; |
124 | 124 |
125 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); | 125 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); |
126 if (frame->loader()->history()->currentItemShouldBeReplaced()) | 126 if (frame->loader().history()->currentItemShouldBeReplaced()) |
127 setLockBackForwardList(true); | 127 setLockBackForwardList(true); |
128 } | 128 } |
129 | 129 |
130 SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); } | 130 SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); } |
131 String url() const { return m_url; } | 131 String url() const { return m_url; } |
132 String referrer() const { return m_referrer; } | 132 String referrer() const { return m_referrer; } |
133 | 133 |
134 private: | 134 private: |
135 RefPtr<SecurityOrigin> m_securityOrigin; | 135 RefPtr<SecurityOrigin> m_securityOrigin; |
136 String m_url; | 136 String m_url; |
137 String m_referrer; | 137 String m_referrer; |
138 bool m_haveToldClient; | 138 bool m_haveToldClient; |
139 }; | 139 }; |
140 | 140 |
141 class ScheduledRedirect : public ScheduledURLNavigation { | 141 class ScheduledRedirect : public ScheduledURLNavigation { |
142 public: | 142 public: |
143 ScheduledRedirect(double delay, SecurityOrigin* securityOrigin, const String
& url, bool lockBackForwardList) | 143 ScheduledRedirect(double delay, SecurityOrigin* securityOrigin, const String
& url, bool lockBackForwardList) |
144 : ScheduledURLNavigation(delay, securityOrigin, url, String(), lockBackF
orwardList, false) | 144 : ScheduledURLNavigation(delay, securityOrigin, url, String(), lockBackF
orwardList, false) |
145 { | 145 { |
146 clearUserGesture(); | 146 clearUserGesture(); |
147 } | 147 } |
148 | 148 |
149 virtual bool shouldStartTimer(Frame* frame) { return frame->loader()->allAnc
estorsAreComplete(); } | 149 virtual bool shouldStartTimer(Frame* frame) { return frame->loader().allAnce
storsAreComplete(); } |
150 | 150 |
151 virtual void fire(Frame* frame) | 151 virtual void fire(Frame* frame) |
152 { | 152 { |
153 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); | 153 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); |
154 FrameLoadRequest request(securityOrigin(), ResourceRequest(KURL(ParsedUR
LString, url()), referrer()), "_self"); | 154 FrameLoadRequest request(securityOrigin(), ResourceRequest(KURL(ParsedUR
LString, url()), referrer()), "_self"); |
155 request.setLockBackForwardList(lockBackForwardList()); | 155 request.setLockBackForwardList(lockBackForwardList()); |
156 if (equalIgnoringFragmentIdentifier(frame->document()->url(), request.re
sourceRequest().url())) | 156 if (equalIgnoringFragmentIdentifier(frame->document()->url(), request.re
sourceRequest().url())) |
157 request.resourceRequest().setCachePolicy(ReloadIgnoringCacheData); | 157 request.resourceRequest().setCachePolicy(ReloadIgnoringCacheData); |
158 request.setClientRedirect(true); | 158 request.setClientRedirect(true); |
159 frame->loader()->load(request); | 159 frame->loader().load(request); |
160 } | 160 } |
161 }; | 161 }; |
162 | 162 |
163 class ScheduledLocationChange : public ScheduledURLNavigation { | 163 class ScheduledLocationChange : public ScheduledURLNavigation { |
164 public: | 164 public: |
165 ScheduledLocationChange(SecurityOrigin* securityOrigin, const String& url, c
onst String& referrer, bool lockBackForwardList) | 165 ScheduledLocationChange(SecurityOrigin* securityOrigin, const String& url, c
onst String& referrer, bool lockBackForwardList) |
166 : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, lockBackFor
wardList, true) { } | 166 : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, lockBackFor
wardList, true) { } |
167 }; | 167 }; |
168 | 168 |
169 class ScheduledRefresh : public ScheduledURLNavigation { | 169 class ScheduledRefresh : public ScheduledURLNavigation { |
170 public: | 170 public: |
171 ScheduledRefresh(SecurityOrigin* securityOrigin, const String& url, const St
ring& referrer) | 171 ScheduledRefresh(SecurityOrigin* securityOrigin, const String& url, const St
ring& referrer) |
172 : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, true, true) | 172 : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, true, true) |
173 { | 173 { |
174 } | 174 } |
175 | 175 |
176 virtual void fire(Frame* frame) | 176 virtual void fire(Frame* frame) |
177 { | 177 { |
178 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); | 178 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); |
179 FrameLoadRequest request(securityOrigin(), ResourceRequest(KURL(ParsedUR
LString, url()), referrer(), ReloadIgnoringCacheData), "_self"); | 179 FrameLoadRequest request(securityOrigin(), ResourceRequest(KURL(ParsedUR
LString, url()), referrer(), ReloadIgnoringCacheData), "_self"); |
180 request.setLockBackForwardList(lockBackForwardList()); | 180 request.setLockBackForwardList(lockBackForwardList()); |
181 request.setClientRedirect(true); | 181 request.setClientRedirect(true); |
182 frame->loader()->load(request); | 182 frame->loader().load(request); |
183 } | 183 } |
184 }; | 184 }; |
185 | 185 |
186 class ScheduledHistoryNavigation : public ScheduledNavigation { | 186 class ScheduledHistoryNavigation : public ScheduledNavigation { |
187 public: | 187 public: |
188 explicit ScheduledHistoryNavigation(int historySteps) | 188 explicit ScheduledHistoryNavigation(int historySteps) |
189 : ScheduledNavigation(0, false, true) | 189 : ScheduledNavigation(0, false, true) |
190 , m_historySteps(historySteps) | 190 , m_historySteps(historySteps) |
191 { | 191 { |
192 } | 192 } |
193 | 193 |
194 virtual void fire(Frame* frame) | 194 virtual void fire(Frame* frame) |
195 { | 195 { |
196 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); | 196 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); |
197 | 197 |
198 if (!m_historySteps) { | 198 if (!m_historySteps) { |
199 FrameLoadRequest frameRequest(frame->document()->securityOrigin(), R
esourceRequest(frame->document()->url())); | 199 FrameLoadRequest frameRequest(frame->document()->securityOrigin(), R
esourceRequest(frame->document()->url())); |
200 frameRequest.setLockBackForwardList(lockBackForwardList()); | 200 frameRequest.setLockBackForwardList(lockBackForwardList()); |
201 // Special case for go(0) from a frame -> reload only the frame | 201 // Special case for go(0) from a frame -> reload only the frame |
202 // To follow Firefox and IE's behavior, history reload can only navi
gate the self frame. | 202 // To follow Firefox and IE's behavior, history reload can only navi
gate the self frame. |
203 frame->loader()->load(frameRequest); | 203 frame->loader().load(frameRequest); |
204 return; | 204 return; |
205 } | 205 } |
206 // go(i!=0) from a frame navigates into the history of the frame only, | 206 // go(i!=0) from a frame navigates into the history of the frame only, |
207 // in both IE and NS (but not in Mozilla). We can't easily do that. | 207 // in both IE and NS (but not in Mozilla). We can't easily do that. |
208 frame->page()->mainFrame()->loader()->client()->navigateBackForward(m_hi
storySteps); | 208 frame->page()->mainFrame()->loader().client()->navigateBackForward(m_his
torySteps); |
209 } | 209 } |
210 | 210 |
211 private: | 211 private: |
212 int m_historySteps; | 212 int m_historySteps; |
213 }; | 213 }; |
214 | 214 |
215 class ScheduledFormSubmission : public ScheduledNavigation { | 215 class ScheduledFormSubmission : public ScheduledNavigation { |
216 public: | 216 public: |
217 ScheduledFormSubmission(PassRefPtr<FormSubmission> submission, bool lockBack
ForwardList) | 217 ScheduledFormSubmission(PassRefPtr<FormSubmission> submission, bool lockBack
ForwardList) |
218 : ScheduledNavigation(0, lockBackForwardList, true) | 218 : ScheduledNavigation(0, lockBackForwardList, true) |
219 , m_submission(submission) | 219 , m_submission(submission) |
220 , m_haveToldClient(false) | 220 , m_haveToldClient(false) |
221 { | 221 { |
222 ASSERT(m_submission->state()); | 222 ASSERT(m_submission->state()); |
223 } | 223 } |
224 | 224 |
225 virtual void fire(Frame* frame) | 225 virtual void fire(Frame* frame) |
226 { | 226 { |
227 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); | 227 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); |
228 FrameLoadRequest frameRequest(m_submission->state()->sourceDocument()->s
ecurityOrigin()); | 228 FrameLoadRequest frameRequest(m_submission->state()->sourceDocument()->s
ecurityOrigin()); |
229 m_submission->populateFrameLoadRequest(frameRequest); | 229 m_submission->populateFrameLoadRequest(frameRequest); |
230 frameRequest.setLockBackForwardList(lockBackForwardList()); | 230 frameRequest.setLockBackForwardList(lockBackForwardList()); |
231 frameRequest.setTriggeringEvent(m_submission->event()); | 231 frameRequest.setTriggeringEvent(m_submission->event()); |
232 frameRequest.setFormState(m_submission->state()); | 232 frameRequest.setFormState(m_submission->state()); |
233 frame->loader()->load(frameRequest); | 233 frame->loader().load(frameRequest); |
234 } | 234 } |
235 | 235 |
236 virtual void didStartTimer(Frame* frame, Timer<NavigationScheduler>* timer) | 236 virtual void didStartTimer(Frame* frame, Timer<NavigationScheduler>* timer) |
237 { | 237 { |
238 if (m_haveToldClient) | 238 if (m_haveToldClient) |
239 return; | 239 return; |
240 m_haveToldClient = true; | 240 m_haveToldClient = true; |
241 | 241 |
242 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); | 242 OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicat
or(); |
243 if (frame->loader()->history()->currentItemShouldBeReplaced()) | 243 if (frame->loader().history()->currentItemShouldBeReplaced()) |
244 setLockBackForwardList(true); | 244 setLockBackForwardList(true); |
245 } | 245 } |
246 | 246 |
247 virtual bool isForm() const { return true; } | 247 virtual bool isForm() const { return true; } |
248 FormSubmission* submission() const { return m_submission.get(); } | 248 FormSubmission* submission() const { return m_submission.get(); } |
249 | 249 |
250 private: | 250 private: |
251 RefPtr<FormSubmission> m_submission; | 251 RefPtr<FormSubmission> m_submission; |
252 bool m_haveToldClient; | 252 bool m_haveToldClient; |
253 }; | 253 }; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 bool NavigationScheduler::mustLockBackForwardList(Frame* targetFrame) | 303 bool NavigationScheduler::mustLockBackForwardList(Frame* targetFrame) |
304 { | 304 { |
305 // Non-user navigation before the page has finished firing onload should not
create a new back/forward item. | 305 // Non-user navigation before the page has finished firing onload should not
create a new back/forward item. |
306 // See https://webkit.org/b/42861 for the original motivation for this. | 306 // See https://webkit.org/b/42861 for the original motivation for this. |
307 if (!UserGestureIndicator::processingUserGesture() && !targetFrame->document
()->loadEventFinished()) | 307 if (!UserGestureIndicator::processingUserGesture() && !targetFrame->document
()->loadEventFinished()) |
308 return true; | 308 return true; |
309 | 309 |
310 // Navigation of a subframe during loading of an ancestor frame does not cre
ate a new back/forward item. | 310 // Navigation of a subframe during loading of an ancestor frame does not cre
ate a new back/forward item. |
311 // The definition of "during load" is any time before all handlers for the l
oad event have been run. | 311 // The definition of "during load" is any time before all handlers for the l
oad event have been run. |
312 // See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motiva
tion for this. | 312 // See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motiva
tion for this. |
313 return targetFrame->tree().parent() && !targetFrame->tree().parent()->loader
()->allAncestorsAreComplete(); | 313 return targetFrame->tree().parent() && !targetFrame->tree().parent()->loader
().allAncestorsAreComplete(); |
314 } | 314 } |
315 | 315 |
316 void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin,
const String& url, const String& referrer, bool lockBackForwardList) | 316 void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin,
const String& url, const String& referrer, bool lockBackForwardList) |
317 { | 317 { |
318 if (!shouldScheduleNavigation(url)) | 318 if (!shouldScheduleNavigation(url)) |
319 return; | 319 return; |
320 if (url.isEmpty()) | 320 if (url.isEmpty()) |
321 return; | 321 return; |
322 | 322 |
323 lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame
); | 323 lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame
); |
324 | 324 |
325 FrameLoader* loader = m_frame->loader(); | |
326 | |
327 // If the URL we're going to navigate to is the same as the current one, exc
ept for the | 325 // If the URL we're going to navigate to is the same as the current one, exc
ept for the |
328 // fragment part, we don't need to schedule the location change. We'll skip
this | 326 // fragment part, we don't need to schedule the location change. We'll skip
this |
329 // optimization for cross-origin navigations to minimize the navigator's abi
lity to | 327 // optimization for cross-origin navigations to minimize the navigator's abi
lity to |
330 // execute timing attacks. | 328 // execute timing attacks. |
331 if (securityOrigin->canAccess(m_frame->document()->securityOrigin())) { | 329 if (securityOrigin->canAccess(m_frame->document()->securityOrigin())) { |
332 KURL parsedURL(ParsedURLString, url); | 330 KURL parsedURL(ParsedURLString, url); |
333 if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier
(m_frame->document()->url(), parsedURL)) { | 331 if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier
(m_frame->document()->url(), parsedURL)) { |
334 FrameLoadRequest request(securityOrigin, ResourceRequest(m_frame->do
cument()->completeURL(url), referrer), "_self"); | 332 FrameLoadRequest request(securityOrigin, ResourceRequest(m_frame->do
cument()->completeURL(url), referrer), "_self"); |
335 request.setLockBackForwardList(lockBackForwardList); | 333 request.setLockBackForwardList(lockBackForwardList); |
336 request.setClientRedirect(true); | 334 request.setClientRedirect(true); |
337 loader->load(request); | 335 m_frame->loader().load(request); |
338 return; | 336 return; |
339 } | 337 } |
340 } | 338 } |
341 | 339 |
342 schedule(adoptPtr(new ScheduledLocationChange(securityOrigin, url, referrer,
lockBackForwardList))); | 340 schedule(adoptPtr(new ScheduledLocationChange(securityOrigin, url, referrer,
lockBackForwardList))); |
343 } | 341 } |
344 | 342 |
345 void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> subm
ission) | 343 void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> subm
ission) |
346 { | 344 { |
347 ASSERT(m_frame->page()); | 345 ASSERT(m_frame->page()); |
348 if (m_redirect && m_redirect->isForm()) { | 346 if (m_redirect && m_redirect->isForm()) { |
349 if (submission->target() != static_cast<ScheduledFormSubmission*>(m_redi
rect.get())->submission()->target()) { | 347 if (submission->target() != static_cast<ScheduledFormSubmission*>(m_redi
rect.get())->submission()->target()) { |
350 const String& target = submission->target().isNull() ? "" : submissi
on->target(); | 348 const String& target = submission->target().isNull() ? "" : submissi
on->target(); |
351 m_additionalFormSubmissions.add(target, adoptPtr(new ScheduledFormSu
bmission(submission, mustLockBackForwardList(m_frame)))); | 349 m_additionalFormSubmissions.add(target, adoptPtr(new ScheduledFormSu
bmission(submission, mustLockBackForwardList(m_frame)))); |
352 return; | 350 return; |
353 } | 351 } |
354 } | 352 } |
355 schedule(adoptPtr(new ScheduledFormSubmission(submission, mustLockBackForwar
dList(m_frame)))); | 353 schedule(adoptPtr(new ScheduledFormSubmission(submission, mustLockBackForwar
dList(m_frame)))); |
356 } | 354 } |
357 | 355 |
358 void NavigationScheduler::scheduleRefresh() | 356 void NavigationScheduler::scheduleRefresh() |
359 { | 357 { |
360 if (!shouldScheduleNavigation()) | 358 if (!shouldScheduleNavigation()) |
361 return; | 359 return; |
362 const KURL& url = m_frame->document()->url(); | 360 const KURL& url = m_frame->document()->url(); |
363 if (url.isEmpty()) | 361 if (url.isEmpty()) |
364 return; | 362 return; |
365 | 363 |
366 schedule(adoptPtr(new ScheduledRefresh(m_frame->document()->securityOrigin()
, url.string(), m_frame->loader()->outgoingReferrer()))); | 364 schedule(adoptPtr(new ScheduledRefresh(m_frame->document()->securityOrigin()
, url.string(), m_frame->loader().outgoingReferrer()))); |
367 } | 365 } |
368 | 366 |
369 void NavigationScheduler::scheduleHistoryNavigation(int steps) | 367 void NavigationScheduler::scheduleHistoryNavigation(int steps) |
370 { | 368 { |
371 if (!shouldScheduleNavigation()) | 369 if (!shouldScheduleNavigation()) |
372 return; | 370 return; |
373 | 371 |
374 // Invalid history navigations (such as history.forward() during a new load)
have the side effect of cancelling any scheduled | 372 // Invalid history navigations (such as history.forward() during a new load)
have the side effect of cancelling any scheduled |
375 // redirects. We also avoid the possibility of cancelling the current load b
y avoiding the scheduled redirection altogether. | 373 // redirects. We also avoid the possibility of cancelling the current load b
y avoiding the scheduled redirection altogether. |
376 BackForwardClient& backForward = m_frame->page()->backForward(); | 374 BackForwardClient& backForward = m_frame->page()->backForward(); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 void NavigationScheduler::cancel() | 432 void NavigationScheduler::cancel() |
435 { | 433 { |
436 if (m_timer.isActive()) | 434 if (m_timer.isActive()) |
437 InspectorInstrumentation::frameClearedScheduledNavigation(m_frame); | 435 InspectorInstrumentation::frameClearedScheduledNavigation(m_frame); |
438 m_timer.stop(); | 436 m_timer.stop(); |
439 m_redirect.clear(); | 437 m_redirect.clear(); |
440 m_additionalFormSubmissions.clear(); | 438 m_additionalFormSubmissions.clear(); |
441 } | 439 } |
442 | 440 |
443 } // namespace WebCore | 441 } // namespace WebCore |
OLD | NEW |