OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009 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 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * | 9 * |
10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 void HistoryController::updateForBackForwardNavigation() | 241 void HistoryController::updateForBackForwardNavigation() |
242 { | 242 { |
243 #if !LOG_DISABLED | 243 #if !LOG_DISABLED |
244 if (m_frame->loader()->documentLoader()) | 244 if (m_frame->loader()->documentLoader()) |
245 LOG(History, "WebCoreHistory: Updating History for back/forward navigati
on in frame %s", m_frame->loader()->documentLoader()->title().utf8().data()); | 245 LOG(History, "WebCoreHistory: Updating History for back/forward navigati
on in frame %s", m_frame->loader()->documentLoader()->title().utf8().data()); |
246 #endif | 246 #endif |
247 | 247 |
248 // Must grab the current scroll position before disturbing it | 248 // Must grab the current scroll position before disturbing it |
249 if (!m_frameLoadComplete) | 249 if (!m_frameLoadComplete) |
250 saveScrollPositionAndViewStateToItem(m_previousItem.get()); | 250 saveScrollPositionAndViewStateToItem(m_previousItem.get()); |
251 | |
252 // When traversing history, we may end up redirecting to a different URL | |
253 // this time (e.g., due to cookies). See http://webkit.org/b/49654. | |
254 updateCurrentItem(); | |
255 } | 251 } |
256 | 252 |
257 void HistoryController::updateForReload() | 253 void HistoryController::updateForReload() |
258 { | 254 { |
259 #if !LOG_DISABLED | 255 #if !LOG_DISABLED |
260 if (m_frame->loader()->documentLoader()) | 256 if (m_frame->loader()->documentLoader()) |
261 LOG(History, "WebCoreHistory: Updating History for reload in frame %s",
m_frame->loader()->documentLoader()->title().utf8().data()); | 257 LOG(History, "WebCoreHistory: Updating History for reload in frame %s",
m_frame->loader()->documentLoader()->title().utf8().data()); |
262 #endif | 258 #endif |
263 | 259 |
264 if (m_currentItem) { | 260 if (m_currentItem) { |
265 pageCache()->remove(m_currentItem.get()); | 261 pageCache()->remove(m_currentItem.get()); |
266 | 262 |
267 if (m_frame->loader()->loadType() == FrameLoadTypeReload || m_frame->loa
der()->loadType() == FrameLoadTypeReloadFromOrigin) | 263 if (m_frame->loader()->loadType() == FrameLoadTypeReload || m_frame->loa
der()->loadType() == FrameLoadTypeReloadFromOrigin) |
268 saveScrollPositionAndViewStateToItem(m_currentItem.get()); | 264 saveScrollPositionAndViewStateToItem(m_currentItem.get()); |
| 265 |
| 266 // Sometimes loading a page again leads to a different result because of
cookies. Bugzilla 4072 |
| 267 if (m_frame->loader()->documentLoader()->unreachableURL().isEmpty()) |
| 268 m_currentItem->setURL(m_frame->loader()->documentLoader()->requestUR
L()); |
269 } | 269 } |
270 | |
271 // When reloading the page, we may end up redirecting to a different URL | |
272 // this time (e.g., due to cookies). See http://webkit.org/b/4072. | |
273 updateCurrentItem(); | |
274 } | 270 } |
275 | 271 |
276 // There are 3 things you might think of as "history", all of which are handled
by these functions. | 272 // There are 3 things you might think of as "history", all of which are handled
by these functions. |
277 // | 273 // |
278 // 1) Back/forward: The m_currentItem is part of this mechanism. | 274 // 1) Back/forward: The m_currentItem is part of this mechanism. |
279 // 2) Global history: Handled by the client. | 275 // 2) Global history: Handled by the client. |
280 // 3) Visited links: Handled by the PageGroup. | 276 // 3) Visited links: Handled by the PageGroup. |
281 | 277 |
282 void HistoryController::updateForStandardLoad(HistoryUpdateType updateType) | 278 void HistoryController::updateForStandardLoad(HistoryUpdateType updateType) |
283 { | 279 { |
(...skipping 11 matching lines...) Expand all Loading... |
295 updateBackForwardListClippedAtTarget(true); | 291 updateBackForwardListClippedAtTarget(true); |
296 if (!needPrivacy) { | 292 if (!needPrivacy) { |
297 frameLoader->client()->updateGlobalHistory(); | 293 frameLoader->client()->updateGlobalHistory(); |
298 frameLoader->documentLoader()->setDidCreateGlobalHistoryEntry(tr
ue); | 294 frameLoader->documentLoader()->setDidCreateGlobalHistoryEntry(tr
ue); |
299 if (frameLoader->documentLoader()->unreachableURL().isEmpty()) | 295 if (frameLoader->documentLoader()->unreachableURL().isEmpty()) |
300 frameLoader->client()->updateGlobalHistoryRedirectLinks(); | 296 frameLoader->client()->updateGlobalHistoryRedirectLinks(); |
301 } | 297 } |
302 if (Page* page = m_frame->page()) | 298 if (Page* page = m_frame->page()) |
303 page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForward()
->currentItem()); | 299 page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForward()
->currentItem()); |
304 } | 300 } |
305 } else { | 301 } else if (frameLoader->documentLoader()->unreachableURL().isEmpty() && m_cu
rrentItem) { |
306 // The client redirect replaces the current history item. | 302 m_currentItem->setURL(frameLoader->documentLoader()->url()); |
307 updateCurrentItem(); | 303 m_currentItem->setFormInfoFromRequest(frameLoader->documentLoader()->req
uest()); |
308 } | 304 } |
309 | 305 |
310 if (!historyURL.isEmpty() && !needPrivacy) { | 306 if (!historyURL.isEmpty() && !needPrivacy) { |
311 if (Page* page = m_frame->page()) | 307 if (Page* page = m_frame->page()) |
312 addVisitedLink(page, historyURL); | 308 addVisitedLink(page, historyURL); |
313 | 309 |
314 if (!frameLoader->documentLoader()->didCreateGlobalHistoryEntry() && fra
meLoader->documentLoader()->unreachableURL().isEmpty() && !frameLoader->url().is
Empty()) | 310 if (!frameLoader->documentLoader()->didCreateGlobalHistoryEntry() && fra
meLoader->documentLoader()->unreachableURL().isEmpty() && !frameLoader->url().is
Empty()) |
315 frameLoader->client()->updateGlobalHistoryRedirectLinks(); | 311 frameLoader->client()->updateGlobalHistoryRedirectLinks(); |
316 } | 312 } |
317 } | 313 } |
(...skipping 16 matching lines...) Expand all Loading... |
334 if (!needPrivacy) { | 330 if (!needPrivacy) { |
335 m_frame->loader()->client()->updateGlobalHistory(); | 331 m_frame->loader()->client()->updateGlobalHistory(); |
336 m_frame->loader()->documentLoader()->setDidCreateGlobalHisto
ryEntry(true); | 332 m_frame->loader()->documentLoader()->setDidCreateGlobalHisto
ryEntry(true); |
337 if (m_frame->loader()->documentLoader()->unreachableURL().is
Empty()) | 333 if (m_frame->loader()->documentLoader()->unreachableURL().is
Empty()) |
338 m_frame->loader()->client()->updateGlobalHistoryRedirect
Links(); | 334 m_frame->loader()->client()->updateGlobalHistoryRedirect
Links(); |
339 } | 335 } |
340 if (Page* page = m_frame->page()) | 336 if (Page* page = m_frame->page()) |
341 page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForwa
rd()->currentItem()); | 337 page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForwa
rd()->currentItem()); |
342 } | 338 } |
343 } | 339 } |
344 // The client redirect replaces the current history item. | 340 if (m_currentItem) { |
345 updateCurrentItem(); | 341 m_currentItem->setURL(m_frame->loader()->documentLoader()->url()); |
| 342 m_currentItem->setFormInfoFromRequest(m_frame->loader()->documentLoa
der()->request()); |
| 343 } |
346 } else { | 344 } else { |
347 Frame* parentFrame = m_frame->tree()->parent(); | 345 Frame* parentFrame = m_frame->tree()->parent(); |
348 if (parentFrame && parentFrame->loader()->history()->m_currentItem) | 346 if (parentFrame && parentFrame->loader()->history()->m_currentItem) |
349 parentFrame->loader()->history()->m_currentItem->setChildItem(create
Item()); | 347 parentFrame->loader()->history()->m_currentItem->setChildItem(create
Item(true)); |
350 } | 348 } |
351 | 349 |
352 if (!historyURL.isEmpty() && !needPrivacy) { | 350 if (!historyURL.isEmpty() && !needPrivacy) { |
353 if (Page* page = m_frame->page()) | 351 if (Page* page = m_frame->page()) |
354 addVisitedLink(page, historyURL); | 352 addVisitedLink(page, historyURL); |
355 | 353 |
356 if (!m_frame->loader()->documentLoader()->didCreateGlobalHistoryEntry()
&& m_frame->loader()->documentLoader()->unreachableURL().isEmpty() && !m_frame->
loader()->url().isEmpty()) | 354 if (!m_frame->loader()->documentLoader()->didCreateGlobalHistoryEntry()
&& m_frame->loader()->documentLoader()->unreachableURL().isEmpty() && !m_frame->
loader()->url().isEmpty()) |
357 m_frame->loader()->client()->updateGlobalHistoryRedirectLinks(); | 355 m_frame->loader()->client()->updateGlobalHistoryRedirectLinks(); |
358 } | 356 } |
359 } | 357 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 // and that was the about:blank Document created when the browsing context | 446 // and that was the about:blank Document created when the browsing context |
449 // was created, then the navigation must be done with replacement enabled.
" | 447 // was created, then the navigation must be done with replacement enabled.
" |
450 return m_currentItem && !m_previousItem && equalIgnoringCase(m_currentItem->
urlString(), blankURL()); | 448 return m_currentItem && !m_previousItem && equalIgnoringCase(m_currentItem->
urlString(), blankURL()); |
451 } | 449 } |
452 | 450 |
453 void HistoryController::setProvisionalItem(HistoryItem* item) | 451 void HistoryController::setProvisionalItem(HistoryItem* item) |
454 { | 452 { |
455 m_provisionalItem = item; | 453 m_provisionalItem = item; |
456 } | 454 } |
457 | 455 |
458 void HistoryController::initializeItem(HistoryItem* item) | 456 PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal) |
459 { | 457 { |
460 DocumentLoader* documentLoader = m_frame->loader()->documentLoader(); | 458 DocumentLoader* documentLoader = m_frame->loader()->documentLoader(); |
461 ASSERT(documentLoader); | 459 |
462 | 460 KURL unreachableURL = documentLoader ? documentLoader->unreachableURL() : KU
RL(); |
463 KURL unreachableURL = documentLoader->unreachableURL(); | 461 |
464 | |
465 KURL url; | 462 KURL url; |
466 KURL originalURL; | 463 KURL originalURL; |
467 | 464 |
468 if (!unreachableURL.isEmpty()) { | 465 if (!unreachableURL.isEmpty()) { |
469 url = unreachableURL; | 466 url = unreachableURL; |
470 originalURL = unreachableURL; | 467 originalURL = unreachableURL; |
471 } else { | 468 } else { |
472 url = documentLoader->url(); | 469 originalURL = documentLoader ? documentLoader->originalURL() : KURL(); |
473 originalURL = documentLoader->originalURL(); | 470 if (useOriginal) |
| 471 url = originalURL; |
| 472 else if (documentLoader) |
| 473 url = documentLoader->requestURL(); |
474 } | 474 } |
475 | 475 |
| 476 LOG(History, "WebCoreHistory: Creating item for %s", url.string().ascii().da
ta()); |
| 477 |
476 // Frames that have never successfully loaded any content | 478 // Frames that have never successfully loaded any content |
477 // may have no URL at all. Currently our history code can't | 479 // may have no URL at all. Currently our history code can't |
478 // deal with such things, so we nip that in the bud here. | 480 // deal with such things, so we nip that in the bud here. |
479 // Later we may want to learn to live with nil for URL. | 481 // Later we may want to learn to live with nil for URL. |
480 // See bug 3368236 and related bugs for more information. | 482 // See bug 3368236 and related bugs for more information. |
481 if (url.isEmpty()) | 483 if (url.isEmpty()) |
482 url = blankURL(); | 484 url = blankURL(); |
483 if (originalURL.isEmpty()) | 485 if (originalURL.isEmpty()) |
484 originalURL = blankURL(); | 486 originalURL = blankURL(); |
485 | 487 |
486 Frame* parentFrame = m_frame->tree()->parent(); | 488 Frame* parentFrame = m_frame->tree()->parent(); |
487 String parent = parentFrame ? parentFrame->tree()->uniqueName() : ""; | 489 String parent = parentFrame ? parentFrame->tree()->uniqueName() : ""; |
488 String title = documentLoader->title(); | 490 String title = documentLoader ? documentLoader->title() : ""; |
489 | 491 |
490 item->setURL(url); | 492 RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->uniqueN
ame(), parent, title); |
491 item->setTarget(m_frame->tree()->uniqueName()); | |
492 item->setParent(parent); | |
493 item->setTitle(title); | |
494 item->setOriginalURLString(originalURL.string()); | 493 item->setOriginalURLString(originalURL.string()); |
495 | 494 |
496 if (!unreachableURL.isEmpty() || documentLoader->response().httpStatusCode()
>= 400) | 495 if (!unreachableURL.isEmpty() || !documentLoader || documentLoader->response
().httpStatusCode() >= 400) |
497 item->setLastVisitWasFailure(true); | 496 item->setLastVisitWasFailure(true); |
498 | 497 |
499 // Save form state if this is a POST | 498 // Save form state if this is a POST |
500 item->setFormInfoFromRequest(documentLoader->request()); | 499 if (documentLoader) { |
501 } | 500 if (useOriginal) |
502 | 501 item->setFormInfoFromRequest(documentLoader->originalRequest()); |
503 PassRefPtr<HistoryItem> HistoryController::createItem() | 502 else |
504 { | 503 item->setFormInfoFromRequest(documentLoader->request()); |
505 RefPtr<HistoryItem> item = HistoryItem::create(); | 504 } |
506 initializeItem(item.get()); | |
507 | 505 |
508 // Set the item for which we will save document state | 506 // Set the item for which we will save document state |
509 m_frameLoadComplete = false; | 507 m_frameLoadComplete = false; |
510 m_previousItem = m_currentItem; | 508 m_previousItem = m_currentItem; |
511 m_currentItem = item; | 509 m_currentItem = item; |
512 | 510 |
513 return item.release(); | 511 return item.release(); |
514 } | 512 } |
515 | 513 |
516 PassRefPtr<HistoryItem> HistoryController::createItemTree(Frame* targetFrame, bo
ol clipAtTarget) | 514 PassRefPtr<HistoryItem> HistoryController::createItemTree(Frame* targetFrame, bo
ol clipAtTarget) |
517 { | 515 { |
518 RefPtr<HistoryItem> bfItem = createItem(); | 516 RefPtr<HistoryItem> bfItem = createItem(m_frame->tree()->parent() ? true : f
alse); |
519 if (!m_frameLoadComplete) | 517 if (!m_frameLoadComplete) |
520 saveScrollPositionAndViewStateToItem(m_previousItem.get()); | 518 saveScrollPositionAndViewStateToItem(m_previousItem.get()); |
521 | 519 |
522 if (!clipAtTarget || m_frame != targetFrame) { | 520 if (!clipAtTarget || m_frame != targetFrame) { |
523 // save frame state for items that aren't loading (khtml doesn't save th
ose) | 521 // save frame state for items that aren't loading (khtml doesn't save th
ose) |
524 saveDocumentState(); | 522 saveDocumentState(); |
525 | 523 |
526 // clipAtTarget is false for navigations within the same document, so | 524 // clipAtTarget is false for navigations within the same document, so |
527 // we should copy the documentSequenceNumber over to the newly create | 525 // we should copy the documentSequenceNumber over to the newly create |
528 // item. Non-target items are just clones, and they should therefore | 526 // item. Non-target items are just clones, and they should therefore |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 ASSERT(mainFrame); | 640 ASSERT(mainFrame); |
643 FrameLoader* frameLoader = mainFrame->loader(); | 641 FrameLoader* frameLoader = mainFrame->loader(); |
644 | 642 |
645 frameLoader->checkDidPerformFirstNavigation(); | 643 frameLoader->checkDidPerformFirstNavigation(); |
646 | 644 |
647 RefPtr<HistoryItem> topItem = frameLoader->history()->createItemTree(m_frame
, doClip); | 645 RefPtr<HistoryItem> topItem = frameLoader->history()->createItemTree(m_frame
, doClip); |
648 LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame
%s", topItem.get(), m_frame->loader()->documentLoader()->url().string().ascii().
data()); | 646 LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame
%s", topItem.get(), m_frame->loader()->documentLoader()->url().string().ascii().
data()); |
649 page->backForward()->addItem(topItem.release()); | 647 page->backForward()->addItem(topItem.release()); |
650 } | 648 } |
651 | 649 |
652 void HistoryController::updateCurrentItem() | |
653 { | |
654 if (!m_currentItem) | |
655 return; | |
656 | |
657 DocumentLoader* documentLoader = m_frame->loader()->documentLoader(); | |
658 | |
659 if (!documentLoader->unreachableURL().isEmpty()) | |
660 return; | |
661 | |
662 if (m_currentItem->url() != documentLoader->url()) { | |
663 // We ended up on a completely different URL this time, so the HistoryIt
em | |
664 // needs to be re-initialized. Preserve the isTargetItem flag as it is
a | |
665 // property of how this HistoryItem was originally created and is not | |
666 // dependent on the document. | |
667 bool isTargetItem = m_currentItem->isTargetItem(); | |
668 m_currentItem->reset(); | |
669 initializeItem(m_currentItem.get()); | |
670 m_currentItem->setIsTargetItem(isTargetItem); | |
671 } else { | |
672 // Even if the final URL didn't change, the form data may have changed. | |
673 m_currentItem->setFormInfoFromRequest(documentLoader->request()); | |
674 } | |
675 } | |
676 | |
677 void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject,
const String& title, const String& urlString) | 650 void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject,
const String& title, const String& urlString) |
678 { | 651 { |
679 if (!m_currentItem) | 652 if (!m_currentItem) |
680 return; | 653 return; |
681 | 654 |
682 Page* page = m_frame->page(); | 655 Page* page = m_frame->page(); |
683 ASSERT(page); | 656 ASSERT(page); |
684 | 657 |
685 // Get a HistoryItem tree for the current frame tree. | 658 // Get a HistoryItem tree for the current frame tree. |
686 RefPtr<HistoryItem> topItem = page->mainFrame()->loader()->history()->create
ItemTree(m_frame, false); | 659 RefPtr<HistoryItem> topItem = page->mainFrame()->loader()->history()->create
ItemTree(m_frame, false); |
(...skipping 12 matching lines...) Expand all Loading... |
699 if (!m_currentItem) | 672 if (!m_currentItem) |
700 return; | 673 return; |
701 | 674 |
702 if (!urlString.isEmpty()) | 675 if (!urlString.isEmpty()) |
703 m_currentItem->setURLString(urlString); | 676 m_currentItem->setURLString(urlString); |
704 m_currentItem->setTitle(title); | 677 m_currentItem->setTitle(title); |
705 m_currentItem->setStateObject(stateObject); | 678 m_currentItem->setStateObject(stateObject); |
706 } | 679 } |
707 | 680 |
708 } // namespace WebCore | 681 } // namespace WebCore |
OLD | NEW |