| 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 |