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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 // <rdar://problem/3979539> back/forward cache navigations should consult po
licy delegate | 229 // <rdar://problem/3979539> back/forward cache navigations should consult po
licy delegate |
230 Page* page = m_frame->page(); | 230 Page* page = m_frame->page(); |
231 if (!page) | 231 if (!page) |
232 return; | 232 return; |
233 if (!m_frame->loader()->client()->shouldGoToHistoryItem(targetItem)) | 233 if (!m_frame->loader()->client()->shouldGoToHistoryItem(targetItem)) |
234 return; | 234 return; |
235 | 235 |
236 // Set the BF cursor before commit, which lets the user quickly click back/f
orward again. | 236 // Set the BF cursor before commit, which lets the user quickly click back/f
orward again. |
237 // - plus, it only makes sense for the top level of the operation through th
e frametree, | 237 // - plus, it only makes sense for the top level of the operation through th
e frametree, |
238 // as opposed to happening for some/one of the page commits that might happe
n soon | 238 // as opposed to happening for some/one of the page commits that might happe
n soon |
239 HistoryItem* currentItem = page->backForward()->currentItem(); | 239 RefPtr<HistoryItem> currentItem = page->backForward()->currentItem(); |
240 page->backForward()->setCurrentItem(targetItem); | 240 page->backForward()->setCurrentItem(targetItem); |
241 Settings* settings = m_frame->settings(); | 241 Settings* settings = m_frame->settings(); |
242 page->setGlobalHistoryItem((!settings || settings->privateBrowsingEnabled())
? 0 : targetItem); | 242 page->setGlobalHistoryItem((!settings || settings->privateBrowsingEnabled())
? 0 : targetItem); |
243 | 243 |
244 // First set the provisional item of any frames that are not actually naviga
ting. | 244 // First set the provisional item of any frames that are not actually naviga
ting. |
245 // This must be done before trying to navigate the desired frame, because so
me | 245 // This must be done before trying to navigate the desired frame, because so
me |
246 // navigations can commit immediately (such as about:blank). We must be sur
e that | 246 // navigations can commit immediately (such as about:blank). We must be sur
e that |
247 // all frames have provisional items set before the commit. | 247 // all frames have provisional items set before the commit. |
248 recursiveSetProvisionalItem(targetItem, currentItem, type); | 248 recursiveSetProvisionalItem(targetItem, currentItem.get(), type); |
249 // Now that all other frames have provisional items, do the actual navigatio
n. | 249 // Now that all other frames have provisional items, do the actual navigatio
n. |
250 recursiveGoToItem(targetItem, currentItem, type); | 250 recursiveGoToItem(targetItem, currentItem.get(), type); |
251 } | 251 } |
252 | 252 |
253 void HistoryController::updateForBackForwardNavigation() | 253 void HistoryController::updateForBackForwardNavigation() |
254 { | 254 { |
255 #if !LOG_DISABLED | 255 #if !LOG_DISABLED |
256 if (m_frame->loader()->documentLoader()) | 256 if (m_frame->loader()->documentLoader()) |
257 LOG(History, "WebCoreHistory: Updating History for back/forward navigati
on in frame %s", m_frame->loader()->documentLoader()->title().utf8().data()); | 257 LOG(History, "WebCoreHistory: Updating History for back/forward navigati
on in frame %s", m_frame->loader()->documentLoader()->title().utf8().data()); |
258 #endif | 258 #endif |
259 | 259 |
260 // Must grab the current scroll position before disturbing it | 260 // Must grab the current scroll position before disturbing it |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 } | 395 } |
396 | 396 |
397 void HistoryController::updateForCommit() | 397 void HistoryController::updateForCommit() |
398 { | 398 { |
399 FrameLoader* frameLoader = m_frame->loader(); | 399 FrameLoader* frameLoader = m_frame->loader(); |
400 #if !LOG_DISABLED | 400 #if !LOG_DISABLED |
401 if (frameLoader->documentLoader()) | 401 if (frameLoader->documentLoader()) |
402 LOG(History, "WebCoreHistory: Updating History for commit in frame %s",
frameLoader->documentLoader()->title().utf8().data()); | 402 LOG(History, "WebCoreHistory: Updating History for commit in frame %s",
frameLoader->documentLoader()->title().utf8().data()); |
403 #endif | 403 #endif |
404 FrameLoadType type = frameLoader->loadType(); | 404 FrameLoadType type = frameLoader->loadType(); |
405 if (isBackForwardLoadType(type) || | 405 if (isBackForwardLoadType(type) |
406 ((type == FrameLoadTypeReload || type == FrameLoadTypeReloadFromOrigin)
&& !frameLoader->provisionalDocumentLoader()->unreachableURL().isEmpty())) { | 406 || isReplaceLoadTypeWithProvisionalItem(type) |
| 407 || ((type == FrameLoadTypeReload || type == FrameLoadTypeReloadFromOrigi
n) && !frameLoader->provisionalDocumentLoader()->unreachableURL().isEmpty())) { |
407 // Once committed, we want to use current item for saving DocState, and | 408 // Once committed, we want to use current item for saving DocState, and |
408 // the provisional item for restoring state. | 409 // the provisional item for restoring state. |
409 // Note previousItem must be set before we close the URL, which will | 410 // Note previousItem must be set before we close the URL, which will |
410 // happen when the data source is made non-provisional below | 411 // happen when the data source is made non-provisional below |
411 m_frameLoadComplete = false; | 412 m_frameLoadComplete = false; |
412 m_previousItem = m_currentItem; | 413 m_previousItem = m_currentItem; |
413 ASSERT(m_provisionalItem); | 414 ASSERT(m_provisionalItem); |
414 m_currentItem = m_provisionalItem; | 415 m_currentItem = m_provisionalItem; |
415 m_provisionalItem = 0; | 416 m_provisionalItem = 0; |
416 | 417 |
417 // Tell all other frames in the tree to commit their provisional items a
nd | 418 // Tell all other frames in the tree to commit their provisional items a
nd |
418 // restore their scroll position. We'll avoid this frame (which has alr
eady | 419 // restore their scroll position. We'll avoid this frame (which has alr
eady |
419 // committed) and its children (which will be replaced). | 420 // committed) and its children (which will be replaced). |
420 Page* page = m_frame->page(); | 421 Page* page = m_frame->page(); |
421 ASSERT(page); | 422 ASSERT(page); |
422 page->mainFrame()->loader()->history()->recursiveUpdateForCommit(); | 423 page->mainFrame()->loader()->history()->recursiveUpdateForCommit(); |
423 } | 424 } |
424 } | 425 } |
425 | 426 |
| 427 bool HistoryController::isReplaceLoadTypeWithProvisionalItem(FrameLoadType type) |
| 428 { |
| 429 // Going back to an error page in a subframe can trigger a FrameLoadTypeRepl
ace |
| 430 // while m_provisionalItem is set, so we need to commit it. |
| 431 return type == FrameLoadTypeReplace && m_provisionalItem; |
| 432 } |
| 433 |
426 void HistoryController::recursiveUpdateForCommit() | 434 void HistoryController::recursiveUpdateForCommit() |
427 { | 435 { |
428 // The frame that navigated will now have a null provisional item. | 436 // The frame that navigated will now have a null provisional item. |
429 // Ignore it and its children. | 437 // Ignore it and its children. |
430 if (!m_provisionalItem) | 438 if (!m_provisionalItem) |
431 return; | 439 return; |
432 | 440 |
433 // For each frame that already had the content the item requested (based on | 441 // For each frame that already had the content the item requested (based on |
434 // (a matching URL and frame tree snapshot), just restore the scroll positio
n. | 442 // (a matching URL and frame tree snapshot), just restore the scroll positio
n. |
435 // Save form state (works from currentItem, since m_frameLoadComplete is tru
e) | 443 // Save form state (works from currentItem, since m_frameLoadComplete is tru
e) |
(...skipping 28 matching lines...) Expand all Loading... |
464 | 472 |
465 Settings* settings = m_frame->settings(); | 473 Settings* settings = m_frame->settings(); |
466 if (!settings || settings->privateBrowsingEnabled()) | 474 if (!settings || settings->privateBrowsingEnabled()) |
467 return; | 475 return; |
468 | 476 |
469 Page* page = m_frame->page(); | 477 Page* page = m_frame->page(); |
470 if (!page) | 478 if (!page) |
471 return; | 479 return; |
472 | 480 |
473 addVisitedLink(page, m_frame->loader()->url()); | 481 addVisitedLink(page, m_frame->loader()->url()); |
| 482 page->mainFrame()->loader()->history()->recursiveUpdateForSameDocumentNaviga
tion(); |
| 483 } |
| 484 |
| 485 void HistoryController::recursiveUpdateForSameDocumentNavigation() |
| 486 { |
| 487 // The frame that navigated will now have a null provisional item. |
| 488 // Ignore it and its children. |
| 489 if (!m_provisionalItem) |
| 490 return; |
| 491 |
| 492 // Commit the provisional item. |
| 493 m_frameLoadComplete = false; |
| 494 m_previousItem = m_currentItem; |
| 495 m_currentItem = m_provisionalItem; |
| 496 m_provisionalItem = 0; |
| 497 |
| 498 // Iterate over the rest of the tree. |
| 499 for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tre
e()->nextSibling()) |
| 500 child->loader()->history()->recursiveUpdateForSameDocumentNavigation(); |
474 } | 501 } |
475 | 502 |
476 void HistoryController::updateForFrameLoadCompleted() | 503 void HistoryController::updateForFrameLoadCompleted() |
477 { | 504 { |
478 // Even if already complete, we might have set a previous item on a frame th
at | 505 // Even if already complete, we might have set a previous item on a frame th
at |
479 // didn't do any data loading on the past transaction. Make sure to track th
at | 506 // didn't do any data loading on the past transaction. Make sure to track th
at |
480 // the load is complete so that we use the current item instead. | 507 // the load is complete so that we use the current item instead. |
481 m_frameLoadComplete = true; | 508 m_frameLoadComplete = true; |
482 } | 509 } |
483 | 510 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 ASSERT(item); | 640 ASSERT(item); |
614 ASSERT(fromItem); | 641 ASSERT(fromItem); |
615 | 642 |
616 if (itemsAreClones(item, fromItem)) { | 643 if (itemsAreClones(item, fromItem)) { |
617 // Set provisional item, which will be committed in recursiveUpdateForCo
mmit. | 644 // Set provisional item, which will be committed in recursiveUpdateForCo
mmit. |
618 m_provisionalItem = item; | 645 m_provisionalItem = item; |
619 | 646 |
620 const HistoryItemVector& childItems = item->children(); | 647 const HistoryItemVector& childItems = item->children(); |
621 | 648 |
622 int size = childItems.size(); | 649 int size = childItems.size(); |
| 650 |
623 for (int i = 0; i < size; ++i) { | 651 for (int i = 0; i < size; ++i) { |
624 String childFrameName = childItems[i]->target(); | 652 String childFrameName = childItems[i]->target(); |
625 HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFram
eName); | 653 HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFram
eName); |
626 ASSERT(fromChildItem); | 654 ASSERT(fromChildItem); |
627 Frame* childFrame = m_frame->tree()->child(childFrameName); | 655 Frame* childFrame = m_frame->tree()->child(childFrameName); |
628 ASSERT(childFrame); | 656 ASSERT(childFrame); |
629 childFrame->loader()->history()->recursiveSetProvisionalItem(childIt
ems[i].get(), fromChildItem, type); | 657 childFrame->loader()->history()->recursiveSetProvisionalItem(childIt
ems[i].get(), fromChildItem, type); |
630 } | 658 } |
631 } | 659 } |
632 } | 660 } |
(...skipping 18 matching lines...) Expand all Loading... |
651 ASSERT(childFrame); | 679 ASSERT(childFrame); |
652 childFrame->loader()->history()->recursiveGoToItem(childItems[i].get
(), fromChildItem, type); | 680 childFrame->loader()->history()->recursiveGoToItem(childItems[i].get
(), fromChildItem, type); |
653 } | 681 } |
654 } else { | 682 } else { |
655 m_frame->loader()->loadItem(item, type); | 683 m_frame->loader()->loadItem(item, type); |
656 } | 684 } |
657 } | 685 } |
658 | 686 |
659 bool HistoryController::itemsAreClones(HistoryItem* item1, HistoryItem* item2) c
onst | 687 bool HistoryController::itemsAreClones(HistoryItem* item1, HistoryItem* item2) c
onst |
660 { | 688 { |
661 // It appears that one of the items can be null in release builds, leading | |
662 // to the crashes seen in http://webkit.org/b/52819. For now, try to | |
663 // narrow it down with a more specific crash. | |
664 if (!item1) | |
665 CRASH(); | |
666 if (!item2) | |
667 CRASH(); | |
668 | |
669 // If the item we're going to is a clone of the item we're at, then we do | 689 // If the item we're going to is a clone of the item we're at, then we do |
670 // not need to load it again. The current frame tree and the frame tree | 690 // not need to load it again. The current frame tree and the frame tree |
671 // snapshot in the item have to match. | 691 // snapshot in the item have to match. |
672 // Note: Some clients treat a navigation to the current history item as | 692 // Note: Some clients treat a navigation to the current history item as |
673 // a reload. Thus, if item1 and item2 are the same, we need to create a | 693 // a reload. Thus, if item1 and item2 are the same, we need to create a |
674 // new document and should not consider them clones. | 694 // new document and should not consider them clones. |
675 // (See http://webkit.org/b/35532 for details.) | 695 // (See http://webkit.org/b/35532 for details.) |
676 return item1 != item2 | 696 return item1 != item2 |
677 && item1->itemSequenceNumber() == item2->itemSequenceNumber() | 697 && item1->itemSequenceNumber() == item2->itemSequenceNumber() |
678 && currentFramesMatchItem(item1) | 698 && currentFramesMatchItem(item1) |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 if (!m_currentItem) | 793 if (!m_currentItem) |
774 return; | 794 return; |
775 | 795 |
776 if (!urlString.isEmpty()) | 796 if (!urlString.isEmpty()) |
777 m_currentItem->setURLString(urlString); | 797 m_currentItem->setURLString(urlString); |
778 m_currentItem->setTitle(title); | 798 m_currentItem->setTitle(title); |
779 m_currentItem->setStateObject(stateObject); | 799 m_currentItem->setStateObject(stateObject); |
780 } | 800 } |
781 | 801 |
782 } // namespace WebCore | 802 } // namespace WebCore |
OLD | NEW |