| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. |
| 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) 2008 Alp Toker <alp@atoker.com> | 5 * Copyright (C) 2008 Alp Toker <alp@atoker.com> |
| 6 * Copyright (C) Research In Motion Limited 2009. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2009. All rights reserved. |
| 7 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> | 7 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> |
| 8 * Copyright (C) 2011 Google Inc. All rights reserved. | 8 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 9 * | 9 * |
| 10 * Redistribution and use in source and binary forms, with or without | 10 * Redistribution and use in source and binary forms, with or without |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 // If not, remove them, relayout, and repaint. | 435 // If not, remove them, relayout, and repaint. |
| 436 m_frame->view()->restoreScrollbar(); | 436 m_frame->view()->restoreScrollbar(); |
| 437 scrollToFragmentWithParentBoundary(m_frame->document()->url()); | 437 scrollToFragmentWithParentBoundary(m_frame->document()->url()); |
| 438 } | 438 } |
| 439 | 439 |
| 440 void FrameLoader::loadDone() | 440 void FrameLoader::loadDone() |
| 441 { | 441 { |
| 442 checkCompleted(); | 442 checkCompleted(); |
| 443 } | 443 } |
| 444 | 444 |
| 445 bool FrameLoader::allChildrenAreComplete() const | 445 static bool allDescendantsAreComplete(Frame* frame) |
| 446 { | 446 { |
| 447 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree
().nextSibling()) { | 447 for (Frame* child = frame->tree().firstChild(); child; child = child->tree()
.traverseNext(frame)) { |
| 448 if (!child->isLocalFrame()) { | 448 if (child->isLoadingAsChild()) |
| 449 if (!child->checkLoadComplete()) { | |
| 450 return false; | |
| 451 } | |
| 452 continue; | |
| 453 } | |
| 454 LocalFrame* frame = toLocalFrame(child); | |
| 455 if (!frame->document()->isLoadCompleted() || frame->loader().m_provision
alDocumentLoader) | |
| 456 return false; | 449 return false; |
| 457 } | 450 } |
| 458 return true; | 451 return true; |
| 459 } | 452 } |
| 460 | 453 |
| 461 bool FrameLoader::allAncestorsAreComplete() const | 454 bool FrameLoader::allAncestorsAreComplete() const |
| 462 { | 455 { |
| 463 for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree().parent
()) { | 456 for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree().parent
()) { |
| 464 if (ancestor->isLocalFrame()) { | 457 if (ancestor->isLoading()) |
| 465 if (!toLocalFrame(ancestor)->document()->loadEventFinished()) | 458 return false; |
| 466 return false; | 459 } |
| 467 } else { | 460 return true; |
| 468 if (!ancestor->checkLoadComplete()) { | 461 } |
| 469 return false; | |
| 470 } | |
| 471 } | |
| 472 | 462 |
| 473 } | 463 static bool shouldComplete(Document* document) |
| 464 { |
| 465 if (document->parsing() || document->isInDOMContentLoaded()) |
| 466 return false; |
| 467 if (!document->haveImportsLoaded()) |
| 468 return false; |
| 469 if (document->fetcher()->requestCount()) |
| 470 return false; |
| 471 if (document->isDelayingLoadEvent()) |
| 472 return false; |
| 473 return allDescendantsAreComplete(document->frame()); |
| 474 } |
| 475 |
| 476 static bool shouldSendCompleteNotifications(LocalFrame* frame) |
| 477 { |
| 478 // Don't send stop notifications for inital empty documents, since they don'
t generate start notifications. |
| 479 if (!frame->loader().stateMachine()->committedFirstRealDocumentLoad()) |
| 480 return false; |
| 481 |
| 482 // FIXME: We might have already sent stop notifications and be re-completing
. |
| 483 if (!frame->isLoading()) |
| 484 return false; |
| 485 |
| 486 // The readystatechanged or load event may have disconnected this frame. |
| 487 if (!frame->client()) |
| 488 return false; |
| 489 |
| 490 // An event might have restarted a child frame. |
| 491 if (!allDescendantsAreComplete(frame)) |
| 492 return false; |
| 493 |
| 494 // An event might have restarted this frame by scheduling a new navigation. |
| 495 if (frame->loader().provisionalDocumentLoader()) |
| 496 return false; |
| 497 |
| 498 // We might have declined to run the load event due to an imminent content-i
nitiated navigation. |
| 499 if (!frame->document()->loadEventFinished()) |
| 500 return false; |
| 474 return true; | 501 return true; |
| 475 } | 502 } |
| 476 | 503 |
| 477 void FrameLoader::checkCompleted() | 504 void FrameLoader::checkCompleted() |
| 478 { | 505 { |
| 479 RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get()); | 506 RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get()); |
| 480 | 507 if (!shouldComplete(m_frame->document())) |
| 481 if (m_frame->document()->isLoadCompleted() && m_stateMachine.committedFirstR
ealDocumentLoad()) | |
| 482 return; | |
| 483 | |
| 484 // Are we still parsing? | |
| 485 if (m_frame->document()->parsing() || m_frame->document()->isInDOMContentLoa
ded()) | |
| 486 return; | |
| 487 | |
| 488 // Still waiting imports? | |
| 489 if (!m_frame->document()->haveImportsLoaded()) | |
| 490 return; | |
| 491 | |
| 492 // Still waiting for images/scripts? | |
| 493 if (m_frame->document()->fetcher()->requestCount()) | |
| 494 return; | |
| 495 | |
| 496 // Still waiting for elements that don't go through a FrameLoader? | |
| 497 if (m_frame->document()->isDelayingLoadEvent()) | |
| 498 return; | |
| 499 | |
| 500 // Any frame that hasn't completed yet? | |
| 501 if (!allChildrenAreComplete()) | |
| 502 return; | 508 return; |
| 503 | 509 |
| 504 // OK, completed. | 510 // OK, completed. |
| 505 m_frame->document()->setReadyState(Document::Complete); | 511 m_frame->document()->setReadyState(Document::Complete); |
| 506 if (m_frame->document()->loadEventStillNeeded()) | 512 if (m_frame->document()->loadEventStillNeeded()) |
| 507 m_frame->document()->implicitClose(); | 513 m_frame->document()->implicitClose(); |
| 508 | 514 |
| 509 m_frame->navigationScheduler().startTimer(); | 515 m_frame->navigationScheduler().startTimer(); |
| 510 | 516 |
| 511 // Retry restoring scroll offset since finishing the load event disables con
tent | 517 // Retry restoring scroll offset since finishing the load event disables con
tent |
| 512 // size clamping. | 518 // size clamping. |
| 513 restoreScrollPositionAndViewState(); | 519 restoreScrollPositionAndViewState(); |
| 514 if (m_frame->view()) | 520 if (m_frame->view()) |
| 515 m_frame->view()->handleLoadCompleted(); | 521 m_frame->view()->handleLoadCompleted(); |
| 516 | 522 |
| 523 if (shouldSendCompleteNotifications(m_frame)) { |
| 524 m_loadType = FrameLoadTypeStandard; |
| 525 m_progressTracker->progressCompleted(); |
| 526 m_frame->localDOMWindow()->finishedLoading(); |
| 527 |
| 528 // Report mobile vs. desktop page statistics. This will only report on A
ndroid. |
| 529 if (m_frame->isMainFrame()) |
| 530 m_frame->document()->viewportDescription().reportMobilePageStats(m_f
rame); |
| 531 client()->dispatchDidFinishLoad(); |
| 532 } |
| 533 |
| 517 Frame* parent = m_frame->tree().parent(); | 534 Frame* parent = m_frame->tree().parent(); |
| 518 if (parent && parent->isLocalFrame()) | 535 if (parent && parent->isLocalFrame()) |
| 519 toLocalFrame(parent)->loader().checkCompleted(); | 536 toLocalFrame(parent)->loader().checkCompleted(); |
| 520 if (m_frame->page()) | |
| 521 checkLoadComplete(); | |
| 522 } | 537 } |
| 523 | 538 |
| 524 void FrameLoader::checkTimerFired(Timer<FrameLoader>*) | 539 void FrameLoader::checkTimerFired(Timer<FrameLoader>*) |
| 525 { | 540 { |
| 526 if (Page* page = m_frame->page()) { | 541 if (Page* page = m_frame->page()) { |
| 527 if (page->defersLoading()) | 542 if (page->defersLoading()) |
| 528 return; | 543 return; |
| 529 } | 544 } |
| 530 checkCompleted(); | 545 checkCompleted(); |
| 531 } | 546 } |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 bool FrameLoader::isLoadingMainFrame() const | 997 bool FrameLoader::isLoadingMainFrame() const |
| 983 { | 998 { |
| 984 return m_frame->isMainFrame(); | 999 return m_frame->isMainFrame(); |
| 985 } | 1000 } |
| 986 | 1001 |
| 987 FrameLoadType FrameLoader::loadType() const | 1002 FrameLoadType FrameLoader::loadType() const |
| 988 { | 1003 { |
| 989 return m_loadType; | 1004 return m_loadType; |
| 990 } | 1005 } |
| 991 | 1006 |
| 992 bool FrameLoader::checkLoadCompleteForThisFrame() | |
| 993 { | |
| 994 ASSERT(client()->hasWebView()); | |
| 995 RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get()); | |
| 996 | |
| 997 bool allChildrenAreDoneLoading = true; | |
| 998 for (RefPtrWillBeRawPtr<Frame> child = m_frame->tree().firstChild(); child;
child = child->tree().nextSibling()) { | |
| 999 allChildrenAreDoneLoading &= child->checkLoadComplete(); | |
| 1000 } | |
| 1001 if (!allChildrenAreDoneLoading) | |
| 1002 return false; | |
| 1003 | |
| 1004 if (!m_frame->isLoading()) | |
| 1005 return true; | |
| 1006 if (m_provisionalDocumentLoader || !m_documentLoader) | |
| 1007 return false; | |
| 1008 if (!m_frame->document()->loadEventFinished()) | |
| 1009 return false; | |
| 1010 if (!m_stateMachine.committedFirstRealDocumentLoad()) | |
| 1011 return true; | |
| 1012 | |
| 1013 m_progressTracker->progressCompleted(); | |
| 1014 m_frame->localDOMWindow()->finishedLoading(); | |
| 1015 | |
| 1016 // Report mobile vs. desktop page statistics. This will only report on Andro
id. | |
| 1017 if (m_frame->isMainFrame()) | |
| 1018 m_frame->document()->viewportDescription().reportMobilePageStats(m_frame
); | |
| 1019 | |
| 1020 client()->dispatchDidFinishLoad(); | |
| 1021 m_loadType = FrameLoadTypeStandard; | |
| 1022 return true; | |
| 1023 } | |
| 1024 | |
| 1025 void FrameLoader::restoreScrollPositionAndViewState() | 1007 void FrameLoader::restoreScrollPositionAndViewState() |
| 1026 { | 1008 { |
| 1027 FrameView* view = m_frame->view(); | 1009 FrameView* view = m_frame->view(); |
| 1028 if (!m_frame->page() || !view || !m_currentItem || !m_stateMachine.committed
FirstRealDocumentLoad()) | 1010 if (!m_frame->page() || !view || !m_currentItem || !m_stateMachine.committed
FirstRealDocumentLoad()) |
| 1029 return; | 1011 return; |
| 1030 | 1012 |
| 1031 if (!needsHistoryItemRestore(m_loadType)) | 1013 if (!needsHistoryItemRestore(m_loadType)) |
| 1032 return; | 1014 return; |
| 1033 | 1015 |
| 1034 // This tries to balance 1. restoring as soon as possible, 2. detecting | 1016 // This tries to balance 1. restoring as soon as possible, 2. detecting |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1062 } else { | 1044 } else { |
| 1063 view->setScrollPositionNonProgrammatically(m_currentItem->scrollPoint())
; | 1045 view->setScrollPositionNonProgrammatically(m_currentItem->scrollPoint())
; |
| 1064 } | 1046 } |
| 1065 | 1047 |
| 1066 if (m_frame->isMainFrame()) { | 1048 if (m_frame->isMainFrame()) { |
| 1067 if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scroll
ingCoordinator()) | 1049 if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scroll
ingCoordinator()) |
| 1068 scrollingCoordinator->frameViewRootLayerDidChange(view); | 1050 scrollingCoordinator->frameViewRootLayerDidChange(view); |
| 1069 } | 1051 } |
| 1070 } | 1052 } |
| 1071 | 1053 |
| 1072 // Called every time a resource is completely loaded or an error is received. | |
| 1073 void FrameLoader::checkLoadComplete() | |
| 1074 { | |
| 1075 ASSERT(client()->hasWebView()); | |
| 1076 m_frame->page()->mainFrame()->checkLoadComplete(); | |
| 1077 } | |
| 1078 | |
| 1079 String FrameLoader::userAgent(const KURL& url) const | 1054 String FrameLoader::userAgent(const KURL& url) const |
| 1080 { | 1055 { |
| 1081 String userAgent = client()->userAgent(url); | 1056 String userAgent = client()->userAgent(url); |
| 1082 InspectorInstrumentation::applyUserAgentOverride(m_frame, &userAgent); | 1057 InspectorInstrumentation::applyUserAgentOverride(m_frame, &userAgent); |
| 1083 return userAgent; | 1058 return userAgent; |
| 1084 } | 1059 } |
| 1085 | 1060 |
| 1086 void FrameLoader::detach() | 1061 void FrameLoader::detach() |
| 1087 { | 1062 { |
| 1088 #if !ENABLE(OILPAN) | 1063 #if !ENABLE(OILPAN) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 m_progressTracker->progressCompleted(); | 1100 m_progressTracker->progressCompleted(); |
| 1126 } else { | 1101 } else { |
| 1127 ASSERT(loader == m_documentLoader); | 1102 ASSERT(loader == m_documentLoader); |
| 1128 if (m_frame->document()->parser()) | 1103 if (m_frame->document()->parser()) |
| 1129 m_frame->document()->parser()->stopParsing(); | 1104 m_frame->document()->parser()->stopParsing(); |
| 1130 if (!m_provisionalDocumentLoader && m_frame->isLoading()) { | 1105 if (!m_provisionalDocumentLoader && m_frame->isLoading()) { |
| 1131 client()->dispatchDidFailLoad(error); | 1106 client()->dispatchDidFailLoad(error); |
| 1132 m_progressTracker->progressCompleted(); | 1107 m_progressTracker->progressCompleted(); |
| 1133 } | 1108 } |
| 1134 } | 1109 } |
| 1135 | |
| 1136 checkCompleted(); | 1110 checkCompleted(); |
| 1137 if (m_frame->page()) | |
| 1138 checkLoadComplete(); | |
| 1139 } | 1111 } |
| 1140 | 1112 |
| 1141 bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const S
tring& httpMethod, FrameLoadType loadType, const KURL& url) | 1113 bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const S
tring& httpMethod, FrameLoadType loadType, const KURL& url) |
| 1142 { | 1114 { |
| 1143 ASSERT(loadType != FrameLoadTypeReloadFromOrigin); | 1115 ASSERT(loadType != FrameLoadTypeReloadFromOrigin); |
| 1144 // We don't do this if we are submitting a form with method other than "GET"
, explicitly reloading, | 1116 // We don't do this if we are submitting a form with method other than "GET"
, explicitly reloading, |
| 1145 // currently displaying a frameset, or if the URL does not have a fragment. | 1117 // currently displaying a frameset, or if the URL does not have a fragment. |
| 1146 return (!isFormSubmission || equalIgnoringCase(httpMethod, "GET")) | 1118 return (!isFormSubmission || equalIgnoringCase(httpMethod, "GET")) |
| 1147 && loadType != FrameLoadTypeReload | 1119 && loadType != FrameLoadTypeReload |
| 1148 && loadType != FrameLoadTypeSame | 1120 && loadType != FrameLoadTypeSame |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1432 | 1404 |
| 1433 // FIXME: We need a way to propagate strict mixed content checking flags to | 1405 // FIXME: We need a way to propagate strict mixed content checking flags to |
| 1434 // out-of-process frames. For now, we'll always enforce. | 1406 // out-of-process frames. For now, we'll always enforce. |
| 1435 if (!parentFrame->isLocalFrame()) | 1407 if (!parentFrame->isLocalFrame()) |
| 1436 return true; | 1408 return true; |
| 1437 | 1409 |
| 1438 return toLocalFrame(parentFrame)->document()->shouldEnforceStrictMixedConten
tChecking(); | 1410 return toLocalFrame(parentFrame)->document()->shouldEnforceStrictMixedConten
tChecking(); |
| 1439 } | 1411 } |
| 1440 | 1412 |
| 1441 } // namespace blink | 1413 } // namespace blink |
| OLD | NEW |