summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/page/page.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/page/page.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/page/page.cc101
1 files changed, 55 insertions, 46 deletions
diff --git a/chromium/third_party/blink/renderer/core/page/page.cc b/chromium/third_party/blink/renderer/core/page/page.cc
index 608f9d8f2b4..8f2a7581185 100644
--- a/chromium/third_party/blink/renderer/core/page/page.cc
+++ b/chromium/third_party/blink/renderer/core/page/page.cc
@@ -21,8 +21,10 @@
#include "third_party/blink/renderer/core/page/page.h"
+#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
@@ -32,6 +34,7 @@
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/css/vision_deficiency.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/node_rare_data.h"
#include "third_party/blink/renderer/core/dom/visited_link_state.h"
#include "third_party/blink/renderer/core/editing/drag_caret.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
@@ -52,6 +55,7 @@
#include "third_party/blink/renderer/core/frame/viewport_data.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
+#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/console_message_storage.h"
#include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
@@ -89,6 +93,19 @@
namespace blink {
+namespace {
+// This seems like a reasonable upper bound, and otherwise mutually
+// recursive frameset pages can quickly bring the program to its knees
+// with exponential growth in the number of frames.
+const int kMaxNumberOfFrames = 1000;
+
+// It is possible to use a reduced frame limit for testing, but only two values
+// are permitted, the default or reduced limit.
+const int kTenFrames = 10;
+
+bool g_limit_max_frames_to_ten_for_testing = false;
+} // namespace
+
// Function defined in third_party/blink/public/web/blink.h.
void ResetPluginCache(bool reload_pages) {
// At this point we already know that the browser has refreshed its list, so
@@ -199,11 +216,9 @@ Page::Page(PageClients& page_clients)
MakeGarbageCollected<ValidationMessageClientImpl>(*this)),
opened_by_dom_(false),
tab_key_cycles_through_elements_(true),
- paused_(false),
device_scale_factor_(1),
visibility_state_(mojom::blink::PageVisibilityState::kVisible),
is_ordinary_(false),
- page_lifecycle_state_(kDefaultPageLifecycleState),
is_cursor_visible_(true),
subframe_count_(0),
next_related_page_(this),
@@ -232,7 +247,7 @@ void Page::CloseSoon() {
// TODO(dcheng): Try to remove this in a followup, it's not obviously needed.
if (auto* main_local_frame = DynamicTo<LocalFrame>(main_frame_.Get()))
- main_local_frame->Loader().StopAllLoaders();
+ main_local_frame->Loader().StopAllLoaders(/*abort_client=*/true);
GetChromeClient().CloseWindowSoon();
}
@@ -328,9 +343,6 @@ void Page::DocumentDetached(Document* document) {
if (validation_message_client_)
validation_message_client_->DocumentDetached(*document);
- if (agent_metrics_collector_)
- agent_metrics_collector_->DidDetachDocument(*document);
-
GetChromeClient().DocumentDetached(*document);
}
@@ -416,13 +428,11 @@ void Page::SetPaused(bool paused) {
return;
paused_ = paused;
- mojom::FrameLifecycleState state = paused
- ? mojom::FrameLifecycleState::kPaused
- : mojom::FrameLifecycleState::kRunning;
for (Frame* frame = MainFrame(); frame;
frame = frame->Tree().TraverseNext()) {
- if (auto* local_frame = DynamicTo<LocalFrame>(frame))
- local_frame->SetLifecycleState(state);
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
+ local_frame->OnPageLifecycleStateUpdated();
+ }
}
}
@@ -540,55 +550,46 @@ bool Page::IsPageVisible() const {
return visibility_state_ == mojom::blink::PageVisibilityState::kVisible;
}
-void Page::SetLifecycleState(PageLifecycleState state) {
- if (state == page_lifecycle_state_)
+void Page::OnSetPageFrozen(bool frozen) {
+ if (frozen_ == frozen)
return;
- DCHECK_NE(state, PageLifecycleState::kUnknown);
-
- base::Optional<mojom::FrameLifecycleState> next_state;
- if (state == PageLifecycleState::kFrozen) {
- next_state = mojom::FrameLifecycleState::kFrozen;
- } else if (page_lifecycle_state_ == PageLifecycleState::kFrozen) {
- // TODO(fmeawad): Only resume the page that just became visible, blocked
- // on task queues per frame.
- DCHECK(state == PageLifecycleState::kActive ||
- state == PageLifecycleState::kHiddenBackgrounded ||
- state == PageLifecycleState::kHiddenForegrounded);
- next_state = mojom::FrameLifecycleState::kRunning;
- }
+ frozen_ = frozen;
- if (next_state) {
- const bool dispatch_before_unload_on_freeze =
- base::FeatureList::IsEnabled(features::kDispatchBeforeUnloadOnFreeze);
- for (Frame* frame = main_frame_.Get(); frame;
- frame = frame->Tree().TraverseNext()) {
- if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
- // TODO(chrisha): Determine if dispatching the before unload
- // makes sense and if so put it into a specification.
- if (dispatch_before_unload_on_freeze &&
- next_state == mojom::FrameLifecycleState::kFrozen) {
- local_frame->DispatchBeforeUnloadEventForFreeze();
- }
- local_frame->SetLifecycleState(next_state.value());
- }
+ for (Frame* frame = main_frame_.Get(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
+ local_frame->OnPageLifecycleStateUpdated();
}
}
- page_lifecycle_state_ = state;
-}
-
-PageLifecycleState Page::LifecycleState() const {
- return page_lifecycle_state_;
}
bool Page::IsCursorVisible() const {
return is_cursor_visible_;
}
+// static
+int Page::MaxNumberOfFrames() {
+ if (UNLIKELY(g_limit_max_frames_to_ten_for_testing))
+ return kTenFrames;
+ return kMaxNumberOfFrames;
+}
+
+// static
+void Page::SetMaxNumberOfFramesToTenForTesting(bool enabled) {
+ g_limit_max_frames_to_ten_for_testing = enabled;
+}
+
#if DCHECK_IS_ON()
void CheckFrameCountConsistency(int expected_frame_count, Frame* frame) {
DCHECK_GE(expected_frame_count, 0);
int actual_frame_count = 0;
+
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
+ actual_frame_count += static_cast<int>(
+ DocumentPortals::From(*local_frame->GetDocument()).GetPortals().size());
+ }
+
for (; frame; frame = frame->Tree().TraverseNext())
++actual_frame_count;
@@ -886,7 +887,7 @@ void Page::AcceptLanguagesChanged() {
frames[i]->DomWindow()->AcceptLanguagesChanged();
}
-void Page::Trace(Visitor* visitor) {
+void Page::Trace(Visitor* visitor) const {
visitor->Trace(animator_);
visitor->Trace(autoscroll_controller_);
visitor->Trace(chrome_client_);
@@ -1089,4 +1090,12 @@ void Page::PrepareForLeakDetection() {
page->RemoveSupplement<InternalSettingsPageSupplementBase>();
}
+// Ensure the 10 bits reserved for connected frame count in NodeRareData are
+// sufficient.
+static_assert(kMaxNumberOfFrames <
+ (1 << NodeRareData::kConnectedFrameCountBits),
+ "Frame limit should fit in rare data count");
+static_assert(kTenFrames < kMaxNumberOfFrames,
+ "Reduced frame limit for testing should actually be lower");
+
} // namespace blink