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