diff --git a/DEPS b/DEPS
index d8dcfb8..aa4d23d3 100644
--- a/DEPS
+++ b/DEPS
@@ -133,11 +133,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'e9d0b9c9d9fb11d393dae81b1bc01493ccb35fa8',
+  'skia_revision': 'fb7fe8882745a8c491b5d203de029f16c1bcaf20',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '3c297f5939a69ae140f4f99ccfaa72476955e627',
+  'v8_revision': '898a71f683439e1fbcde9acb3dfa3046f2b45db7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -145,11 +145,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'b6a2f6bcf65759b0ae37aacce762cc7fcf84e570',
+  'angle_revision': '49c9dfe3b832a5dafefff299552ea68b83c9cd8a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '856ebf878c7109b932419fbf17079b876f19a6f7',
+  'swiftshader_revision': 'ebefaf7ce64ab692abaddea96126924e93225346',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -196,7 +196,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '26a1944e90800456d5b3c3f8672bac6209406c1d',
+  'catapult_revision': 'b88eedc51a92ae50442c0c356043ba31ea77d1ce',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -260,7 +260,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '9bf529ec9421dcd6a27b9d07fbe3edf6bea598d3',
+  'dawn_revision': '070052f6b7d5eac0ed59373a3431d77036459a80',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -752,7 +752,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '0e5424d46467bfe7e8246c429b87de5c6f216c1a',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '2261af73b786139161e797ad3939f0869262f9cd',
       'condition': 'checkout_linux',
   },
 
@@ -1119,7 +1119,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '28c23b46037ca515143ec79421b1a5b1c438133e',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'ac7b61edde0e1c81d34a752ae2a03c2512e838d2',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1293,7 +1293,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a0f51b2e123f39c9ff12e621b0b47dd28dd64424',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '184f6d5d75c198cb7b70b8f9b75e0b5096c6e577',
+    Var('webrtc_git') + '/src.git' + '@' + 'c0c3e966d34b12bc776040f3d1fb7d0aa1987d8d',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc
index f2f8b120..d76a079 100644
--- a/android_webview/renderer/aw_content_renderer_client.cc
+++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -278,13 +278,12 @@
       replacements, nullptr);
 }
 
-unsigned long long AwContentRendererClient::VisitedLinkHash(
-    const char* canonical_url,
-    size_t length) {
+uint64_t AwContentRendererClient::VisitedLinkHash(const char* canonical_url,
+                                                  size_t length) {
   return visited_link_slave_->ComputeURLFingerprint(canonical_url, length);
 }
 
-bool AwContentRendererClient::IsLinkVisited(unsigned long long link_hash) {
+bool AwContentRendererClient::IsLinkVisited(uint64_t link_hash) {
   return visited_link_slave_->IsVisited(link_hash);
 }
 
diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h
index 327616c2..415555b 100644
--- a/android_webview/renderer/aw_content_renderer_client.h
+++ b/android_webview/renderer/aw_content_renderer_client.h
@@ -44,9 +44,8 @@
                         const std::string& http_method,
                         bool ignoring_cache,
                         std::string* error_html) override;
-  unsigned long long VisitedLinkHash(const char* canonical_url,
-                                     size_t length) override;
-  bool IsLinkVisited(unsigned long long link_hash) override;
+  uint64_t VisitedLinkHash(const char* canonical_url, size_t length) override;
+  bool IsLinkVisited(uint64_t link_hash) override;
   void AddSupportedKeySystems(
       std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
       override;
diff --git a/ash/accessibility/accessibility_controller.cc b/ash/accessibility/accessibility_controller.cc
index b315ed1..9d069279 100644
--- a/ash/accessibility/accessibility_controller.cc
+++ b/ash/accessibility/accessibility_controller.cc
@@ -15,6 +15,7 @@
 #include "ash/events/select_to_speak_event_handler.h"
 #include "ash/events/switch_access_event_handler.h"
 #include "ash/high_contrast/high_contrast_controller.h"
+#include "ash/keyboard/ash_keyboard_controller.h"
 #include "ash/policy/policy_recommendation_restorer.h"
 #include "ash/public/cpp/ash_pref_names.h"
 #include "ash/public/cpp/notification_utils.h"
@@ -1219,6 +1220,7 @@
   if (virtual_keyboard_enabled_ == enabled)
     return;
 
+  const bool was_enabled = virtual_keyboard_enabled_;
   virtual_keyboard_enabled_ = enabled;
 
   NotifyAccessibilityStatusChanged();
@@ -1237,10 +1239,8 @@
   // provide a layout with larger keys to facilitate touch typing. In the event
   // that the a11y keyboard is being disabled, an on-screen keyboard might still
   // be enabled and a forced reset is required to pick up the layout change.
-  if (keyboard::IsKeyboardEnabled())
-    Shell::Get()->EnableKeyboard();
-  else
-    Shell::Get()->DisableKeyboard();
+  if (was_enabled)
+    Shell::Get()->ash_keyboard_controller()->RebuildKeyboardIfEnabled();
 }
 
 void AccessibilityController::GetBatteryDescription(
diff --git a/ash/autoclick/autoclick_ring_handler.cc b/ash/autoclick/autoclick_ring_handler.cc
index 06c94872..64805cb 100644
--- a/ash/autoclick/autoclick_ring_handler.cc
+++ b/ash/autoclick/autoclick_ring_handler.cc
@@ -136,15 +136,14 @@
         current_angle_(kAutoclickRingAngleStartValue),
         current_scale_(kAutoclickRingScaleStartValue),
         outer_radius_(outer_radius),
-        inner_radius_(inner_radius) {
+        inner_radius_(inner_radius),
+        is_v2_enabled_(base::CommandLine::ForCurrentProcess()->HasSwitch(
+            switches::kEnableExperimentalAccessibilityAutoclick)) {
     widget_->SetContentsView(this);
 
     // We are owned by the AutoclickRingHandler.
     set_owned_by_client();
     SetNewLocation(event_location);
-
-    is_v2_enabled_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
-        switches::kEnableExperimentalAccessibilityAutoclick);
   }
 
   ~AutoclickRingView() override = default;
diff --git a/ash/keyboard/ash_keyboard_controller.cc b/ash/keyboard/ash_keyboard_controller.cc
index c683923..0fcc82a 100644
--- a/ash/keyboard/ash_keyboard_controller.cc
+++ b/ash/keyboard/ash_keyboard_controller.cc
@@ -24,6 +24,25 @@
 
 namespace ash {
 
+namespace {
+
+class AshKeyboardUIFactory : public keyboard::KeyboardUIFactory {
+ public:
+  explicit AshKeyboardUIFactory(AshKeyboardController* controller)
+      : controller_(controller) {}
+
+  // keyboard::KeyboardUIFactory:
+  std::unique_ptr<keyboard::KeyboardUI> CreateKeyboardUI() override {
+    return std::make_unique<AshKeyboardUI>(controller_);
+  }
+
+ private:
+  AshKeyboardController* controller_;
+  DISALLOW_COPY_AND_ASSIGN(AshKeyboardUIFactory);
+};
+
+}  // namespace
+
 AshKeyboardController::AshKeyboardController(
     SessionController* session_controller)
     : session_controller_(session_controller),
@@ -44,29 +63,15 @@
   bindings_.AddBinding(this, std::move(request));
 }
 
-void AshKeyboardController::EnableKeyboard() {
-  if (!keyboard_controller_->IsKeyboardEnableRequested())
-    return;
-
-  // KeyboardController::EnableKeyboard will reload the keyboard if it's already
-  // enabled. TODO(https://crbug.com/731537): Add a separate function for
-  // reloading the keyboard.
-  keyboard_controller_->EnableKeyboard(
-      keyboard_ui_factory_ ? keyboard_ui_factory_->CreateKeyboardUI()
-                           : std::make_unique<AshKeyboardUI>(this),
-      virtual_keyboard_controller_.get());
-}
-
-void AshKeyboardController::DisableKeyboard() {
-  keyboard_controller_->DisableKeyboard();
-}
-
 void AshKeyboardController::CreateVirtualKeyboard(
     std::unique_ptr<keyboard::KeyboardUIFactory> keyboard_ui_factory) {
   DCHECK(keyboard_ui_factory || features::IsUsingWindowService())
       << "keyboard_ui_factory can be null only when window service is used.";
-  keyboard_ui_factory_ = std::move(keyboard_ui_factory);
   virtual_keyboard_controller_ = std::make_unique<VirtualKeyboardController>();
+  keyboard_controller_->Initialize(
+      keyboard_ui_factory ? std::move(keyboard_ui_factory)
+                          : std::make_unique<AshKeyboardUIFactory>(this),
+      virtual_keyboard_controller_.get());
 
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           keyboard::switches::kEnableVirtualKeyboard)) {
@@ -77,6 +82,7 @@
 
 void AshKeyboardController::DestroyVirtualKeyboard() {
   virtual_keyboard_controller_.reset();
+  keyboard_controller_->Shutdown();
 }
 
 void AshKeyboardController::SendOnKeyboardVisibleBoundsChanged(
@@ -126,15 +132,11 @@
 }
 
 void AshKeyboardController::SetEnableFlag(KeyboardEnableFlag flag) {
-  bool was_enabled = keyboard_controller_->IsEnabled();
   keyboard_controller_->SetEnableFlag(flag);
-  UpdateEnableFlag(was_enabled);
 }
 
 void AshKeyboardController::ClearEnableFlag(KeyboardEnableFlag flag) {
-  bool was_enabled = keyboard_controller_->IsEnabled();
   keyboard_controller_->ClearEnableFlag(flag);
-  UpdateEnableFlag(was_enabled);
 }
 
 void AshKeyboardController::GetEnableFlags(GetEnableFlagsCallback callback) {
@@ -153,8 +155,7 @@
   // Test IsKeyboardEnableRequested in case of an unlikely edge case where this
   // is called while after the enable state changed to disabled (in which case
   // we do not want to override the requested state).
-  if (keyboard_controller_->IsKeyboardEnableRequested())
-    EnableKeyboard();
+  keyboard_controller_->RebuildKeyboardIfEnabled();
 }
 
 void AshKeyboardController::IsKeyboardVisible(
@@ -219,7 +220,7 @@
 // SessionObserver
 void AshKeyboardController::OnSessionStateChanged(
     session_manager::SessionState state) {
-  if (!keyboard_controller_->IsKeyboardEnableRequested())
+  if (!keyboard_controller_->IsEnabled())
     return;
 
   switch (state) {
@@ -230,7 +231,7 @@
       // proper IME. |LOGGED_IN_NOT_ACTIVE| is needed so that the virtual
       // keyboard works on supervised user creation, http://crbug.com/712873.
       // |ACTIVE| is also needed for guest user workflow.
-      EnableKeyboard();
+      RebuildKeyboardIfEnabled();
       break;
     default:
       break;
@@ -248,15 +249,6 @@
   }
 }
 
-void AshKeyboardController::UpdateEnableFlag(bool was_enabled) {
-  bool is_enabled = keyboard_controller_->IsKeyboardEnableRequested();
-  if (is_enabled && !was_enabled) {
-    EnableKeyboard();
-  } else if (!is_enabled && was_enabled) {
-    DisableKeyboard();
-  }
-}
-
 void AshKeyboardController::OnKeyboardConfigChanged() {
   KeyboardConfigPtr config =
       KeyboardConfig::New(keyboard_controller_->keyboard_config());
diff --git a/ash/keyboard/ash_keyboard_controller.h b/ash/keyboard/ash_keyboard_controller.h
index 6cf9e6d..f7d5302c 100644
--- a/ash/keyboard/ash_keyboard_controller.h
+++ b/ash/keyboard/ash_keyboard_controller.h
@@ -45,13 +45,6 @@
   // Called from RegisterInterfaces to bind this to the Ash service.
   void BindRequest(mojom::KeyboardControllerRequest request);
 
-  // Enables the keyboard controller if enabling has been requested. If already
-  // enabled, the keyboard is disabled and re-enabled.
-  void EnableKeyboard();
-
-  // Disables the keyboard.
-  void DisableKeyboard();
-
   // Create or destroy the virtual keyboard. Called from Shell. TODO(stevenjb):
   // Fix dependencies so that the virtual keyboard can be created with the
   // keyboard controller.
@@ -106,10 +99,6 @@
   void OnRootWindowClosing(aura::Window* root_window);
 
  private:
-  // Called whenever the enable flags may have changed the enabled state from
-  // |was_enabled|. If changed, enables or disables the keyboard.
-  void UpdateEnableFlag(bool was_enabled);
-
   // keyboard::KeyboardControllerObserver
   void OnKeyboardConfigChanged() override;
   void OnKeyboardVisibilityStateChanged(bool is_visible) override;
@@ -122,7 +111,6 @@
   void OnKeyboardEnabledChanged(bool is_enabled) override;
 
   SessionController* session_controller_;  // unowned
-  std::unique_ptr<keyboard::KeyboardUIFactory> keyboard_ui_factory_;
   std::unique_ptr<keyboard::KeyboardController> keyboard_controller_;
   std::unique_ptr<VirtualKeyboardController> virtual_keyboard_controller_;
   mojo::BindingSet<mojom::KeyboardController> bindings_;
diff --git a/ash/keyboard/ash_keyboard_controller_unittest.cc b/ash/keyboard/ash_keyboard_controller_unittest.cc
index c02c96a..073a8de 100644
--- a/ash/keyboard/ash_keyboard_controller_unittest.cc
+++ b/ash/keyboard/ash_keyboard_controller_unittest.cc
@@ -140,6 +140,8 @@
     keyboard_controller_ptr_.FlushForTesting();
   }
 
+  void FlushMojoForTesting() { keyboard_controller_ptr_.FlushForTesting(); }
+
   int got_keyboard_config_count() const { return got_keyboard_config_count_; }
   const KeyboardConfig& keyboard_config() const { return keyboard_config_; }
 
@@ -186,11 +188,6 @@
 
   bool IsOverscrollAllowed() const override { return true; }
 
-  bool IsDragHandle(const gfx::Vector2d& offset,
-                    const gfx::Size& keyboard_size) const override {
-    return false;
-  }
-
   void SavePosition(const gfx::Rect& keyboard_bounds_in_screen,
                     const gfx::Size& screen_size) override {}
 
@@ -458,4 +455,22 @@
   EXPECT_EQ(bounds, behavior->draggable_area());
 }
 
+TEST_F(AshKeyboardControllerTest, ChangingSessionRebuildsKeyboard) {
+  // Enable the keyboard.
+  test_client()->SetEnableFlag(KeyboardEnableFlag::kExtensionEnabled);
+
+  // LOGGED_IN_NOT_ACTIVE session state needs to rebuild keyboard for supervised
+  // user profile.
+  Shell::Get()->ash_keyboard_controller()->OnSessionStateChanged(
+      session_manager::SessionState::LOGGED_IN_NOT_ACTIVE);
+  test_client()->FlushMojoForTesting();
+  EXPECT_EQ(1, test_observer()->destroyed_count());
+
+  // ACTIVE session state also needs to rebuild keyboard for guest user profile.
+  Shell::Get()->ash_keyboard_controller()->OnSessionStateChanged(
+      session_manager::SessionState::ACTIVE);
+  test_client()->FlushMojoForTesting();
+  EXPECT_EQ(2, test_observer()->destroyed_count());
+}
+
 }  // namespace ash
diff --git a/ash/keyboard/virtual_keyboard_controller.cc b/ash/keyboard/virtual_keyboard_controller.cc
index ba77ff15..af0cfcf 100644
--- a/ash/keyboard/virtual_keyboard_controller.cc
+++ b/ash/keyboard/virtual_keyboard_controller.cc
@@ -41,8 +41,6 @@
 
 void ResetVirtualKeyboard() {
   keyboard::SetKeyboardEnabledFromShelf(false);
-  if (!keyboard::IsKeyboardEnabled())
-    Shell::Get()->DisableKeyboard();
 
   // Reset the keyset after disabling the virtual keyboard to prevent the IME
   // extension from accidentally loading the default keyset while it's shutting
@@ -189,9 +187,10 @@
 
 void VirtualKeyboardController::UpdateKeyboardEnabled() {
   if (IsVirtualKeyboardEnabled()) {
-    SetKeyboardEnabled(Shell::Get()
-                           ->tablet_mode_controller()
-                           ->AreInternalInputDeviceEventsBlocked());
+    keyboard::SetTouchKeyboardEnabled(
+        Shell::Get()
+            ->tablet_mode_controller()
+            ->AreInternalInputDeviceEventsBlocked());
     return;
   }
   bool ignore_internal_keyboard = Shell::Get()
@@ -199,26 +198,14 @@
                                       ->AreInternalInputDeviceEventsBlocked();
   bool is_internal_keyboard_active =
       has_internal_keyboard_ && !ignore_internal_keyboard;
-  SetKeyboardEnabled(!is_internal_keyboard_active && has_touchscreen_ &&
-                     (!has_external_keyboard_ || ignore_external_keyboard_));
+  keyboard::SetTouchKeyboardEnabled(
+      !is_internal_keyboard_active && has_touchscreen_ &&
+      (!has_external_keyboard_ || ignore_external_keyboard_));
   Shell::Get()->system_tray_notifier()->NotifyVirtualKeyboardSuppressionChanged(
       !is_internal_keyboard_active && has_touchscreen_ &&
       has_external_keyboard_);
 }
 
-void VirtualKeyboardController::SetKeyboardEnabled(bool enabled) {
-  bool was_enabled = keyboard::IsKeyboardEnabled();
-  keyboard::SetTouchKeyboardEnabled(enabled);
-  bool is_enabled = keyboard::IsKeyboardEnabled();
-  if (is_enabled == was_enabled)
-    return;
-  if (is_enabled) {
-    Shell::Get()->EnableKeyboard();
-  } else {
-    Shell::Get()->DisableKeyboard();
-  }
-}
-
 void VirtualKeyboardController::ForceShowKeyboard() {
   // If the virtual keyboard is enabled, show the keyboard directly.
   auto* keyboard_controller = keyboard::KeyboardController::Get();
@@ -230,7 +217,6 @@
   // Otherwise, temporarily enable the virtual keyboard until it is dismissed.
   DCHECK(!keyboard::GetKeyboardEnabledFromShelf());
   keyboard::SetKeyboardEnabledFromShelf(true);
-  Shell::Get()->EnableKeyboard();
   keyboard_controller->ShowKeyboard(false);
 }
 
@@ -257,8 +243,7 @@
 void VirtualKeyboardController::OnActiveUserSessionChanged(
     const AccountId& account_id) {
   // Force on-screen keyboard to reset.
-  if (keyboard::IsKeyboardEnabled())
-    Shell::Get()->EnableKeyboard();
+  Shell::Get()->ash_keyboard_controller()->RebuildKeyboardIfEnabled();
 }
 
 void VirtualKeyboardController::OnBluetoothAdapterOrDeviceChanged(
diff --git a/ash/keyboard/virtual_keyboard_controller.h b/ash/keyboard/virtual_keyboard_controller.h
index 92ab062..630359ba 100644
--- a/ash/keyboard/virtual_keyboard_controller.h
+++ b/ash/keyboard/virtual_keyboard_controller.h
@@ -67,9 +67,6 @@
   // Updates the keyboard state.
   void UpdateKeyboardEnabled();
 
-  // Creates the keyboard if |enabled|, else destroys it.
-  void SetKeyboardEnabled(bool enabled);
-
   // Force enable the keyboard and show it, even in laptop mode.
   void ForceShowKeyboard();
 
diff --git a/ash/keyboard/virtual_keyboard_controller_unittest.cc b/ash/keyboard/virtual_keyboard_controller_unittest.cc
index 1f4e679..ac657b1 100644
--- a/ash/keyboard/virtual_keyboard_controller_unittest.cc
+++ b/ash/keyboard/virtual_keyboard_controller_unittest.cc
@@ -148,7 +148,7 @@
   Shell::Get()->ime_controller()->SetClient(client.CreateInterfacePtr());
 
   // Should show the keyboard by enabling it temporarily.
-  EXPECT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
   EXPECT_FALSE(keyboard_controller()->IsEnableFlagSet(
       KeyboardEnableFlag::kShelfEnabled));
 
@@ -158,7 +158,7 @@
 
   EXPECT_TRUE(keyboard_controller()->IsEnableFlagSet(
       KeyboardEnableFlag::kShelfEnabled));
-  EXPECT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
 
   // Keyset should be emoji.
   EXPECT_EQ(chromeos::input_method::mojom::ImeKeyset::kEmoji,
@@ -172,7 +172,7 @@
   base::RunLoop().RunUntilIdle();
 
   // The keyboard should still be disabled again.
-  EXPECT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
   EXPECT_FALSE(keyboard_controller()->IsEnableFlagSet(
       KeyboardEnableFlag::kShelfEnabled));
 
@@ -195,7 +195,7 @@
 
   EXPECT_TRUE(keyboard_controller()->IsEnableFlagSet(
       KeyboardEnableFlag::kShelfEnabled));
-  EXPECT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
 
   // Keyset should be emoji.
   EXPECT_EQ(chromeos::input_method::mojom::ImeKeyset::kEmoji,
@@ -211,7 +211,7 @@
   // The keyboard should still be enabled.
   EXPECT_TRUE(keyboard_controller()->IsEnableFlagSet(
       KeyboardEnableFlag::kShelfEnabled));
-  EXPECT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
 
   // Keyset should still be emoji.
   EXPECT_EQ(chromeos::input_method::mojom::ImeKeyset::kEmoji,
@@ -270,13 +270,13 @@
   keyboard_devices.push_back(ui::InputDevice(
       1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard"));
   ws::InputDeviceClientTestApi().SetKeyboardDevices(keyboard_devices);
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
   // Remove the internal keyboard. Virtual keyboard should now show.
   ws::InputDeviceClientTestApi().SetKeyboardDevices({});
-  EXPECT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
   // Replug in the internal keyboard. Virtual keyboard should hide.
   ws::InputDeviceClientTestApi().SetKeyboardDevices(keyboard_devices);
-  EXPECT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
 }
 
 TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) {
@@ -286,10 +286,10 @@
       ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_USB,
                             "Touchscreen", gfx::Size(800, 600), 0));
   ws::InputDeviceClientTestApi().SetTouchscreenDevices(devices);
-  EXPECT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
   // Remove touchscreen. Keyboard should hide.
   ws::InputDeviceClientTestApi().SetTouchscreenDevices({});
-  EXPECT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
 }
 
 TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) {
@@ -302,28 +302,28 @@
   keyboard_devices.push_back(
       ui::InputDevice(1, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard"));
   ws::InputDeviceClientTestApi().SetKeyboardDevices(keyboard_devices);
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
-  ASSERT_TRUE(notified());
-  ASSERT_TRUE(IsVirtualKeyboardSuppressed());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
+  EXPECT_TRUE(notified());
+  EXPECT_TRUE(IsVirtualKeyboardSuppressed());
   // Toggle show keyboard. Keyboard should be visible.
   ResetObserver();
   GetVirtualKeyboardController()->ToggleIgnoreExternalKeyboard();
-  ASSERT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
-  ASSERT_TRUE(notified());
-  ASSERT_TRUE(IsVirtualKeyboardSuppressed());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
+  EXPECT_TRUE(notified());
+  EXPECT_TRUE(IsVirtualKeyboardSuppressed());
   // Toggle show keyboard. Keyboard should be hidden.
   ResetObserver();
   GetVirtualKeyboardController()->ToggleIgnoreExternalKeyboard();
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
-  ASSERT_TRUE(notified());
-  ASSERT_TRUE(IsVirtualKeyboardSuppressed());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
+  EXPECT_TRUE(notified());
+  EXPECT_TRUE(IsVirtualKeyboardSuppressed());
   // Remove external keyboard. Should be notified that the keyboard is not
   // suppressed.
   ResetObserver();
   ws::InputDeviceClientTestApi().SetKeyboardDevices({});
-  ASSERT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
-  ASSERT_TRUE(notified());
-  ASSERT_FALSE(IsVirtualKeyboardSuppressed());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
+  EXPECT_TRUE(notified());
+  EXPECT_FALSE(IsVirtualKeyboardSuppressed());
 }
 
 // Tests handling multiple keyboards. Catches crbug.com/430252
@@ -336,7 +336,7 @@
   keyboards.push_back(
       ui::InputDevice(3, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard"));
   ws::InputDeviceClientTestApi().SetKeyboardDevices(keyboards);
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
 }
 
 // Tests tablet mode interaction without disabling the internal keyboard.
@@ -350,13 +350,13 @@
   keyboard_devices.push_back(ui::InputDevice(
       1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
   ws::InputDeviceClientTestApi().SetKeyboardDevices(keyboard_devices);
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
   // Toggle tablet mode on.
   TabletModeControllerTestApi().EnterTabletMode();
-  ASSERT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
   // Toggle tablet mode off.
   TabletModeControllerTestApi().LeaveTabletMode();
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
 }
 
 // Tests that keyboard gets suppressed in tablet mode.
@@ -374,32 +374,32 @@
   ws::InputDeviceClientTestApi().SetKeyboardDevices(keyboard_devices);
   // Toggle tablet mode on.
   TabletModeControllerTestApi().EnterTabletMode();
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
-  ASSERT_TRUE(notified());
-  ASSERT_TRUE(IsVirtualKeyboardSuppressed());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
+  EXPECT_TRUE(notified());
+  EXPECT_TRUE(IsVirtualKeyboardSuppressed());
   // Toggle show keyboard. Keyboard should be visible.
   ResetObserver();
   GetVirtualKeyboardController()->ToggleIgnoreExternalKeyboard();
-  ASSERT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
-  ASSERT_TRUE(notified());
-  ASSERT_TRUE(IsVirtualKeyboardSuppressed());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
+  EXPECT_TRUE(notified());
+  EXPECT_TRUE(IsVirtualKeyboardSuppressed());
   // Toggle show keyboard. Keyboard should be hidden.
   ResetObserver();
   GetVirtualKeyboardController()->ToggleIgnoreExternalKeyboard();
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
-  ASSERT_TRUE(notified());
-  ASSERT_TRUE(IsVirtualKeyboardSuppressed());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
+  EXPECT_TRUE(notified());
+  EXPECT_TRUE(IsVirtualKeyboardSuppressed());
   // Remove external keyboard. Should be notified that the keyboard is not
   // suppressed.
   ResetObserver();
   keyboard_devices.pop_back();
   ws::InputDeviceClientTestApi().SetKeyboardDevices(keyboard_devices);
-  ASSERT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
-  ASSERT_TRUE(notified());
-  ASSERT_FALSE(IsVirtualKeyboardSuppressed());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
+  EXPECT_TRUE(notified());
+  EXPECT_FALSE(IsVirtualKeyboardSuppressed());
   // Toggle tablet mode oFF.
   TabletModeControllerTestApi().LeaveTabletMode();
-  ASSERT_FALSE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_FALSE(keyboard_controller()->IsEnabled());
 }
 
 class VirtualKeyboardControllerAlwaysEnabledTest
@@ -431,7 +431,7 @@
   keyboard_devices.push_back(
       ui::InputDevice(1, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard"));
   ws::InputDeviceClientTestApi().SetKeyboardDevices(keyboard_devices);
-  ASSERT_TRUE(keyboard_controller()->IsKeyboardEnableRequested());
+  EXPECT_TRUE(keyboard_controller()->IsEnabled());
 }
 
 // Test for http://crbug.com/297858. |GetContainerForDefaultDisplay| should
diff --git a/ash/keyboard/virtual_keyboard_unittest.cc b/ash/keyboard/virtual_keyboard_unittest.cc
index c8f312ad..7230635b 100644
--- a/ash/keyboard/virtual_keyboard_unittest.cc
+++ b/ash/keyboard/virtual_keyboard_unittest.cc
@@ -25,7 +25,6 @@
         keyboard::switches::kEnableVirtualKeyboard);
     AshTestBase::SetUp();
     keyboard::SetTouchKeyboardEnabled(true);
-    Shell::Get()->EnableKeyboard();
   }
 
   void TearDown() override {
diff --git a/ash/magnifier/magnification_controller_unittest.cc b/ash/magnifier/magnification_controller_unittest.cc
index c6e406c1..421cf780 100644
--- a/ash/magnifier/magnification_controller_unittest.cc
+++ b/ash/magnifier/magnification_controller_unittest.cc
@@ -980,7 +980,6 @@
 
   // Set up and show the keyboard.
   keyboard::SetAccessibilityKeyboardEnabled(true);
-  ash::Shell::Get()->EnableKeyboard();
   auto* keyboard_controller = keyboard::KeyboardController::Get();
   keyboard_controller->ShowKeyboard(true);
 
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 0ec80fd..226c8ae 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -714,7 +714,7 @@
 
   root_window_layout_manager_->OnWindowResized();
   if (root_window_type == RootWindowType::PRIMARY) {
-    shell->EnableKeyboard();
+    shell->ash_keyboard_controller()->RebuildKeyboardIfEnabled();
   } else {
     window_tree_host_->Show();
 
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index f837b99..2181eae 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -2721,7 +2721,6 @@
     UpdateDisplay("800x600");
     keyboard::SetTouchKeyboardEnabled(true);
     keyboard::SetAccessibilityKeyboardEnabled(true);
-    Shell::Get()->EnableKeyboard();
   }
 
   // AshTestBase:
diff --git a/ash/shell.cc b/ash/shell.cc
index f2c7a239..d70fc4f 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -485,16 +485,6 @@
     observer.OnDictationEnded();
 }
 
-void Shell::EnableKeyboard() {
-  // The keyboard controller is persistent; this will create or recreate the
-  // keyboard window as necessary.
-  ash_keyboard_controller_->EnableKeyboard();
-}
-
-void Shell::DisableKeyboard() {
-  ash_keyboard_controller_->DisableKeyboard();
-}
-
 bool Shell::ShouldSaveDisplaySettings() {
   return !(
       screen_orientation_controller_->ignore_display_configuration_updates() ||
@@ -767,10 +757,6 @@
   // need to be removed.
   tablet_mode_controller_.reset();
 
-  // Destroy the keyboard before closing the shelf, since it will invoke a shelf
-  // layout.
-  DisableKeyboard();
-
   toast_manager_.reset();
 
   tray_bluetooth_helper_.reset();
@@ -1224,11 +1210,14 @@
   system_notification_controller_ =
       std::make_unique<SystemNotificationController>();
 
+  window_tree_host_manager_->InitHosts();
+
+  // Create virtual keyboard after WindowTreeHostManager::InitHosts() since
+  // it may enable the virtual keyboard immediately, which requires a
+  // WindowTreeHostManager to host the keyboard window.
   ash_keyboard_controller_->CreateVirtualKeyboard(
       std::move(keyboard_ui_factory));
 
-  window_tree_host_manager_->InitHosts();
-
   cursor_manager_->HideCursor();  // Hide the mouse cursor on startup.
   cursor_manager_->SetCursor(ui::CursorType::kPointer);
 
diff --git a/ash/shell.h b/ash/shell.h
index 70869c4..e6bb0723 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -317,13 +317,6 @@
   // Called when dictation is ended.
   void OnDictationEnded();
 
-  // Enables the keyboard and associate it with the primary root window
-  // controller.
-  void EnableKeyboard();
-
-  // Hides and disables the virtual keyboard.
-  void DisableKeyboard();
-
   // Test if TabletModeWindowManager is not enabled, and if
   // TabletModeController is not currently setting a display rotation. Or if
   // the |resolution_notification_controller_| is not showing its confirmation
diff --git a/ash/shell_test_api.cc b/ash/shell_test_api.cc
index c636176..1cdbdda8 100644
--- a/ash/shell_test_api.cc
+++ b/ash/shell_test_api.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "ash/accelerators/accelerator_commands.h"
+#include "ash/keyboard/ash_keyboard_controller.h"
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/system/power/backlights_forced_off_setter.h"
@@ -84,7 +85,11 @@
 }
 
 void ShellTestApi::EnableVirtualKeyboard(EnableVirtualKeyboardCallback cb) {
-  shell_->EnableKeyboard();
+  // TODO(https://crbug.com/845780): The callers to this function have already
+  // enabled the virtual keyboard. For some reason, in those tests, the virtual
+  // keyboard requires a rebuild. Remove this function once we no longer need a
+  // rebuild.
+  shell_->ash_keyboard_controller()->RebuildKeyboardIfEnabled();
   std::move(cb).Run();
 }
 
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc
index 6fb6528..41c9b2b 100644
--- a/ash/shell_unittest.cc
+++ b/ash/shell_unittest.cc
@@ -553,21 +553,6 @@
   Shell::Get()->aura_env()->RemovePreTargetHandler(&event_handler);
 }
 
-// Verifies keyboard is re-enabled on proper timing.
-TEST_F(ShellTest, KeyboardCreation) {
-  keyboard::SetTouchKeyboardEnabled(true);
-
-  ASSERT_TRUE(keyboard::IsKeyboardEnabled());
-
-  EXPECT_FALSE(keyboard::KeyboardController::Get()->IsEnabled());
-
-  mojom::SessionInfoPtr info = mojom::SessionInfo::New();
-  info->state = session_manager::SessionState::LOGGED_IN_NOT_ACTIVE;
-  ash::Shell::Get()->session_controller()->SetSessionInfo(std::move(info));
-
-  EXPECT_TRUE(keyboard::KeyboardController::Get()->IsEnabled());
-}
-
 // This verifies WindowObservers are removed when a window is destroyed after
 // the Shell is destroyed. This scenario (aura::Windows being deleted after the
 // Shell) occurs if someone is holding a reference to an unparented Window, as
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index c952bb3..14de605 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -235,13 +235,10 @@
   CreateWindowService();
 
   // Create the test keyboard controller observer to respond to
-  // OnLoadKeyboardContentsRequested() and enable the virtual keyboard. Note:
-  // enabling the keyboard just makes it available, it does not show it or
-  // otherwise affect behavior.
+  // OnLoadKeyboardContentsRequested().
   test_keyboard_controller_observer_ =
       std::make_unique<TestKeyboardControllerObserver>(
           shell->ash_keyboard_controller());
-  shell->ash_keyboard_controller()->EnableKeyboard();
 }
 
 void AshTestHelper::TearDown() {
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc
index ca8f12f..a515da0 100644
--- a/ash/wm/default_state.cc
+++ b/ash/wm/default_state.cc
@@ -389,7 +389,8 @@
 // static
 void DefaultState::SetBounds(WindowState* window_state,
                              const SetBoundsEvent* event) {
-  if (window_state->is_dragged() || window_state->allow_set_bounds_direct()) {
+  if (!event->animate() &&
+      (window_state->is_dragged() || window_state->allow_set_bounds_direct())) {
     // TODO(oshima|varkha): Is this still needed? crbug.com/485612.
     window_state->SetBoundsDirect(event->requested_bounds());
   } else if (!SetMaximizedOrFullscreenBounds(window_state)) {
diff --git a/ash/wm/pip/pip_positioner_unittest.cc b/ash/wm/pip/pip_positioner_unittest.cc
index fd56d2d..c2f4fa4 100644
--- a/ash/wm/pip/pip_positioner_unittest.cc
+++ b/ash/wm/pip/pip_positioner_unittest.cc
@@ -95,8 +95,6 @@
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         keyboard::switches::kEnableVirtualKeyboard);
     AshTestBase::SetUp();
-    SetTouchKeyboardEnabled(true);
-    Shell::Get()->EnableKeyboard();
 
     const std::string& display_string = std::get<0>(GetParam());
     const std::size_t root_window_index = std::get<1>(GetParam());
@@ -108,7 +106,6 @@
 
   void TearDown() override {
     scoped_root_.reset();
-    SetTouchKeyboardEnabled(false);
     AshTestBase::TearDown();
   }
 
@@ -226,7 +223,7 @@
 }
 
 TEST_P(PipPositionerDisplayTest, PipRestingPositionWorksIfKeyboardIsDisabled) {
-  Shell::Get()->DisableKeyboard();
+  SetTouchKeyboardEnabled(false);
   auto display = GetDisplay();
 
   // Snap near top edge to top.
diff --git a/ash/wm/pip/pip_unittest.cc b/ash/wm/pip/pip_unittest.cc
index c9d1d354..f94a2a32 100644
--- a/ash/wm/pip/pip_unittest.cc
+++ b/ash/wm/pip/pip_unittest.cc
@@ -141,7 +141,6 @@
   window_state->OnWMEvent(&enter_pip);
   window->Show();
 
-  Shell::Get()->EnableKeyboard();
   auto* keyboard_controller = keyboard::KeyboardController::Get();
   keyboard_controller->ShowKeyboard(/*lock=*/true);
   ASSERT_TRUE(keyboard::WaitUntilShown());
@@ -156,7 +155,6 @@
 
 TEST_F(PipTest, TargetBoundsAffectedByWorkAreaChange) {
   UpdateDisplay("400x400");
-  Shell::Get()->EnableKeyboard();
 
   // Place a keyboard window at the initial position of a PIP window.
   auto* keyboard_controller = keyboard::KeyboardController::Get();
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index 92a2e57..1b1307b4 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -1792,7 +1792,6 @@
        IgnoreWorkAreaChangeinNonStickyMode) {
   keyboard::SetAccessibilityKeyboardEnabled(true);
   InitKeyboardBounds();
-  Shell::Get()->EnableKeyboard();
   auto* kb_controller = keyboard::KeyboardController::Get();
 
   gfx::Rect work_area(
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 0183fca..855a41b 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-9622b5e49a17bc72966697339c9cad3ed56e07c5
\ No newline at end of file
+4c348725452cc929f3f95888d3e170f2e9c0eb5d
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 97573a42..4167b0b 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-f80a3a8d25335a8121173e65b280d018fe7cb615
\ No newline at end of file
+97a3dbff0a280ef9daa362e93b1453d691ac5e45
\ No newline at end of file
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 70f8f33..14e0aa1 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1849,7 +1849,7 @@
 
   additional_apks = [
     "//chrome/android/webapk/libs/runtime_library/javatests/apk_with_webapk_service:apk_with_webapk_service",
-    "//chrome/android/webapk/shell_apk:webapk",
+    "//chrome/android/webapk/shell_apk:javatests_webapk",
     "//chrome/android/webapk/shell_apk/javatests/dex_optimizer:dex_optimizer_apk",
     "//chrome/test/android/chrome_public_test_support:chrome_public_test_support_apk",
   ]
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index 2ea2fd9..47daf71 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -772,6 +772,15 @@
         </activity>
         {% endfor %}
 
+        <activity android:name="org.chromium.chrome.browser.webapps.ActivateWebApkActivity"
+            android:theme="@android:style/Theme.NoDisplay"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="org.chromium.chrome.browser.webapps.ActivateWebApkActivity.ACTIVATE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="org.chromium.chrome.browser.media.router.caf.remoting.CafExpandedControllerActivity"
             android:theme="@style/Theme.Chromium.Activity"
             android:label="Chrome.CafExpandedControllerActivity"
diff --git a/chrome/android/java/monochrome_public_apk.AndroidManifest.expected b/chrome/android/java/monochrome_public_apk.AndroidManifest.expected
index 2da7a4e..ecb78f2 100644
--- a/chrome/android/java/monochrome_public_apk.AndroidManifest.expected
+++ b/chrome/android/java/monochrome_public_apk.AndroidManifest.expected
@@ -948,6 +948,15 @@
       </intent-filter>
     </activity>
     <activity
+        android:exported="true"
+        android:name="org.chromium.chrome.browser.webapps.ActivateWebApkActivity"
+        android:theme="@android:style/Theme.NoDisplay">
+      <intent-filter>
+        <action android:name="org.chromium.chrome.browser.webapps.ActivateWebApkActivity.ACTIVATE"/>
+        <category android:name="android.intent.category.DEFAULT"/>
+      </intent-filter>
+    </activity>
+    <activity
         android:label="@string/license_activity_title"
         android:name="com.android.webview.chromium.LicenseActivity">
       <intent-filter>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index bdfe652..28c03c7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -90,7 +90,6 @@
 import org.chromium.content_public.common.ResourceRequestBody;
 import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.base.WindowAndroid;
-import org.chromium.ui.mojom.WindowOpenDisposition;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -2245,55 +2244,6 @@
         if (view != null) view.requestFocus();
     }
 
-    @CalledByNative
-    protected void openNewTab(String url, String initiatorOrigin, String extraHeaders,
-            ResourceRequestBody postData, int disposition, boolean hasParent,
-            boolean isRendererInitiated) {
-        if (isClosing()) return;
-
-        boolean incognito = isIncognito();
-        @TabLaunchType
-        int tabLaunchType = TabLaunchType.FROM_LONGPRESS_FOREGROUND;
-        Tab parentTab = hasParent ? this : null;
-
-        switch (disposition) {
-            case WindowOpenDisposition.NEW_WINDOW: // fall through
-            case WindowOpenDisposition.NEW_FOREGROUND_TAB:
-                break;
-            case WindowOpenDisposition.NEW_POPUP: // fall through
-            case WindowOpenDisposition.NEW_BACKGROUND_TAB:
-                tabLaunchType = TabLaunchType.FROM_LONGPRESS_BACKGROUND;
-                break;
-            case WindowOpenDisposition.OFF_THE_RECORD:
-                assert incognito;
-                incognito = true;
-                break;
-            default:
-                assert false;
-        }
-
-        // If shouldIgnoreNewTab returns true, the intent is handled by another
-        // activity. As a result, don't launch a new tab to open the URL. If TabModelSelector
-        // is not accessible, then we can't open a new tab.
-        if (shouldIgnoreNewTab(url, incognito) || getTabModelSelector() == null) return;
-
-        LoadUrlParams loadUrlParams = new LoadUrlParams(url);
-        loadUrlParams.setInitiatorOrigin(initiatorOrigin);
-        loadUrlParams.setVerbatimHeaders(extraHeaders);
-        loadUrlParams.setPostData(postData);
-        loadUrlParams.setIsRendererInitiated(isRendererInitiated);
-        getTabModelSelector().openNewTab(
-                loadUrlParams, tabLaunchType, parentTab, incognito);
-    }
-
-    /**
-     * @return True if the Tab should block the creation of new tabs via {@link #openNewTab}.
-     */
-    private boolean shouldIgnoreNewTab(String url, boolean incognito) {
-        InterceptNavigationDelegateImpl delegate = getInterceptNavigationDelegate();
-        return delegate != null && delegate.shouldIgnoreNewTab(url, incognito);
-    }
-
     /**
      * See {@link #mInterceptNavigationDelegate}.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java
index 9ea3e0b..349bd51 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java
@@ -47,7 +47,6 @@
 import org.chromium.content_public.browser.GestureListenerManager;
 import org.chromium.content_public.browser.InvalidateTypes;
 import org.chromium.content_public.browser.WebContents;
-import org.chromium.content_public.common.ResourceRequestBody;
 import org.chromium.ui.modaldialog.DialogDismissalCause;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogProperties;
@@ -292,12 +291,6 @@
                 ? false : mTab.getFullscreenManager().getPersistentFullscreenMode();
     }
 
-    @Override
-    public void openNewTab(String url, String extraHeaders, ResourceRequestBody postData,
-            int disposition, boolean isRendererInitiated) {
-        mTab.openNewTab(url, null, extraHeaders, postData, disposition, true, isRendererInitiated);
-    }
-
     protected TabModel getTabModel() {
         // TODO(dfalcantara): Remove this when DocumentActivity.getTabModelSelector()
         //                    can return a TabModelSelector that activateContents() can use.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
index 4d88ff9..25b4b8f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
@@ -10,10 +10,14 @@
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.ntp.RecentlyClosedBridge;
 import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
+import org.chromium.chrome.browser.tab.InterceptNavigationDelegateImpl;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator;
 import org.chromium.chrome.browser.util.MathUtils;
+import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.common.ResourceRequestBody;
+import org.chromium.ui.mojom.WindowOpenDisposition;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -740,6 +744,46 @@
     }
 
     @Override
+    public void openNewTab(Tab parent, String url, String initiatorOrigin, String extraHeaders,
+            ResourceRequestBody postData, int disposition, boolean persistParentage,
+            boolean isRendererInitiated) {
+        if (parent.isClosing()) return;
+
+        boolean incognito = parent.isIncognito();
+        @TabLaunchType
+        int tabLaunchType = TabLaunchType.FROM_LONGPRESS_FOREGROUND;
+
+        switch (disposition) {
+            case WindowOpenDisposition.NEW_WINDOW: // fall through
+            case WindowOpenDisposition.NEW_FOREGROUND_TAB:
+                break;
+            case WindowOpenDisposition.NEW_POPUP: // fall through
+            case WindowOpenDisposition.NEW_BACKGROUND_TAB:
+                tabLaunchType = TabLaunchType.FROM_LONGPRESS_BACKGROUND;
+                break;
+            case WindowOpenDisposition.OFF_THE_RECORD:
+                assert incognito;
+                incognito = true;
+                break;
+            default:
+                assert false;
+        }
+
+        // If shouldIgnoreNewTab returns true, the intent is handled by another
+        // activity. As a result, don't launch a new tab to open the URL.
+        InterceptNavigationDelegateImpl delegate = parent.getInterceptNavigationDelegate();
+        if (delegate != null && delegate.shouldIgnoreNewTab(url, incognito)) return;
+
+        LoadUrlParams loadUrlParams = new LoadUrlParams(url);
+        loadUrlParams.setInitiatorOrigin(initiatorOrigin);
+        loadUrlParams.setVerbatimHeaders(extraHeaders);
+        loadUrlParams.setPostData(postData);
+        loadUrlParams.setIsRendererInitiated(isRendererInitiated);
+        getTabCreator(incognito).createNewTab(
+                loadUrlParams, tabLaunchType, persistParentage ? parent : null);
+    }
+
+    @Override
     public int getCount() {
         return mTabs.size();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
index 7ea3ee2..9e7153c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
@@ -12,6 +12,7 @@
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.common.ResourceRequestBody;
 
 /**
  * Bridges between the C++ and Java {@link TabModel} interfaces.
@@ -123,6 +124,11 @@
     protected abstract boolean createTabWithWebContents(Tab parent, boolean incognito,
             WebContents webContents, int parentId);
 
+    @CalledByNative
+    protected abstract void openNewTab(Tab parent, String url, String initiatorOrigin,
+            String extraHeaders, ResourceRequestBody postData, int disposition,
+            boolean persistParentage, boolean isRendererInitiated);
+
     /**
      * Creates a Tab with the given WebContents for DevTools.
      * @param url URL to show.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java
index 178cac9..ecd9c43 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java
@@ -22,6 +22,7 @@
 import org.chromium.chrome.browser.tabmodel.TabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabSelectionType;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.common.ResourceRequestBody;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -274,6 +275,11 @@
     }
 
     @Override
+    public void openNewTab(Tab tab, String url, String initiatorOrigin, String extraHeaders,
+            ResourceRequestBody postData, int disposition, boolean hasParent,
+            boolean isRendererInitiated) {}
+
+    @Override
     protected boolean isSessionRestoreInProgress() {
         return mCurrentState < STATE_FULLY_LOADED;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivateWebApkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivateWebApkActivity.java
new file mode 100644
index 0000000..cda83eb
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ActivateWebApkActivity.java
@@ -0,0 +1,17 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.webapps;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/** Do-nothing activity that is launched to bring a WebAPK to the foreground. */
+public class ActivateWebApkActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        finish();
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java
index 8c45ade..7956fd6e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.webapps;
 
 import android.content.Intent;
+import android.os.Build;
 
 import org.chromium.base.ContextUtils;
 import org.chromium.chrome.browser.ShortcutHelper;
@@ -28,6 +29,10 @@
     private static class WebappWebContentsDelegateAndroid extends TabWebContentsDelegateAndroid {
         private final WebappActivity mActivity;
 
+        /** Action for do-nothing activity for activating WebAPK. */
+        private static final String ACTION_ACTIVATE_WEBAPK =
+                "org.chromium.chrome.browser.webapps.ActivateWebApkActivity.ACTIVATE";
+
         public WebappWebContentsDelegateAndroid(WebappActivity activity, Tab tab) {
             super(tab);
             mActivity = activity;
@@ -43,9 +48,20 @@
 
             WebappInfo webappInfo = mActivity.getWebappInfo();
             if (webappInfo.isForWebApk()) {
-                Intent intent = WebApkNavigationClient.createLaunchWebApkIntent(
-                        webappInfo.webApkPackageName(), startUrl, false /* forceNavigation */);
-                IntentUtils.safeStartActivity(ContextUtils.getApplicationContext(), intent);
+                Intent activateIntent = null;
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+                    activateIntent = new Intent(ACTION_ACTIVATE_WEBAPK);
+                    activateIntent.setPackage(
+                            ContextUtils.getApplicationContext().getPackageName());
+                } else {
+                    // For WebAPKs with new-style splash screen we cannot activate the WebAPK by
+                    // sending an intent because that would relaunch the WebAPK.
+                    assert !webappInfo.isSplashProvidedByWebApk();
+
+                    activateIntent = WebApkNavigationClient.createLaunchWebApkIntent(
+                            webappInfo.webApkPackageName(), startUrl, false /* forceNavigation */);
+                }
+                IntentUtils.safeStartActivity(mActivity, activateIntent);
                 return;
             }
 
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index af48943..38b867f0 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1671,6 +1671,7 @@
   "java/src/org/chromium/chrome/browser/util/ViewUtils.java",
   "java/src/org/chromium/chrome/browser/vr/ArDelegate.java",
   "java/src/org/chromium/chrome/browser/vr/ArDelegateProvider.java",
+  "java/src/org/chromium/chrome/browser/webapps/ActivateWebApkActivity.java",
   "java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java",
   "java/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialog.java",
   "java/src/org/chromium/chrome/browser/webapps/AddToHomescreenManager.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
index 295ae4f..cd1c766 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
@@ -115,7 +115,7 @@
     private void startWebApkActivity(final String startUrl) throws InterruptedException {
         Intent intent =
                 new Intent(InstrumentationRegistry.getTargetContext(), WebApkActivity.class);
-        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, "org.chromium.webapk");
+        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, "org.chromium.webapk.test");
         intent.putExtra(ShortcutHelper.EXTRA_URL, startUrl);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
index 0d5b772..e1ee2cc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
@@ -16,16 +16,19 @@
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.CommandLine;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.DeferredStartupHandler;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
+import org.chromium.chrome.browser.tab.TabWebContentsDelegateAndroid;
 import org.chromium.chrome.browser.test.MockCertVerifierRuleAndroid;
 import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.chrome.test.ChromeActivityTestRule;
@@ -66,10 +69,11 @@
     public void startWebApkActivity(String webApkPackageName, final String startUrl)
             throws InterruptedException {
         Intent intent =
-                new Intent(InstrumentationRegistry.getTargetContext(), WebApkActivity.class);
+                new Intent(InstrumentationRegistry.getTargetContext(), WebApkActivity0.class);
         intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, webApkPackageName);
         intent.putExtra(ShortcutHelper.EXTRA_URL, startUrl);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK | ApiCompatibilityUtils.getActivityNewDocumentFlag());
 
         WebApkActivity webApkActivity =
                 (WebApkActivity) InstrumentationRegistry.getInstrumentation().startActivitySync(
@@ -118,6 +122,7 @@
         Uri mapToUri = Uri.parse(mTestServerRule.getServer().getURL("/"));
         CommandLine.getInstance().appendSwitchWithValue(
                 ContentSwitches.HOST_RESOLVER_RULES, "MAP * " + mapToUri.getAuthority());
+        WebApkValidator.disableValidationForTesting();
     }
 
     /**
@@ -134,9 +139,8 @@
         intent.setPackage(InstrumentationRegistry.getTargetContext().getPackageName());
         intent.setAction(WebappLauncherActivity.ACTION_START_WEBAPP);
         intent.putExtra(WebApkConstants.EXTRA_URL, pwaRocksUrl)
-                .putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, "org.chromium.webapk");
+                .putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, "org.chromium.webapk.test");
 
-        WebApkValidator.disableValidationForTesting();
         mActivityTestRule.startActivityCompletely(intent);
 
         WebApkActivity lastActivity = (WebApkActivity) mActivityTestRule.getActivity();
@@ -151,7 +155,7 @@
     @LargeTest
     @Feature({"WebApk"})
     public void testLaunchAndNavigateOffOrigin() throws Exception {
-        startWebApkActivity("org.chromium.webapk", getUrlForHost("pwa.rocks"));
+        startWebApkActivity("org.chromium.webapk.test", getUrlForHost("pwa.rocks"));
         waitUntilSplashscreenHides();
         WebApkActivity webApkActivity = (WebApkActivity) mActivityTestRule.getActivity();
         WebappActivityTestRule.assertToolbarShowState(webApkActivity, false);
@@ -174,7 +178,7 @@
     @Feature({"WebApk"})
     public void testLaunchAndOpenNewWindowInOrigin() throws Exception {
         String pwaRocksUrl = getUrlForHost("pwa.rocks");
-        startWebApkActivity("org.chromium.webapk", pwaRocksUrl);
+        startWebApkActivity("org.chromium.webapk.test", pwaRocksUrl);
         waitUntilSplashscreenHides();
 
         WebappActivityTestRule.jsWindowOpen(mActivityTestRule.getActivity(), pwaRocksUrl);
@@ -198,7 +202,7 @@
     public void testLaunchAndNavigationInNewWindowOffandInOrigin() throws Exception {
         String pwaRocksUrl = getUrlForHost("pwa.rocks");
         String googleUrl = getUrlForHost("www.google.com");
-        startWebApkActivity("org.chromium.webapk", pwaRocksUrl);
+        startWebApkActivity("org.chromium.webapk.test", pwaRocksUrl);
         waitUntilSplashscreenHides();
 
         WebappActivityTestRule.jsWindowOpen(mActivityTestRule.getActivity(), googleUrl);
@@ -223,7 +227,7 @@
     @Feature({"WebApk"})
     public void testLaunchIntervalHistogramNotRecordedOnFirstLaunch() throws Exception {
         final String histogramName = "WebApk.LaunchInterval";
-        final String packageName = "org.chromium.webapk";
+        final String packageName = "org.chromium.webapk.test";
         startWebApkActivity(packageName, getUrlForHost("pwa.rocks"));
 
         CriteriaHelper.pollUiThread(new Criteria("Deferred startup never completed") {
@@ -246,7 +250,7 @@
         mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess();
 
         final String histogramName = "WebApk.LaunchInterval2";
-        final String packageName = "org.chromium.webapk";
+        final String packageName = "org.chromium.webapk.test";
 
         WebappDataStorage storage =
                 registerWithStorage(WebApkConstants.WEBAPK_ID_PREFIX + packageName);
@@ -265,4 +269,32 @@
 
         Assert.assertEquals(1, RecordHistogram.getHistogramTotalCountForTesting(histogramName));
     }
+
+    /**
+     * Test that {@link TabWebContentsDelegateAndroid#activateContents} brings a WebAPK to the
+     * foreground.
+     */
+    @LargeTest
+    @Test
+    public void testActivateWebApk() throws Exception {
+        // Launch WebAPK.
+        startWebApkActivity("org.chromium.webapk.test", getUrlForHost("pwa.rocks"));
+        waitUntilSplashscreenHides();
+
+        // Move WebAPK to the background by launching Chrome.
+        Intent intent =
+                new Intent(InstrumentationRegistry.getTargetContext(), ChromeTabbedActivity.class);
+        intent.setFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK | ApiCompatibilityUtils.getActivityNewDocumentFlag());
+        InstrumentationRegistry.getTargetContext().startActivity(intent);
+        ChromeActivityTestRule.waitFor(ChromeTabbedActivity.class);
+
+        WebApkActivity webApkActivity = (WebApkActivity) mActivityTestRule.getActivity();
+        TabWebContentsDelegateAndroid tabDelegate =
+                webApkActivity.getActivityTab().getTabWebContentsDelegateAndroid();
+        tabDelegate.activateContents();
+
+        // WebApkActivity should have been brought back to the foreground.
+        ChromeActivityTestRule.waitFor(WebApkActivity.class);
+    }
 }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index ad7eb14..38b2066 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-74.0.3725.0_rc-r1-merged.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-74.0.3729.5_rc-r1-merged.afdo.bz2
\ No newline at end of file
diff --git a/chrome/android/webapk/shell_apk/BUILD.gn b/chrome/android/webapk/shell_apk/BUILD.gn
index d7ef39e..3bb2c818 100644
--- a/chrome/android/webapk/shell_apk/BUILD.gn
+++ b/chrome/android/webapk/shell_apk/BUILD.gn
@@ -266,6 +266,14 @@
   apk_package_name = "org.chromium.webapk.new.splash"
 }
 
+# Used by javatests
+webapk_tmpl("javatests_webapk") {
+  config_file = "manifest/bound_manifest_config.json"
+  delta_config_file = "manifest/javatest_manifest_config_delta.json"
+  apk_name = "JavatestsWebApk"
+  apk_package_name = "org.chromium.webapk.test"
+}
+
 # Used by webapk_shell_apk_h2o_junit_tests
 webapk_tmpl("h2o_j_unit_webapk") {
   use_new_splash = true
diff --git a/chrome/android/webapk/shell_apk/current_version/current_version.gni b/chrome/android/webapk/shell_apk/current_version/current_version.gni
index e820661..e9560178 100644
--- a/chrome/android/webapk/shell_apk/current_version/current_version.gni
+++ b/chrome/android/webapk/shell_apk/current_version/current_version.gni
@@ -12,4 +12,4 @@
 # //chrome/android/webapk/shell_apk:webapk is changed. This includes
 # Java files, Android resource files and AndroidManifest.xml. Does not affect
 # Chrome.apk
-current_shell_apk_version = 82
+current_shell_apk_version = 83
diff --git a/chrome/android/webapk/shell_apk/manifest/javatest_manifest_config_delta.json b/chrome/android/webapk/shell_apk/manifest/javatest_manifest_config_delta.json
new file mode 100644
index 0000000..a85c4eb0
--- /dev/null
+++ b/chrome/android/webapk/shell_apk/manifest/javatest_manifest_config_delta.json
@@ -0,0 +1,5 @@
+{
+  "bound_webapk": {
+    "runtime_host": "org.chromium.chrome.tests"
+  }
+}
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java
index 8d4a9dfb..3e8e3010 100644
--- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java
+++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java
@@ -26,15 +26,17 @@
 
     private static final int MINIMUM_REQUIRED_INTENT_HELPER_VERSION = 2;
 
+    private static final String VERSION_NAME_DEVELOPER_BUILD = "Developer Build";
+
     private static final String TAG = "cr_HostBrowserUtils";
 
     /**
      * The package names of the browsers that support WebAPKs. The most preferred one comes first.
      */
-    private static List<String> sBrowsersSupportingWebApk =
-            new ArrayList<String>(Arrays.asList("com.google.android.apps.chrome",
-                    "com.android.chrome", "com.chrome.beta", "com.chrome.dev", "com.chrome.canary",
-                    "org.chromium.chrome", "org.chromium.arc.intent_helper"));
+    private static List<String> sBrowsersSupportingWebApk = new ArrayList<String>(
+            Arrays.asList("com.google.android.apps.chrome", "com.android.chrome", "com.chrome.beta",
+                    "com.chrome.dev", "com.chrome.canary", "org.chromium.chrome",
+                    "org.chromium.chrome.tests", "org.chromium.arc.intent_helper"));
 
     /** Caches the package name of the host browser. */
     private static String sHostPackage;
@@ -117,6 +119,11 @@
             return -1;
         }
         String versionName = info.versionName;
+
+        if (TextUtils.equals(versionName, VERSION_NAME_DEVELOPER_BUILD)) {
+            return Integer.MAX_VALUE;
+        }
+
         int dotIndex = versionName.indexOf(".");
         if (dotIndex < 0) {
             return -1;
diff --git a/chrome/app/file_manager_strings.grdp b/chrome/app/file_manager_strings.grdp
index 29ad45aa..dd40795f 100644
--- a/chrome/app/file_manager_strings.grdp
+++ b/chrome/app/file_manager_strings.grdp
@@ -44,8 +44,8 @@
   <message name="IDS_FILE_BROWSER_DRIVE_MY_DRIVE_LABEL" desc="A label for the 'My Drive' collection of Google Drive.">
     My Drive
   </message>
-  <message name="IDS_FILE_BROWSER_DRIVE_TEAM_DRIVES_LABEL" desc="A label for the 'Team Drives' collection of Google Drive.">
-    Team Drives
+  <message name="IDS_FILE_BROWSER_DRIVE_SHARED_DRIVES_LABEL" desc="A label for the 'Team Drives' collection of Google Drive.">
+    Shared drives
   </message>
   <message name="IDS_FILE_BROWSER_DRIVE_COMPUTERS_LABEL" desc="A label for the 'Computers' collection of Google Drive.">
     Computers
diff --git a/chrome/app/file_manager_strings_grdp/IDS_FILE_BROWSER_DRIVE_SHARED_DRIVES_LABEL.png.sha1 b/chrome/app/file_manager_strings_grdp/IDS_FILE_BROWSER_DRIVE_SHARED_DRIVES_LABEL.png.sha1
new file mode 100644
index 0000000..6dba61d
--- /dev/null
+++ b/chrome/app/file_manager_strings_grdp/IDS_FILE_BROWSER_DRIVE_SHARED_DRIVES_LABEL.png.sha1
@@ -0,0 +1 @@
+7a98f1c534039d635e3d1876138f98b7b7d5d0f6
\ No newline at end of file
diff --git a/chrome/browser/accessibility/image_annotation_browsertest.cc b/chrome/browser/accessibility/image_annotation_browsertest.cc
new file mode 100644
index 0000000..25a23e5
--- /dev/null
+++ b/chrome/browser/accessibility/image_annotation_browsertest.cc
@@ -0,0 +1,168 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/feature_list.h"
+#include "base/logging.h"
+#include "base/strings/string_split.h"
+#include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
+#include "services/image_annotation/public/cpp/image_processor.h"
+#include "services/image_annotation/public/mojom/constants.mojom.h"
+#include "services/image_annotation/public/mojom/image_annotation.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_binding.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+constexpr base::FilePath::CharType kDocRoot[] =
+    FILE_PATH_LITERAL("chrome/test/data/accessibility");
+
+namespace {
+
+// A fake implementation of the Annotator mojo interface that
+// returns predictable results based on the filename of the image
+// it's asked to annotate. Enables us to test the rest of the
+// system without using the real annotator that queries a back-end
+// API.
+class FakeAnnotator : public image_annotation::mojom::Annotator {
+ public:
+  FakeAnnotator() = default;
+  ~FakeAnnotator() override = default;
+
+  void BindRequest(image_annotation::mojom::AnnotatorRequest request) {
+    bindings_.AddBinding(this, std::move(request));
+  }
+
+  void AnnotateImage(const std::string& image_id,
+                     image_annotation::mojom::ImageProcessorPtr image_processor,
+                     AnnotateImageCallback callback) override {
+    // Use the filename to create an annotation string.
+    std::string image_filename = GURL(image_id).ExtractFileName();
+    image_annotation::mojom::AnnotationPtr ocr_annotation =
+        image_annotation::mojom::Annotation::New(
+            image_annotation::mojom::AnnotationType::kOcr, 1.0,
+            image_filename + " Annotation");
+
+    // Return that result as an annotation.
+    std::vector<image_annotation::mojom::AnnotationPtr> annotations;
+    annotations.push_back(std::move(ocr_annotation));
+
+    image_annotation::mojom::AnnotateImageResultPtr result =
+        image_annotation::mojom::AnnotateImageResult::NewAnnotations(
+            std::move(annotations));
+    std::move(callback).Run(std::move(result));
+  }
+
+ private:
+  mojo::BindingSet<image_annotation::mojom::Annotator> bindings_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeAnnotator);
+};
+
+// The fake ImageAnnotationService, which handles mojo calls from the renderer
+// process and passes them to FakeAnnotator.
+class FakeImageAnnotationService : public service_manager::Service {
+ public:
+  explicit FakeImageAnnotationService(
+      service_manager::mojom::ServiceRequest request)
+      : service_binding_(this, std::move(request)) {}
+
+  ~FakeImageAnnotationService() override = default;
+
+ private:
+  // service_manager::Service:
+  void OnBindInterface(const service_manager::BindSourceInfo& source_info,
+                       const std::string& interface_name,
+                       mojo::ScopedMessagePipeHandle interface_pipe) override {
+    registry_.BindInterface(interface_name, std::move(interface_pipe));
+  }
+
+  void OnStart() override {
+    registry_.AddInterface<image_annotation::mojom::Annotator>(
+        base::BindRepeating(&FakeAnnotator::BindRequest,
+                            base::Unretained(&annotator_)));
+  }
+
+  service_manager::BinderRegistry registry_;
+  service_manager::ServiceBinding service_binding_;
+
+  FakeAnnotator annotator_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeImageAnnotationService);
+};
+
+void HandleImageAnnotatorServiceRequest(
+    service_manager::mojom::ServiceRequest request) {
+  new FakeImageAnnotationService(std::move(request));
+}
+
+}  // namespace
+
+class ImageAnnotationBrowserTest : public InProcessBrowserTest {
+ public:
+  ImageAnnotationBrowserTest()
+      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
+    https_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
+  }
+
+ protected:
+  void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kExperimentalAccessibilityLabels);
+    InProcessBrowserTest::SetUp();
+  }
+
+  void SetUpOnMainThread() override {
+    InProcessBrowserTest::SetUpOnMainThread();
+
+    ASSERT_TRUE(https_server_.Start());
+
+    content::WebContents* web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+
+    content::ServiceManagerConnection* service_manager_connection =
+        content::BrowserContext::GetServiceManagerConnectionFor(
+            web_contents->GetBrowserContext());
+
+    service_manager_connection->AddServiceRequestHandler(
+        image_annotation::mojom::kServiceName,
+        base::BindRepeating(&HandleImageAnnotatorServiceRequest));
+
+    ui::AXMode mode = ui::kAXModeComplete;
+    mode.set_mode(ui::AXMode::kLabelImages, true);
+    web_contents->SetAccessibilityMode(mode);
+  }
+
+ protected:
+  net::EmbeddedTestServer https_server_;
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(ImageAnnotationBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ImageAnnotationBrowserTest,
+                       AnnotateImageInAccessibilityTree) {
+  ui_test_utils::NavigateToURL(browser(),
+                               https_server_.GetURL("/image_annotation.html"));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  content::WaitForAccessibilityTreeToContainNodeWithName(
+      web_contents, "Appears to say: red.png Annotation");
+}
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc
index a82a0fa..4bb77b1a 100644
--- a/chrome/browser/android/tab_android.cc
+++ b/chrome/browser/android/tab_android.cc
@@ -72,7 +72,6 @@
 #include "ui/android/view_android.h"
 #include "ui/android/window_android.h"
 #include "ui/base/resource/resource_bundle.h"
-#include "ui/base/window_open_disposition.h"
 
 using base::android::AttachCurrentThread;
 using base::android::ConvertUTF8ToJavaString;
@@ -215,45 +214,6 @@
   session_tab_helper->SetWindowID(session_window_id_);
 }
 
-void TabAndroid::HandlePopupNavigation(NavigateParams* params) {
-  DCHECK_EQ(params->source_contents, web_contents());
-  DCHECK(!params->contents_to_insert);
-  DCHECK(!params->switch_to_singleton_tab);
-
-  WindowOpenDisposition disposition = params->disposition;
-  const GURL& url = params->url;
-
-  bool supported = disposition == WindowOpenDisposition::NEW_POPUP ||
-                   disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB ||
-                   disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB ||
-                   disposition == WindowOpenDisposition::NEW_WINDOW ||
-                   disposition == WindowOpenDisposition::OFF_THE_RECORD;
-  if (!supported) {
-    NOTIMPLEMENTED();
-    return;
-  }
-
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> jobj = weak_java_tab_.get(env);
-  ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(env, url.spec()));
-  ScopedJavaLocalRef<jstring> jheaders(
-      ConvertUTF8ToJavaString(env, params->extra_headers));
-  ScopedJavaLocalRef<jstring> jinitiator_origin;
-  if (params->initiator_origin) {
-    jinitiator_origin =
-        ConvertUTF8ToJavaString(env, params->initiator_origin->Serialize());
-  }
-  ScopedJavaLocalRef<jobject> jpost_data;
-  if (params->uses_post && params->post_data) {
-    jpost_data =
-        content::ConvertResourceRequestBodyToJavaObject(env, params->post_data);
-  }
-  Java_Tab_openNewTab(env, jobj, jurl, jinitiator_origin, jheaders, jpost_data,
-                      static_cast<int>(disposition),
-                      params->created_with_opener,
-                      params->is_renderer_initiated);
-}
-
 bool TabAndroid::HasPrerenderedUrl(GURL gurl) {
   prerender::PrerenderManager* prerender_manager = GetPrerenderManager();
   if (!prerender_manager)
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
index 0b4b450..896cd3073 100644
--- a/chrome/browser/android/tab_android.h
+++ b/chrome/browser/android/tab_android.h
@@ -28,8 +28,6 @@
 class Layer;
 }
 
-struct NavigateParams;
-
 namespace android {
 class TabWebContentsDelegateAndroid;
 class TabContentManager;
@@ -107,8 +105,6 @@
   void SetWindowSessionID(SessionID window_id);
   void SetSyncId(int sync_id);
 
-  void HandlePopupNavigation(NavigateParams* params);
-
   bool HasPrerenderedUrl(GURL gurl);
 
   // Returns true if this tab is currently presented in the context of custom
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc
index d305c2e3..fa44872 100644
--- a/chrome/browser/android/tab_web_contents_delegate_android.cc
+++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -33,6 +33,7 @@
 #include "chrome/browser/ssl/security_state_tab_helper.h"
 #include "chrome/browser/ui/android/bluetooth_chooser_android.h"
 #include "chrome/browser/ui/android/infobars/framebust_block_infobar.h"
+#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
 #include "chrome/browser/ui/blocked_content/popup_blocker.h"
 #include "chrome/browser/ui/blocked_content/popup_tracker.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
@@ -387,9 +388,14 @@
                                  params.url, &prerender_params)) {
       return prerender_params.replaced_contents;
     }
+
+    // Ask the parent to handle in-place opening.
+    return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
   }
 
-  return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
+  nav_params.created_with_opener = true;
+  TabModelList::HandlePopupNavigation(&nav_params);
+  return nullptr;
 }
 
 bool TabWebContentsDelegateAndroid::ShouldResumeRequestsForCreatedWindow() {
diff --git a/chrome/browser/banners/app_banner_infobar_delegate_desktop.cc b/chrome/browser/banners/app_banner_infobar_delegate_desktop.cc
index acb91fb..1e88eda 100644
--- a/chrome/browser/banners/app_banner_infobar_delegate_desktop.cc
+++ b/chrome/browser/banners/app_banner_infobar_delegate_desktop.cc
@@ -91,7 +91,7 @@
   has_user_interaction_ = true;
 
   if (weak_manager_)
-    weak_manager_->CreateBookmarkApp(install_source_);
+    weak_manager_->CreateWebApp(install_source_);
 
   return true;
 }
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h
index 6933ca6..ec0d45a 100644
--- a/chrome/browser/banners/app_banner_manager.h
+++ b/chrome/browser/banners/app_banner_manager.h
@@ -18,6 +18,7 @@
 #include "chrome/browser/installable/installable_ambient_badge_infobar_delegate.h"
 #include "chrome/browser/installable/installable_logging.h"
 #include "chrome/browser/installable/installable_manager.h"
+#include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "third_party/blink/public/common/manifest/web_display_mode.h"
@@ -26,17 +27,16 @@
 enum class WebappInstallSource;
 class InstallableManager;
 class SkBitmap;
-struct WebApplicationInfo;
 
 namespace content {
 class RenderFrameHost;
 class WebContents;
 }  // namespace content
 
-// This forward declaration exists solely for the DidFinishCreatingBookmarkApp
+// This forward declaration exists solely for the DidFinishCreatingWebApp
 // callback, implemented and called on desktop platforms only.
-namespace extensions {
-class Extension;
+namespace web_app {
+enum class InstallResultCode;
 }
 
 namespace banners {
@@ -175,16 +175,15 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
-  // Overridden on desktop platforms. Called to initiate the bookmark app
+  // Overridden on desktop platforms. Called to initiate the web app
   // install. Not used on Android.
-  virtual void CreateBookmarkApp(WebappInstallSource install_source) {}
+  virtual void CreateWebApp(WebappInstallSource install_source) {}
 
   // Overridden and passed through base::Bind on desktop platforms. Called when
-  // the bookmark app install initiated by a banner has completed. Not used on
+  // the web app install initiated by a banner has completed. Not used on
   // Android.
-  virtual void DidFinishCreatingBookmarkApp(
-      const extensions::Extension* extension,
-      const WebApplicationInfo& web_app_info) {}
+  virtual void DidFinishCreatingWebApp(const web_app::AppId& app_id,
+                                       web_app::InstallResultCode code) {}
 
   // Overridden and passed through base::Bind on Android. Called when the
   // download of a native app's icon is complete, as native banners use an icon
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc
index 39e044a8..821d627 100644
--- a/chrome/browser/banners/app_banner_manager_desktop.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -11,8 +11,9 @@
 #include "chrome/browser/banners/app_banner_infobar_delegate_desktop.h"
 #include "chrome/browser/banners/app_banner_metrics.h"
 #include "chrome/browser/banners/app_banner_settings_helper.h"
-#include "chrome/browser/extensions/bookmark_app_helper.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
+#include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/extensions/bookmark_app_util.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/web_application_info.h"
@@ -47,53 +48,45 @@
 
 AppBannerManagerDesktop::~AppBannerManagerDesktop() { }
 
-void AppBannerManagerDesktop::CreateBookmarkApp(
-    WebappInstallSource install_source) {
+void AppBannerManagerDesktop::CreateWebApp(WebappInstallSource install_source) {
   content::WebContents* contents = web_contents();
   DCHECK(contents);
 
-  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
-  WebApplicationInfo web_app_info;
-
-  bookmark_app_helper_.reset(new extensions::BookmarkAppHelper(
-      profile, web_app_info, contents, install_source));
-
-  bookmark_app_helper_->Create(base::BindRepeating(
-      &AppBannerManager::DidFinishCreatingBookmarkApp, GetWeakPtr()));
+  // TODO(loyso): Take appropriate action if WebApps disabled for profile.
+  web_app::CreateWebAppFromBanner(
+      contents, install_source,
+      base::BindOnce(&AppBannerManager::DidFinishCreatingWebApp, GetWeakPtr()));
 }
 
-void AppBannerManagerDesktop::DidFinishCreatingBookmarkApp(
-    const extensions::Extension* extension,
-    const WebApplicationInfo& web_app_info) {
+void AppBannerManagerDesktop::DidFinishCreatingWebApp(
+    const web_app::AppId& app_id,
+    web_app::InstallResultCode code) {
   content::WebContents* contents = web_contents();
   if (!contents)
     return;
 
-  if (extension) {
-    SendBannerAccepted();
-    AppBannerSettingsHelper::RecordBannerInstallEvent(
-        contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB);
-
-    // OnInstall must be called last since it resets Mojo bindings.
-    OnInstall(false /* is_native app */, blink::kWebDisplayModeStandalone);
-    return;
-  }
-
-  // |extension| is null, so we assume that the confirmation dialog was
-  // cancelled. Alternatively, the extension installation may have failed, but
+  // BookmarkAppInstallManager returns kFailedUnknownReason for any error.
+  // We can't distinguish kUserInstallDeclined case so far.
+  // If kFailedUnknownReason, we assume that the confirmation dialog was
+  // cancelled. Alternatively, the web app installation may have failed, but
   // we can't tell the difference here.
   // TODO(crbug.com/789381): plumb through enough information to be able to
   // distinguish between extension install failures and user-cancellations of
   // the app install dialog.
-  SendBannerDismissed();
-  TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED);
-  AppBannerSettingsHelper::RecordBannerDismissEvent(
-      contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB);
-}
+  if (code != web_app::InstallResultCode::kSuccess) {
+    SendBannerDismissed();
+    TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED);
+    AppBannerSettingsHelper::RecordBannerDismissEvent(
+        contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB);
+    return;
+  }
 
-void AppBannerManagerDesktop::ResetCurrentPageData() {
-  bookmark_app_helper_.reset();
-  AppBannerManager::ResetCurrentPageData();
+  SendBannerAccepted();
+  AppBannerSettingsHelper::RecordBannerInstallEvent(
+      contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB);
+
+  // OnInstall must be called last since it resets Mojo bindings.
+  OnInstall(false /* is_native app */, blink::kWebDisplayModeStandalone);
 }
 
 bool AppBannerManagerDesktop::IsWebAppConsideredInstalled(
@@ -111,7 +104,7 @@
     TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_CREATED);
     TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
     ReportStatus(SHOWING_APP_INSTALLATION_DIALOG);
-    CreateBookmarkApp(install_source);
+    CreateWebApp(install_source);
     return;
   }
 
diff --git a/chrome/browser/banners/app_banner_manager_desktop.h b/chrome/browser/banners/app_banner_manager_desktop.h
index aadeac0..784fe0f 100644
--- a/chrome/browser/banners/app_banner_manager_desktop.h
+++ b/chrome/browser/banners/app_banner_manager_desktop.h
@@ -11,10 +11,6 @@
 #include "chrome/browser/banners/app_banner_manager.h"
 #include "content/public/browser/web_contents_user_data.h"
 
-namespace extensions {
-class BookmarkAppHelper;
-}
-
 namespace banners {
 
 // Manages web app banners for desktop platforms.
@@ -36,11 +32,9 @@
   explicit AppBannerManagerDesktop(content::WebContents* web_contents);
 
   // AppBannerManager overrides.
-  void CreateBookmarkApp(WebappInstallSource install_source) override;
-  void DidFinishCreatingBookmarkApp(
-      const extensions::Extension* extension,
-      const WebApplicationInfo& web_app_info) override;
-  void ResetCurrentPageData() override;
+  void CreateWebApp(WebappInstallSource install_source) override;
+  void DidFinishCreatingWebApp(const web_app::AppId& app_id,
+                               web_app::InstallResultCode code) override;
 
  private:
   friend class content::WebContentsUserData<AppBannerManagerDesktop>;
@@ -62,8 +56,6 @@
                          double score,
                          SiteEngagementService::EngagementType type) override;
 
-  std::unique_ptr<extensions::BookmarkAppHelper> bookmark_app_helper_;
-
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 
   DISALLOW_COPY_AND_ASSIGN(AppBannerManagerDesktop);
diff --git a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
index dbf95d3..d68d5a6c 100644
--- a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/run_loop.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/bind_test_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/banners/app_banner_manager_browsertest_base.h"
 #include "chrome/browser/banners/app_banner_manager_desktop.h"
@@ -18,6 +19,8 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
+#include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
@@ -55,11 +58,9 @@
     }
   }
 
-  void DidFinishCreatingBookmarkApp(
-      const extensions::Extension* extension,
-      const WebApplicationInfo& web_app_info) override {
-    AppBannerManagerDesktop::DidFinishCreatingBookmarkApp(extension,
-                                                          web_app_info);
+  void DidFinishCreatingWebApp(const web_app::AppId& app_id,
+                               web_app::InstallResultCode code) override {
+    AppBannerManagerDesktop::DidFinishCreatingWebApp(app_id, code);
     OnFinished();
   }
 
@@ -162,9 +163,24 @@
     // Trigger the installation prompt and wait for installation to occur.
     base::RunLoop run_loop;
     manager->PrepareDone(run_loop.QuitClosure());
+
+    const GURL url = GetBannerURL();
+    bool callback_called = false;
+
+    web_app::SetInstalledCallbackForTesting(
+        base::BindLambdaForTesting([&](const web_app::AppId& installed_app_id,
+                                       web_app::InstallResultCode code) {
+          EXPECT_EQ(web_app::InstallResultCode::kSuccess, code);
+          EXPECT_EQ(installed_app_id, web_app::GenerateAppIdFromURL(url));
+          callback_called = true;
+        }));
+
     ExecuteScript(browser(), "callStashedPrompt();", true /* with_gesture */);
+
     run_loop.Run();
+
     EXPECT_EQ(State::COMPLETE, manager->state());
+    EXPECT_TRUE(callback_called);
   }
 
   // Ensure that the appinstalled event fires.
@@ -173,3 +189,45 @@
   content::TitleWatcher watcher(web_contents, title);
   EXPECT_EQ(title, watcher.WaitAndGetTitle());
 }
+
+IN_PROC_BROWSER_TEST_F(AppBannerManagerDesktopBrowserTest, DestroyWebContents) {
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  auto* manager =
+      FakeAppBannerManagerDesktop::CreateForWebContents(web_contents);
+
+  {
+    base::RunLoop run_loop;
+    manager->PrepareDone(run_loop.QuitClosure());
+
+    ui_test_utils::NavigateToURL(browser(),
+                                 GetBannerURLWithAction("stash_event"));
+    run_loop.Run();
+    EXPECT_EQ(State::PENDING_PROMPT, manager->state());
+  }
+
+  {
+    // Trigger the installation and wait for termination to occur.
+    base::RunLoop run_loop;
+    bool callback_called = false;
+
+    web_app::SetInstalledCallbackForTesting(
+        base::BindLambdaForTesting([&](const web_app::AppId& installed_app_id,
+                                       web_app::InstallResultCode code) {
+          EXPECT_EQ(web_app::InstallResultCode::kWebContentsDestroyed, code);
+          callback_called = true;
+          run_loop.Quit();
+        }));
+
+    ExecuteScript(browser(), "callStashedPrompt();", true /* with_gesture */);
+
+    // Closing WebContents destroys WebContents and AppBannerManager.
+    browser()->tab_strip_model()->CloseWebContentsAt(
+        browser()->tab_strip_model()->active_index(), 0);
+    manager = nullptr;
+    web_contents = nullptr;
+
+    run_loop.Run();
+    EXPECT_TRUE(callback_called);
+  }
+}
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index fba8f91..54beb10 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -225,7 +225,7 @@
 
 // Returned by ChromeBrowsingDataRemoverDelegate::GetOriginTypeMatcher().
 bool DoesOriginMatchEmbedderMask(int origin_type_mask,
-                                 const GURL& origin,
+                                 const url::Origin& origin,
                                  storage::SpecialStoragePolicy* policy) {
   DCHECK_EQ(
       0,
@@ -236,7 +236,7 @@
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   // Packaged apps and extensions match iff EXTENSION.
-  if ((origin.GetOrigin().scheme() == extensions::kExtensionScheme) &&
+  if ((origin.scheme() == extensions::kExtensionScheme) &&
       (origin_type_mask &
        ChromeBrowsingDataRemoverDelegate::ORIGIN_TYPE_EXTENSION)) {
     return true;
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index 34c0592..d885b87 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1263,7 +1263,8 @@
   bool Match(const GURL& origin,
              int mask,
              storage::SpecialStoragePolicy* policy) {
-    return remover_->DoesOriginMatchMask(mask, origin, policy);
+    return remover_->DoesOriginMatchMask(mask, url::Origin::Create(origin),
+                                         policy);
   }
 
  private:
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 17bc2cf..0f68a47 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -425,6 +425,7 @@
 #include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h"
 #include "chrome/browser/chrome_browser_main_android.h"
 #include "chrome/browser/offline_pages/android/offline_page_auto_fetcher.h"
+#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
 #include "chrome/common/descriptors_android.h"
 #include "chrome/services/media_gallery_util/public/mojom/constants.mojom.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
@@ -2982,9 +2983,7 @@
       SingleTabModeTabHelper::FromWebContents(web_contents);
   if (single_tab_mode_helper &&
       single_tab_mode_helper->block_all_new_windows()) {
-    if (TabAndroid* tab_android = TabAndroid::FromWebContents(web_contents)) {
-      tab_android->HandlePopupNavigation(&nav_params);
-    }
+    TabModelList::HandlePopupNavigation(&nav_params);
     return false;
   }
 #endif
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.cc b/chrome/browser/chromeos/arc/arc_optin_uma.cc
index 38a3a9d..1bdefd4 100644
--- a/chrome/browser/chromeos/arc/arc_optin_uma.cc
+++ b/chrome/browser/chromeos/arc/arc_optin_uma.cc
@@ -64,17 +64,11 @@
 
 void UpdateEnabledStateByUserTypeUMA() {
   const Profile* profile = ProfileManager::GetPrimaryUserProfile();
-  // Don't record UMA for the set of cases:
-  // * No primary profile is set at this moment.
-  // * Primary profile matches the built-in profile used for signing in or the
-  //   lock screen.
-  // * Primary profile matches guest session.
-  // * Primary profile is in incognito mode.
-  if (!profile || chromeos::ProfileHelper::IsSigninProfile(profile) ||
-      chromeos::ProfileHelper::IsLockScreenAppProfile(profile) ||
-      profile->IsOffTheRecord() || profile->IsGuestSession()) {
+
+  // Don't record UMA if current primary user profile should be ignored in the
+  // first place, or we're currently in guest session.
+  if (!IsRealUserProfile(profile) || profile->IsGuestSession())
     return;
-  }
 
   base::Optional<bool> enabled_state;
   if (auto* stability_metrics_manager = StabilityMetricsManager::Get())
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc
index cd34d7a..1a133357 100644
--- a/chrome/browser/chromeos/arc/arc_service_launcher.cc
+++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -34,7 +34,6 @@
 #include "chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h"
 #include "chrome/browser/chromeos/arc/pip/arc_pip_bridge.h"
 #include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h"
-#include "chrome/browser/chromeos/arc/policy/arc_policy_util.h"
 #include "chrome/browser/chromeos/arc/print/arc_print_service.h"
 #include "chrome/browser/chromeos/arc/process/arc_process_service.h"
 #include "chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.h"
@@ -114,13 +113,6 @@
   if (!IsArcAllowedForProfile(profile))
     return;
 
-  // TODO(khmel): Move this to IsArcAllowedForProfile.
-  if (policy_util::IsArcDisabledForEnterprise() &&
-      policy_util::IsAccountManaged(profile)) {
-    VLOG(2) << "Enterprise users are not supported in ARC.";
-    return;
-  }
-
   // Do not expect it in real use case, but it is used for testing.
   // Because the ArcService instances tied to the old profile is kept,
   // and ones tied to the new profile are added, which is unexpected situation.
diff --git a/chrome/browser/chromeos/arc/arc_util.cc b/chrome/browser/chromeos/arc/arc_util.cc
index 43c7d0cc..175d46e 100644
--- a/chrome/browser/chromeos/arc/arc_util.cc
+++ b/chrome/browser/chromeos/arc/arc_util.cc
@@ -215,6 +215,13 @@
     return false;
   }
 
+  if (policy_util::IsArcDisabledForEnterprise() &&
+      policy_util::IsAccountManaged(profile)) {
+    VLOG_IF(1, should_report_reason)
+        << "ARC is disabled by flag for managed users.";
+    return false;
+  }
+
   // Play Store requires an appropriate application install mechanism. Normal
   // users do this through GAIA, but Kiosk and Active Directory users use
   // different application install mechanism. ARC is not allowed otherwise
@@ -247,13 +254,16 @@
 
 }  // namespace
 
+bool IsRealUserProfile(const Profile* profile) {
+  // Return false for signin, lock screen and incognito profiles.
+  return profile && !chromeos::ProfileHelper::IsSigninProfile(profile) &&
+         !chromeos::ProfileHelper::IsLockScreenAppProfile(profile) &&
+         !profile->IsOffTheRecord();
+}
+
 bool IsArcAllowedForProfile(const Profile* profile) {
-  // Silently ignore default, lock screen and incognito profiles.
-  if (!profile || chromeos::ProfileHelper::IsSigninProfile(profile) ||
-      profile->IsOffTheRecord() ||
-      chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) {
+  if (!IsRealUserProfile(profile))
     return false;
-  }
 
   auto it = g_profile_status_check.Get().find(profile);
 
diff --git a/chrome/browser/chromeos/arc/arc_util.h b/chrome/browser/chromeos/arc/arc_util.h
index c913e34..2cf6ca4 100644
--- a/chrome/browser/chromeos/arc/arc_util.h
+++ b/chrome/browser/chromeos/arc/arc_util.h
@@ -48,6 +48,11 @@
   // "compatible" state. Be careful in the case adding a new enum value.
 };
 
+// Returns false if |profile| is not a real user profile but some internal
+// profile for service purposes, which should be ignored for ARC and metrics
+// recording. Also returns false if |profile| is null.
+bool IsRealUserProfile(const Profile* profile);
+
 // Returns true if ARC is allowed to run for the given profile.
 // Otherwise, returns false, e.g. if the Profile is not for the primary user,
 // ARC is not available on the device, it is in the flow to set up managed
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_util.h b/chrome/browser/chromeos/arc/policy/arc_policy_util.h
index fc243c9..ff30faba 100644
--- a/chrome/browser/chromeos/arc/policy/arc_policy_util.h
+++ b/chrome/browser/chromeos/arc/policy/arc_policy_util.h
@@ -42,7 +42,7 @@
 // Returns true if the account is managed. Otherwise false.
 bool IsAccountManaged(const Profile* profile);
 
-// Returns true if ARC is disabled by --enterprise-diable-arc flag.
+// Returns true if ARC is disabled by --enterprise-disable-arc flag.
 bool IsArcDisabledForEnterprise();
 
 // Returns the default ecryptfs migration action for a managed user.
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index ce6ff531..45629b28 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -582,7 +582,10 @@
         TestCase("dirContextMenuCrostini"),
         TestCase("dirContextMenuPlayFiles"),
         TestCase("dirContextMenuUsbs"),
+        TestCase("dirContextMenuMtp"),
+        TestCase("dirContextMenuUsbDcim"),
         TestCase("dirContextMenuFsp"),
+        TestCase("dirContextMenuDocumentsProvider").EnableDocumentsProvider(),
         TestCase("dirContextMenuShortcut")));
 
 WRAPPED_INSTANTIATE_TEST_SUITE_P(
@@ -976,6 +979,11 @@
         TestCase("metadataLargeDrive").EnableDriveFs(),
         TestCase("metadataLargeDrive").EnableDriveFs().EnableMyFilesVolume()));
 
+WRAPPED_INSTANTIATE_TEST_SUITE_P(
+    NavigationList, /* navigation_list.js */
+    FilesAppBrowserTest,
+    ::testing::Values(TestCase("navigationScrollsWhenClipped")));
+
 // Structure to describe an account info.
 struct TestAccountInfo {
   const char* const gaia_id;
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
index c12b008c..02c5b92 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -654,6 +654,8 @@
                                                  "text.txt", "hello.txt")
                     .SetMimeType("text/plain"));
 
+    CreateEntry(AddEntriesMessage::TestEntryInfo(AddEntriesMessage::DIRECTORY,
+                                                 "", "Folder"));
     base::RunLoop().RunUntilIdle();
     return true;
   }
diff --git a/chrome/browser/chromeos/file_manager/file_manager_string_util.cc b/chrome/browser/chromeos/file_manager/file_manager_string_util.cc
index a4d03a0b..5b16632 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_string_util.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_string_util.cc
@@ -119,8 +119,8 @@
   SET_STRING("DRIVE_MOBILE_CONNECTION_OPTION",
              IDS_FILE_BROWSER_DRIVE_MOBILE_CONNECTION_OPTION);
   SET_STRING("DRIVE_MY_DRIVE_LABEL", IDS_FILE_BROWSER_DRIVE_MY_DRIVE_LABEL);
-  SET_STRING("DRIVE_TEAM_DRIVES_LABEL",
-             IDS_FILE_BROWSER_DRIVE_TEAM_DRIVES_LABEL);
+  SET_STRING("DRIVE_SHARED_DRIVES_LABEL",
+             IDS_FILE_BROWSER_DRIVE_SHARED_DRIVES_LABEL);
   SET_STRING("DRIVE_COMPUTERS_LABEL", IDS_FILE_BROWSER_DRIVE_COMPUTERS_LABEL);
   SET_STRING("DRIVE_NOT_REACHED", IDS_FILE_BROWSER_DRIVE_NOT_REACHED);
   SET_STRING("DRIVE_OFFLINE_COLLECTION_LABEL",
diff --git a/chrome/browser/chromeos/file_manager/path_util.cc b/chrome/browser/chromeos/file_manager/path_util.cc
index c87ae88..70449664 100644
--- a/chrome/browser/chromeos/file_manager/path_util.cc
+++ b/chrome/browser/chromeos/file_manager/path_util.cc
@@ -531,7 +531,7 @@
                                .value(),
                            base::FilePath(kDisplayNameGoogleDrive)
                                .Append(l10n_util::GetStringUTF8(
-                                   IDS_FILE_BROWSER_DRIVE_TEAM_DRIVES_LABEL))
+                                   IDS_FILE_BROWSER_DRIVE_SHARED_DRIVES_LABEL))
                                .value())) {
   } else if (drive_integration_service &&
              ReplacePrefix(&result,
@@ -558,7 +558,7 @@
                                .value(),
                            base::FilePath(kDisplayNameGoogleDrive)
                                .Append(l10n_util::GetStringUTF8(
-                                   IDS_FILE_BROWSER_DRIVE_TEAM_DRIVES_LABEL))
+                                   IDS_FILE_BROWSER_DRIVE_SHARED_DRIVES_LABEL))
                                .value())) {
   } else if (drive_integration_service &&
              ReplacePrefix(&result,
diff --git a/chrome/browser/chromeos/file_manager/path_util_unittest.cc b/chrome/browser/chromeos/file_manager/path_util_unittest.cc
index bd9595c..c2ee306 100644
--- a/chrome/browser/chromeos/file_manager/path_util_unittest.cc
+++ b/chrome/browser/chromeos/file_manager/path_util_unittest.cc
@@ -195,7 +195,7 @@
               GetPathDisplayTextForSettings(
                   profile_.get(), "/special/drive-0123456789abcdef/root/foo"));
     EXPECT_EQ(
-        "Google Drive \u203a Team Drives \u203a A Team Drive \u203a foo",
+        "Google Drive \u203a Shared drives \u203a A Team Drive \u203a foo",
         GetPathDisplayTextForSettings(
             profile_.get(),
             "/special/drive-0123456789abcdef/team_drives/A Team Drive/foo"));
@@ -225,11 +225,12 @@
         GetPathDisplayTextForSettings(
             &profile2,
             "/media/fuse/drivefs-84675c855b63e12f384d45f033826980/root/foo"));
-    EXPECT_EQ("Google Drive \u203a Team Drives \u203a A Team Drive \u203a foo",
-              GetPathDisplayTextForSettings(
-                  &profile2,
-                  "/media/fuse/drivefs-84675c855b63e12f384d45f033826980/"
-                  "team_drives/A Team Drive/foo"));
+    EXPECT_EQ(
+        "Google Drive \u203a Shared drives \u203a A Team Drive \u203a foo",
+        GetPathDisplayTextForSettings(
+            &profile2,
+            "/media/fuse/drivefs-84675c855b63e12f384d45f033826980/"
+            "team_drives/A Team Drive/foo"));
     EXPECT_EQ(
         "Google Drive \u203a Computers \u203a My Other Computer \u203a bar",
         GetPathDisplayTextForSettings(
@@ -241,7 +242,7 @@
               GetPathDisplayTextForSettings(
                   &profile2, "/special/drive-0123456789abcdef/root/foo"));
     EXPECT_EQ(
-        "Google Drive \u203a Team Drives \u203a A Team Drive \u203a foo",
+        "Google Drive \u203a Shared drives \u203a A Team Drive \u203a foo",
         GetPathDisplayTextForSettings(
             &profile2,
             "/special/drive-0123456789abcdef/team_drives/A Team Drive/foo"));
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index 370fb71..d4e64ce 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -388,17 +388,17 @@
   virtual void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) {
     WaitForSigninScreen();
 
-    SetupAuthFlowChangeListener();
-
     content::DOMMessageQueue message_queue;  // Start observe before SAML.
+    SetupAuthFlowChangeListener();
     LoginDisplayHost::default_host()
         ->GetOobeUI()
         ->GetGaiaScreenView()
         ->ShowSigninScreenForTest(gaia_email, "", "[]");
 
     std::string message;
-    ASSERT_TRUE(message_queue.WaitForMessage(&message));
-    EXPECT_EQ("\"SamlLoaded\"", message);
+    do {
+      ASSERT_TRUE(message_queue.WaitForMessage(&message));
+    } while (message != "\"SamlLoaded\"");
   }
 
   void SendConfirmPassword(const std::string& password_to_confirm) {
@@ -476,10 +476,10 @@
   base::ReplaceSubstringsAfterOffset(&js, 0, "$Host", kIdPHost);
   test::OobeJS().ExpectTrue(js);
 
-  SetupAuthFlowChangeListener();
 
-  // Click on 'cancel'.
   content::DOMMessageQueue message_queue;  // Observe before 'cancel'.
+  SetupAuthFlowChangeListener();
+  // Click on 'cancel'.
   content::ExecuteScriptAsync(GetLoginUI()->GetWebContents(),
                               "$('gaia-navigation').$.closeButton.click();");
 
@@ -542,6 +542,7 @@
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
 
+  content::DOMMessageQueue message_queue;
   // Make sure that the password is scraped correctly.
   ASSERT_TRUE(content::ExecuteScript(
       GetLoginUI()->GetWebContents(),
@@ -559,7 +560,6 @@
   content::WindowedNotificationObserver session_start_waiter(
       chrome::NOTIFICATION_SESSION_STARTED,
       content::NotificationService::AllSources());
-  content::DOMMessageQueue message_queue;
   ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
   std::string message;
   do {
@@ -1126,20 +1126,22 @@
 
 void SAMLPolicyTest::ShowGAIALoginForm() {
   login_screen_load_observer_->Wait();
+  content::DOMMessageQueue message_queue;
   ASSERT_TRUE(content::ExecuteScript(
       GetLoginUI()->GetWebContents(),
       "$('gaia-signin').gaiaAuthHost_.addEventListener('ready', function() {"
       "  window.domAutomationController.send('ready');"
       "});"));
   ASSERT_TRUE(test::LoginScreenTester().ClickAddUserButton());
-  content::DOMMessageQueue message_queue;
   std::string message;
-  ASSERT_TRUE(message_queue.WaitForMessage(&message));
-  EXPECT_EQ("\"ready\"", message);
+  do {
+    ASSERT_TRUE(message_queue.WaitForMessage(&message));
+  } while (message != "\"ready\"");
 }
 
 void SAMLPolicyTest::ShowSAMLInterstitial() {
   login_screen_load_observer_->Wait();
+  content::DOMMessageQueue message_queue;
   ASSERT_TRUE(
       content::ExecuteScript(GetLoginUI()->GetWebContents(),
                              "{"
@@ -1157,10 +1159,10 @@
                              "}"));
   ASSERT_TRUE(test::LoginScreenTester().ClickAddUserButton());
 
-  content::DOMMessageQueue message_queue;
   std::string message;
-  ASSERT_TRUE(message_queue.WaitForMessage(&message));
-  EXPECT_EQ("\"samlInterstitialPageReady\"", message);
+  do {
+    ASSERT_TRUE(message_queue.WaitForMessage(&message));
+  } while (message != "\"samlInterstitialPageReady\"");
 }
 
 void SAMLPolicyTest::ClickNextOnSAMLInterstitialPage() {
@@ -1176,11 +1178,11 @@
   do {
     ASSERT_TRUE(message_queue.WaitForMessage(&message));
   } while (message != "\"SamlLoaded\"");
-  EXPECT_EQ("\"SamlLoaded\"", message);
 }
 
 void SAMLPolicyTest::ClickChangeAccountOnSAMLInterstitialPage() {
   login_screen_load_observer_->Wait();
+  content::DOMMessageQueue message_queue;
   ASSERT_TRUE(content::ExecuteScript(
       GetLoginUI()->GetWebContents(),
       "$('gaia-signin').gaiaAuthHost_.addEventListener('ready', function() {"
@@ -1188,10 +1190,10 @@
       "});"
       "$('saml-interstitial').changeAccountLink.click();"));
 
-  content::DOMMessageQueue message_queue;
   std::string message;
-  ASSERT_TRUE(message_queue.WaitForMessage(&message));
-  EXPECT_EQ("\"ready\"", message);
+  do {
+    ASSERT_TRUE(message_queue.WaitForMessage(&message));
+  } while (message != "\"ready\"");
 }
 
 void SAMLPolicyTest::LogInWithSAML(const std::string& user_id,
diff --git a/chrome/browser/extensions/api/device_permissions_manager_unittest.cc b/chrome/browser/extensions/api/device_permissions_manager_unittest.cc
index 4b3185b1..b8555d6 100644
--- a/chrome/browser/extensions/api/device_permissions_manager_unittest.cc
+++ b/chrome/browser/extensions/api/device_permissions_manager_unittest.cc
@@ -19,6 +19,7 @@
 #include "extensions/browser/api/usb/usb_device_manager.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/common/extension.h"
+#include "services/device/public/cpp/hid/fake_hid_manager.h"
 #include "services/device/public/mojom/hid.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -28,26 +29,12 @@
 namespace {
 
 using device::FakeUsbDeviceInfo;
+using device::mojom::HidBusType;
 using testing::_;
 using testing::DoAll;
 using testing::Return;
 using testing::SetArgPointee;
 
-const char* kTestDeviceGuids[] = {"A", "B", "C", "D"};
-
-class FakeHidDeviceManager : public HidDeviceManager {
- public:
-  explicit FakeHidDeviceManager(content::BrowserContext* context)
-      : HidDeviceManager(context) {}
-
-  void LazyInitialize() override {}
-};
-
-std::unique_ptr<KeyedService> CreateHidDeviceManager(
-    content::BrowserContext* context) {
-  return std::make_unique<FakeHidDeviceManager>(context);
-}
-
 }  // namespace
 
 class DevicePermissionsManagerTest : public testing::Test {
@@ -81,31 +68,20 @@
     device3_ = fake_usb_manager_.CreateAndAddDevice(0, 0, "Test Manufacturer",
                                                     "Test Product", "");
 
-    HidDeviceManager::GetFactoryInstance()->SetTestingFactory(
-        env_->profile(), base::BindRepeating(&CreateHidDeviceManager));
-    device4_ = device::mojom::HidDeviceInfo::New();
-    device4_->guid = kTestDeviceGuids[0];
-    device4_->product_name = "Test HID Device";
-    device4_->serial_number = "abcde";
-    device4_->bus_type = device::mojom::HidBusType::kHIDBusTypeUSB;
+    device::mojom::HidManagerPtr hid_manager_ptr;
+    fake_hid_manager_.Bind(mojo::MakeRequest(&hid_manager_ptr));
+    HidDeviceManager::Get(env_->profile())
+        ->SetFakeHidManagerForTesting(std::move(hid_manager_ptr));
+    base::RunLoop().RunUntilIdle();
 
-    device5_ = device::mojom::HidDeviceInfo::New();
-    device5_->guid = kTestDeviceGuids[1];
-    device5_->product_name = "Test HID Device";
-    device5_->serial_number = "";
-    device5_->bus_type = device::mojom::HidBusType::kHIDBusTypeUSB;
-
-    device6_ = device::mojom::HidDeviceInfo::New();
-    device6_->guid = kTestDeviceGuids[2];
-    device6_->product_name = "Test HID Device";
-    device6_->serial_number = "67890";
-    device6_->bus_type = device::mojom::HidBusType::kHIDBusTypeUSB;
-
-    device7_ = device::mojom::HidDeviceInfo::New();
-    device7_->guid = kTestDeviceGuids[3];
-    device7_->product_name = "Test HID Device";
-    device7_->serial_number = "";
-    device7_->bus_type = device::mojom::HidBusType::kHIDBusTypeUSB;
+    device4_ = fake_hid_manager_.CreateAndAddDevice("Test HID Device", "abcde",
+                                                    HidBusType::kHIDBusTypeUSB);
+    device5_ = fake_hid_manager_.CreateAndAddDevice("Test HID Device", "",
+                                                    HidBusType::kHIDBusTypeUSB);
+    device6_ = fake_hid_manager_.CreateAndAddDevice("Test HID Device", "67890",
+                                                    HidBusType::kHIDBusTypeUSB);
+    device7_ = fake_hid_manager_.CreateAndAddDevice("Test HID Device", "",
+                                                    HidBusType::kHIDBusTypeUSB);
   }
 
   void TearDown() override { env_.reset(nullptr); }
@@ -118,6 +94,7 @@
   device::mojom::UsbDeviceInfoPtr device2_;
   device::mojom::UsbDeviceInfoPtr device3_;
 
+  device::FakeHidManager fake_hid_manager_;
   device::mojom::HidDeviceInfoPtr device4_;
   device::mojom::HidDeviceInfoPtr device5_;
   device::mojom::HidDeviceInfoPtr device6_;
@@ -214,10 +191,9 @@
   fake_usb_manager_.RemoveDevice(device0_->guid);
   fake_usb_manager_.RemoveDevice(device1_->guid);
 
-  manager->RemoveEntryByDeviceGUID(DevicePermissionEntry::Type::HID,
-                                   device4_->guid);
-  manager->RemoveEntryByDeviceGUID(DevicePermissionEntry::Type::HID,
-                                   device5_->guid);
+  fake_hid_manager_.RemoveDevice(device4_->guid);
+  fake_hid_manager_.RemoveDevice(device5_->guid);
+
   base::RunLoop().RunUntilIdle();
 
   // Device 0 will be accessible when it is reconnected because it can be
diff --git a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
index 3ea72e0..678bf64 100644
--- a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
+++ b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
@@ -91,8 +91,7 @@
     url_request_context_.Init();
     network_context_ = std::make_unique<network::NetworkContext>(
         nullptr, mojo::MakeRequest(&network_context_ptr_),
-        &url_request_context_,
-        /*cors_exempt_header_list=*/std::vector<std::string>());
+        &url_request_context_);
     partition_.set_network_context(network_context_ptr_.get());
   }
 
diff --git a/chrome/browser/extensions/api/socket/tls_socket_unittest.cc b/chrome/browser/extensions/api/socket/tls_socket_unittest.cc
index 4f556798..dadab921 100644
--- a/chrome/browser/extensions/api/socket/tls_socket_unittest.cc
+++ b/chrome/browser/extensions/api/socket/tls_socket_unittest.cc
@@ -91,8 +91,7 @@
     url_request_context_.Init();
     network_context_ = std::make_unique<network::NetworkContext>(
         nullptr, mojo::MakeRequest(&network_context_ptr_),
-        &url_request_context_,
-        /*cors_exempt_header_list=*/std::vector<std::string>());
+        &url_request_context_);
     partition_.set_network_context(network_context_ptr_.get());
   }
 
diff --git a/chrome/browser/loader/cors_origin_access_list_browsertest.cc b/chrome/browser/loader/cors_origin_access_list_browsertest.cc
index 6751d1c..6f84bc1 100644
--- a/chrome/browser/loader/cors_origin_access_list_browsertest.cc
+++ b/chrome/browser/loader/cors_origin_access_list_browsertest.cc
@@ -41,34 +41,16 @@
 const char kTestHostInDifferentCase[] = "CrossOrigin.example.com";
 const char kTestSubdomainHost[] = "subdomain.crossorigin.example.com";
 
-enum class TestMode {
-  kOutOfBlinkCorsWithServicification,
-  kOutOfBlinkCorsWithoutServicification,
-};
-
 // Tests end to end functionality of CORS access origin allow lists.
-class CorsOriginAccessListBrowserTest
-    : public InProcessBrowserTest,
-      public testing::WithParamInterface<TestMode> {
+class CorsOriginAccessListBrowserTest : public InProcessBrowserTest {
  public:
   CorsOriginAccessListBrowserTest() {
-    switch (GetParam()) {
-      case TestMode::kOutOfBlinkCorsWithServicification:
-        scoped_feature_list_.InitWithFeatures(
-            // Enabled features
-            {network::features::kOutOfBlinkCors,
-             network::features::kNetworkService},
-            // Disabled features
-            {});
-        break;
-      case TestMode::kOutOfBlinkCorsWithoutServicification:
-        scoped_feature_list_.InitWithFeatures(
-            // Enabled features
-            {network::features::kOutOfBlinkCors},
-            // Disabled features
-            {network::features::kNetworkService});
-        break;
-    }
+    scoped_feature_list_.InitWithFeatures(
+        // Enabled features
+        {network::features::kOutOfBlinkCors,
+         network::features::kNetworkService},
+        // Disabled features
+        {});
   }
 
  protected:
@@ -166,7 +148,7 @@
 };
 
 // Tests if specifying only protocol allows all hosts to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAll) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowAll) {
   SetAllowList("http", "", kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -177,7 +159,7 @@
 }
 
 // Tests if specifying only protocol allows all IP address based hosts to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAllForIp) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowAllForIp) {
   SetAllowList("http", "", kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -190,7 +172,7 @@
 }
 
 // Tests if complete allow list set allows only exactly matched host to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowExactHost) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowExactHost) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -202,7 +184,7 @@
 
 // Tests if complete allow list set allows host that matches exactly, but in
 // case insensitive way to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        AllowExactHostInCaseInsensitive) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
@@ -216,7 +198,7 @@
 
 // Tests if complete allow list set does not allow a host with a different port
 // to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -227,7 +209,7 @@
 }
 
 // Tests if complete allow list set allows a subdomain to pass if it is allowed.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowSubdomain) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowSubdomain) {
   SetAllowList("http", kTestHost, kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -238,7 +220,7 @@
 }
 
 // Tests if complete allow list set does not allow a subdomain to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockSubdomain) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, BlockSubdomain) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -250,7 +232,7 @@
 
 // Tests if complete allow list set does not allow a host with a different
 // protocol to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        BlockDifferentProtocol) {
   SetAllowList("https", kTestHost, kDisallowSubdomains);
 
@@ -262,7 +244,7 @@
 }
 
 // Tests if IP address based hosts should not follow subdomain match rules.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        SubdomainMatchShouldNotBeAppliedForIPAddress) {
   SetAllowList("http", "*.0.0.1", kAllowSubdomains);
 
@@ -275,17 +257,4 @@
   EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()) << GetReason();
 }
 
-INSTANTIATE_TEST_SUITE_P(
-    OutOfBlinkCorsWithServicification,
-    CorsOriginAccessListBrowserTest,
-    ::testing::Values(TestMode::kOutOfBlinkCorsWithServicification));
-
-INSTANTIATE_TEST_SUITE_P(
-    OutOfBlinkCorsWithoutServicification,
-    CorsOriginAccessListBrowserTest,
-    ::testing::Values(TestMode::kOutOfBlinkCorsWithoutServicification));
-
-// TODO(toyoshim): Instantiates tests for the case kOutOfBlinkCors is disabled
-// and remove relevant web tests if it's possible.
-
 }  // namespace
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
index 8d52d96a..28e33c3 100644
--- a/chrome/browser/net/system_network_context_manager.cc
+++ b/chrome/browser/net/system_network_context_manager.cc
@@ -40,12 +40,10 @@
 #include "components/policy/policy_constants.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
-#include "components/variations/net/variations_http_headers.h"
 #include "components/variations/variations_associated_data.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
@@ -592,8 +590,6 @@
 SystemNetworkContextManager::CreateDefaultNetworkContextParams() {
   network::mojom::NetworkContextParamsPtr network_context_params =
       network::mojom::NetworkContextParams::New();
-  content::UpdateCorsExemptHeader(network_context_params.get());
-  variations::UpdateCorsExemptHeaderForVariations(network_context_params.get());
 
   network_context_params->enable_brotli =
       base::FeatureList::IsEnabled(features::kBrotliEncoding);
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index be291ab..f2f7ff20e 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -1411,26 +1411,6 @@
   EXPECT_TRUE(prefs->IsManagedPreference(bookmarks::prefs::kShowBookmarkBar));
   EXPECT_TRUE(prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar));
   EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
-
-  // The NTP has special handling of the bookmark bar.
-  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL));
-  EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
-
-  policies.Set(key::kBookmarkBarEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               std::make_unique<base::Value>(false), nullptr);
-  UpdateProviderPolicy(policies);
-  EXPECT_TRUE(prefs->IsManagedPreference(bookmarks::prefs::kShowBookmarkBar));
-  EXPECT_FALSE(prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar));
-  // The bookmark bar is hidden in the NTP when disabled by policy.
-  EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
-
-  policies.Clear();
-  UpdateProviderPolicy(policies);
-  EXPECT_FALSE(prefs->IsManagedPreference(bookmarks::prefs::kShowBookmarkBar));
-  EXPECT_FALSE(prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar));
-  // The bookmark bar is shown detached in the NTP, when disabled by prefs only.
-  EXPECT_EQ(BookmarkBar::DETACHED, browser()->bookmark_bar_state());
 }
 
 IN_PROC_BROWSER_TEST_F(PolicyTest, PRE_PRE_DefaultCookiesSetting) {
diff --git a/chrome/browser/resources/app_management/app.html b/chrome/browser/resources/app_management/app.html
index 1cc85b41..3b99164 100644
--- a/chrome/browser/resources/app_management/app.html
+++ b/chrome/browser/resources/app_management/app.html
@@ -19,24 +19,25 @@
 <dom-module id="app-management-app">
   <template>
     <style include="app-management-shared-css">
-    :host {
-      display: flex;
-      flex-direction: column;
-      font-size: var(--app-management-font-size);
-      height: 100%;
-      line-height: var(--app-management-line-height);
-      overflow: hidden;
-    }
+      :host {
+        display: flex;
+        flex-direction: column;
+        font-size: var(--app-management-font-size);
+        height: 100%;
+        line-height: var(--app-management-line-height);
+        overflow: hidden;
+      }
 
-    cr-toolbar {
-      background: var(--md-toolbar-color);
-      min-height: var(--toolbar-height);
-    }
+      cr-toolbar {
+        background: var(--md-toolbar-color);
+        min-height: var(--toolbar-height);
+      }
 
-    #main-container {
-      overflow: auto;
-      padding: 0 40px;
-    }
+      #main-container {
+        flex: 1;
+        overflow: auto;
+        padding: 0 40px;
+      }
     </style>
     <cr-toolbar
         page-name="$i18n{title}"
diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc
index bfa14cd..7dafefc3 100644
--- a/chrome/browser/sessions/session_data_deleter.cc
+++ b/chrome/browser/sessions/session_data_deleter.cc
@@ -25,9 +25,10 @@
 
 namespace {
 
-bool OriginMatcher(const GURL& origin, storage::SpecialStoragePolicy* policy) {
-  return policy->IsStorageSessionOnly(origin) &&
-         !policy->IsStorageProtected(origin);
+bool OriginMatcher(const url::Origin& origin,
+                   storage::SpecialStoragePolicy* policy) {
+  return policy->IsStorageSessionOnly(origin.GetURL()) &&
+         !policy->IsStorageProtected(origin.GetURL());
 }
 
 class SessionDataDeleter
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index d38c4555..3f4cbd65 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -63,7 +63,6 @@
 #include "components/password_manager/core/browser/password_store.h"
 #include "components/password_manager/core/browser/sync/password_model_worker.h"
 #include "components/search_engines/search_engine_data_type_controller.h"
-#include "components/search_engines/search_engine_model_type_controller.h"
 #include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
 #include "components/spellcheck/spellcheck_buildflags.h"
 #include "components/sync/base/pref_names.h"
@@ -395,20 +394,19 @@
 
   // Search Engine sync is enabled by default.  Register unless explicitly
   // disabled. The service can be null in tests.
-  TemplateURLService* template_url_service =
-      TemplateURLServiceFactory::GetForProfile(profile_);
   if (!disabled_types.Has(syncer::SEARCH_ENGINES)) {
-    // TODO(mastiz): For the null case exercised in some tests, we should also
-    // exercise the new controller (which currently requires a non-null
-    // service).
-    if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSSearchEngines) &&
-        template_url_service) {
-      controllers.push_back(std::make_unique<SearchEngineModelTypeController>(
-          dump_stack, GetModelTypeStoreService()->GetStoreFactory(),
-          template_url_service));
+    if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSSearchEngines)) {
+      controllers.push_back(
+          std::make_unique<syncer::SyncableServiceBasedModelTypeController>(
+              syncer::SEARCH_ENGINES,
+              GetModelTypeStoreService()->GetStoreFactory(),
+              base::BindOnce(&ChromeSyncClient::GetSyncableServiceForType,
+                             base::Unretained(this), syncer::SEARCH_ENGINES),
+              dump_stack));
     } else {
       controllers.push_back(std::make_unique<SearchEngineDataTypeController>(
-          dump_stack, sync_service, this, template_url_service));
+          dump_stack, sync_service, this,
+          TemplateURLServiceFactory::GetForProfile(profile_)));
     }
   }
 #endif  // !defined(OS_ANDROID)
diff --git a/chrome/browser/ui/android/tab_model/tab_model.h b/chrome/browser/ui/android/tab_model/tab_model.h
index ca25f2c..df4e18e 100644
--- a/chrome/browser/ui/android/tab_model/tab_model.h
+++ b/chrome/browser/ui/android/tab_model/tab_model.h
@@ -16,6 +16,8 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 
+struct NavigateParams;
+
 namespace browser_sync {
 class SyncedWindowDelegateAndroid;
 }
@@ -122,6 +124,9 @@
                          content::WebContents* web_contents,
                          int parent_tab_id) = 0;
 
+  virtual void HandlePopupNavigation(TabAndroid* parent,
+                                     NavigateParams* params) = 0;
+
   // Used by Developer Tools to create a new tab with a given URL.
   // Replaces CreateTabForTesting.
   virtual content::WebContents* CreateNewTabForDevTools(const GURL& url) = 0;
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
index e964dec..595ba1f 100644
--- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
@@ -19,8 +19,11 @@
 #include "chrome/browser/tab_contents/tab_util.h"
 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
 #include "chrome/browser/ui/android/tab_model/tab_model_observer_jni_bridge.h"
+#include "chrome/browser/ui/browser_navigator_params.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/resource_request_body_android.h"
 #include "jni/TabModelJniBridge_jni.h"
+#include "ui/base/window_open_disposition.h"
 
 using base::android::AttachCurrentThread;
 using base::android::ConvertUTF8ToJavaString;
@@ -96,6 +99,45 @@
       web_contents->GetJavaWebContents(), parent_tab_id);
 }
 
+void TabModelJniBridge::HandlePopupNavigation(TabAndroid* parent,
+                                              NavigateParams* params) {
+  DCHECK_EQ(params->source_contents, parent->web_contents());
+  DCHECK(!params->contents_to_insert);
+  DCHECK(!params->switch_to_singleton_tab);
+
+  WindowOpenDisposition disposition = params->disposition;
+  bool supported = disposition == WindowOpenDisposition::NEW_POPUP ||
+                   disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB ||
+                   disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB ||
+                   disposition == WindowOpenDisposition::NEW_WINDOW ||
+                   disposition == WindowOpenDisposition::OFF_THE_RECORD;
+  if (!supported) {
+    NOTIMPLEMENTED();
+    return;
+  }
+
+  const GURL& url = params->url;
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> jobj = java_object_.get(env);
+  ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(env, url.spec()));
+  ScopedJavaLocalRef<jstring> jheaders(
+      ConvertUTF8ToJavaString(env, params->extra_headers));
+  ScopedJavaLocalRef<jstring> jinitiator_origin;
+  if (params->initiator_origin) {
+    jinitiator_origin =
+        ConvertUTF8ToJavaString(env, params->initiator_origin->Serialize());
+  }
+  ScopedJavaLocalRef<jobject> jpost_data;
+  if (params->uses_post && params->post_data) {
+    jpost_data =
+        content::ConvertResourceRequestBodyToJavaObject(env, params->post_data);
+  }
+  Java_TabModelJniBridge_openNewTab(
+      env, jobj, parent->GetJavaObject(), jurl, jinitiator_origin, jheaders,
+      jpost_data, static_cast<int>(disposition), params->created_with_opener,
+      params->is_renderer_initiated);
+}
+
 WebContents* TabModelJniBridge::GetWebContentsAt(int index) const {
   TabAndroid* tab = GetTabAt(index);
   return tab == NULL ? NULL : tab->web_contents();
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h
index e32c92d..443b19b2 100644
--- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h
+++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h
@@ -54,6 +54,8 @@
   void CreateTab(TabAndroid* parent,
                  content::WebContents* web_contents,
                  int parent_tab_id) override;
+  void HandlePopupNavigation(TabAndroid* parent,
+                             NavigateParams* params) override;
 
   content::WebContents* CreateNewTabForDevTools(const GURL& url) override;
 
diff --git a/chrome/browser/ui/android/tab_model/tab_model_list.cc b/chrome/browser/ui/android/tab_model/tab_model_list.cc
index 2306f3c..12ff919 100644
--- a/chrome/browser/ui/android/tab_model/tab_model_list.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model_list.cc
@@ -59,7 +59,9 @@
 
   // NOTE: If this fails contact dtrainor@.
   DCHECK(tab);
-  tab->HandlePopupNavigation(params);
+  TabModel* model = FindTabModelWithId(tab->window_id());
+  if (model)
+    model->HandlePopupNavigation(tab, params);
 }
 
 TabModel* TabModelList::GetTabModelForWebContents(
diff --git a/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc
index 59db338..d603b9ba 100644
--- a/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc
@@ -25,6 +25,8 @@
   void CreateTab(TabAndroid* parent,
                  content::WebContents* web_contents,
                  int parent_tab_id) override {}
+  void HandlePopupNavigation(TabAndroid* parent,
+                             NavigateParams* params) override {}
   content::WebContents* CreateNewTabForDevTools(const GURL& url) override {
     return nullptr;
   }
diff --git a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
index 3a067f4..1a5e579f 100644
--- a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
@@ -38,6 +38,8 @@
   void CreateTab(TabAndroid* parent,
                  content::WebContents* web_contents,
                  int parent_tab_id) override {}
+  void HandlePopupNavigation(TabAndroid* parent,
+                             NavigateParams* params) override {}
   content::WebContents* CreateNewTabForDevTools(const GURL& url) override {
     return NULL;
   }
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc b/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc
index e824787..609610a 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc
@@ -132,7 +132,7 @@
       keyboard::KeyboardController::HasInstance()) {
     // In classic Ash, keyboard::KeyboardController owns ChromeKeyboardUI which
     // accesses this class, so make sure that the UI has been destroyed.
-    keyboard::KeyboardController::Get()->DisableKeyboard();
+    keyboard::KeyboardController::Get()->Shutdown();
   }
   keyboard_contents_.reset();
 }
diff --git a/chrome/browser/ui/ash/keyboard/keyboard_controller_browsertest.cc b/chrome/browser/ui/ash/keyboard/keyboard_controller_browsertest.cc
index 53f5407e..40af67d5 100644
--- a/chrome/browser/ui/ash/keyboard/keyboard_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/keyboard/keyboard_controller_browsertest.cc
@@ -426,7 +426,7 @@
   EXPECT_EQ(controller->GetStateForTest(),
             keyboard::KeyboardControllerState::LOADING_EXTENSION);
 
-  controller->DisableKeyboard();
+  controller->Shutdown();
   EXPECT_EQ(controller->GetStateForTest(),
             keyboard::KeyboardControllerState::INITIAL);
 }
diff --git a/chrome/browser/ui/bookmarks/bookmark_bar.h b/chrome/browser/ui/bookmarks/bookmark_bar.h
index 3dd2899..1034757 100644
--- a/chrome/browser/ui/bookmarks/bookmark_bar.h
+++ b/chrome/browser/ui/bookmarks/bookmark_bar.h
@@ -16,8 +16,7 @@
     // The bookmark bar is visible and not detached.
     SHOW,
 
-    // The bookmark bar is visible and detached from the location bar (as
-    // happens on the new tab page).
+    // The bookmark bar is visible and detached from the location bar.
     DETACHED
   };
 
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
index b85ec7c..2c48fe0 100644
--- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/search.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper_observer.h"
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #include "chrome/browser/ui/sad_tab.h"
@@ -17,59 +16,17 @@
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/common/bookmark_pref_names.h"
 #include "components/sync_preferences/pref_service_syncable.h"
-#include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 
 using bookmarks::BookmarkModel;
 using bookmarks::BookmarkNode;
 
-namespace {
-
-bool IsNTP(content::WebContents* web_contents) {
-  // Use the committed entry so the bookmarks bar disappears at the same time
-  // the page does.
-  content::NavigationEntry* entry =
-      web_contents->GetController().GetLastCommittedEntry();
-  if (!entry)
-    entry = web_contents->GetController().GetVisibleEntry();
-  return (entry && NewTabUI::IsNewTab(entry->GetURL())) ||
-         search::NavEntryIsInstantNTP(web_contents, entry);
-}
-
-}  // namespace
-
 BookmarkTabHelper::~BookmarkTabHelper() {
   if (bookmark_model_)
     bookmark_model_->RemoveObserver(this);
 }
 
-bool BookmarkTabHelper::ShouldShowBookmarkBar() const {
-  if (web_contents()->ShowingInterstitialPage())
-    return false;
-
-  if (SadTab::ShouldShow(web_contents()->GetCrashedStatus()))
-    return false;
-
-  if (!browser_defaults::bookmarks_enabled)
-    return false;
-
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
-
-#if !defined(OS_CHROMEOS)
-  if (profile->IsGuestSession())
-    return false;
-#endif
-
-  PrefService* prefs = profile->GetPrefs();
-  if (prefs->IsManagedPreference(bookmarks::prefs::kShowBookmarkBar) &&
-      !prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar))
-    return false;
-
-  return IsNTP(web_contents());
-}
-
 void BookmarkTabHelper::AddObserver(BookmarkTabHelperObserver* observer) {
   observers_.AddObserver(observer);
 }
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
index 56334cf..280310aa 100644
--- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
+++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
@@ -51,9 +51,6 @@
 
   bool is_starred() const { return is_starred_; }
 
-  // Returns true if the bookmark bar should be shown detached.
-  bool ShouldShowBookmarkBar() const;
-
   void AddObserver(BookmarkTabHelperObserver* observer);
   void RemoveObserver(BookmarkTabHelperObserver* observer);
   bool HasObserver(BookmarkTabHelperObserver* observer) const;
diff --git a/chrome/browser/ui/bookmarks/bookmark_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_unittest.cc
index 374c6258c..34141ff 100644
--- a/chrome/browser/ui/bookmarks/bookmark_unittest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_unittest.cc
@@ -19,12 +19,6 @@
 
 typedef BrowserWithTestWindowTest BookmarkTest;
 
-// Verify that the detached bookmark bar is visible on the new tab page.
-TEST_F(BookmarkTest, DetachedBookmarkBarOnNTP) {
-  AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
-  EXPECT_EQ(BookmarkBar::DETACHED, browser()->bookmark_bar_state());
-}
-
 // Verify that the detached bookmark bar is hidden on custom NTP pages.
 TEST_F(BookmarkTest, DetachedBookmarkBarOnCustomNTP) {
   // Create a empty commited web contents.
@@ -76,10 +70,3 @@
 
   DISALLOW_COPY_AND_ASSIGN(BookmarkInstantExtendedTest);
 };
-
-// Verify that in instant extended mode the detached bookmark bar is visible on
-// the new tab page.
-TEST_F(BookmarkInstantExtendedTest, DetachedBookmarkBarOnNTP) {
-  AddTab(browser(), GURL(chrome::kChromeUINewTabURL));
-  EXPECT_EQ(BookmarkBar::DETACHED, browser()->bookmark_bar_state());
-}
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index b31b3d5..c90f0f8 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -2636,13 +2636,7 @@
       !ShouldHideUIForFullscreen()) {
     state = BookmarkBar::SHOW;
   } else {
-    WebContents* web_contents = tab_strip_model_->GetActiveWebContents();
-    BookmarkTabHelper* bookmark_tab_helper =
-        web_contents ? BookmarkTabHelper::FromWebContents(web_contents) : NULL;
-    if (bookmark_tab_helper && bookmark_tab_helper->ShouldShowBookmarkBar())
-      state = BookmarkBar::DETACHED;
-    else
-      state = BookmarkBar::HIDDEN;
+    state = BookmarkBar::HIDDEN;
   }
 
   if (state == bookmark_bar_state_)
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index 26cd325..5749e22 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -2360,7 +2360,7 @@
 
   // Start with NTP.
   ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
-  ASSERT_EQ(BookmarkBar::DETACHED, browser()->bookmark_bar_state());
+  ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderViewHost* prev_rvh = web_contents->GetRenderViewHost();
diff --git a/chrome/browser/ui/browser_unittest.cc b/chrome/browser/ui/browser_unittest.cc
index 936c6b88..06802f6 100644
--- a/chrome/browser/ui/browser_unittest.cc
+++ b/chrome/browser/ui/browser_unittest.cc
@@ -341,8 +341,8 @@
 
   // Open a tab to NTP.
   AddTab(browser(), ntp_url);
-  EXPECT_EQ(BookmarkBar::DETACHED, browser()->bookmark_bar_state());
-  EXPECT_EQ(BookmarkBar::DETACHED, window_bookmark_bar_state());
+  EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
+  EXPECT_EQ(BookmarkBar::HIDDEN, window_bookmark_bar_state());
 
   // Navigate 1st tab to a non-NTP URL.
   NavigateAndCommitActiveTab(non_ntp_url);
@@ -351,8 +351,8 @@
 
   // Open a tab to NTP at index 0.
   AddTab(browser(), ntp_url);
-  EXPECT_EQ(BookmarkBar::DETACHED, browser()->bookmark_bar_state());
-  EXPECT_EQ(BookmarkBar::DETACHED, window_bookmark_bar_state());
+  EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
+  EXPECT_EQ(BookmarkBar::HIDDEN, window_bookmark_bar_state());
 
   // Activate the 2nd tab which is non-NTP.
   browser()->tab_strip_model()->ActivateTabAt(
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
index 5b49549..2941145 100644
--- a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
@@ -4,9 +4,7 @@
 
 #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
 
-#include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/engagement/site_engagement_service.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
@@ -112,10 +110,6 @@
              profile, page_url, extensions::LAUNCH_CONTAINER_WINDOW);
 }
 
-// TODO(loyso): Erase this histogram. crbug.com/918089.
-const char kPwaWindowEngagementTypeHistogram[] =
-    "Webapp.Engagement.EngagementType";
-
 // static
 bool HostedAppBrowserController::IsForExperimentalHostedAppBrowser(
     const Browser* browser) {
@@ -154,8 +148,7 @@
 }
 
 HostedAppBrowserController::HostedAppBrowserController(Browser* browser)
-    : SiteEngagementObserver(SiteEngagementService::Get(browser->profile())),
-      browser_(browser),
+    : browser_(browser),
       extension_id_(web_app::GetAppIdFromApplicationName(browser->app_name())),
       // If a bookmark app has a URL handler, then it is a PWA.
       // TODO(https://crbug.com/774918): Replace once there is a more explicit
@@ -356,24 +349,6 @@
   return GetExtension();
 }
 
-void HostedAppBrowserController::OnEngagementEvent(
-    content::WebContents* web_contents,
-    const GURL& /*url*/,
-    double /*score*/,
-    SiteEngagementService::EngagementType type) {
-  if (!created_for_installed_pwa_)
-    return;
-
-  // Check the event belongs to the controller's associated browser window.
-  if (!web_contents ||
-      web_contents != browser_->tab_strip_model()->GetActiveWebContents()) {
-    return;
-  }
-
-  UMA_HISTOGRAM_ENUMERATION(kPwaWindowEngagementTypeHistogram, type,
-                            SiteEngagementService::ENGAGEMENT_LAST);
-}
-
 void HostedAppBrowserController::OnTabStripModelChanged(
     TabStripModel* tab_strip_model,
     const TabStripModelChange& change,
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.h b/chrome/browser/ui/extensions/hosted_app_browser_controller.h
index 0f92234..645c0bb 100644
--- a/chrome/browser/ui/extensions/hosted_app_browser_controller.h
+++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.h
@@ -10,7 +10,6 @@
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/strings/string16.h"
-#include "chrome/browser/engagement/site_engagement_observer.h"
 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -30,14 +29,10 @@
                  const GURL& page_url,
                  content::BrowserContext* profile);
 
-// TODO(loyso): Erase this histogram. crbug.com/918089.
-extern const char kPwaWindowEngagementTypeHistogram[];
-
 class Extension;
 
 // Class to encapsulate logic to control the browser UI for hosted apps.
-class HostedAppBrowserController : public SiteEngagementObserver,
-                                   public TabStripModelObserver,
+class HostedAppBrowserController : public TabStripModelObserver,
                                    public ExtensionUninstallDialog::Delegate {
  public:
   // Returns whether |browser| uses the experimental hosted app experience.
@@ -115,12 +110,6 @@
   // the lifetime of HostedAppBrowserController).
   bool IsInstalled() const;
 
-  // SiteEngagementObserver overrides.
-  void OnEngagementEvent(content::WebContents* web_contents,
-                         const GURL& url,
-                         double score,
-                         SiteEngagementService::EngagementType type) override;
-
   // TabStripModelObserver overrides.
   void OnTabStripModelChanged(
       TabStripModel* tab_strip_model,
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index b33d5ade..3a79644e 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -17,7 +17,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind_test_util.h"
-#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
@@ -25,7 +24,6 @@
 #include "chrome/browser/badging/badge_manager_delegate.h"
 #include "chrome/browser/badging/badge_manager_factory.h"
 #include "chrome/browser/banners/test_app_banner_manager_desktop.h"
-#include "chrome/browser/engagement/site_engagement_service.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_util.h"
@@ -90,7 +88,6 @@
 namespace {
 
 constexpr const char kExampleURL[] = "http://example.org/";
-constexpr const char kExampleURL2[] = "http://example.com/";
 constexpr const char kImagePath[] = "/ssl/google_files/logo.gif";
 constexpr const char kAppDotComManifest[] =
     "{"
@@ -1649,113 +1646,6 @@
   NavigateAndCheckForToolbar(app_browser_, app_url, false);
 }
 
-// TODO(loyso): crbug.com/918089. This test is deprecated in favor of
-// BookmarkAppTest.EngagementHistogramForAppInWindow and
-// BookmarkAppTest.EngagementHistogramForAppInTab.
-IN_PROC_BROWSER_TEST_P(HostedAppPWAOnlyTest, EngagementHistogram) {
-  base::HistogramTester histograms;
-  WebApplicationInfo web_app_info;
-  web_app_info.app_url = GURL(kExampleURL);
-  web_app_info.scope = GURL(kExampleURL);
-  web_app_info.theme_color = base::Optional<SkColor>();
-  const extensions::Extension* app = InstallBookmarkApp(web_app_info);
-  Browser* app_browser = LaunchAppBrowser(app);
-  NavigateToURLAndWait(app_browser, GURL(kExampleURL));
-
-  // Test shortcut launch.
-  EXPECT_EQ(web_app::GetAppIdFromApplicationName(app_browser->app_name()),
-            app->id());
-
-  histograms.ExpectUniqueSample(
-      extensions::kPwaWindowEngagementTypeHistogram,
-      SiteEngagementService::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH, 1);
-
-  // Test some other engagement events by directly calling into
-  // SiteEngagementService.
-  content::WebContents* web_contents =
-      app_browser->tab_strip_model()->GetActiveWebContents();
-  SiteEngagementService* site_engagement_service =
-      SiteEngagementService::Get(app_browser->profile());
-  site_engagement_service->HandleMediaPlaying(web_contents, false);
-  site_engagement_service->HandleMediaPlaying(web_contents, true);
-  site_engagement_service->HandleNavigation(web_contents,
-                                            ui::PAGE_TRANSITION_TYPED);
-  site_engagement_service->HandleUserInput(
-      web_contents, SiteEngagementService::ENGAGEMENT_MOUSE);
-
-  histograms.ExpectTotalCount(extensions::kPwaWindowEngagementTypeHistogram, 5);
-  histograms.ExpectBucketCount(extensions::kPwaWindowEngagementTypeHistogram,
-                               SiteEngagementService::ENGAGEMENT_MEDIA_VISIBLE,
-                               1);
-  histograms.ExpectBucketCount(extensions::kPwaWindowEngagementTypeHistogram,
-                               SiteEngagementService::ENGAGEMENT_MEDIA_HIDDEN,
-                               1);
-  histograms.ExpectBucketCount(extensions::kPwaWindowEngagementTypeHistogram,
-                               SiteEngagementService::ENGAGEMENT_NAVIGATION, 1);
-  histograms.ExpectBucketCount(extensions::kPwaWindowEngagementTypeHistogram,
-                               SiteEngagementService::ENGAGEMENT_MOUSE, 1);
-}
-
-// TODO(loyso): crbug.com/918089. This test is deprecated in favor of
-// BookmarkAppTest.EngagementHistogramAppWithoutScope and
-// BookmarkAppTest.EngagementHistogramRecordedForNonApps.
-IN_PROC_BROWSER_TEST_P(HostedAppPWAOnlyTest,
-                       EngagementHistogramNotRecordedIfNoScope) {
-  base::HistogramTester histograms;
-  WebApplicationInfo web_app_info;
-  // App with no scope.
-  web_app_info.app_url = GURL(kExampleURL);
-  web_app_info.theme_color = base::Optional<SkColor>();
-  const extensions::Extension* app = InstallBookmarkApp(web_app_info);
-  Browser* app_browser = LaunchAppBrowser(app);
-
-  EXPECT_EQ(web_app::GetAppIdFromApplicationName(app_browser->app_name()),
-            app->id());
-
-  histograms.ExpectTotalCount(extensions::kPwaWindowEngagementTypeHistogram, 0);
-}
-
-// TODO(loyso): crbug.com/918089. This test is deprecated in favor of
-// BookmarkAppTest.EngagementHistogramTwoApps.
-IN_PROC_BROWSER_TEST_P(HostedAppPWAOnlyTest, EngagementHistogramTwoApps) {
-  base::HistogramTester histograms;
-  const extensions::Extension *app1, *app2;
-
-  // Install two apps.
-  {
-    WebApplicationInfo web_app_info;
-    web_app_info.app_url = GURL(kExampleURL);
-    web_app_info.scope = GURL(kExampleURL);
-    web_app_info.theme_color = base::Optional<SkColor>();
-    app1 = InstallBookmarkApp(web_app_info);
-  }
-  {
-    WebApplicationInfo web_app_info;
-    web_app_info.app_url = GURL(kExampleURL2);
-    web_app_info.scope = GURL(kExampleURL2);
-    web_app_info.theme_color = base::Optional<SkColor>();
-    app2 = InstallBookmarkApp(web_app_info);
-  }
-
-  // Launch them three times. This ensures that each launch only logs once.
-  // (Since all apps receive the notification on launch, there is a danger that
-  // we might log too many times.)
-  Browser* app_browser1 = LaunchAppBrowser(app1);
-  Browser* app_browser2 = LaunchAppBrowser(app1);
-  Browser* app_browser3 = LaunchAppBrowser(app2);
-
-  EXPECT_EQ(web_app::GetAppIdFromApplicationName(app_browser1->app_name()),
-            app1->id());
-  EXPECT_EQ(web_app::GetAppIdFromApplicationName(app_browser2->app_name()),
-            app1->id());
-  EXPECT_EQ(web_app::GetAppIdFromApplicationName(app_browser3->app_name()),
-            app2->id());
-
-  histograms.ExpectUniqueSample(
-      extensions::kPwaWindowEngagementTypeHistogram,
-      SiteEngagementService::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH, 3);
-}
-
 // Common app manifest for HostedAppProcessModelTests.
 constexpr const char kHostedAppProcessModelManifest[] =
     R"( { "name": "Hosted App Process Model Test",
diff --git a/chrome/browser/ui/views/frame/browser_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
index 680ce42..d7e37f4 100644
--- a/chrome/browser/ui/views/frame/browser_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
@@ -215,7 +215,7 @@
 // Verifies we don't unnecessarily change the visibility of the BookmarkBarView.
 IN_PROC_BROWSER_TEST_F(BrowserViewTest, AvoidUnnecessaryVisibilityChanges) {
   // Create two tabs, the first empty and the second the ntp. Make it so the
-  // BookmarkBarView isn't shown (meaning it'll only be shown when on the ntp).
+  // BookmarkBarView isn't shown.
   browser()->profile()->GetPrefs()->SetBoolean(
       bookmarks::prefs::kShowBookmarkBar, false);
   GURL new_tab_url(chrome::kChromeUINewTabURL);
@@ -226,34 +226,29 @@
   BookmarkBarViewObserverImpl observer;
   BookmarkBarView* bookmark_bar = browser_view()->bookmark_bar();
   bookmark_bar->AddObserver(&observer);
-  EXPECT_TRUE(bookmark_bar->visible());
+  EXPECT_FALSE(bookmark_bar->visible());
 
   // Go to empty tab. Bookmark bar should hide.
   browser()->tab_strip_model()->ActivateTabAt(
       0, {TabStripModel::GestureType::kOther});
   EXPECT_FALSE(bookmark_bar->visible());
-  EXPECT_EQ(1, observer.change_count());
+  EXPECT_EQ(0, observer.change_count());
   observer.clear_change_count();
 
-  // Go to ntp tab. Bookmark bar should show.
+  // Go to ntp tab. Bookmark bar should not show.
   browser()->tab_strip_model()->ActivateTabAt(
       1, {TabStripModel::GestureType::kOther});
-  EXPECT_TRUE(bookmark_bar->visible());
-  EXPECT_EQ(1, observer.change_count());
+  EXPECT_FALSE(bookmark_bar->visible());
+  EXPECT_EQ(0, observer.change_count());
   observer.clear_change_count();
 
   // Repeat with the bookmark bar always visible.
   browser()->profile()->GetPrefs()->SetBoolean(
       bookmarks::prefs::kShowBookmarkBar, true);
   browser()->tab_strip_model()->ActivateTabAt(
-      1, {TabStripModel::GestureType::kOther});
-  EXPECT_TRUE(bookmark_bar->visible());
-  observer.clear_change_count();
-
-  browser()->tab_strip_model()->ActivateTabAt(
       0, {TabStripModel::GestureType::kOther});
   EXPECT_TRUE(bookmark_bar->visible());
-  EXPECT_EQ(0, observer.change_count());
+  EXPECT_EQ(1, observer.change_count());
   observer.clear_change_count();
 
   browser()->tab_strip_model()->ActivateTabAt(
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc
index 2e7f4f5..0111590 100644
--- a/chrome/browser/ui/views/frame/browser_view_unittest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -137,13 +137,12 @@
   EXPECT_FALSE(bookmark_bar->visible());
   EXPECT_FALSE(bookmark_bar->IsDetached());
 
-  // Bookmark bar is reparented to BrowserView on NTP.
+  // The NTP should be treated the same as any other page.
   NavigateAndCommitActiveTabWithTitle(browser,
                                       GURL(chrome::kChromeUINewTabURL),
                                       base::string16());
-  EXPECT_TRUE(bookmark_bar->visible());
-  EXPECT_TRUE(bookmark_bar->IsDetached());
-  EXPECT_EQ(browser_view(), bookmark_bar->parent());
+  EXPECT_FALSE(bookmark_bar->visible());
+  EXPECT_EQ(top_container, bookmark_bar->parent());
 
   // Find bar host is still at the front of the view hierarchy, followed by the
   // infobar container and then top container.
@@ -161,14 +160,6 @@
             contents_container->y());
   EXPECT_EQ(contents_web_view->y(), devtools_web_view->y());
 
-  // Bookmark bar is parented back to top container on normal page.
-  NavigateAndCommitActiveTabWithTitle(browser,
-                                      GURL("about:blank"),
-                                      base::string16());
-  EXPECT_FALSE(bookmark_bar->visible());
-  EXPECT_FALSE(bookmark_bar->IsDetached());
-  EXPECT_EQ(top_container, bookmark_bar->parent());
-
   BookmarkBarView::DisableAnimationsForTesting(false);
 }
 
diff --git a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
index 8807e6a7..99334c9 100644
--- a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
+++ b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/feature_list.h"
 #include "base/no_destructor.h"
@@ -56,14 +57,18 @@
   }
 }
 
-WebAppInstalledCallbackForTesting& GetInstalledCallbackForTesting() {
-  static base::NoDestructor<WebAppInstalledCallbackForTesting> instance;
+WebAppInstalledCallback& GetInstalledCallbackForTesting() {
+  static base::NoDestructor<WebAppInstalledCallback> instance;
   return *instance;
 }
 
-void OnWebAppInstalled(const AppId& installed_app_id, InstallResultCode code) {
+void OnWebAppInstalled(WebAppInstalledCallback callback,
+                       const AppId& installed_app_id,
+                       InstallResultCode code) {
   if (GetInstalledCallbackForTesting())
     std::move(GetInstalledCallbackForTesting()).Run(installed_app_id, code);
+
+  std::move(callback).Run(installed_app_id, code);
 }
 
 }  // namespace
@@ -87,15 +92,29 @@
   auto* provider = WebAppProvider::GetForWebContents(web_contents);
   DCHECK(provider);
 
+  WebAppInstalledCallback installed_callback = base::DoNothing();
+
   provider->install_manager().InstallWebApp(
       web_contents, force_shortcut_app,
       InstallableMetrics::GetInstallSource(web_contents, InstallTrigger::MENU),
       base::BindOnce(WebAppInstallDialogCallback),
-      base::BindOnce(OnWebAppInstalled));
+      base::BindOnce(OnWebAppInstalled, std::move(installed_callback)));
 }
 
-void SetInstalledCallbackForTesting(
-    WebAppInstalledCallbackForTesting callback) {
+bool CreateWebAppFromBanner(content::WebContents* web_contents,
+                            WebappInstallSource install_source,
+                            WebAppInstalledCallback installed_callback) {
+  auto* provider = WebAppProvider::GetForWebContents(web_contents);
+  if (!provider)
+    return false;
+
+  provider->install_manager().InstallWebAppFromBanner(
+      web_contents, install_source, base::BindOnce(WebAppInstallDialogCallback),
+      base::BindOnce(OnWebAppInstalled, std::move(installed_callback)));
+  return true;
+}
+
+void SetInstalledCallbackForTesting(WebAppInstalledCallback callback) {
   GetInstalledCallbackForTesting() = std::move(callback);
 }
 
diff --git a/chrome/browser/ui/web_applications/web_app_dialog_utils.h b/chrome/browser/ui/web_applications/web_app_dialog_utils.h
index f77d132e..6d41f19c 100644
--- a/chrome/browser/ui/web_applications/web_app_dialog_utils.h
+++ b/chrome/browser/ui/web_applications/web_app_dialog_utils.h
@@ -8,12 +8,20 @@
 #include "base/callback_forward.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 
+enum class WebappInstallSource;
 class Browser;
 
+namespace content {
+class WebContents;
+}
+
 namespace web_app {
 
 enum class InstallResultCode;
 
+// TODO(loyso): Rework these functions (API) once BookmarkAppHelper erased.
+// crbug.com/915043.
+
 // Returns true if a WebApp installation is allowed for the current page.
 bool CanCreateWebApp(const Browser* browser);
 
@@ -21,9 +29,17 @@
 void CreateWebAppFromCurrentWebContents(Browser* browser,
                                         bool force_shortcut_app);
 
-using WebAppInstalledCallbackForTesting =
+using WebAppInstalledCallback =
     base::OnceCallback<void(const AppId& app_id, InstallResultCode code)>;
-void SetInstalledCallbackForTesting(WebAppInstalledCallbackForTesting callback);
+
+// Starts install of a WebApp for a given |web_contents|, initiated from
+// Application's Banner UI.
+// Returns false if WebApps are disabled for the profile behind |web_contents|.
+bool CreateWebAppFromBanner(content::WebContents* web_contents,
+                            WebappInstallSource install_source,
+                            WebAppInstalledCallback installed_callback);
+
+void SetInstalledCallbackForTesting(WebAppInstalledCallback callback);
 
 }  // namespace web_app
 
diff --git a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.cc b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.cc
index d5aefed..d95ecec 100644
--- a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.cc
+++ b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.cc
@@ -4,16 +4,86 @@
 
 #include "chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h"
 
+#include <memory>
+#include <utility>
+
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/extensions/bookmark_app_helper.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
+#include "chrome/common/web_application_info.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "extensions/common/extension.h"
 
 namespace extensions {
 
+namespace {
+
+// A single installation task. It is possible to have many concurrent
+// installations per one |web_contents|.
+// This class is a simple holder of BookmarkAppHelper and limits its lifetime to
+// match WebContents.
+class InstallTask : public content::WebContentsObserver {
+ public:
+  InstallTask(content::WebContents* web_contents,
+              std::unique_ptr<BookmarkAppHelper> bookmark_app_helper,
+              web_app::InstallManager::OnceInstallCallback callback)
+      : WebContentsObserver(web_contents),
+        bookmark_app_helper_(std::move(bookmark_app_helper)),
+        callback_(std::move(callback)) {}
+
+  // WebContentsObserver:
+  void WebContentsDestroyed() override {
+    if (callback_) {
+      CallInstallCallback(web_app::AppId(),
+                          web_app::InstallResultCode::kWebContentsDestroyed);
+    }
+    // BookmarkAppHelper should not outsurvive |web_contents|.
+    // This |reset| invalidates all weak references to BookmarkAppHelper and
+    // cancels BookmarkAppHelper-related tasks posted to message loops.
+    bookmark_app_helper_.reset();
+  }
+
+  void CallInstallCallback(const web_app::AppId& app_id,
+                           web_app::InstallResultCode code) {
+    DCHECK(callback_);
+    std::move(callback_).Run(app_id, code);
+  }
+
+ private:
+  std::unique_ptr<BookmarkAppHelper> bookmark_app_helper_;
+  web_app::InstallManager::OnceInstallCallback callback_;
+  DISALLOW_COPY_AND_ASSIGN(InstallTask);
+};
+
+void DestroyInstallTask(std::unique_ptr<InstallTask> install_task) {
+  install_task.reset();
+}
+
+void OnBookmarkAppInstalled(std::unique_ptr<InstallTask> install_task,
+                            const Extension* app,
+                            const WebApplicationInfo& web_app_info) {
+  if (app) {
+    install_task->CallInstallCallback(app->id(),
+                                      web_app::InstallResultCode::kSuccess);
+  } else {
+    install_task->CallInstallCallback(
+        web_app::AppId(), web_app::InstallResultCode::kFailedUnknownReason);
+  }
+
+  // OnBookmarkAppInstalled is called synchronously by BookmarkAppHelper.
+  // Post async task to destroy InstallTask with BookmarkAppHelper later.
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(DestroyInstallTask, std::move(install_task)));
+}
+
+}  // namespace
+
 BookmarkAppInstallManager::BookmarkAppInstallManager() = default;
 
 BookmarkAppInstallManager::~BookmarkAppInstallManager() = default;
@@ -30,11 +100,9 @@
     WebappInstallSource install_source,
     WebAppInstallDialogCallback dialog_callback,
     OnceInstallCallback callback) {
-  // Ignore dialog_callback for legacy installations.
-  // BookmarkAppHelper directly uses chrome::ShowPWAInstallDialog from UI
-  // (which is a layering violation).
-  // Ignore install_source: extensions::TabHelper specifies it.
-  // TODO(loyso): Unify it. crbug.com/915043.
+  // |dialog_callback| is ignored here: BookmarkAppHelper directly uses UI's
+  // chrome::ShowPWAInstallDialog.
+  // |install_source| is also ignored here: extensions::TabHelper specifies it.
   extensions::TabHelper::FromWebContents(web_contents)
       ->CreateHostedAppFromWebContents(
           force_shortcut_app,
@@ -49,4 +117,30 @@
               std::move(callback)));
 }
 
+void BookmarkAppInstallManager::InstallWebAppFromBanner(
+    content::WebContents* web_contents,
+    WebappInstallSource install_source,
+    WebAppInstallDialogCallback dialog_callback,
+    OnceInstallCallback callback) {
+  // |dialog_callback| is ignored here:
+  // BookmarkAppHelper directly uses UI's chrome::ShowPWAInstallDialog.
+
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
+  WebApplicationInfo web_app_info;
+
+  auto bookmark_app_helper = std::make_unique<BookmarkAppHelper>(
+      profile, web_app_info, web_contents, install_source);
+
+  BookmarkAppHelper* helper = bookmark_app_helper.get();
+
+  auto install_task = std::make_unique<InstallTask>(
+      web_contents, std::move(bookmark_app_helper), std::move(callback));
+
+  // BookmarkAppHelper is owned by the bind state and will be disposed in
+  // DestroyInstallTask.
+  helper->Create(base::BindRepeating(OnBookmarkAppInstalled,
+                                     base::Passed(std::move(install_task))));
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h
index ea63493..61651e8 100644
--- a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h
+++ b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h
@@ -10,6 +10,8 @@
 
 namespace extensions {
 
+// TODO(loyso): Erase this subclass together with BookmarkAppHelper.
+// crbug.com/915043.
 class BookmarkAppInstallManager final : public web_app::InstallManager {
  public:
   BookmarkAppInstallManager();
@@ -22,6 +24,10 @@
                      WebappInstallSource install_source,
                      WebAppInstallDialogCallback dialog_callback,
                      OnceInstallCallback callback) override;
+  void InstallWebAppFromBanner(content::WebContents* web_contents,
+                               WebappInstallSource install_source,
+                               WebAppInstallDialogCallback dialog_callback,
+                               OnceInstallCallback callback) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(BookmarkAppInstallManager);
diff --git a/chrome/browser/web_applications/components/install_manager.h b/chrome/browser/web_applications/components/install_manager.h
index 19ba8a4..3123b9e 100644
--- a/chrome/browser/web_applications/components/install_manager.h
+++ b/chrome/browser/web_applications/components/install_manager.h
@@ -22,6 +22,8 @@
 
 enum class InstallResultCode;
 
+// TODO(loyso): Rework this interface once BookmarkAppHelper erased. Unify the
+// API and merge similar InstallWebAppZZZZ functions. crbug.com/915043.
 class InstallManager {
  public:
   using OnceInstallCallback =
@@ -53,6 +55,14 @@
                              WebAppInstallDialogCallback dialog_callback,
                              OnceInstallCallback callback) = 0;
 
+  // Starts a web app installation process for a given |web_contents|, initiated
+  // by WebApp script. Bypasses the GetWebApplicationInfo from renderer step.
+  virtual void InstallWebAppFromBanner(
+      content::WebContents* web_contents,
+      WebappInstallSource install_source,
+      WebAppInstallDialogCallback dialog_callback,
+      OnceInstallCallback callback) = 0;
+
   virtual ~InstallManager() = default;
 };
 
diff --git a/chrome/browser/web_applications/web_app_install_manager.cc b/chrome/browser/web_applications/web_app_install_manager.cc
index c809e59..f5df242c 100644
--- a/chrome/browser/web_applications/web_app_install_manager.cc
+++ b/chrome/browser/web_applications/web_app_install_manager.cc
@@ -65,6 +65,15 @@
                      weak_ptr_factory_.GetWeakPtr(), force_shortcut_app));
 }
 
+void WebAppInstallManager::InstallWebAppFromBanner(
+    content::WebContents* contents,
+    WebappInstallSource install_source,
+    WebAppInstallDialogCallback dialog_callback,
+    OnceInstallCallback callback) {
+  // TODO(loyso): Implement it.
+  NOTIMPLEMENTED();
+}
+
 void WebAppInstallManager::WebContentsDestroyed() {
   ReturnError(InstallResultCode::kWebContentsDestroyed);
 }
diff --git a/chrome/browser/web_applications/web_app_install_manager.h b/chrome/browser/web_applications/web_app_install_manager.h
index 20d2b42..0ab47a2 100644
--- a/chrome/browser/web_applications/web_app_install_manager.h
+++ b/chrome/browser/web_applications/web_app_install_manager.h
@@ -44,6 +44,10 @@
                      WebappInstallSource install_source,
                      WebAppInstallDialogCallback dialog_callback,
                      OnceInstallCallback callback) override;
+  void InstallWebAppFromBanner(content::WebContents* contents,
+                               WebappInstallSource install_source,
+                               WebAppInstallDialogCallback dialog_callback,
+                               OnceInstallCallback callback) override;
 
   // WebContentsObserver:
   void WebContentsDestroyed() override;
diff --git a/chrome/common/extensions/docs/templates/articles/content_scripts.html b/chrome/common/extensions/docs/templates/articles/content_scripts.html
index c9cbfdb..7b30fa29 100644
--- a/chrome/common/extensions/docs/templates/articles/content_scripts.html
+++ b/chrome/common/extensions/docs/templates/articles/content_scripts.html
@@ -232,6 +232,25 @@
      for information on how to exclude URLs.
    </td>
  </tr>
+ <tr id="matches_about_blank">
+   <td>
+     <code>matches_about_blank</code>
+   </td>
+   <td>
+     boolean
+   </td>
+   <td>
+     <em>Optional.</em>
+     Defaults to <code>false</code>.
+     <br><br>
+     Whether to insert the content script on <code>about:blank</code> and
+     <code>about:srcdoc</code>. Content scripts will only be injected on pages
+     when the URL of the document that created the frame or window is matched
+     by one of the declared patterns in the <code>matches</code> field.
+     <br>
+     Content scripts cannot be inserted in sandboxed frames.
+   </td>
+ </tr>
  <tr id="css">
    <td>
      <code>css<code>
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 27f4cff3..82ac3067 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1318,13 +1318,13 @@
          prerender::PREFETCH_ONLY;
 }
 
-unsigned long long ChromeContentRendererClient::VisitedLinkHash(
-    const char* canonical_url, size_t length) {
+uint64_t ChromeContentRendererClient::VisitedLinkHash(const char* canonical_url,
+                                                      size_t length) {
   return chrome_observer_->visited_link_slave()->ComputeURLFingerprint(
       canonical_url, length);
 }
 
-bool ChromeContentRendererClient::IsLinkVisited(unsigned long long link_hash) {
+bool ChromeContentRendererClient::IsLinkVisited(uint64_t link_hash) {
   return chrome_observer_->visited_link_slave()->IsVisited(link_hash);
 }
 
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 315fade..c9c7992 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -145,9 +145,8 @@
                        bool* attach_same_site_cookies) override;
   bool IsPrefetchOnly(content::RenderFrame* render_frame,
                       const blink::WebURLRequest& request) override;
-  unsigned long long VisitedLinkHash(const char* canonical_url,
-                                     size_t length) override;
-  bool IsLinkVisited(unsigned long long link_hash) override;
+  uint64_t VisitedLinkHash(const char* canonical_url, size_t length) override;
+  bool IsLinkVisited(uint64_t link_hash) override;
   blink::WebPrescientNetworking* GetPrescientNetworking() override;
   bool IsPrerenderingFrame(const content::RenderFrame* render_frame) override;
   bool IsExternalPepperPlugin(const std::string& module_name) override;
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.cc b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
index b1fc9d2..8ab33ba3 100644
--- a/chrome/renderer/extensions/automation_internal_custom_bindings.cc
+++ b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
@@ -34,6 +34,7 @@
 #include "gin/converter.h"
 #include "gin/data_object_builder.h"
 #include "ipc/message_filter.h"
+#include "third_party/blink/public/web/web_local_frame.h"
 #include "ui/accessibility/ax_enum_util.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/accessibility/ax_event.h"
@@ -438,11 +439,12 @@
 
 class AutomationMessageFilter : public IPC::MessageFilter {
  public:
-  explicit AutomationMessageFilter(AutomationInternalCustomBindings* owner)
-      : owner_(owner), removed_(false) {
+  AutomationMessageFilter(
+      AutomationInternalCustomBindings* owner,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+      : owner_(owner), removed_(false), task_runner_(std::move(task_runner)) {
     DCHECK(owner);
     content::RenderThread::Get()->AddFilter(this);
-    task_runner_ = base::ThreadTaskRunnerHandle::Get();
   }
 
   void Detach() {
@@ -1243,8 +1245,12 @@
   if (should_ignore_context_)
     return;
 
-  if (!message_filter_)
-    message_filter_ = new AutomationMessageFilter(this);
+  if (!message_filter_) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+        context()->web_frame()->GetTaskRunner(
+            blink::TaskType::kInternalDefault);
+    message_filter_ = new AutomationMessageFilter(this, std::move(task_runner));
+  }
 }
 
 void AutomationInternalCustomBindings::GetSchemaAdditions(
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc b/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
index c711cbd8..f9eb25a 100644
--- a/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
+++ b/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
@@ -41,9 +41,8 @@
   ~TestChromeContentRendererClient() override {}
   // Since visited_link_slave_ in ChromeContentRenderClient never get initiated,
   // overrides VisitedLinkedHash() function to prevent crashing.
-  unsigned long long VisitedLinkHash(const char* canonical_url,
-                                     size_t length) override {
-    return 0LL;
+  uint64_t VisitedLinkHash(const char* canonical_url, size_t length) override {
+    return 0;
   }
 };
 
diff --git a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
index ad89e44..c50d133 100644
--- a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
+++ b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
@@ -131,9 +131,8 @@
   ~TestChromeContentRendererClient() override {}
   // Since visited_link_slave_ in ChromeContentRenderClient never get initiated,
   // overrides VisitedLinkedHash() function to prevent crashing.
-  unsigned long long VisitedLinkHash(const char* canonical_url,
-                                     size_t length) override {
-    return 0LL;
+  uint64_t VisitedLinkHash(const char* canonical_url, size_t length) override {
+    return 0;
   }
 };
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 4c08f50..a501322 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -581,6 +581,7 @@
       "../app/chrome_version.rc.version",
       "../browser/accessibility/accessibility_labels_service_browsertest.cc",
       "../browser/accessibility/browser_accessibility_state_browsertest.cc",
+      "../browser/accessibility/image_annotation_browsertest.cc",
       "../browser/accessibility/interstitial_accessibility_browsertest.cc",
       "../browser/app_controller_mac_browsertest.mm",
       "../browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm",
@@ -4074,6 +4075,7 @@
       "//google_apis",
       "//google_apis/drive",
       "//media/cast:test_support",
+      "//services/device/public/cpp/hid:test_support",
       "//services/network/public/mojom",
 
       # This will add all of the unit tests for the schema compiler to this
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc
index 73729a41..1d43bf2d 100644
--- a/chrome/test/chromedriver/capabilities.cc
+++ b/chrome/test/chromedriver/capabilities.cc
@@ -756,7 +756,14 @@
   } else {
     parser_map["chromeOptions"] = base::BindRepeating(&ParseChromeOptions);
   }
-  parser_map["loggingPrefs"] = base::BindRepeating(&ParseLoggingPrefs);
+  // goog:loggingPrefs is spec-compliant name, but loggingPrefs is still
+  // supported in legacy mode.
+  if (w3c_compliant ||
+      desired_caps.GetDictionary("goog:loggingPrefs", nullptr)) {
+    parser_map["goog:loggingPrefs"] = base::BindRepeating(&ParseLoggingPrefs);
+  } else {
+    parser_map["loggingPrefs"] = base::BindRepeating(&ParseLoggingPrefs);
+  }
   // Network emulation requires device mode, which is only enabled when
   // mobile emulation is on.
   if (desired_caps.GetDictionary("goog:chromeOptions.mobileEmulation",
diff --git a/chrome/test/chromedriver/capabilities_unittest.cc b/chrome/test/chromedriver/capabilities_unittest.cc
index 9c31b18..824a0d2 100644
--- a/chrome/test/chromedriver/capabilities_unittest.cc
+++ b/chrome/test/chromedriver/capabilities_unittest.cc
@@ -380,7 +380,7 @@
   base::DictionaryValue logging_prefs;
   logging_prefs.SetString("Network", "INFO");
   base::DictionaryValue caps;
-  caps.SetKey("loggingPrefs", std::move(logging_prefs));
+  caps.SetKey("goog:loggingPrefs", std::move(logging_prefs));
   Status status = capabilities.Parse(caps);
   ASSERT_TRUE(status.IsOk());
   ASSERT_EQ(1u, capabilities.logging_prefs.size());
@@ -390,7 +390,7 @@
 TEST(ParseCapabilities, LoggingPrefsNotDict) {
   Capabilities capabilities;
   base::DictionaryValue caps;
-  caps.SetString("loggingPrefs", "INFO");
+  caps.SetString("goog:loggingPrefs", "INFO");
   Status status = capabilities.Parse(caps);
   ASSERT_FALSE(status.IsOk());
 }
@@ -401,7 +401,7 @@
   base::DictionaryValue logging_prefs;
   logging_prefs.SetString(WebDriverLog::kPerformanceType, "INFO");
   base::DictionaryValue desired_caps;
-  desired_caps.SetKey("loggingPrefs", std::move(logging_prefs));
+  desired_caps.SetKey("goog:loggingPrefs", std::move(logging_prefs));
   ASSERT_EQ(PerfLoggingPrefs::InspectorDomainStatus::kDefaultEnabled,
             capabilities.perf_logging_prefs.network);
   ASSERT_EQ(PerfLoggingPrefs::InspectorDomainStatus::kDefaultEnabled,
@@ -425,7 +425,7 @@
   base::DictionaryValue logging_prefs;
   logging_prefs.SetString(WebDriverLog::kPerformanceType, "INFO");
   base::DictionaryValue desired_caps;
-  desired_caps.SetKey("loggingPrefs", std::move(logging_prefs));
+  desired_caps.SetKey("goog:loggingPrefs", std::move(logging_prefs));
   ASSERT_EQ("", capabilities.perf_logging_prefs.trace_categories);
   base::DictionaryValue perf_logging_prefs;
   perf_logging_prefs.SetString("traceCategories", "benchmark,blink.console");
@@ -446,7 +446,7 @@
   base::DictionaryValue logging_prefs;
   logging_prefs.SetString(WebDriverLog::kPerformanceType, "INFO");
   base::DictionaryValue desired_caps;
-  desired_caps.SetKey("loggingPrefs", std::move(logging_prefs));
+  desired_caps.SetKey("goog:loggingPrefs", std::move(logging_prefs));
   base::DictionaryValue perf_logging_prefs;
   // A bufferUsageReportingInterval interval <= 0 will cause DevTools errors.
   perf_logging_prefs.SetInteger("bufferUsageReportingInterval", 0);
@@ -462,7 +462,7 @@
   base::DictionaryValue logging_prefs;
   logging_prefs.SetString(WebDriverLog::kPerformanceType, "INFO");
   base::DictionaryValue desired_caps;
-  desired_caps.SetKey("loggingPrefs", std::move(logging_prefs));
+  desired_caps.SetKey("goog:loggingPrefs", std::move(logging_prefs));
   desired_caps.SetString("goog:chromeOptions.perfLoggingPrefs",
                          "traceCategories");
   Status status = capabilities.Parse(desired_caps);
@@ -487,7 +487,7 @@
   // Disable performance log by setting logging level to OFF.
   logging_prefs.SetString(WebDriverLog::kPerformanceType, "OFF");
   base::DictionaryValue desired_caps;
-  desired_caps.SetKey("loggingPrefs", std::move(logging_prefs));
+  desired_caps.SetKey("goog:loggingPrefs", std::move(logging_prefs));
   base::DictionaryValue perf_logging_prefs;
   perf_logging_prefs.SetBoolean("enableNetwork", true);
   desired_caps.SetPath({"goog:chromeOptions", "perfLoggingPrefs"},
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py
index 16299e4..94ee53a 100644
--- a/chrome/test/chromedriver/client/chromedriver.py
+++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -231,7 +231,7 @@
 
     params = {
         'goog:chromeOptions': options,
-        'loggingPrefs': logging_prefs
+        'goog:loggingPrefs': logging_prefs
     }
 
     if page_load_strategy:
diff --git a/chrome/test/data/accessibility/green.png b/chrome/test/data/accessibility/green.png
new file mode 100644
index 0000000..c7510d38
--- /dev/null
+++ b/chrome/test/data/accessibility/green.png
Binary files differ
diff --git a/chrome/test/data/accessibility/image_annotation.html b/chrome/test/data/accessibility/image_annotation.html
new file mode 100644
index 0000000..27fb7af
--- /dev/null
+++ b/chrome/test/data/accessibility/image_annotation.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<body>
+  <img src="red.png" width=16 height=16>
+  <img src="green.png" width=16 height=16>
+  <img src="printer.png">
+</body>
diff --git a/chrome/test/data/accessibility/printer.png b/chrome/test/data/accessibility/printer.png
new file mode 100644
index 0000000..a38a537
--- /dev/null
+++ b/chrome/test/data/accessibility/printer.png
Binary files differ
diff --git a/chrome/test/data/accessibility/red.png b/chrome/test/data/accessibility/red.png
new file mode 100644
index 0000000..38e6aa33
--- /dev/null
+++ b/chrome/test/data/accessibility/red.png
Binary files differ
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index e34d073..f777f46 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -167,7 +167,6 @@
     "//components/metrics",
     "//components/metrics:gpu",
     "//components/metrics:net",
-    "//components/variations/net",
 
     # TODO(gfhuang): Eliminate this dependency if ScreenInfoMetricsProvider
     # isn't needed. crbug.com/541577
@@ -403,7 +402,6 @@
 
   deps = [
     "//base",
-    "//components/variations/net",
     "//content/public/browser",
     "//net",
     "//services/network:network_service",
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS
index 70336de..ea72b8b 100644
--- a/chromecast/browser/DEPS
+++ b/chromecast/browser/DEPS
@@ -20,7 +20,6 @@
   "+components/proxy_config",
   "+components/storage_monitor",
   "+components/user_prefs",
-  "+components/variations/net",
   "+components/version_info",
   "+components/viz/common/switches.h",
   "+components/zoom",
diff --git a/chromecast/browser/cast_network_contexts.cc b/chromecast/browser/cast_network_contexts.cc
index 3028b60..c5faa86 100644
--- a/chromecast/browser/cast_network_contexts.cc
+++ b/chromecast/browser/cast_network_contexts.cc
@@ -17,7 +17,6 @@
 #include "chromecast/browser/url_request_context_factory.h"
 #include "chromecast/common/cast_content_client.h"
 #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
-#include "components/variations/net/variations_http_headers.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/network_service_instance.h"
@@ -101,14 +100,9 @@
                   scoped_refptr<net::URLRequestContextGetter> context_getter) {
     DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
     context_getter_ = std::move(context_getter);
-    network::mojom::NetworkContextParamsPtr network_context_params =
-        network::mojom::NetworkContextParams::New();
-    variations::UpdateCorsExemptHeaderForVariations(
-        network_context_params.get());
     network_context_ = std::make_unique<network::NetworkContext>(
         content::GetNetworkServiceImpl(), std::move(network_context_request),
-        context_getter_->GetURLRequestContext(),
-        network_context_params->cors_exempt_header_list);
+        context_getter_->GetURLRequestContext());
   }
 
  private:
diff --git a/chromecast/browser/network_context_manager.cc b/chromecast/browser/network_context_manager.cc
index 3594894..0375567 100644
--- a/chromecast/browser/network_context_manager.cc
+++ b/chromecast/browser/network_context_manager.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/task/post_task.h"
-#include "components/variations/net/variations_http_headers.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/network_service_instance.h"
@@ -50,13 +49,9 @@
   network::NetworkService* network_service =
       network_service_for_test_ ? network_service_for_test_.get()
                                 : content::GetNetworkServiceImpl();
-  network::mojom::NetworkContextParamsPtr network_context_params =
-      network::mojom::NetworkContextParams::New();
-  variations::UpdateCorsExemptHeaderForVariations(network_context_params.get());
   network_context_ = std::make_unique<network::NetworkContext>(
       network_service, mojo::MakeRequest(&network_context_ptr_),
-      url_request_context_getter_->GetURLRequestContext(),
-      network_context_params->cors_exempt_header_list);
+      url_request_context_getter_->GetURLRequestContext());
 }
 
 void NetworkContextManager::BindRequestOnIOThread(
diff --git a/chromeos/services/ime/public/cpp/rulebased/def/vi_vni.cc b/chromeos/services/ime/public/cpp/rulebased/def/vi_vni.cc
index f1e28c9..5ac5f6b 100644
--- a/chromeos/services/ime/public/cpp/rulebased/def/vi_vni.cc
+++ b/chromeos/services/ime/public/cpp/rulebased/def/vi_vni.cc
@@ -15,29 +15,29 @@
     u8"\u0111",
     u8"D\u001d?9",
     u8"\u0110",
-    u8"(.*)a\u001d?6",
+    u8"(\\w*)a\u001d?6",
     u8"\\1\u00e2",
-    u8"(.*)e\u001d?6",
+    u8"(\\w*)e\u001d?6",
     u8"\\1\u00ea",
-    u8"(.*)o\u001d?6",
+    u8"(\\w*)o\u001d?6",
     u8"\\1\u00f4",
-    u8"(.*)a\u001d?8",
+    u8"(\\w*)a\u001d?8",
     u8"\\1\u0103",
-    u8"(.*)o\u001d?7",
+    u8"(\\w*)o\u001d?7",
     u8"\\1\u01a1",
-    u8"(.*)u\u001d?7",
+    u8"(\\w*)u\u001d?7",
     u8"\\1\u01b0",
-    u8"(.*)A\u001d?6",
+    u8"(\\w*)A\u001d?6",
     u8"\\1\u00c2",
-    u8"(.*)E\u001d?6",
+    u8"(\\w*)E\u001d?6",
     u8"\\1\u00ca",
-    u8"(.*)O\u001d?6",
+    u8"(\\w*)O\u001d?6",
     u8"\\1\u00d4",
-    u8"(.*)A\u001d?8",
+    u8"(\\w*)A\u001d?8",
     u8"\\1\u0102",
-    u8"(.*)O\u001d?7",
+    u8"(\\w*)O\u001d?7",
     u8"\\1\u01a0",
-    u8"(.*)U\u001d?7",
+    u8"(\\w*)U\u001d?7",
     u8"\\1\u01af",
     u8"(([qQ][uU]|[gG][iI])?[aeiouyAEIOUY])([aeiouyAEIOUY]?|["
     u8"bcdghklmnpqtvBCDGHKLMNPQTV]+)\u001d?2",
diff --git a/chromeos/services/ime/public/cpp/shared_lib/interfaces.h b/chromeos/services/ime/public/cpp/shared_lib/interfaces.h
index de8ab1f..babb647 100644
--- a/chromeos/services/ime/public/cpp/shared_lib/interfaces.h
+++ b/chromeos/services/ime/public/cpp/shared_lib/interfaces.h
@@ -65,6 +65,9 @@
 // This class should be provided by the IME service before creating an
 // `ImeEngineMainEntry` and be always owned by the IME service.
 class Platform {
+ protected:
+  ~Platform() = default;
+
  public:
   // The three methods below are Getters of the local data directories on the
   // platform. It's possible for the IME service to be running in a mode where
@@ -76,11 +79,11 @@
   // Get the local IME bundle directory, which is read-only.
   virtual const char* GetImeBundleDir() = 0;
 
-  // Get the local IME global directory, which is accessible to all users.
+  // Get the IME global directory, which is accessible to all users.
   virtual const char* GetImeGlobalDir() = 0;
 
-  // Get the local IME directory in the acitve user's home, which is only
-  // accessible to that user.
+  // Get the local IME directory in home directory of the active user, which
+  // is only accessible to the user itself.
   virtual const char* GetImeUserHomeDir() = 0;
 
   // TODO(https://crbug.com/837156): Provide Downloader/Logger for main entry.
@@ -91,6 +94,9 @@
 // This is used to send messages to connected IME client from an IME engine.
 // IME service will create then pass it to the engine.
 class ImeClientDelegate {
+ protected:
+  ~ImeClientDelegate() = default;
+
  public:
   // Returns the c_str() of the internal IME specification of ImeClientDelegate.
   // The IME specification will be invalidated by its `Destroy` method.
@@ -103,9 +109,6 @@
   // Destroy the `ImeClientDelegate` instance, which is called in the shared
   // library when the bound engine is destroyed.
   virtual void Destroy() = 0;
-
- protected:
-  ~ImeClientDelegate();
 };
 
 // The main entry point of an IME shared library.
@@ -114,6 +117,9 @@
 // clients of the IME service. The shared library will exposes its create
 // function to the IME service.
 class ImeEngineMainEntry {
+ protected:
+  ~ImeEngineMainEntry() = default;
+
  public:
   // Returns whether a specific IME is supported by this IME shared library.
   // The argument is the specfiation name of an IME, and the caller should
@@ -133,9 +139,6 @@
   // Destroy the `ImeEngineMainEntry` instance, which is called in IME service
   // on demand.
   virtual void Destroy() = 0;
-
- protected:
-  ~ImeEngineMainEntry();
 };
 
 // Create ImeEngineMainEntry instance from the IME engine shared library.
diff --git a/components/cast_channel/cast_socket_unittest.cc b/components/cast_channel/cast_socket_unittest.cc
index 9dbb116..9f1d9ca 100644
--- a/components/cast_channel/cast_socket_unittest.cc
+++ b/components/cast_channel/cast_socket_unittest.cc
@@ -389,8 +389,7 @@
     url_request_context_.Init();
     network_context_ = std::make_unique<network::NetworkContext>(
         nullptr, mojo::MakeRequest(&network_context_ptr_),
-        &url_request_context_,
-        /*cors_exempt_header_list=*/std::vector<std::string>());
+        &url_request_context_);
   }
 
   // Runs all pending tasks in the message loop.
diff --git a/components/password_manager/core/browser/hsts_query_unittest.cc b/components/password_manager/core/browser/hsts_query_unittest.cc
index ebd21cb..e9c4fcd1 100644
--- a/components/password_manager/core/browser/hsts_query_unittest.cc
+++ b/components/password_manager/core/browser/hsts_query_unittest.cc
@@ -64,8 +64,7 @@
         network_context_(std::make_unique<network::NetworkContext>(
             nullptr,
             mojo::MakeRequest(&network_context_pipe_),
-            request_context_->GetURLRequestContext(),
-            /*cors_exempt_header_list=*/std::vector<std::string>())) {}
+            request_context_->GetURLRequestContext())) {}
 
   network::NetworkContext* network_context() { return network_context_.get(); }
 
diff --git a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
index a61e7c3..953610cd 100644
--- a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
+++ b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
@@ -177,8 +177,7 @@
   network::mojom::NetworkContextPtr network_context_pipe;
   auto network_context = std::make_unique<network::NetworkContext>(
       nullptr, mojo::MakeRequest(&network_context_pipe),
-      request_context->GetURLRequestContext(),
-      /*cors_exempt_header_list=*/std::vector<std::string>());
+      request_context->GetURLRequestContext());
 
   if (test.is_hsts_enabled) {
     base::RunLoop run_loop;
@@ -285,8 +284,7 @@
     network::mojom::NetworkContextPtr network_context_pipe;
     auto network_context = std::make_unique<network::NetworkContext>(
         nullptr, mojo::MakeRequest(&network_context_pipe),
-        request_context->GetURLRequestContext(),
-        /*cors_exempt_header_list=*/std::vector<std::string>());
+        request_context->GetURLRequestContext());
 
     MockCredentialsCleanerObserver observer;
     HttpCredentialCleaner cleaner(
diff --git a/components/safe_browsing/browser/safe_browsing_network_context.cc b/components/safe_browsing/browser/safe_browsing_network_context.cc
index 9dda8d74d..5f1f917 100644
--- a/components/safe_browsing/browser/safe_browsing_network_context.cc
+++ b/components/safe_browsing/browser/safe_browsing_network_context.cc
@@ -149,8 +149,7 @@
       request_context_getter_ = std::move(request_context_getter);
       network_context_impl_ = std::make_unique<network::NetworkContext>(
           content::GetNetworkServiceImpl(), std::move(network_context_request),
-          request_context_getter_->GetURLRequestContext(),
-          /*cors_exempt_header_list=*/std::vector<std::string>());
+          request_context_getter_->GetURLRequestContext());
     }
 
     scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
diff --git a/components/search_engines/BUILD.gn b/components/search_engines/BUILD.gn
index e8ad401..458c948 100644
--- a/components/search_engines/BUILD.gn
+++ b/components/search_engines/BUILD.gn
@@ -19,8 +19,6 @@
     "keyword_web_data_service.h",
     "search_engine_data_type_controller.cc",
     "search_engine_data_type_controller.h",
-    "search_engine_model_type_controller.cc",
-    "search_engine_model_type_controller.h",
     "search_engine_type.h",
     "search_engines_pref_names.cc",
     "search_engines_pref_names.h",
diff --git a/components/search_engines/search_engine_model_type_controller.cc b/components/search_engines/search_engine_model_type_controller.cc
deleted file mode 100644
index d655198..0000000
--- a/components/search_engines/search_engine_model_type_controller.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/search_engines/search_engine_model_type_controller.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "components/search_engines/template_url_service.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/model_impl/client_tag_based_model_type_processor.h"
-#include "components/sync/model_impl/forwarding_model_type_controller_delegate.h"
-#include "components/sync/model_impl/syncable_service_based_bridge.h"
-
-namespace browser_sync {
-
-namespace {
-
-// Similar to ForwardingModelTypeControllerDelegate, but allows owning a bridge
-// and deferring OnSyncStarting() until TemplateURLService is loaded.
-class ControllerDelegate
-    : public syncer::ForwardingModelTypeControllerDelegate {
- public:
-  // |bridge| and |template_url_service| must not be null.
-  ControllerDelegate(std::unique_ptr<syncer::ModelTypeSyncBridge> bridge,
-                     TemplateURLService* template_url_service)
-      : ForwardingModelTypeControllerDelegate(
-            bridge->change_processor()->GetControllerDelegate().get()),
-        bridge_(std::move(bridge)),
-        template_url_service_(template_url_service) {}
-
-  ~ControllerDelegate() override = default;
-
-  void OnSyncStarting(const syncer::DataTypeActivationRequest& request,
-                      StartCallback callback) override {
-    DCHECK(!template_url_subscription_);
-
-    // We force a load here to allow remote updates to be processed, without
-    // waiting for TemplateURLService's lazy load.
-    template_url_service_->Load();
-
-    // If the service is loaded, continue normally, which means requesting the
-    // processor to start.
-    if (template_url_service_->loaded()) {
-      ForwardingModelTypeControllerDelegate::OnSyncStarting(
-          request, std::move(callback));
-      return;
-    }
-
-    // Otherwise, wait until it becomes ready. Using base::Unretained() should
-    // be safe here because the subscription itself will be destroyed together
-    // with this object.
-    template_url_subscription_ =
-        template_url_service_->RegisterOnLoadedCallback(
-            base::AdaptCallbackForRepeating(base::BindOnce(
-                &ControllerDelegate::OnTemplateURLServiceLoaded,
-                base::Unretained(this), request, std::move(callback))));
-  }
-
- private:
-  void OnTemplateURLServiceLoaded(
-      const syncer::DataTypeActivationRequest& request,
-      StartCallback callback) {
-    template_url_subscription_.reset();
-    DCHECK(template_url_service_->loaded());
-    // Now that we're loaded, continue normally, which means requesting the
-    // processor to start.
-    ForwardingModelTypeControllerDelegate::OnSyncStarting(request,
-                                                          std::move(callback));
-  }
-
-  const std::unique_ptr<syncer::ModelTypeSyncBridge> bridge_;
-  TemplateURLService* const template_url_service_;
-  std::unique_ptr<TemplateURLService::Subscription> template_url_subscription_;
-
-  DISALLOW_COPY_AND_ASSIGN(ControllerDelegate);
-};
-
-// Helper function to construct the various objects needed to run this datatype.
-std::unique_ptr<ControllerDelegate> BuildDelegate(
-    const base::RepeatingClosure& dump_stack,
-    syncer::OnceModelTypeStoreFactory store_factory,
-    TemplateURLService* template_url_service) {
-  DCHECK(template_url_service);
-
-  auto processor = std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
-      syncer::SEARCH_ENGINES, dump_stack);
-
-  auto bridge = std::make_unique<syncer::SyncableServiceBasedBridge>(
-      syncer::SEARCH_ENGINES, std::move(store_factory), std::move(processor),
-      template_url_service);
-
-  return std::make_unique<ControllerDelegate>(std::move(bridge),
-                                              template_url_service);
-}
-
-}  // namespace
-
-SearchEngineModelTypeController::SearchEngineModelTypeController(
-    const base::RepeatingClosure& dump_stack,
-    syncer::OnceModelTypeStoreFactory store_factory,
-    TemplateURLService* template_url_service)
-    : ModelTypeController(syncer::SEARCH_ENGINES,
-                          BuildDelegate(dump_stack,
-                                        std::move(store_factory),
-                                        template_url_service)) {}
-
-SearchEngineModelTypeController::~SearchEngineModelTypeController() = default;
-
-}  // namespace browser_sync
diff --git a/components/search_engines/search_engine_model_type_controller.h b/components/search_engines/search_engine_model_type_controller.h
deleted file mode 100644
index 79a96b960..0000000
--- a/components/search_engines/search_engine_model_type_controller.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SEARCH_ENGINES_SEARCH_ENGINE_MODEL_TYPE_CONTROLLER_H_
-#define COMPONENTS_SEARCH_ENGINES_SEARCH_ENGINE_MODEL_TYPE_CONTROLLER_H_
-
-#include "base/callback_forward.h"
-#include "base/macros.h"
-#include "components/sync/driver/model_type_controller.h"
-#include "components/sync/model/model_type_store.h"
-
-class TemplateURLService;
-
-namespace browser_sync {
-
-// Controller for the SEARCH_ENGINES sync data type. This class tells sync how
-// to load the model for this data type, and the superclasses manage controlling
-// the rest of the state of the datatype with regards to sync. This is analogous
-// to SearchEngineDataTypeController but allows exercising the more modern USS
-// architecture.
-class SearchEngineModelTypeController : public syncer::ModelTypeController {
- public:
-  // |template_url_service| represents the syncable service itself for
-  // SEARCH_ENGINES. It must not be null and must outlive this object.
-  // |dump_stack| allows the internal implementation (the processor) to report
-  // error dumps. |store_factory| is used to instantiate a ModelTypeStore that
-  // is used to persist sync [meta]data.
-  SearchEngineModelTypeController(
-      const base::RepeatingClosure& dump_stack,
-      syncer::OnceModelTypeStoreFactory store_factory,
-      TemplateURLService* template_url_service);
-  ~SearchEngineModelTypeController() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SearchEngineModelTypeController);
-};
-
-}  // namespace browser_sync
-
-#endif  // COMPONENTS_SEARCH_ENGINES_SEARCH_ENGINE_MODEL_TYPE_CONTROLLER_H_
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index 386b649..ecfc9b0 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -887,6 +887,17 @@
   web_data_service_ = nullptr;
 }
 
+void TemplateURLService::WaitUntilReadyToSync(base::OnceClosure done) {
+  // We force a load here to allow remote updates to be processed, without
+  // waiting for the lazy load.
+  Load();
+
+  if (loaded_)
+    std::move(done).Run();
+  else
+    on_loaded_callback_for_sync_ = std::move(done);
+}
+
 syncer::SyncDataList TemplateURLService::GetAllSyncData(
     syncer::ModelType type) const {
   DCHECK_EQ(syncer::SEARCH_ENGINES, type);
@@ -1584,6 +1595,9 @@
       default_search_provider_source_);
   initial_default_search_provider_.reset();
 
+  if (on_loaded_callback_for_sync_)
+    std::move(on_loaded_callback_for_sync_).Run();
+
   on_loaded_callbacks_.Notify();
 }
 
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h
index 93cd041..fbd54db 100644
--- a/components/search_engines/template_url_service.h
+++ b/components/search_engines/template_url_service.h
@@ -346,6 +346,9 @@
 
   // syncer::SyncableService implementation.
 
+  // Waits until keywords have been loaded.
+  void WaitUntilReadyToSync(base::OnceClosure done) override;
+
   // Returns all syncable TemplateURLs from this model as SyncData. This should
   // include every search engine and no Extension keywords.
   syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override;
@@ -830,6 +833,9 @@
   // Stores a list of callbacks to be run after TemplateURLService has loaded.
   base::CallbackList<void(void)> on_loaded_callbacks_;
 
+  // Similar to |on_loaded_callbacks_| but used for WaitUntilReadyToSync().
+  base::OnceClosure on_loaded_callback_for_sync_;
+
   // Helper class to manage the default search engine.
   DefaultSearchManager default_search_manager_;
 
diff --git a/components/variations/net/DEPS b/components/variations/net/DEPS
index 4b6ac37..432ab454 100644
--- a/components/variations/net/DEPS
+++ b/components/variations/net/DEPS
@@ -3,5 +3,4 @@
   "+components/metrics",
   "+net",
   "+services/network/public/cpp",
-  "+services/network/public/mojom",
 ]
diff --git a/components/variations/net/variations_http_headers.cc b/components/variations/net/variations_http_headers.cc
index 0a0ca46..c06fd47 100644
--- a/components/variations/net/variations_http_headers.cc
+++ b/components/variations/net/variations_http_headers.cc
@@ -112,10 +112,9 @@
       return false;
 
     if (resource_request_) {
-      // Set the variations header to cors_exempt_headers rather than headers
-      // to be exempted from CORS checks.
-      resource_request_->cors_exempt_headers.SetHeaderIfMissing(
-          kClientDataHeader, variations_header_);
+      // Set the variations header to client_data_header rather than headers to
+      // be exempted from CORS checks.
+      resource_request_->client_data_header = variations_header_;
     } else if (url_request_) {
       url_request_->SetExtraRequestHeaderByName(kClientDataHeader,
                                                 variations_header_, false);
@@ -230,16 +229,11 @@
 }
 
 bool HasVariationsHeader(const network::ResourceRequest& request) {
-  return request.cors_exempt_headers.HasHeader(kClientDataHeader);
+  return !request.client_data_header.empty();
 }
 
 bool ShouldAppendVariationsHeaderForTesting(const GURL& url) {
   return ShouldAppendVariationsHeader(url);
 }
 
-void UpdateCorsExemptHeaderForVariations(
-    network::mojom::NetworkContextParams* params) {
-  params->cors_exempt_header_list.push_back(kClientDataHeader);
-}
-
 }  // namespace variations
diff --git a/components/variations/net/variations_http_headers.h b/components/variations/net/variations_http_headers.h
index a18c6ed..a25f45d 100644
--- a/components/variations/net/variations_http_headers.h
+++ b/components/variations/net/variations_http_headers.h
@@ -10,8 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "services/network/public/mojom/network_context.mojom.h"
-
 namespace net {
 struct NetworkTrafficAnnotationTag;
 struct RedirectInfo;
@@ -114,11 +112,6 @@
 // Calls the internal ShouldAppendVariationsHeader() for testing.
 bool ShouldAppendVariationsHeaderForTesting(const GURL& url);
 
-// Updates |cors_exempt_header_list| field of the given |param| to register the
-// variation headers.
-void UpdateCorsExemptHeaderForVariations(
-    network::mojom::NetworkContextParams* params);
-
 }  // namespace variations
 
 #endif  // COMPONENTS_VARIATIONS_NET_VARIATIONS_HTTP_HEADERS_H_
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 2194b54..de8ee67 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -67,7 +67,6 @@
     "//components/ui_devtools",
     "//components/url_formatter",
     "//components/variations",
-    "//components/variations/net",
     "//components/viz/client",
     "//components/viz/common",
     "//components/viz/host",
diff --git a/content/browser/DEPS b/content/browser/DEPS
index d0baf6f..3cbe1f2 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -25,7 +25,6 @@
   "+components/tracing",
   "+components/ukm",
   "+components/url_formatter",
-  "+components/variations/net/variations_http_headers.h",
   "+components/viz",
   "+components/cbor",
 
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.cc b/content/browser/browsing_data/browsing_data_remover_impl.cc
index 087240e..6d4fb5d 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl.cc
+++ b/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -33,6 +33,7 @@
 #include "ppapi/buildflags/buildflags.h"
 #include "services/network/public/cpp/features.h"
 #include "storage/browser/quota/special_storage_policy.h"
+#include "url/gurl.h"
 #include "url/origin.h"
 
 using base::UserMetricsAction;
@@ -64,17 +65,16 @@
     const base::Callback<bool(const GURL&)>& predicate,
     const BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher&
         embedder_matcher,
-    const GURL& origin,
+    const url::Origin& origin,
     storage::SpecialStoragePolicy* policy) {
-  if (!predicate.is_null() && !predicate.Run(origin))
+  if (!predicate.is_null() && !predicate.Run(origin.GetURL()))
     return false;
 
   const std::vector<std::string>& schemes = url::GetWebStorageSchemes();
-  bool is_web_scheme =
-      base::ContainsValue(schemes, origin.GetOrigin().scheme());
+  bool is_web_scheme = base::ContainsValue(schemes, origin.scheme());
 
   // If a websafe origin is unprotected, it matches iff UNPROTECTED_WEB.
-  if ((!policy || !policy->IsStorageProtected(origin.GetOrigin())) &&
+  if ((!policy || !policy->IsStorageProtected(origin.GetURL())) &&
       is_web_scheme &&
       (origin_type_mask & BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB)) {
     return true;
@@ -82,8 +82,7 @@
   origin_type_mask &= ~BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB;
 
   // Hosted applications (protected and websafe origins) iff PROTECTED_WEB.
-  if (policy && policy->IsStorageProtected(origin.GetOrigin()) &&
-      is_web_scheme &&
+  if (policy && policy->IsStorageProtected(origin.GetURL()) && is_web_scheme &&
       (origin_type_mask & BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB)) {
     return true;
   }
@@ -144,7 +143,7 @@
 
 bool BrowsingDataRemoverImpl::DoesOriginMatchMask(
     int origin_type_mask,
-    const GURL& origin,
+    const url::Origin& origin,
     storage::SpecialStoragePolicy* policy) const {
   BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher embedder_matcher;
   if (embedder_delegate_)
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.h b/content/browser/browsing_data/browsing_data_remover_impl.h
index ef4ffdf..b3b72de 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl.h
+++ b/content/browser/browsing_data/browsing_data_remover_impl.h
@@ -20,7 +20,7 @@
 #include "build/build_config.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/browsing_data_remover.h"
-#include "url/gurl.h"
+#include "url/origin.h"
 
 namespace content {
 
@@ -43,7 +43,7 @@
       BrowsingDataRemoverDelegate* embedder_delegate) override;
   bool DoesOriginMatchMask(
       int origin_type_mask,
-      const GURL& origin,
+      const url::Origin& origin,
       storage::SpecialStoragePolicy* special_storage_policy) const override;
   void Remove(const base::Time& delete_begin,
               const base::Time& delete_end,
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
index aa307b8..15553c4 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
+++ b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
@@ -102,12 +102,13 @@
 // For HTTP auth.
 const char kTestRealm[] = "TestRealm";
 
-const GURL kOrigin1(kTestOrigin1);
-const GURL kOrigin2(kTestOrigin2);
-const GURL kOrigin3(kTestOrigin3);
-const GURL kOrigin4(kTestOrigin4);
-const GURL kOriginExt(kTestOriginExt);
-const GURL kOriginDevTools(kTestOriginDevTools);
+const url::Origin kOrigin1 = url::Origin::Create(GURL(kTestOrigin1));
+const url::Origin kOrigin2 = url::Origin::Create(GURL(kTestOrigin2));
+const url::Origin kOrigin3 = url::Origin::Create(GURL(kTestOrigin3));
+const url::Origin kOrigin4 = url::Origin::Create(GURL(kTestOrigin4));
+const url::Origin kOriginExt = url::Origin::Create(GURL(kTestOriginExt));
+const url::Origin kOriginDevTools =
+    url::Origin::Create(GURL(kTestOriginDevTools));
 
 struct StoragePartitionRemovalData {
   StoragePartitionRemovalData()
@@ -149,10 +150,10 @@
   base::RepeatingCallback<bool(const GURL&)> url_matcher;
 };
 
-net::CanonicalCookie CreateCookieWithHost(const GURL& source) {
+net::CanonicalCookie CreateCookieWithHost(const url::Origin& origin) {
   std::unique_ptr<net::CanonicalCookie> cookie(
       std::make_unique<net::CanonicalCookie>(
-          "A", "1", source.host(), "/", base::Time::Now(), base::Time::Now(),
+          "A", "1", origin.host(), "/", base::Time::Now(), base::Time::Now(),
           base::Time(), false, false, net::CookieSameSite::DEFAULT_MODE,
           net::COOKIE_PRIORITY_MEDIUM));
   EXPECT_TRUE(cookie);
@@ -264,8 +265,8 @@
     if (filter.is_null() != to_match_.is_null())
       return false;
 
-    const GURL urls_to_test_[] = {kOrigin1, kOrigin2, kOrigin3,
-                                  GURL("invalid spec")};
+    const GURL urls_to_test_[] = {kOrigin1.GetURL(), kOrigin2.GetURL(),
+                                  kOrigin3.GetURL(), GURL("invalid spec")};
     for (GURL url : urls_to_test_) {
       if (filter.Run(url) != to_match_.Run(url)) {
         if (listener)
@@ -479,7 +480,8 @@
   bool Match(const GURL& origin,
              int mask,
              storage::SpecialStoragePolicy* policy) {
-    return remover_->DoesOriginMatchMask(mask, origin, policy);
+    return remover_->DoesOriginMatchMask(mask, url::Origin::Create(origin),
+                                         policy);
   }
 
  private:
@@ -585,18 +587,18 @@
   ASSERT_TRUE(http_session);
 
   net::HttpAuthCache* http_auth_cache = http_session->http_auth_cache();
-  http_auth_cache->Add(kOrigin1, kTestRealm, net::HttpAuth::AUTH_SCHEME_BASIC,
-                       "test challenge",
+  http_auth_cache->Add(kOrigin1.GetURL(), kTestRealm,
+                       net::HttpAuth::AUTH_SCHEME_BASIC, "test challenge",
                        net::AuthCredentials(base::ASCIIToUTF16("foo"),
                                             base::ASCIIToUTF16("bar")),
                        "/");
-  ASSERT_TRUE(http_auth_cache->Lookup(kOrigin1, kTestRealm,
+  ASSERT_TRUE(http_auth_cache->Lookup(kOrigin1.GetURL(), kTestRealm,
                                       net::HttpAuth::AUTH_SCHEME_BASIC));
 
   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
                                 BrowsingDataRemover::DATA_TYPE_COOKIES, false);
 
-  EXPECT_EQ(nullptr, http_auth_cache->Lookup(kOrigin1, kTestRealm,
+  EXPECT_EQ(nullptr, http_auth_cache->Lookup(kOrigin1.GetURL(), kTestRealm,
                                              net::HttpAuth::AUTH_SCHEME_BASIC));
 }
 
@@ -613,12 +615,13 @@
   ASSERT_TRUE(http_session);
 
   net::HttpAuthCache* http_auth_cache = http_session->http_auth_cache();
-  net::HttpAuthCache::Entry* entry = http_auth_cache->Add(
-      kOrigin1, kTestRealm, net::HttpAuth::AUTH_SCHEME_BASIC, "test challenge",
-      net::AuthCredentials(base::ASCIIToUTF16("foo"),
-                           base::ASCIIToUTF16("bar")),
-      "/");
-  ASSERT_TRUE(http_auth_cache->Lookup(kOrigin1, kTestRealm,
+  net::HttpAuthCache::Entry* entry =
+      http_auth_cache->Add(kOrigin1.GetURL(), kTestRealm,
+                           net::HttpAuth::AUTH_SCHEME_BASIC, "test challenge",
+                           net::AuthCredentials(base::ASCIIToUTF16("foo"),
+                                                base::ASCIIToUTF16("bar")),
+                           "/");
+  ASSERT_TRUE(http_auth_cache->Lookup(kOrigin1.GetURL(), kTestRealm,
                                       net::HttpAuth::AUTH_SCHEME_BASIC));
 
   BlockUntilBrowsingDataRemoved(
@@ -628,7 +631,7 @@
       false);
 
   // The entry stays unchanged.
-  EXPECT_EQ(entry, http_auth_cache->Lookup(kOrigin1, kTestRealm,
+  EXPECT_EQ(entry, http_auth_cache->Lookup(kOrigin1.GetURL(), kTestRealm,
                                            net::HttpAuth::AUTH_SCHEME_BASIC));
 }
 
@@ -722,7 +725,7 @@
 TEST_F(BrowsingDataRemoverImplTest, RemoveUnprotectedLocalStorageForever) {
   MockSpecialStoragePolicy* policy = CreateMockPolicy();
   // Protect kOrigin1.
-  policy->AddProtected(kOrigin1.GetOrigin());
+  policy->AddProtected(kOrigin1.GetURL());
 
   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
                                 BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
@@ -750,7 +753,7 @@
 TEST_F(BrowsingDataRemoverImplTest, RemoveProtectedLocalStorageForever) {
   // Protect kOrigin1.
   MockSpecialStoragePolicy* policy = CreateMockPolicy();
-  policy->AddProtected(kOrigin1.GetOrigin());
+  policy->AddProtected(kOrigin1.GetURL());
 
   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
                                 BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
@@ -1124,7 +1127,7 @@
 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedUnprotectedOrigins) {
   MockSpecialStoragePolicy* policy = CreateMockPolicy();
   // Protect kOrigin1.
-  policy->AddProtected(kOrigin1.GetOrigin());
+  policy->AddProtected(kOrigin1.GetURL());
 
   BlockUntilBrowsingDataRemoved(
       base::Time(), base::Time::Max(),
@@ -1168,7 +1171,7 @@
 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedProtectedSpecificOrigin) {
   MockSpecialStoragePolicy* policy = CreateMockPolicy();
   // Protect kOrigin1.
-  policy->AddProtected(kOrigin1.GetOrigin());
+  policy->AddProtected(kOrigin1.GetURL());
 
   std::unique_ptr<BrowsingDataFilterBuilder> builder(
       BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
@@ -1219,7 +1222,7 @@
 TEST_F(BrowsingDataRemoverImplTest, RemoveQuotaManagedProtectedOrigins) {
   MockSpecialStoragePolicy* policy = CreateMockPolicy();
   // Protect kOrigin1.
-  policy->AddProtected(kOrigin1.GetOrigin());
+  policy->AddProtected(kOrigin1.GetURL());
 
   // Try to remove kOrigin1. Expect success.
   BlockUntilBrowsingDataRemoved(
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index d3f372e..3d74235a 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -962,10 +962,18 @@
   new_request->SetReferrer(network::ComputeReferrer(request_data.referrer));
   new_request->set_referrer_policy(request_data.referrer_policy);
 
-  // Internal headers must be set here to avoid being blocked by CORS checks.
-  net::HttpRequestHeaders merged_headers = headers;
-  merged_headers.MergeFrom(request_data.cors_exempt_headers);
-  new_request->SetExtraRequestHeaders(merged_headers);
+  new_request->SetExtraRequestHeaders(headers);
+  // X-Requested-With and X-Client-Data header must be set here to avoid
+  // breaking CORS checks. They are non-empty when the values are given by the
+  // UA code, therefore they should be ignored by CORS checks.
+  if (!request_data.requested_with_header.empty()) {
+    new_request->SetExtraRequestHeaderByName(
+        "X-Requested-With", request_data.requested_with_header, true);
+  }
+  if (!request_data.client_data_header.empty()) {
+    new_request->SetExtraRequestHeaderByName(
+        "X-Client-Data", request_data.client_data_header, true);
+  }
 
   std::unique_ptr<network::ScopedThrottlingToken> throttling_token =
       network::ScopedThrottlingToken::MaybeCreate(
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc
index 0ad9d31..1eb5cfc 100644
--- a/content/browser/network_service_restart_browsertest.cc
+++ b/content/browser/network_service_restart_browsertest.cc
@@ -20,7 +20,6 @@
 #include "content/browser/url_loader_factory_getter.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
diff --git a/content/browser/plugin_private_storage_helper.cc b/content/browser/plugin_private_storage_helper.cc
index a75e02c6..e9973be 100644
--- a/content/browser/plugin_private_storage_helper.cc
+++ b/content/browser/plugin_private_storage_helper.cc
@@ -437,7 +437,8 @@
     std::set<GURL> origins_to_check;
     origins_to_check.swap(origins);
     for (const auto& origin : origins_to_check) {
-      if (origin_matcher.Run(origin, special_storage_policy.get()))
+      if (origin_matcher.Run(url::Origin::Create(origin),
+                             special_storage_policy.get()))
         origins.insert(origin);
     }
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 7b7be300..98103fb 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2260,6 +2260,9 @@
 
   bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
 
+  if (!processed)
+    processed = GetView()->OnUnconsumedKeyboardEventAck(event);
+
   // We only send unprocessed key event upwards if we are not hidden,
   // because the user has moved away from us and no longer expect any effect
   // of this key event.
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 92dbe46..bf2ca4d 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -84,6 +84,7 @@
 #include "ui/events/android/gesture_event_type.h"
 #include "ui/events/android/motion_event_android.h"
 #include "ui/events/blink/blink_event_util.h"
+#include "ui/events/blink/blink_features.h"
 #include "ui/events/blink/did_overscroll_params.h"
 #include "ui/events/blink/web_input_event_traits.h"
 #include "ui/events/gesture_detection/gesture_provider_config_helper.h"
@@ -176,6 +177,8 @@
       using_browser_compositor_(CompositorImpl::IsInitialized()),
       synchronous_compositor_client_(nullptr),
       observing_root_window_(false),
+      fallback_cursor_mode_enabled_(
+          base::FeatureList::IsEnabled(features::kFallbackCursorMode)),
       prev_top_shown_pix_(0.f),
       prev_top_controls_translate_(0.f),
       prev_bottom_shown_pix_(0.f),
@@ -1591,6 +1594,13 @@
   gesture_listener_manager_->GestureEventAck(event, ack_result);
 }
 
+bool RenderWidgetHostViewAndroid::OnUnconsumedKeyboardEventAck(
+    const NativeWebKeyboardEventWithLatencyInfo& event) {
+  return fallback_cursor_mode_enabled_ &&
+         event.event.GetType() == blink::WebInputEvent::kKeyDown &&
+         view_.OnUnconsumedKeyboardEventAck(event.event.native_key_code);
+}
+
 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
     const blink::WebInputEvent& input_event) {
   if (overscroll_controller_ &&
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 1b78456..5eb77b8 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -139,6 +139,8 @@
       const blink::WebGestureEvent& gesture_event) override;
   void GestureEventAck(const blink::WebGestureEvent& event,
                        InputEventAckState ack_result) override;
+  bool OnUnconsumedKeyboardEventAck(
+      const NativeWebKeyboardEventWithLatencyInfo& event) override;
   BrowserAccessibilityManager* CreateBrowserAccessibilityManager(
       BrowserAccessibilityDelegate* delegate, bool for_root_frame) override;
   bool LockMouse() override;
@@ -487,6 +489,9 @@
   bool observing_root_window_;
 
   bool controls_initialized_ = false;
+
+  bool fallback_cursor_mode_enabled_;
+
   float prev_top_shown_pix_;
   float prev_top_controls_translate_;
   float prev_bottom_shown_pix_;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index cbee55a..908bf96 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -764,7 +764,14 @@
 void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
   if (insets != insets_) {
     insets_ = insets;
-    host()->SynchronizeVisualProperties(!insets_.IsEmpty());
+    window_->AllocateLocalSurfaceId();
+    if (!insets.IsEmpty()) {
+      inset_surface_id_allocation_ = window_->GetLocalSurfaceIdAllocation();
+    } else {
+      inset_surface_id_allocation_ = viz::LocalSurfaceIdAllocation();
+    }
+    SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+                                window_->GetLocalSurfaceIdAllocation());
   }
 }
 
@@ -1971,6 +1978,15 @@
   const cc::RenderFrameMetadata& metadata =
       host()->render_frame_metadata_provider()->LastRenderFrameMetadata();
   SetContentBackgroundColor(metadata.root_background_color);
+  if (inset_surface_id_allocation_.IsValid() &&
+      metadata.local_surface_id_allocation &&
+      metadata.local_surface_id_allocation.value().IsValid() &&
+      metadata.local_surface_id_allocation.value()
+          .local_surface_id()
+          .IsSameOrNewerThan(inset_surface_id_allocation_.local_surface_id())) {
+    inset_surface_id_allocation_ = viz::LocalSurfaceIdAllocation();
+    ScrollFocusedEditableNodeIntoRect(gfx::Rect());
+  }
 
   if (metadata.selection.start != selection_start_ ||
       metadata.selection.end != selection_end_) {
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index a2dedc2..d8d009e 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -456,6 +456,8 @@
                            TakeFallbackContent);
   FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
                            DiscardDelegatedFrames);
+  FRIEND_TEST_ALL_PREFIXES(SitePerProcessHitTestBrowserTest,
+                           ScrollOOPIFEditableElement);
 
   class WindowObserver;
   friend class WindowObserver;
@@ -708,6 +710,7 @@
       ui::EventPointerType::POINTER_TYPE_UNKNOWN;
 
   bool is_first_navigation_ = true;
+  viz::LocalSurfaceIdAllocation inset_surface_id_allocation_;
 
   base::WeakPtrFactory<RenderWidgetHostViewAura> weak_ptr_factory_;
 
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index 2672a26d..e93471a 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -18,6 +18,7 @@
 #include "content/browser/gpu/gpu_data_manager_impl.h"
 #include "content/browser/renderer_host/delegated_frame_host.h"
 #include "content/browser/renderer_host/display_util.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
 #include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
@@ -381,6 +382,11 @@
     InputEventAckState ack_result) {
 }
 
+bool RenderWidgetHostViewBase::OnUnconsumedKeyboardEventAck(
+    const NativeWebKeyboardEventWithLatencyInfo& event) {
+  return false;
+}
+
 void RenderWidgetHostViewBase::ForwardTouchpadZoomEventIfNecessary(
     const blink::WebGestureEvent& event,
     InputEventAckState ack_result) {
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 8cdb72a..104be412 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -249,6 +249,10 @@
   virtual void GestureEventAck(const blink::WebGestureEvent& event,
                                InputEventAckState ack_result);
 
+  // When key event is not uncosumed in render, browser may want to consume it.
+  virtual bool OnUnconsumedKeyboardEventAck(
+      const NativeWebKeyboardEventWithLatencyInfo& event);
+
   // Create a platform specific SyntheticGestureTarget implementation that will
   // be used to inject synthetic input events.
   virtual std::unique_ptr<SyntheticGestureTarget>
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index f307891..2d8a9f2 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -479,9 +479,18 @@
   if (blink::ServiceWorkerUtils::IsServicificationEnabled())
     DCHECK(!request_->blob);
 #endif  // DCHECK_IS_ON()
+  TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
+      "ServiceWorker", "ServiceWorkerFetchDispatcher::DispatchFetchEvent", this,
+      "event_type", ServiceWorkerMetrics::EventTypeToString(GetEventType()));
 }
 
-ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() = default;
+ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {
+  if (!did_complete_) {
+    TRACE_EVENT_NESTABLE_ASYNC_END0(
+        "ServiceWorker", "ServiceWorkerFetchDispatcher::DispatchFetchEvent",
+        this);
+  }
+}
 
 void ServiceWorkerFetchDispatcher::Run() {
   DCHECK(version_->status() == ServiceWorkerVersion::ACTIVATING ||
@@ -489,6 +498,9 @@
       << version_->status();
 
   if (version_->status() == ServiceWorkerVersion::ACTIVATING) {
+    TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+        "ServiceWorker", "ServiceWorkerFetchDispatcher::WaitForActivation",
+        this);
     version_->RegisterStatusChangeCallback(
         base::BindOnce(&ServiceWorkerFetchDispatcher::DidWaitForActivation,
                        weak_factory_.GetWeakPtr()));
@@ -498,6 +510,8 @@
 }
 
 void ServiceWorkerFetchDispatcher::DidWaitForActivation() {
+  TRACE_EVENT_NESTABLE_ASYNC_END0(
+      "ServiceWorker", "ServiceWorkerFetchDispatcher::WaitForActivation", this);
   StartWorker();
 }
 
@@ -515,6 +529,8 @@
     return;
   }
 
+  TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+      "ServiceWorker", "ServiceWorkerFetchDispatcher::StartWorker", this);
   version_->RunAfterStartWorker(
       GetEventType(),
       base::BindOnce(&ServiceWorkerFetchDispatcher::DidStartWorker,
@@ -523,6 +539,9 @@
 
 void ServiceWorkerFetchDispatcher::DidStartWorker(
     blink::ServiceWorkerStatusCode status) {
+  TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker",
+                                  "ServiceWorkerFetchDispatcher::StartWorker",
+                                  this, "status", status);
   if (status != blink::ServiceWorkerStatusCode::kOk) {
     DidFail(status);
     return;
@@ -543,6 +562,8 @@
   // Run callback to say that the fetch event will be dispatched.
   DCHECK(prepare_callback_);
   std::move(prepare_callback_).Run();
+  TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+      "ServiceWorker", "ServiceWorkerFetchDispatcher::FetchEvent", this);
 
   // Set up for receiving the response.
   blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_ptr;
@@ -588,6 +609,9 @@
 void ServiceWorkerFetchDispatcher::DidFailToDispatch(
     std::unique_ptr<ResponseCallback> response_callback,
     blink::ServiceWorkerStatusCode status) {
+  TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker",
+                                  "ServiceWorkerFetchDispatcher::FetchEvent",
+                                  this, "status", status);
   DidFail(status);
 }
 
@@ -605,6 +629,8 @@
     blink::mojom::FetchAPIResponsePtr response,
     blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
     blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
+  TRACE_EVENT_NESTABLE_ASYNC_END0(
+      "ServiceWorker", "ServiceWorkerFetchDispatcher::FetchEvent", this);
   Complete(blink::ServiceWorkerStatusCode::kOk, fetch_result,
            std::move(response), std::move(body_as_stream), std::move(timing));
 }
@@ -618,6 +644,9 @@
   DCHECK(fetch_callback_);
 
   did_complete_ = true;
+  TRACE_EVENT_NESTABLE_ASYNC_END1(
+      "ServiceWorker", "ServiceWorkerFetchDispatcher::DispatchFetchEvent", this,
+      "result", fetch_result);
   std::move(fetch_callback_)
       .Run(status, fetch_result, std::move(response), std::move(body_as_stream),
            std::move(timing), version_);
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index 84e8ebd2..14b5e882 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -2374,6 +2374,78 @@
                                   blink::WebInputEvent::kMouseWheel));
 }
 
+// Tests that touching an OOPIF editable element correctly resizes the
+// viewport and scrolls the element into view so that the element is not
+// occluded by the on screen keyboard (https://crbug.com/927483)
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
+                       ScrollOOPIFEditableElement) {
+  GURL main_url(embedded_test_server()->GetURL(
+      "/frame_tree/oopif_form_scroll_main.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+  ASSERT_EQ(1U, root->child_count());
+
+  // Get the first iframe, which contains the editable element
+  FrameTreeNode* child_node = root->child_at(0);
+  GURL site_url(embedded_test_server()->GetURL(
+      "baz.com", "/frame_tree/page_with_editable_elements.html"));
+  ASSERT_EQ(site_url, child_node->current_url());
+
+  // Make sure the child frame is indeed a OOPIF
+  EXPECT_TRUE(child_node->current_frame_host()->IsCrossProcessSubframe());
+
+  // Set focus on an element in the OOPIF
+  EXPECT_TRUE(ExecJs(child_node->current_frame_host(),
+                     "document.getElementById('oopif_element').focus()"));
+  MainThreadFrameObserver observer(
+      root->current_frame_host()->GetRenderWidgetHost());
+  observer.Wait();
+  // We reset the scroll to 0,0 because setting focus on element
+  // will bring it into view
+  ASSERT_TRUE(ExecJs(root->current_frame_host(),
+                     base::StringPrintf("window.scrollTo(%d, %d);", 0, 0)));
+  content::RenderFrameSubmissionObserver root_frame_observer(root);
+  gfx::Vector2dF zero_offset;
+  root_frame_observer.WaitForScrollOffset(zero_offset);
+  ASSERT_TRUE(ExecJs(child_node->current_frame_host(),
+                     base::StringPrintf("window.scrollTo(%d, %d);", 0, 0)));
+  content::RenderFrameSubmissionObserver child_frame_observer(child_node);
+  child_frame_observer.WaitForScrollOffset(zero_offset);
+
+  RenderWidgetHostViewChildFrame* child_render_widget_host_view_child_frame =
+      static_cast<RenderWidgetHostViewChildFrame*>(
+          child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
+
+  RenderWidgetHostViewAura* parent_render_widget_host_aura =
+      static_cast<RenderWidgetHostViewAura*>(
+          child_render_widget_host_view_child_frame->GetRootView());
+
+  gfx::Size original_viewport_size =
+      parent_render_widget_host_aura->GetVisibleViewportSize();
+  parent_render_widget_host_aura->SetLastPointerType(
+      ui::EventPointerType::POINTER_TYPE_TOUCH);
+  parent_render_widget_host_aura->FocusedNodeTouched(true);
+  parent_render_widget_host_aura->SetInsets(gfx::Insets(0, 0, 200, 0));
+
+  // After focus on editable element, we expect element to be scrolled
+  // into view. Verify that the scroll offset on the root document
+  // matches a value that would make the OOPIF element visible.
+  gfx::Vector2dF final_root_offset(0, 904);
+  root_frame_observer.WaitForScrollOffset(final_root_offset);
+  EXPECT_EQ(EvalJs(root->current_frame_host(), "window.scrollY").ExtractInt(),
+            704);
+  EXPECT_GE(
+      EvalJs(child_node->current_frame_host(), "window.scrollY").ExtractInt(),
+      721);
+  // Viewport should be resized by keyboard height
+  EXPECT_NE(parent_render_widget_host_aura->GetVisibleViewportSize(),
+            original_viewport_size);
+}
+
 IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
                        InputEventRouterWheelCoalesceTest) {
   GURL main_url(embedded_test_server()->GetURL(
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index c85dd4b..a9aa36a 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -24,7 +24,6 @@
 #include "base/syslog_logging.h"
 #include "base/task/post_task.h"
 #include "build/build_config.h"
-#include "components/variations/net/variations_http_headers.h"
 #include "content/browser/background_fetch/background_fetch_context.h"
 #include "content/browser/blob_storage/blob_registry_wrapper.h"
 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
@@ -45,7 +44,6 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/dom_storage_context.h"
 #include "content/public/browser/indexed_db_context.h"
 #include "content/public/browser/network_service_instance.h"
@@ -181,8 +179,7 @@
       base::BarrierClosure(infos.size(), std::move(done_callback));
   for (size_t i = 0; i < infos.size(); ++i) {
     if (!origin_matcher.is_null() &&
-        !origin_matcher.Run(infos[i].origin.GetURL(),
-                            special_storage_policy.get())) {
+        !origin_matcher.Run(infos[i].origin, special_storage_policy.get())) {
       barrier.Run();
       continue;
     }
@@ -217,7 +214,8 @@
 
   for (size_t i = 0; i < infos.size(); ++i) {
     if (!origin_matcher.is_null() &&
-        !origin_matcher.Run(infos[i].origin, special_storage_policy.get())) {
+        !origin_matcher.Run(url::Origin::Create(infos[i].origin),
+                            special_storage_policy.get())) {
       barrier.Run();
       continue;
     }
@@ -238,7 +236,7 @@
 
   if (!storage_origin.is_empty()) {
     bool can_delete = origin_matcher.is_null() ||
-                      origin_matcher.Run(storage_origin,
+                      origin_matcher.Run(url::Origin::Create(storage_origin),
                                          special_storage_policy.get());
     if (can_delete) {
       dom_storage_context->DeleteLocalStorage(
@@ -285,18 +283,10 @@
   void Initialize(network::mojom::NetworkContextRequest network_context_request,
                   scoped_refptr<net::URLRequestContextGetter> context_getter) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-    network::mojom::NetworkContextParamsPtr network_context_params =
-        network::mojom::NetworkContextParams::New();
-    content::UpdateCorsExemptHeader(network_context_params.get());
-    variations::UpdateCorsExemptHeaderForVariations(
-
-        network_context_params.get());
     context_getter_ = std::move(context_getter);
     network_context_ = std::make_unique<network::NetworkContext>(
         GetNetworkServiceImpl(), std::move(network_context_request),
-        context_getter_->GetURLRequestContext(),
-        network_context_params->cors_exempt_header_list);
+        context_getter_->GetURLRequestContext());
   }
 
  private:
@@ -1127,7 +1117,7 @@
       continue;
 
     if (!origin_matcher.is_null() &&
-        !origin_matcher.Run(origin.GetURL(), special_storage_policy.get())) {
+        !origin_matcher.Run(origin, special_storage_policy.get())) {
       continue;
     }
 
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc
index 41a5dcf..67044446 100644
--- a/content/browser/storage_partition_impl_unittest.cc
+++ b/content/browser/storage_partition_impl_unittest.cc
@@ -576,28 +576,28 @@
 #endif  // BUILDFLAG(ENABLE_PLUGINS)
 
 bool IsWebSafeSchemeForTest(const std::string& scheme) {
-  return scheme == "http";
+  return scheme == url::kHttpScheme;
 }
 
 bool DoesOriginMatchForUnprotectedWeb(
-    const GURL& origin,
+    const url::Origin& origin,
     storage::SpecialStoragePolicy* special_storage_policy) {
   if (IsWebSafeSchemeForTest(origin.scheme()))
-    return !special_storage_policy->IsStorageProtected(origin.GetOrigin());
+    return !special_storage_policy->IsStorageProtected(origin.GetURL());
 
   return false;
 }
 
 bool DoesOriginMatchForBothProtectedAndUnprotectedWeb(
-    const GURL& origin,
+    const url::Origin& origin,
     storage::SpecialStoragePolicy* special_storage_policy) {
   return true;
 }
 
 bool DoesOriginMatchUnprotected(
-    const GURL& origin,
+    const url::Origin& origin,
     storage::SpecialStoragePolicy* special_storage_policy) {
-  return origin.GetOrigin().scheme() != kOriginDevTools.scheme();
+  return origin.scheme() != kOriginDevTools.scheme();
 }
 
 void ClearQuotaData(content::StoragePartition* partition,
diff --git a/content/browser/web_package/signed_exchange_handler_unittest.cc b/content/browser/web_package/signed_exchange_handler_unittest.cc
index 4c536aa0..46754ff 100644
--- a/content/browser/web_package/signed_exchange_handler_unittest.cc
+++ b/content/browser/web_package/signed_exchange_handler_unittest.cc
@@ -263,8 +263,7 @@
     url_request_context_ = std::move(context);
     network_context_ = std::make_unique<network::NetworkContext>(
         nullptr, mojo::MakeRequest(&network_context_ptr_),
-        url_request_context_.get(),
-        /*cors_exempt_header_list=*/std::vector<std::string>());
+        url_request_context_.get());
     SignedExchangeHandler::SetNetworkContextForTesting(network_context_.get());
 
     handler_ = std::make_unique<SignedExchangeHandler>(
diff --git a/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc b/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
index a0083e8..bf700ca 100644
--- a/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
+++ b/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
@@ -18,7 +18,7 @@
 
 // See content/test/data/sxg/README on how to generate these data.
 // clang-format off
-constexpr char kSignatureHeaderECDSAP256[] = R"(label; sig=*MEUCICLHwHwNFwbVUeu6a9AV8hVxvXfcYkWEMHnPFHYQfN/UAiEA3VQwLi1TJFvihZqasnpzuYlJte2E7Q4YEvtEnVZPOXE=*; validity-url="https://example.com/resource.validity.msg"; integrity="digest/mi-sha256-03"; cert-url="https://example.com/cert.msg"; cert-sha256=*KX+BYLSMgDOON8Ju65RoId39Qvajxa12HO+WnD4HpS0=*; date=1517892341; expires=1517895941)";
+constexpr char kSignatureHeaderECDSAP256[] = R"(label; sig=*MEUCIQCG/Oyo2geBPXXVRy6aN44z9Zn/B/6y/2MBwJfgltYjzAIgXIL1cdNfyHb8pC9efCsSqhVDCuMAS2XwYMLpvfJ0lCo=*; validity-url="https://test.example.org/resource.validity.msg"; integrity="digest/mi-sha256-03"; cert-url="https://example.com/cert.msg"; cert-sha256=*KX+BYLSMgDOON8Ju65RoId39Qvajxa12HO+WnD4HpS0=*; date=1517892341; expires=1517895941)";
 constexpr uint8_t kCborHeadersECDSAP256[] = {
   0xa4, 0x46, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x58, 0x39, 0x6d, 0x69,
   0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2d, 0x30, 0x33, 0x3d, 0x77,
@@ -34,7 +34,7 @@
   0x69, 0x6e, 0x67, 0x4c, 0x6d, 0x69, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35,
   0x36, 0x2d, 0x30, 0x33
 };
-constexpr char kSignatureHeaderECDSAP384[] = R"(label; sig=*MGQCMC0aEYoyk7KXfA3xy6RUiIMAk4t3VGe3aLVHZTQ67+ti1NuFP31x6UBhtuc87xXQRgIwUPJLxGuo6K4vGtBvI69lFY9cGUn/FmgiutReZ42Ju/onGt7RL1rjTe8AhsO1Z8xc*; validity-url="https://example.com/resource.validity.msg"; integrity="digest/mi-sha256-03"; cert-url="https://example.com/cert.msg"; cert-sha256=*8X8y8nj8vDJHSSa0cxn+TCu+8zGpIJfbdzAnd5cW+jA=*; date=1517892341; expires=1517895941)";
+constexpr char kSignatureHeaderECDSAP384[] = R"(label; sig=*MGUCMEeJujTLUifd561fwNZEzDptyEkXIKzkMOzbQFwlUpU3SWjY//58aRr6w6+V1jFa9wIxAPVlX3ia5a0wRYLfAXHO0Jm9bRKPoPUk7o9H/95eroC7BUL7ow+4H1W+20MuO1wbkw==*; validity-url="https://test.example.org/resource.validity.msg"; integrity="digest/mi-sha256-03"; cert-url="https://example.com/cert.msg"; cert-sha256=*8X8y8nj8vDJHSSa0cxn+TCu+8zGpIJfbdzAnd5cW+jA=*; date=1517892341; expires=1517895941)";
 // clang-format on
 
 // |expires| (1518497142) is more than 7 days (604800 seconds) after |date|
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 12f1bca6..4cd2de4 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -307,7 +307,7 @@
   if (base::FeatureList::IsEnabled(features::kGenericSensorExtraClasses))
     WebRuntimeFeatures::EnableGenericSensorExtraClasses(true);
 
-  if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCors))
+  if (network::features::ShouldEnableOutOfBlinkCors())
     WebRuntimeFeatures::EnableOutOfBlinkCors(true);
 
   WebRuntimeFeatures::EnableMediaCastOverlayButton(
diff --git a/content/common/content_constants_internal.cc b/content/common/content_constants_internal.cc
index d6e2a4f..be2463a 100644
--- a/content/common/content_constants_internal.cc
+++ b/content/common/content_constants_internal.cc
@@ -37,6 +37,4 @@
 const char kMachBootstrapName[] = "rohitfork";
 #endif
 
-const char kCorsExemptRequestedWithHeaderName[] = "X-Requested-With";
-
 } // namespace content
diff --git a/content/common/content_constants_internal.h b/content/common/content_constants_internal.h
index b520383..9c0767b 100644
--- a/content/common/content_constants_internal.h
+++ b/content/common/content_constants_internal.h
@@ -45,11 +45,6 @@
 CONTENT_EXPORT extern const char kMachBootstrapName[];
 #endif
 
-// Defines a HTTP header name that is set internally, and some code places
-// in content need to know the name to manage the header stored in
-// network::ResourceRequest::cors_exempt_headers.
-extern const char kCorsExemptRequestedWithHeaderName[];
-
 } // namespace content
 
 #endif  // CONTENT_COMMON_CONTENT_CONSTANTS_INTERNAL_H_
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
index 272bf4b4..5350660 100644
--- a/content/ppapi_plugin/ppapi_blink_platform_impl.cc
+++ b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -66,14 +66,13 @@
 #endif
 }
 
-unsigned long long PpapiBlinkPlatformImpl::VisitedLinkHash(
-    const char* canonical_url,
-    size_t length) {
+uint64_t PpapiBlinkPlatformImpl::VisitedLinkHash(const char* canonical_url,
+                                                 size_t length) {
   NOTREACHED();
   return 0;
 }
 
-bool PpapiBlinkPlatformImpl::IsLinkVisited(unsigned long long link_hash) {
+bool PpapiBlinkPlatformImpl::IsLinkVisited(uint64_t link_hash) {
   NOTREACHED();
   return false;
 }
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.h b/content/ppapi_plugin/ppapi_blink_platform_impl.h
index 1acdf7e9..41a4f9b 100644
--- a/content/ppapi_plugin/ppapi_blink_platform_impl.h
+++ b/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -30,9 +30,8 @@
 
   // BlinkPlatformImpl methods:
   blink::WebSandboxSupport* GetSandboxSupport() override;
-  unsigned long long VisitedLinkHash(const char* canonical_url,
-                                     size_t length) override;
-  bool IsLinkVisited(unsigned long long link_hash) override;
+  uint64_t VisitedLinkHash(const char* canonical_url, size_t length) override;
+  bool IsLinkVisited(uint64_t link_hash) override;
   blink::WebString DefaultLocale() override;
   blink::WebThemeEngine* ThemeEngine() override;
   blink::WebData GetDataResource(const char* name) override;
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index f945ea0..e07e88c 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -107,8 +107,6 @@
     "content_browser_client.cc",
     "content_browser_client.h",
     "cookie_store_factory.h",
-    "cors_exempt_headers.cc",
-    "cors_exempt_headers.h",
     "cors_origin_pattern_setter.cc",
     "cors_origin_pattern_setter.h",
     "delegate_to_browser_gpu_service_accelerator_factory.h",
diff --git a/content/public/browser/DEPS b/content/public/browser/DEPS
index 805504c5..49fd1ed 100644
--- a/content/public/browser/DEPS
+++ b/content/public/browser/DEPS
@@ -18,7 +18,6 @@
 specific_include_rules = {
   ".*\.cc": [
     "+content/browser",
-    "+content/common/content_constants_internal.h",
     "-content/browser/loader",
 
     # TODO: content/browser/loader is being separated out of content, and this
diff --git a/content/public/browser/browsing_data_remover.h b/content/public/browser/browsing_data_remover.h
index 60055a79..6708519 100644
--- a/content/public/browser/browsing_data_remover.h
+++ b/content/public/browser/browsing_data_remover.h
@@ -12,12 +12,14 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 
-class GURL;
-
 namespace storage {
 class SpecialStoragePolicy;
 }
 
+namespace url {
+class Origin;
+}
+
 namespace content {
 
 class BrowsingDataFilterBuilder;
@@ -151,7 +153,7 @@
   // the |special_storage_policy|.
   virtual bool DoesOriginMatchMask(
       int origin_type_mask,
-      const GURL& origin,
+      const url::Origin& origin,
       storage::SpecialStoragePolicy* special_storage_policy) const = 0;
 
   // Removes browsing data within the given |time_range|, with datatypes being
diff --git a/content/public/browser/browsing_data_remover_delegate.h b/content/public/browser/browsing_data_remover_delegate.h
index faf7f83..1081457 100644
--- a/content/public/browser/browsing_data_remover_delegate.h
+++ b/content/public/browser/browsing_data_remover_delegate.h
@@ -7,8 +7,6 @@
 
 #include "base/callback_forward.h"
 
-class GURL;
-
 namespace base {
 class Time;
 }
@@ -17,6 +15,10 @@
 class SpecialStoragePolicy;
 }
 
+namespace url {
+class Origin;
+}
+
 namespace content {
 
 class BrowsingDataFilterBuilder;
@@ -25,10 +27,10 @@
  public:
   // Determines whether |origin| matches |origin_type_mask| given
   // the |special_storage_policy|.
-  typedef base::Callback<bool(int origin_type_mask,
-                              const GURL& origin,
-                              storage::SpecialStoragePolicy* policy)>
-      EmbedderOriginTypeMatcher;
+  using EmbedderOriginTypeMatcher =
+      base::Callback<bool(int origin_type_mask,
+                          const url::Origin& origin,
+                          storage::SpecialStoragePolicy* policy)>;
 
   virtual ~BrowsingDataRemoverDelegate() {}
 
diff --git a/content/public/browser/cors_exempt_headers.cc b/content/public/browser/cors_exempt_headers.cc
deleted file mode 100644
index c82e8d71..0000000
--- a/content/public/browser/cors_exempt_headers.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/public/browser/cors_exempt_headers.h"
-
-#include "content/common/content_constants_internal.h"
-
-namespace content {
-
-void UpdateCorsExemptHeader(network::mojom::NetworkContextParams* params) {
-  // Note: This mechanism will be deprecated in the near future. You can find
-  // a recommended alternative approach on URLRequest::cors_exempt_headers at
-  // services/network/public/mojom/url_loader.mojom.
-  params->cors_exempt_header_list.push_back(kCorsExemptRequestedWithHeaderName);
-}
-
-}  // namespace content
diff --git a/content/public/browser/cors_exempt_headers.h b/content/public/browser/cors_exempt_headers.h
deleted file mode 100644
index c9b5cf1..0000000
--- a/content/public/browser/cors_exempt_headers.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_CORS_EXEMPT_HEADERS_H_
-#define CONTENT_PUBLIC_BROWSER_CORS_EXEMPT_HEADERS_H_
-
-#include "content/common/content_export.h"
-#include "services/network/public/mojom/network_context.mojom.h"
-
-namespace content {
-
-// Updates |cors_exempt_header_list| field of the given |param| to register
-// headers that are used in content for special purpose and should not be
-// blocked by CORS checks.
-CONTENT_EXPORT void UpdateCorsExemptHeader(
-    network::mojom::NetworkContextParams* params);
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_CORS_EXEMPT_HEADERS_H_
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index f3bf35ed..de7455a 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -160,8 +160,8 @@
   // A callback type to check if a given origin matches a storage policy.
   // Can be passed empty/null where used, which means the origin will always
   // match.
-  typedef base::Callback<bool(const GURL&, storage::SpecialStoragePolicy*)>
-      OriginMatcherFunction;
+  using OriginMatcherFunction =
+      base::Callback<bool(const url::Origin&, storage::SpecialStoragePolicy*)>;
 
   // Similar to ClearDataForOrigin().
   // Deletes all data out for the StoragePartition if |storage_origin| is empty.
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index cac858f8..e917d74 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -134,12 +134,12 @@
   return false;
 }
 
-unsigned long long ContentRendererClient::VisitedLinkHash(
-    const char* canonical_url, size_t length) {
-  return 0LL;
+uint64_t ContentRendererClient::VisitedLinkHash(const char* canonical_url,
+                                                size_t length) {
+  return 0;
 }
 
-bool ContentRendererClient::IsLinkVisited(unsigned long long link_hash) {
+bool ContentRendererClient::IsLinkVisited(uint64_t link_hash) {
   return false;
 }
 
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index 3b5c53a..b8da045 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -248,9 +248,8 @@
                               const blink::WebURLRequest& request);
 
   // See blink::Platform.
-  virtual unsigned long long VisitedLinkHash(const char* canonical_url,
-                                             size_t length);
-  virtual bool IsLinkVisited(unsigned long long link_hash);
+  virtual uint64_t VisitedLinkHash(const char* canonical_url, size_t length);
+  virtual bool IsLinkVisited(uint64_t link_hash);
   virtual blink::WebPrescientNetworking* GetPrescientNetworking();
   virtual bool IsPrerenderingFrame(const RenderFrame* render_frame);
 
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index bba42569..a34d7b6 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -1901,7 +1901,11 @@
 
 bool AccessibilityTreeContainsNodeWithName(BrowserAccessibility* node,
                                            const std::string& name) {
-  if (node->GetStringAttribute(ax::mojom::StringAttribute::kName) == name)
+  // If an image annotation is set, it plays the same role as a name, so it
+  // makes sense to check both in the same test helper.
+  if (node->GetStringAttribute(ax::mojom::StringAttribute::kName) == name ||
+      node->GetStringAttribute(ax::mojom::StringAttribute::kImageAnnotation) ==
+          name)
     return true;
   for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
     if (AccessibilityTreeContainsNodeWithName(node->PlatformGetChild(i), name))
diff --git a/content/renderer/input/frame_input_handler_impl.cc b/content/renderer/input/frame_input_handler_impl.cc
index 3e1a0a5..6611df0f 100644
--- a/content/renderer/input/frame_input_handler_impl.cc
+++ b/content/renderer/input/frame_input_handler_impl.cc
@@ -398,6 +398,11 @@
   if (!render_frame_)
     return;
 
+  // OnSynchronizeVisualProperties does not call DidChangeVisibleViewport
+  // on OOPIFs. Since we are starting a new scroll operation now, call
+  // DidChangeVisibleViewport to ensure that we don't assume the element
+  // is already in view and ignore the scroll.
+  render_frame_->ResetHasScrolledFocusedEditableIntoView();
   render_frame_->ScrollFocusedEditableElementIntoRect(rect);
 }
 
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index b0e49d2..dd5c24a 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -27,7 +27,6 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "content/child/child_thread_impl.h"
-#include "content/common/content_constants_internal.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/navigation_policy.h"
@@ -727,13 +726,10 @@
     resource_request->headers.SetHeaderIfMissing(network::kAcceptHeader,
                                                  network::kDefaultAcceptHeader);
   }
-  // Set X-Requested-With header to cors_exempt_headers rather than headers to
-  // be exempted from CORS checks.
-  if (!request.GetRequestedWithHeader().IsEmpty()) {
-    resource_request->cors_exempt_headers.SetHeader(
-        kCorsExemptRequestedWithHeaderName,
-        WebString(request.GetRequestedWithHeader()).Utf8());
-  }
+  resource_request->requested_with_header =
+      WebString(request.GetRequestedWithHeader()).Utf8();
+  resource_request->client_data_header =
+      WebString(request.GetClientDataHeader()).Utf8();
 
   if (resource_request->resource_type == RESOURCE_TYPE_PREFETCH ||
       resource_request->resource_type == RESOURCE_TYPE_FAVICON) {
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index ea7e926..586d4e4 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6929,7 +6929,7 @@
   }
 }
 
-void RenderFrameImpl::DidChangeVisibleViewport() {
+void RenderFrameImpl::ResetHasScrolledFocusedEditableIntoView() {
   has_scrolled_focused_editable_node_into_rect_ = false;
 }
 
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 8f17a70..972329b8 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -948,7 +948,7 @@
   void SyncSelectionIfRequired();
 
   void ScrollFocusedEditableElementIntoRect(const gfx::Rect& rect);
-  void DidChangeVisibleViewport();
+  void ResetHasScrolledFocusedEditableIntoView();
 
   // Called to notify a frame that it called |window.focus()| on a different
   // frame.
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index bab1a37..2af70a5 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -879,11 +879,15 @@
       SynchronizeVisualProperties(params);
       if (old_visible_viewport_size != visible_viewport_size_) {
         for (auto& render_frame : render_frames_)
-          render_frame.DidChangeVisibleViewport();
+          render_frame.ResetHasScrolledFocusedEditableIntoView();
       }
     }
   }
 
+  // TODO(crbug.com/939118): ScrollFocusedNodeIntoViewForWidget does not work
+  // when the focused node is inside an OOPIF. This code path where
+  // scroll_focused_node_into_view is set is used only for WebView, crbug
+  // 939118 tracks fixing webviews to not use scroll_focused_node_into_view.
   if (delegate() && params.scroll_focused_node_into_view)
     delegate()->ScrollFocusedNodeIntoViewForWidget();
 }
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index b837bc63..0a1e3bcb 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -368,13 +368,12 @@
       switches::kSingleProcess);
 }
 
-unsigned long long RendererBlinkPlatformImpl::VisitedLinkHash(
-    const char* canonical_url,
-    size_t length) {
+uint64_t RendererBlinkPlatformImpl::VisitedLinkHash(const char* canonical_url,
+                                                    size_t length) {
   return GetContentClient()->renderer()->VisitedLinkHash(canonical_url, length);
 }
 
-bool RendererBlinkPlatformImpl::IsLinkVisited(unsigned long long link_hash) {
+bool RendererBlinkPlatformImpl::IsLinkVisited(uint64_t link_hash) {
   return GetContentClient()->renderer()->IsLinkVisited(link_hash);
 }
 
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index b5eca2c..76f8c0f 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -78,9 +78,8 @@
   std::unique_ptr<blink::WebSpeechSynthesizer> CreateSpeechSynthesizer(
       blink::WebSpeechSynthesizerClient* client) override;
   virtual bool sandboxEnabled();
-  unsigned long long VisitedLinkHash(const char* canonicalURL,
-                                     size_t length) override;
-  bool IsLinkVisited(unsigned long long linkHash) override;
+  uint64_t VisitedLinkHash(const char* canonicalURL, size_t length) override;
+  bool IsLinkVisited(uint64_t linkHash) override;
   blink::WebPrescientNetworking* PrescientNetworking() override;
   blink::WebString UserAgent() override;
   blink::UserAgentMetadata UserAgentMetadata() override;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index c94a37e..b4e40533 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -18,7 +18,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "content/public/browser/client_certificate_delegate.h"
-#include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/login_delegate.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/page_navigator.h"
@@ -560,7 +559,6 @@
   network::mojom::NetworkContextPtr network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       network::mojom::NetworkContextParams::New();
-  UpdateCorsExemptHeader(context_params.get());
   context_params->user_agent = GetUserAgent();
   context_params->accept_language = "en-us,en";
   context_params->enable_data_url_support = true;
diff --git a/content/test/data/frame_tree/oopif_form_scroll_main.html b/content/test/data/frame_tree/oopif_form_scroll_main.html
new file mode 100644
index 0000000..32a215c
--- /dev/null
+++ b/content/test/data/frame_tree/oopif_form_scroll_main.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+  <style>
+    .frame{
+        position: absolute;
+        top: 1000px;
+    }
+  </style>
+  <body>
+    <iframe class="frame" id="formPage" src="/cross-site/baz.com/frame_tree/page_with_editable_elements.html" width=500
+    height=300 />
+  </body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/frame_tree/page_with_editable_elements.html b/content/test/data/frame_tree/page_with_editable_elements.html
new file mode 100644
index 0000000..e855111
--- /dev/null
+++ b/content/test/data/frame_tree/page_with_editable_elements.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+  <style>
+    .form{
+        position: absolute;
+        top: 1000px;
+    }
+  </style>
+  <body>
+    <input type="hidden" autofocus="true" />
+    <input class="form" id="oopif_element" placeholder="oopif_element">
+  </body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/sxg/generate-test-sxgs.sh b/content/test/data/sxg/generate-test-sxgs.sh
index fb5f651..21d31d5b 100755
--- a/content/test/data/sxg/generate-test-sxgs.sh
+++ b/content/test/data/sxg/generate-test-sxgs.sh
@@ -155,17 +155,19 @@
   -certificate ./prime256v1-sha256.public.pem \
   -privateKey ./prime256v1.key \
   -date 2018-02-06T04:45:41Z \
+  -validityUrl https://test.example.org/resource.validity.msg \
   -o $tmpdir/out.htxg \
   -dumpHeadersCbor $tmpdir/out.cborheader
 
 dumpSignature kSignatureHeaderECDSAP256 $tmpdir/out.htxg
 
-echo 'constexpr uint8_t kCborHeaderECDSAP256[] = {'
+echo 'constexpr uint8_t kCborHeadersECDSAP256[] = {'
 xxd --include $tmpdir/out.cborheader | sed '1d;$d'
 
 gen-signedexchange \
   -version 1b3 \
   -uri https://test.example.org/test/ \
+  -validityUrl https://test.example.org/resource.validity.msg \
   -content test.html \
   -certificate ./secp384r1-sha256.public.pem \
   -privateKey ./secp384r1.key \
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 41f5eba..492e6f3 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -495,6 +495,7 @@
     "//extensions/shell:browser_tests",
     "//net:test_support",
     "//services/device/public/cpp/hid",
+    "//services/device/public/cpp/hid:test_support",
     "//services/device/public/mojom",
     "//services/service_manager/public/cpp",
     "//ui/display:test_support",
diff --git a/extensions/browser/api/hid/hid_apitest.cc b/extensions/browser/api/hid/hid_apitest.cc
index 2a316779..7532453 100644
--- a/extensions/browser/api/hid/hid_apitest.cc
+++ b/extensions/browser/api/hid/hid_apitest.cc
@@ -15,15 +15,14 @@
 #include "extensions/shell/browser/shell_extensions_api_client.h"
 #include "extensions/shell/test/shell_apitest.h"
 #include "extensions/test/extension_test_message_listener.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/device/public/cpp/hid/fake_hid_manager.h"
 #include "services/device/public/cpp/hid/hid_report_descriptor.h"
 #include "services/device/public/mojom/constants.mojom.h"
 #include "services/device/public/mojom/hid.mojom.h"
 #include "services/service_manager/public/cpp/service_binding.h"
 
 using base::ThreadTaskRunnerHandle;
+using device::FakeHidManager;
 using device::HidReportDescriptor;
 
 const char* const kTestDeviceGuids[] = {"A", "B", "C", "D", "E"};
@@ -43,161 +42,6 @@
 
 namespace extensions {
 
-class FakeHidConnectionImpl : public device::mojom::HidConnection {
- public:
-  explicit FakeHidConnectionImpl(device::mojom::HidDeviceInfoPtr device)
-      : device_(std::move(device)) {}
-
-  ~FakeHidConnectionImpl() override = default;
-
-  // device::mojom::HidConnection implemenation:
-  void Read(ReadCallback callback) override {
-    const char kResult[] = "This is a HID input report.";
-    uint8_t report_id = device_->has_report_id ? 1 : 0;
-
-    std::vector<uint8_t> buffer(kResult, kResult + sizeof(kResult) - 1);
-
-    std::move(callback).Run(true, report_id, buffer);
-  }
-
-  void Write(uint8_t report_id,
-             const std::vector<uint8_t>& buffer,
-             WriteCallback callback) override {
-    const char kExpected[] = "o-report";  // 8 bytes
-    if (buffer.size() != sizeof(kExpected) - 1) {
-      std::move(callback).Run(false);
-      return;
-    }
-
-    int expected_report_id = device_->has_report_id ? 1 : 0;
-    if (report_id != expected_report_id) {
-      std::move(callback).Run(false);
-      return;
-    }
-
-    if (memcmp(buffer.data(), kExpected, sizeof(kExpected) - 1) != 0) {
-      std::move(callback).Run(false);
-      return;
-    }
-
-    std::move(callback).Run(true);
-  }
-
-  void GetFeatureReport(uint8_t report_id,
-                        GetFeatureReportCallback callback) override {
-    uint8_t expected_report_id = device_->has_report_id ? 1 : 0;
-    if (report_id != expected_report_id) {
-      std::move(callback).Run(false, base::nullopt);
-      return;
-    }
-
-    const char kResult[] = "This is a HID feature report.";
-    std::vector<uint8_t> buffer;
-    if (device_->has_report_id)
-      buffer.push_back(report_id);
-    buffer.insert(buffer.end(), kResult, kResult + sizeof(kResult) - 1);
-
-    std::move(callback).Run(true, buffer);
-  }
-
-  void SendFeatureReport(uint8_t report_id,
-                         const std::vector<uint8_t>& buffer,
-                         SendFeatureReportCallback callback) override {
-    const char kExpected[] = "The app is setting this HID feature report.";
-    if (buffer.size() != sizeof(kExpected) - 1) {
-      std::move(callback).Run(false);
-      return;
-    }
-
-    int expected_report_id = device_->has_report_id ? 1 : 0;
-    if (report_id != expected_report_id) {
-      std::move(callback).Run(false);
-      return;
-    }
-
-    if (memcmp(buffer.data(), kExpected, sizeof(kExpected) - 1) != 0) {
-      std::move(callback).Run(false);
-      return;
-    }
-
-    std::move(callback).Run(true);
-  }
-
- private:
-  device::mojom::HidDeviceInfoPtr device_;
-};
-
-class FakeHidManager : public device::mojom::HidManager {
- public:
-  FakeHidManager() {}
-  ~FakeHidManager() override = default;
-
-  void Bind(device::mojom::HidManagerRequest request) {
-    bindings_.AddBinding(this, std::move(request));
-  }
-
-  // device::mojom::HidManager implementation:
-  void GetDevicesAndSetClient(
-      device::mojom::HidManagerClientAssociatedPtrInfo client,
-      GetDevicesCallback callback) override {
-    std::vector<device::mojom::HidDeviceInfoPtr> device_list;
-    for (auto& map_entry : devices_)
-      device_list.push_back(map_entry.second->Clone());
-
-    std::move(callback).Run(std::move(device_list));
-
-    device::mojom::HidManagerClientAssociatedPtr client_ptr;
-    client_ptr.Bind(std::move(client));
-    clients_.AddPtr(std::move(client_ptr));
-  }
-
-  void GetDevices(GetDevicesCallback callback) override {
-    // Clients of HidManager in extensions only use GetDevicesAndSetClient().
-    NOTREACHED();
-  }
-
-  void Connect(const std::string& device_guid,
-               ConnectCallback callback) override {
-    if (!base::ContainsKey(devices_, device_guid)) {
-      std::move(callback).Run(nullptr);
-      return;
-    }
-
-    // Strong binds a instance of FakeHidConnctionImpl.
-    device::mojom::HidConnectionPtr client;
-    mojo::MakeStrongBinding(
-        std::make_unique<FakeHidConnectionImpl>(devices_[device_guid]->Clone()),
-        mojo::MakeRequest(&client));
-    std::move(callback).Run(std::move(client));
-  }
-
-  void AddDevice(device::mojom::HidDeviceInfoPtr device) {
-    std::string guid = device->guid;
-    devices_[guid] = std::move(device);
-
-    device::mojom::HidDeviceInfo* device_info = devices_[guid].get();
-    clients_.ForAllPtrs([device_info](device::mojom::HidManagerClient* client) {
-      client->DeviceAdded(device_info->Clone());
-    });
-  }
-
-  void RemoveDevice(const std::string& guid) {
-    if (base::ContainsKey(devices_, guid)) {
-      device::mojom::HidDeviceInfo* device_info = devices_[guid].get();
-      clients_.ForAllPtrs(
-          [device_info](device::mojom::HidManagerClient* client) {
-            client->DeviceRemoved(device_info->Clone());
-          });
-      devices_.erase(guid);
-    }
-  }
-
- private:
-  std::map<std::string, device::mojom::HidDeviceInfoPtr> devices_;
-  mojo::AssociatedInterfacePtrSet<device::mojom::HidManagerClient> clients_;
-  mojo::BindingSet<device::mojom::HidManager> bindings_;
-};
-
 class TestDevicePermissionsPrompt
     : public DevicePermissionsPrompt,
       public DevicePermissionsPrompt::Prompt::Observer {
diff --git a/extensions/browser/api/hid/hid_device_manager.cc b/extensions/browser/api/hid/hid_device_manager.cc
index da6f97f..ecaf885 100644
--- a/extensions/browser/api/hid/hid_device_manager.cc
+++ b/extensions/browser/api/hid/hid_device_manager.cc
@@ -280,22 +280,22 @@
   if (initialized_) {
     return;
   }
+  // |hid_manager_| may already be initialized in tests.
+  if (!hid_manager_) {
+    // |hid_manager_| is initialized and safe to use whether or not the
+    // connection is successful.
+    device::mojom::HidManagerRequest request = mojo::MakeRequest(&hid_manager_);
 
-  DCHECK(!hid_manager_);
-
-  // |hid_manager_| is initialized and safe to use whether or not the
-  // connection is successful.
-  device::mojom::HidManagerRequest request = mojo::MakeRequest(&hid_manager_);
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+    DCHECK(content::ServiceManagerConnection::GetForProcess());
+    auto* connector =
+        content::ServiceManagerConnection::GetForProcess()->GetConnector();
+    connector->BindInterface(device::mojom::kServiceName, std::move(request));
+  }
+  // Enumerate HID devices and set client.
+  std::vector<device::mojom::HidDeviceInfoPtr> empty_devices;
   device::mojom::HidManagerClientAssociatedPtrInfo client;
   binding_.Bind(mojo::MakeRequest(&client));
-
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(content::ServiceManagerConnection::GetForProcess());
-  auto* connector =
-      content::ServiceManagerConnection::GetForProcess()->GetConnector();
-  connector->BindInterface(device::mojom::kServiceName, std::move(request));
-
-  std::vector<device::mojom::HidDeviceInfoPtr> empty_devices;
   hid_manager_->GetDevicesAndSetClient(
       std::move(client),
       mojo::WrapCallbackWithDefaultInvokeIfNotRun(
@@ -306,6 +306,13 @@
   initialized_ = true;
 }
 
+void HidDeviceManager::SetFakeHidManagerForTesting(
+    device::mojom::HidManagerPtr fake_hid_manager) {
+  DCHECK(!hid_manager_);
+  DCHECK(fake_hid_manager);
+  hid_manager_ = std::move(fake_hid_manager);
+  LazyInitialize();
+}
 std::unique_ptr<base::ListValue> HidDeviceManager::CreateApiDeviceList(
     const Extension* extension,
     const std::vector<HidDeviceFilter>& filters) {
diff --git a/extensions/browser/api/hid/hid_device_manager.h b/extensions/browser/api/hid/hid_device_manager.h
index ee59e8b5..9ba8fafe 100644
--- a/extensions/browser/api/hid/hid_device_manager.h
+++ b/extensions/browser/api/hid/hid_device_manager.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "base/macros.h"
@@ -77,6 +78,9 @@
   // the first API customer makes a request or registers an event listener.
   virtual void LazyInitialize();
 
+  void SetFakeHidManagerForTesting(
+      device::mojom::HidManagerPtr fake_hid_manager);
+
  private:
   friend class BrowserContextKeyedAPIFactory<HidDeviceManager>;
 
@@ -92,7 +96,6 @@
   // BrowserContextKeyedAPI:
   static const char* service_name() { return "HidDeviceManager"; }
   static const bool kServiceHasOwnInstanceInIncognito = true;
-  static const bool kServiceIsNULLWhileTesting = true;
 
   // EventRouter::Observer:
   void OnListenerAdded(const EventListenerInfo& details) override;
diff --git a/extensions/renderer/script_injection_manager.cc b/extensions/renderer/script_injection_manager.cc
index cc922885..6f42300a 100644
--- a/extensions/renderer/script_injection_manager.cc
+++ b/extensions/renderer/script_injection_manager.cc
@@ -186,11 +186,13 @@
   // delayed task from here - but if we finish everything before that point
   // (i.e., RunScriptsAtDocumentIdle() is triggered), then there's no reason to
   // keep waiting.
-  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE,
-      base::BindOnce(&ScriptInjectionManager::RFOHelper::RunIdle,
-                     weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMilliseconds(kScriptIdleTimeoutInMs));
+  render_frame()
+      ->GetTaskRunner(blink::TaskType::kInternalDefault)
+      ->PostDelayedTask(
+          FROM_HERE,
+          base::BindOnce(&ScriptInjectionManager::RFOHelper::RunIdle,
+                         weak_factory_.GetWeakPtr()),
+          base::TimeDelta::FromMilliseconds(kScriptIdleTimeoutInMs));
 
   ExtensionFrameHelper::Get(render_frame())
       ->ScheduleAtDocumentIdle(
diff --git a/fuchsia/runners/cast/cast_runner_integration_test.cc b/fuchsia/runners/cast/cast_runner_integration_test.cc
index 10749925..1278185b8 100644
--- a/fuchsia/runners/cast/cast_runner_integration_test.cc
+++ b/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -119,7 +119,7 @@
 
     // Create the CastRunner, published into |test_services_|.
     cast_runner_ = std::make_unique<CastRunner>(
-        public_services_.get(), WebContentRunner::CreateDefaultWebContext(),
+        public_services_.get(), WebContentRunner::CreateIncognitoWebContext(),
         std::move(app_config_manager_ptr), cast_runner_run_loop_.QuitClosure());
 
     // Connect to the CastRunner's fuchsia.sys.Runner interface.
diff --git a/fuchsia/runners/cast/main.cc b/fuchsia/runners/cast/main.cc
index 1cefdf6f..4a4b9dc 100644
--- a/fuchsia/runners/cast/main.cc
+++ b/fuchsia/runners/cast/main.cc
@@ -14,7 +14,7 @@
 
   CastRunner runner(
       base::fuchsia::ServiceDirectory::GetDefault(),
-      WebContentRunner::CreateDefaultWebContext(),
+      WebContentRunner::CreateIncognitoWebContext(),
       base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
           ->ConnectToService<chromium::cast::ApplicationConfigManager>(),
       run_loop.QuitClosure());
diff --git a/fuchsia/runners/common/web_content_runner.cc b/fuchsia/runners/common/web_content_runner.cc
index 36a4c362..ec05c3a0 100644
--- a/fuchsia/runners/common/web_content_runner.cc
+++ b/fuchsia/runners/common/web_content_runner.cc
@@ -11,6 +11,7 @@
 
 #include "base/bind.h"
 #include "base/files/file.h"
+#include "base/files/file_util.h"
 #include "base/fuchsia/file_utils.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/fuchsia/scoped_service_binding.h"
@@ -21,20 +22,29 @@
 #include "fuchsia/runners/common/web_component.h"
 #include "url/gurl.h"
 
-// static
-chromium::web::ContextPtr WebContentRunner::CreateDefaultWebContext() {
+namespace {
+
+fidl::InterfaceHandle<fuchsia::io::Directory> OpenDirectory(
+    const base::FilePath& path) {
+  fidl::InterfaceHandle<fuchsia::io::Directory> directory(
+      zx::channel(base::fuchsia::GetHandleFromFile(
+          base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ))));
+  CHECK(directory) << "Failed to open " << path;
+  return directory;
+}
+
+chromium::web::ContextPtr CreateWebContextWithDataDirectory(
+    fidl::InterfaceHandle<fuchsia::io::Directory> data_directory) {
   auto web_context_provider =
       base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
           ->ConnectToService<chromium::web::ContextProvider>();
 
   chromium::web::CreateContextParams2 create_params;
 
-  // Clone /svc to the context.
-  fidl::InterfaceHandle<fuchsia::io::Directory> directory;
-  zx_status_t result = fdio_service_connect(
-      "/svc", directory.NewRequest().TakeChannel().release());
-  ZX_CHECK(result == ZX_OK, result) << "Failed to open /svc";
-  create_params.set_service_directory(std::move(directory));
+  // Pass /svc and /data to the context.
+  create_params.set_service_directory(OpenDirectory(base::FilePath("/svc")));
+  if (data_directory)
+    create_params.set_data_directory(std::move(data_directory));
 
   chromium::web::ContextPtr web_context;
   web_context_provider->Create2(std::move(create_params),
@@ -48,6 +58,20 @@
   return web_context;
 }
 
+}  // namespace
+
+// static
+chromium::web::ContextPtr WebContentRunner::CreateDefaultWebContext() {
+  return CreateWebContextWithDataDirectory(
+      OpenDirectory(base::FilePath("/data")));
+}
+
+// static
+chromium::web::ContextPtr WebContentRunner::CreateIncognitoWebContext() {
+  return CreateWebContextWithDataDirectory(
+      fidl::InterfaceHandle<fuchsia::io::Directory>());
+}
+
 WebContentRunner::WebContentRunner(
     base::fuchsia::ServiceDirectory* service_directory,
     chromium::web::ContextPtr context,
diff --git a/fuchsia/runners/common/web_content_runner.h b/fuchsia/runners/common/web_content_runner.h
index c65f30e..5bba5fee 100644
--- a/fuchsia/runners/common/web_content_runner.h
+++ b/fuchsia/runners/common/web_content_runner.h
@@ -26,6 +26,11 @@
   // is configured to exit this process on error.
   static chromium::web::ContextPtr CreateDefaultWebContext();
 
+  // Creates and returns an incognito web.Context  with access to the same
+  // services as this Runner. The returned binding is configured to exit this
+  // process on error.
+  static chromium::web::ContextPtr CreateIncognitoWebContext();
+
   // |service_directory|: ServiceDirectory into which this Runner will be
   //   published. |on_idle_closure| will be invoked when the final client of the
   //   published service disconnects, even if one or more Components are still
diff --git a/fuchsia/runners/web/sandbox_policy b/fuchsia/runners/web/sandbox_policy
index 0d084f2..58a297fc 100644
--- a/fuchsia/runners/web/sandbox_policy
+++ b/fuchsia/runners/web/sandbox_policy
@@ -1,5 +1,7 @@
 {
-  "features": [],
+  "features": [
+    "isolated-persistent-storage"
+  ],
   "services": [
       "chromium.web.ContextProvider",
       "fuchsia.fonts.Provider",
diff --git a/google_apis/gcm/base/socket_stream_unittest.cc b/google_apis/gcm/base/socket_stream_unittest.cc
index 476ec3d..949713b9 100644
--- a/google_apis/gcm/base/socket_stream_unittest.cc
+++ b/google_apis/gcm/base/socket_stream_unittest.cc
@@ -116,8 +116,7 @@
 
   network_context_ = std::make_unique<network::NetworkContext>(
       network_service_.get(), mojo::MakeRequest(&network_context_ptr_),
-      &url_request_context_,
-      /*cors_exempt_header_list=*/std::vector<std::string>());
+      &url_request_context_);
 }
 
 GCMSocketStreamTest::~GCMSocketStreamTest() {}
diff --git a/google_apis/gcm/engine/connection_handler_impl_unittest.cc b/google_apis/gcm/engine/connection_handler_impl_unittest.cc
index f8fe0f9..7ec425e 100644
--- a/google_apis/gcm/engine/connection_handler_impl_unittest.cc
+++ b/google_apis/gcm/engine/connection_handler_impl_unittest.cc
@@ -217,8 +217,7 @@
 
   network_context_ = std::make_unique<network::NetworkContext>(
       network_service_.get(), mojo::MakeRequest(&network_context_ptr_),
-      &url_request_context_,
-      /*cors_exempt_header_list=*/std::vector<std::string>());
+      &url_request_context_);
 }
 
 GCMConnectionHandlerImplTest::~GCMConnectionHandlerImplTest() {
diff --git a/google_apis/gcm/tools/mcs_probe.cc b/google_apis/gcm/tools/mcs_probe.cc
index 1b6c0b78..d28951a 100644
--- a/google_apis/gcm/tools/mcs_probe.cc
+++ b/google_apis/gcm/tools/mcs_probe.cc
@@ -359,8 +359,7 @@
   // Wrap it up with network service APIs.
   network_context_ = std::make_unique<network::NetworkContext>(
       nullptr /* network_service */, mojo::MakeRequest(&network_context_pipe_),
-      url_request_context_.get(),
-      /*cors_exempt_header_list=*/std::vector<std::string>());
+      url_request_context_.get());
   auto url_loader_factory_params =
       network::mojom::URLLoaderFactoryParams::New();
   url_loader_factory_params->process_id = network::mojom::kBrowserProcessId;
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index ea57f9e2..0641526 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -113,7 +113,6 @@
     "//components/unified_consent",
     "//components/url_formatter",
     "//components/variations",
-    "//components/variations/net",
     "//components/variations/service",
     "//components/version_info",
     "//components/webdata_services",
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS
index 03e168a..7bb2e46 100644
--- a/ios/chrome/browser/DEPS
+++ b/ios/chrome/browser/DEPS
@@ -97,7 +97,6 @@
   "+components/upload_list",
   "+components/url_formatter",
   "+components/variations",
-  "+components/variations/net",
   "+components/version_info",
   "+components/version_ui",
   "+components/web_resource",
diff --git a/ios/chrome/browser/ios_chrome_io_thread.mm b/ios/chrome/browser/ios_chrome_io_thread.mm
index 23b26f0..db06e723 100644
--- a/ios/chrome/browser/ios_chrome_io_thread.mm
+++ b/ios/chrome/browser/ios_chrome_io_thread.mm
@@ -4,7 +4,6 @@
 
 #include "ios/chrome/browser/ios_chrome_io_thread.h"
 
-#include "components/variations/net/variations_http_headers.h"
 #include "ios/chrome/browser/net/ios_chrome_network_delegate.h"
 #include "ios/chrome/common/channel_info.h"
 #include "ios/web/public/network_context_owner.h"
@@ -33,13 +32,8 @@
 
 network::mojom::NetworkContext* IOSChromeIOThread::GetSystemNetworkContext() {
   if (!network_context_) {
-    network::mojom::NetworkContextParamsPtr network_context_params =
-        network::mojom::NetworkContextParams::New();
-    variations::UpdateCorsExemptHeaderForVariations(
-        network_context_params.get());
     network_context_owner_ = std::make_unique<web::NetworkContextOwner>(
-        system_url_request_context_getter(),
-        network_context_params->cors_exempt_header_list, &network_context_);
+        system_url_request_context_getter(), &network_context_);
   }
   return network_context_.get();
 }
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
index b9d7f99..74d83953 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -391,13 +391,10 @@
                                           : variations::InIncognito::kNo,
       &resource_request);
   NSMutableDictionary* result = [NSMutableDictionary dictionary];
-  // The variations header appears in cors_exempt_headers rather than in
-  // headers.
-  net::HttpRequestHeaders::Iterator header_iterator(
-      resource_request.cors_exempt_headers);
-  while (header_iterator.GetNext()) {
-    NSString* name = base::SysUTF8ToNSString(header_iterator.name());
-    NSString* value = base::SysUTF8ToNSString(header_iterator.value());
+  if (!resource_request.client_data_header.empty()) {
+    NSString* name = base::SysUTF8ToNSString("X-Client-Data");
+    NSString* value =
+        base::SysUTF8ToNSString(resource_request.client_data_header);
     result[name] = value;
   }
   return [result copy];
diff --git a/ios/chrome/browser/ui/static_content/static_html_native_content_unittest.mm b/ios/chrome/browser/ui/static_content/static_html_native_content_unittest.mm
index 9f64523..02a6e2985 100644
--- a/ios/chrome/browser/ui/static_content/static_html_native_content_unittest.mm
+++ b/ios/chrome/browser/ui/static_content/static_html_native_content_unittest.mm
@@ -8,7 +8,6 @@
 
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #include "ios/chrome/browser/ui/static_content/static_html_view_controller.h"
-#import "ios/chrome/browser/ui/url_loader.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
diff --git a/ios/chrome/browser/ui/static_content/static_html_view_controller.h b/ios/chrome/browser/ui/static_content/static_html_view_controller.h
index 1aae923..c439f15 100644
--- a/ios/chrome/browser/ui/static_content/static_html_view_controller.h
+++ b/ios/chrome/browser/ui/static_content/static_html_view_controller.h
@@ -8,8 +8,8 @@
 #import <UIKit/UIKit.h>
 #import <WebKit/WebKit.h>
 
-#import "ios/chrome/browser/ui/url_loader.h"
 #import "ios/web/public/block_types.h"
+#include "url/gurl.h"
 
 @protocol CRWNativeContentDelegate;
 
diff --git a/ios/chrome/browser/ui/static_content/static_html_view_controller_unittest.mm b/ios/chrome/browser/ui/static_content/static_html_view_controller_unittest.mm
index de42863..30f3b2a 100644
--- a/ios/chrome/browser/ui/static_content/static_html_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/static_content/static_html_view_controller_unittest.mm
@@ -9,7 +9,6 @@
 #import "base/mac/foundation_util.h"
 #import "base/test/ios/wait_util.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
-#import "ios/chrome/browser/ui/url_loader.h"
 #include "ios/chrome/browser/url_loading/test_url_loading_service.h"
 #include "ios/chrome/browser/url_loading/url_loading_service_factory.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -27,6 +26,7 @@
 #import "third_party/ocmock/OCMock/OCMock.h"
 #include "third_party/ocmock/gtest_support.h"
 #include "ui/base/l10n/l10n_util_mac.h"
+#include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -52,27 +52,6 @@
 }
 @end
 
-@interface LoadTestMockLoader : OCMockComplexTypeHelper
-@end
-
-@implementation LoadTestMockLoader
-
-typedef void (^LoadURL_Referrer_transition_renderInitiated)(
-    const GURL&,
-    const web::Referrer&,
-    ui::PageTransition,
-    BOOL);
-
-- (void)loadURL:(const GURL&)url
-             referrer:(const web::Referrer&)referrer
-           transition:(ui::PageTransition)transition
-    rendererInitiated:(BOOL)rendererInitiated {
-  static_cast<LoadURL_Referrer_transition_renderInitiated>([self
-      blockForSelector:_cmd])(url, referrer, transition, rendererInitiated);
-}
-
-@end
-
 namespace {
 
 bool isRunLoopDry = true;
@@ -119,10 +98,6 @@
 
 // Tests the creation of a StaticHtmlViewController displaying a resource file.
 TEST_F(StaticHtmlViewControllerTest, LoadResourceTest) {
-  id loader = [[LoadTestMockLoader alloc]
-      initWithRepresentedObject:[OCMockObject
-                                    mockForProtocol:@protocol(UrlLoader)]];
-
   id<CRWNativeContentDelegate> delegate =
       [OCMockObject mockForProtocol:@protocol(CRWNativeContentDelegate)];
   GURL referrer_url("chrome://foo");
@@ -144,32 +119,18 @@
   TestUrlLoadingService* url_loader =
       (TestUrlLoadingService*)UrlLoadingServiceFactory::GetForBrowserState(
           chrome_browser_state_.get());
-  EXPECT_EQ(GURL("terms_en.html"), url_loader->last_web_params.url);
-
-  ASSERT_OCMOCK_VERIFY((OCMockObject*)delegate);
-  id block = [(id) ^ (const GURL& url, const web::Referrer& referrer,
-                      ui::PageTransition transition, BOOL rendererInitiated) {
-    EXPECT_EQ(url, GURL());
-    EXPECT_EQ(referrer.url, referrer_url);
-    EXPECT_EQ(referrer.policy, web::ReferrerPolicyDefault);
-    EXPECT_TRUE(PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK));
-    EXPECT_TRUE(rendererInitiated);
-  } copy];
-
-  [loader onSelector:@selector(loadURL:referrer:transition:rendererInitiated:)
-      callBlockExpectation:block];
+  EXPECT_EQ(0, url_loader->load_url_call_count);
+  EXPECT_EQ(0, url_loader->open_new_tab_call_count);
 
   DryRunLoop(true);
-  ASSERT_OCMOCK_VERIFY(loader);
+
+  EXPECT_EQ(0, url_loader->load_url_call_count);
+  EXPECT_EQ(0, url_loader->open_new_tab_call_count);
   ASSERT_OCMOCK_VERIFY((OCMockObject*)delegate);
 }
 
 // Tests the creation of a StaticHtmlViewController displaying a local file.
 TEST_F(StaticHtmlViewControllerTest, LoadFileURLTest) {
-  id loader = [[LoadTestMockLoader alloc]
-      initWithRepresentedObject:[OCMockObject
-                                    mockForProtocol:@protocol(UrlLoader)]];
-
   id<CRWNativeContentDelegate> delegate =
       [OCMockObject mockForProtocol:@protocol(CRWNativeContentDelegate)];
   GURL referrer_url("chrome://foo");
@@ -197,23 +158,13 @@
   TestUrlLoadingService* url_loader =
       (TestUrlLoadingService*)UrlLoadingServiceFactory::GetForBrowserState(
           chrome_browser_state_.get());
-  EXPECT_EQ(GURL("terms_en.html"), url_loader->last_web_params.url);
-
-  ASSERT_OCMOCK_VERIFY((OCMockObject*)delegate);
-  id block = [(id) ^ (const GURL& url, const web::Referrer& referrer,
-                      ui::PageTransition transition, BOOL rendererInitiated) {
-    EXPECT_EQ(url, GURL());
-    EXPECT_EQ(referrer.url, referrer_url);
-    EXPECT_EQ(referrer.policy, web::ReferrerPolicyDefault);
-    EXPECT_TRUE(PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK));
-    EXPECT_TRUE(rendererInitiated);
-  } copy];
-
-  [loader onSelector:@selector(loadURL:referrer:transition:rendererInitiated:)
-      callBlockExpectation:block];
+  EXPECT_EQ(0, url_loader->load_url_call_count);
+  EXPECT_EQ(0, url_loader->open_new_tab_call_count);
 
   DryRunLoop(true);
-  ASSERT_OCMOCK_VERIFY(loader);
+
+  EXPECT_EQ(0, url_loader->load_url_call_count);
+  EXPECT_EQ(0, url_loader->open_new_tab_call_count);
   ASSERT_OCMOCK_VERIFY((OCMockObject*)delegate);
 }
 
diff --git a/ios/chrome/browser/url_loading/test_url_loading_service.h b/ios/chrome/browser/url_loading/test_url_loading_service.h
index d4ed907..799599a8 100644
--- a/ios/chrome/browser/url_loading/test_url_loading_service.h
+++ b/ios/chrome/browser/url_loading/test_url_loading_service.h
@@ -28,6 +28,9 @@
   web::NavigationManager::WebLoadParams last_web_params;
   WindowOpenDisposition last_disposition;
   OpenNewTabCommand* last_command;
+  int load_url_call_count = 0;
+  int switch_tab_call_count = 0;
+  int open_new_tab_call_count = 0;
 };
 
 #endif  // IOS_CHROME_BROWSER_URL_LOADING_TEST_URL_LOADING_SERVICE_H_
diff --git a/ios/chrome/browser/url_loading/test_url_loading_service.mm b/ios/chrome/browser/url_loading/test_url_loading_service.mm
index d811b8f..be67fd6 100644
--- a/ios/chrome/browser/url_loading/test_url_loading_service.mm
+++ b/ios/chrome/browser/url_loading/test_url_loading_service.mm
@@ -18,14 +18,17 @@
     const ChromeLoadParams& chrome_params) {
   last_web_params = chrome_params.web_params;
   last_disposition = chrome_params.disposition;
+  load_url_call_count++;
 }
 
 void TestUrlLoadingService::SwitchToTab(
     const web::NavigationManager::WebLoadParams& web_params) {
   last_web_params = web_params;
   last_disposition = WindowOpenDisposition::SWITCH_TO_TAB;
+  switch_tab_call_count++;
 }
 
 void TestUrlLoadingService::OpenUrlInNewTab(OpenNewTabCommand* command) {
   last_command = command;
+  open_new_tab_call_count++;
 }
diff --git a/ios/web/browser_state.mm b/ios/web/browser_state.mm
index a8bf14f..ae1b9e1b 100644
--- a/ios/web/browser_state.mm
+++ b/ios/web/browser_state.mm
@@ -256,9 +256,8 @@
 
   net::URLRequestContextGetter* request_context = GetRequestContext();
   DCHECK(request_context);
-  network_context_owner_ = std::make_unique<NetworkContextOwner>(
-      request_context, /*cors_exempt_header_list=*/std::vector<std::string>(),
-      &network_context_);
+  network_context_owner_ =
+      std::make_unique<NetworkContextOwner>(request_context, &network_context_);
 }
 
 // static
diff --git a/ios/web/network_context_owner.cc b/ios/web/network_context_owner.cc
index 6066487..3d239cb 100644
--- a/ios/web/network_context_owner.cc
+++ b/ios/web/network_context_owner.cc
@@ -5,8 +5,6 @@
 #include "ios/web/public/network_context_owner.h"
 
 #include <memory>
-#include <string>
-#include <vector>
 
 #include "base/bind.h"
 #include "base/task/post_task.h"
@@ -20,7 +18,6 @@
 
 NetworkContextOwner::NetworkContextOwner(
     net::URLRequestContextGetter* request_context,
-    const std::vector<std::string>& cors_exempt_header_list,
     network::mojom::NetworkContextPtr* network_context_client)
     : request_context_(request_context) {
   DCHECK_CURRENTLY_ON(WebThread::UI);
@@ -29,7 +26,7 @@
       base::BindOnce(&NetworkContextOwner::InitializeOnIOThread,
                      // This is safe, since |this| will be deleted on the IO
                      // thread, which would have to happen afterwards.
-                     base::Unretained(this), cors_exempt_header_list,
+                     base::Unretained(this),
                      mojo::MakeRequest(network_context_client)));
 }
 
@@ -40,14 +37,13 @@
 }
 
 void NetworkContextOwner::InitializeOnIOThread(
-    const std::vector<std::string> cors_exempt_header_list,
     network::mojom::NetworkContextRequest network_context_request) {
   DCHECK_CURRENTLY_ON(WebThread::IO);
   DCHECK(!network_context_);
 
   network_context_ = std::make_unique<network::NetworkContext>(
       nullptr, std::move(network_context_request),
-      request_context_->GetURLRequestContext(), cors_exempt_header_list);
+      request_context_->GetURLRequestContext());
   request_context_->AddObserver(this);
 }
 
diff --git a/ios/web/network_context_owner_unittest.cc b/ios/web/network_context_owner_unittest.cc
index 77525be..314e8b2 100644
--- a/ios/web/network_context_owner_unittest.cc
+++ b/ios/web/network_context_owner_unittest.cc
@@ -4,9 +4,6 @@
 
 #include "ios/web/public/network_context_owner.h"
 
-#include <string>
-#include <vector>
-
 #include "base/bind.h"
 #include "base/run_loop.h"
 #include "base/task/post_task.h"
@@ -52,9 +49,7 @@
 TEST_F(NetworkContextOwnerTest, Basic) {
   EXPECT_FALSE(network_context_.is_bound());
   network_context_owner_ = std::make_unique<NetworkContextOwner>(
-      context_getter_.get(),
-      /*cors_exempt_header_list=*/std::vector<std::string>(),
-      &network_context_);
+      context_getter_.get(), &network_context_);
   EXPECT_TRUE(network_context_.is_bound());
   WatchForErrors();
   base::RunLoop().RunUntilIdle();
@@ -71,9 +66,7 @@
 TEST_F(NetworkContextOwnerTest, ShutdownHandling) {
   EXPECT_FALSE(network_context_.is_bound());
   network_context_owner_ = std::make_unique<NetworkContextOwner>(
-      context_getter_.get(),
-      /*cors_exempt_header_list=*/std::vector<std::string>(),
-      &network_context_);
+      context_getter_.get(), &network_context_);
   EXPECT_TRUE(network_context_.is_bound());
   WatchForErrors();
   base::RunLoop().RunUntilIdle();
diff --git a/ios/web/public/network_context_owner.h b/ios/web/public/network_context_owner.h
index 390fd1a..690c4d1d 100644
--- a/ios/web/public/network_context_owner.h
+++ b/ios/web/public/network_context_owner.h
@@ -6,8 +6,6 @@
 #define IOS_WEB_PUBLIC_NETWORK_CONTEXT_OWNER_H_
 
 #include <memory>
-#include <string>
-#include <vector>
 
 #include "ios/web/public/web_thread.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -33,7 +31,6 @@
   // connects the pipe in |network_context_client| to it.
   NetworkContextOwner(
       net::URLRequestContextGetter* request_context,
-      const std::vector<std::string>& cors_exempt_header_list,
       network::mojom::NetworkContextPtr* network_context_client);
 
   ~NetworkContextOwner() override;
@@ -43,7 +40,6 @@
 
  private:
   void InitializeOnIOThread(
-      const std::vector<std::string> cors_exempt_header_list,
       network::mojom::NetworkContextRequest network_context_request);
 
   scoped_refptr<net::URLRequestContextGetter> request_context_;
diff --git a/ios/web_view/internal/app/application_context.mm b/ios/web_view/internal/app/application_context.mm
index 44b3cff..ac16940 100644
--- a/ios/web_view/internal/app/application_context.mm
+++ b/ios/web_view/internal/app/application_context.mm
@@ -154,9 +154,7 @@
 network::mojom::NetworkContext* ApplicationContext::GetSystemNetworkContext() {
   if (!network_context_) {
     network_context_owner_ = std::make_unique<web::NetworkContextOwner>(
-        GetSystemURLRequestContext(),
-        /*cors_exempt_header_list=*/std::vector<std::string>(),
-        &network_context_);
+        GetSystemURLRequestContext(), &network_context_);
   }
   return network_context_.get();
 }
diff --git a/jingle/glue/network_service_config_test_util.cc b/jingle/glue/network_service_config_test_util.cc
index 745b4225..5abedba 100644
--- a/jingle/glue/network_service_config_test_util.cc
+++ b/jingle/glue/network_service_config_test_util.cc
@@ -109,8 +109,7 @@
   DCHECK(net_runner_->RunsTasksInCurrentSequence());
   network_context_ = std::make_unique<network::NetworkContext>(
       nullptr, std::move(network_context_request),
-      url_request_context_getter_->GetURLRequestContext(),
-      /*cors_exempt_header_list=*/std::vector<std::string>());
+      url_request_context_getter_->GetURLRequestContext());
   if (notify)
     notify->Signal();
 }
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc
index f5c7da2..a10eb27 100644
--- a/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -1441,6 +1441,9 @@
   std::vector<VAConfigAttrib> required_attribs =
       GetRequiredAttribs(mode, va_profile);
 
+  if ((mode == CodecMode::kEncode) && IsLowPowerEncSupported(va_profile))
+    entrypoint = VAEntrypointEncSliceLP;
+
   base::AutoLock auto_lock(*va_lock_);
 
   VAStatus va_res =
@@ -1554,4 +1557,38 @@
     DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
 }
 
+// Check the support for low-power encode
+bool VaapiWrapper::IsLowPowerEncSupported(VAProfile va_profile) const {
+  // Only enabled for H264/AVC
+  if (va_profile != VAProfileH264ConstrainedBaseline &&
+      va_profile != VAProfileH264Main && va_profile != VAProfileH264High)
+    return false;
+
+  constexpr VAEntrypoint kLowPowerEncEntryPoint = VAEntrypointEncSliceLP;
+  const std::vector<VAConfigAttrib> required_attribs =
+      GetRequiredAttribs(VaapiWrapper::CodecMode::kEncode, va_profile);
+
+  base::AutoLock auto_lock(*va_lock_);
+  // Query the driver for required attributes.
+  std::vector<VAConfigAttrib> attribs = required_attribs;
+  for (size_t i = 0; i < required_attribs.size(); ++i)
+    attribs[i].value = 0;
+
+  VAStatus va_res =
+      vaGetConfigAttributes(va_display_, va_profile, kLowPowerEncEntryPoint,
+                            &attribs[0], attribs.size());
+  VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false);
+
+  for (size_t i = 0; i < required_attribs.size(); ++i) {
+    if (attribs[i].type != required_attribs[i].type ||
+        (attribs[i].value & required_attribs[i].value) !=
+            required_attribs[i].value) {
+      DVLOG(1) << "Unsupported value " << required_attribs[i].value
+               << " for attribute type " << required_attribs[i].type;
+      return false;
+    }
+  }
+  return true;
+}
+
 }  // namespace media
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h
index 9a0b45a6..0b7751ba 100644
--- a/media/gpu/vaapi/vaapi_wrapper.h
+++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -240,6 +240,9 @@
   // Attempt to set render mode to "render to texture.". Failure is non-fatal.
   void TryToSetVADisplayAttributeToLocalGPU();
 
+  // Check low-power encode support for the given profile
+  bool IsLowPowerEncSupported(VAProfile va_profile) const;
+
   // Pointer to VADisplayState's member |va_lock_|. Guaranteed to be valid for
   // the lifetime of VaapiWrapper.
   base::Lock* va_lock_;
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 10db102..241d6c4 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -294,7 +294,6 @@
     "http/http_util.h",
     "http/http_vary_data.cc",
     "http/http_vary_data.h",
-    "http/transport_security_state.cc",
     "http/transport_security_state.h",
     "http/transport_security_state_source.cc",
     "http/transport_security_state_source.h",
@@ -384,6 +383,7 @@
 
   deps = [
     ":net_deps",
+    "//net/http:transport_security_state_generated_files",
   ]
 
   public_deps = [
@@ -401,6 +401,7 @@
     "//net/dns:host_resolver",
     "//net/dns:mdns_client",
     "//net/dns/public",
+    "//net/http:transport_security_state_generated_files",
   ]
 
   if (!is_nacl) {
@@ -2225,6 +2226,7 @@
     "//net/dns:host_resolver",
     "//net/dns:mdns_client",
     "//net/dns/public",
+    "//net/http:transport_security_state_generated_files",
   ]
 
   public_deps = [
@@ -2239,10 +2241,6 @@
 
   public_configs = net_configs
 
-  if (include_transport_security_state_preload_list) {
-    public_deps += [ "//net/http:generate_transport_security_state" ]
-  }
-
   if (!is_nacl) {
     public_deps += [
       "//base/third_party/dynamic_annotations",
@@ -2292,6 +2290,7 @@
     "//net/dns:host_resolver",
     "//net/dns:mdns_client",
     "//net/dns/public",
+    "//net/http:transport_security_state_generated_files",
   ]
 
   public_deps = [
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
index ac1ff228..27894e72 100644
--- a/net/dns/BUILD.gn
+++ b/net/dns/BUILD.gn
@@ -9,7 +9,10 @@
 
 source_set("dns") {
   # Due to circular dependencies, should only be depended on through //net.
-  visibility = [ "//net" ]
+  visibility = [
+    "//net",
+    "//net/http:transport_security_state_generated_files",
+  ]
 
   # Internals only intended for use inside network stack (and tests).
   friend = [
diff --git a/net/http/BUILD.gn b/net/http/BUILD.gn
index d00da41d..3799a9fc 100644
--- a/net/http/BUILD.gn
+++ b/net/http/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/compiled_action.gni")
+import("//net/features.gni")
 
 # Generates a header file based on the real preload list.
 compiled_action("generate_transport_security_state") {
@@ -60,3 +61,24 @@
       [ rebase_path("{{source_name_part}}.json", root_build_dir) ] +
       rebase_path(inputs, root_build_dir) + rebase_path(outputs, root_build_dir)
 }
+
+# This has separated source_set not to let other compiles wait for the
+# generate_transport_security_state task to complete.
+source_set("transport_security_state_generated_files") {
+  # Do not publicize any header to remove build dependency.
+  public = []
+
+  sources = [
+    "transport_security_state.cc",
+  ]
+
+  deps = [
+    "//net:net_deps",
+    "//net:net_public_deps",
+    "//net/dns",
+  ]
+
+  if (include_transport_security_state_preload_list) {
+    deps += [ ":generate_transport_security_state" ]
+  }
+}
diff --git a/services/device/public/cpp/hid/BUILD.gn b/services/device/public/cpp/hid/BUILD.gn
index da35bf9..3408f2bca 100644
--- a/services/device/public/cpp/hid/BUILD.gn
+++ b/services/device/public/cpp/hid/BUILD.gn
@@ -33,3 +33,17 @@
     "//services/service_manager/public/cpp",
   ]
 }
+
+static_library("test_support") {
+  testonly = true
+
+  sources = [
+    "fake_hid_manager.cc",
+    "fake_hid_manager.h",
+  ]
+
+  public_deps = [
+    "//base",
+    "//services/device/public/mojom",
+  ]
+}
diff --git a/services/device/public/cpp/hid/fake_hid_manager.cc b/services/device/public/cpp/hid/fake_hid_manager.cc
new file mode 100644
index 0000000..9c3af41
--- /dev/null
+++ b/services/device/public/cpp/hid/fake_hid_manager.cc
@@ -0,0 +1,168 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/device/public/cpp/hid/fake_hid_manager.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/guid.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace device {
+
+FakeHidConnection::FakeHidConnection(mojom::HidDeviceInfoPtr device)
+    : device_(std::move(device)) {}
+
+FakeHidConnection::~FakeHidConnection() = default;
+
+// mojom::HidConnection implementation:
+void FakeHidConnection::Read(ReadCallback callback) {
+  const char kResult[] = "This is a HID input report.";
+  uint8_t report_id = device_->has_report_id ? 1 : 0;
+
+  std::vector<uint8_t> buffer(kResult, kResult + sizeof(kResult) - 1);
+
+  std::move(callback).Run(true, report_id, buffer);
+}
+
+void FakeHidConnection::Write(uint8_t report_id,
+                              const std::vector<uint8_t>& buffer,
+                              WriteCallback callback) {
+  const char kExpected[] = "o-report";  // 8 bytes
+  if (buffer.size() != sizeof(kExpected) - 1) {
+    std::move(callback).Run(false);
+    return;
+  }
+
+  int expected_report_id = device_->has_report_id ? 1 : 0;
+  if (report_id != expected_report_id) {
+    std::move(callback).Run(false);
+    return;
+  }
+
+  if (memcmp(buffer.data(), kExpected, sizeof(kExpected) - 1) != 0) {
+    std::move(callback).Run(false);
+    return;
+  }
+
+  std::move(callback).Run(true);
+}
+
+void FakeHidConnection::GetFeatureReport(uint8_t report_id,
+                                         GetFeatureReportCallback callback) {
+  uint8_t expected_report_id = device_->has_report_id ? 1 : 0;
+  if (report_id != expected_report_id) {
+    std::move(callback).Run(false, base::nullopt);
+    return;
+  }
+
+  const char kResult[] = "This is a HID feature report.";
+  std::vector<uint8_t> buffer;
+  if (device_->has_report_id)
+    buffer.push_back(report_id);
+  buffer.insert(buffer.end(), kResult, kResult + sizeof(kResult) - 1);
+
+  std::move(callback).Run(true, buffer);
+}
+
+void FakeHidConnection::SendFeatureReport(uint8_t report_id,
+                                          const std::vector<uint8_t>& buffer,
+                                          SendFeatureReportCallback callback) {
+  const char kExpected[] = "The app is setting this HID feature report.";
+  if (buffer.size() != sizeof(kExpected) - 1) {
+    std::move(callback).Run(false);
+    return;
+  }
+
+  int expected_report_id = device_->has_report_id ? 1 : 0;
+  if (report_id != expected_report_id) {
+    std::move(callback).Run(false);
+    return;
+  }
+
+  if (memcmp(buffer.data(), kExpected, sizeof(kExpected) - 1) != 0) {
+    std::move(callback).Run(false);
+    return;
+  }
+
+  std::move(callback).Run(true);
+}
+
+// Implementation of FakeHidManager.
+FakeHidManager::FakeHidManager() {}
+FakeHidManager::~FakeHidManager() = default;
+
+void FakeHidManager::Bind(mojom::HidManagerRequest request) {
+  bindings_.AddBinding(this, std::move(request));
+}
+
+// mojom::HidManager implementation:
+void FakeHidManager::GetDevicesAndSetClient(
+    mojom::HidManagerClientAssociatedPtrInfo client,
+    GetDevicesCallback callback) {
+  std::vector<mojom::HidDeviceInfoPtr> device_list;
+  for (auto& map_entry : devices_)
+    device_list.push_back(map_entry.second->Clone());
+
+  std::move(callback).Run(std::move(device_list));
+
+  mojom::HidManagerClientAssociatedPtr client_ptr;
+  client_ptr.Bind(std::move(client));
+  clients_.AddPtr(std::move(client_ptr));
+}
+
+void FakeHidManager::GetDevices(GetDevicesCallback callback) {
+  // Clients of HidManager in extensions only use GetDevicesAndSetClient().
+  NOTREACHED();
+}
+
+void FakeHidManager::Connect(const std::string& device_guid,
+                             ConnectCallback callback) {
+  if (!base::ContainsKey(devices_, device_guid)) {
+    std::move(callback).Run(nullptr);
+    return;
+  }
+
+  mojom::HidConnectionPtr client;
+  mojo::MakeStrongBinding(
+      std::make_unique<FakeHidConnection>(devices_[device_guid]->Clone()),
+      mojo::MakeRequest(&client));
+  std::move(callback).Run(std::move(client));
+}
+
+mojom::HidDeviceInfoPtr FakeHidManager::CreateAndAddDevice(
+    const std::string& product_name,
+    const std::string& serial_number,
+    mojom::HidBusType bus_type) {
+  mojom::HidDeviceInfoPtr device = device::mojom::HidDeviceInfo::New();
+  device->guid = base::GenerateGUID();
+  device->product_name = product_name;
+  device->serial_number = serial_number;
+  device->bus_type = bus_type;
+  AddDevice(device.Clone());
+  return device;
+}
+
+void FakeHidManager::AddDevice(mojom::HidDeviceInfoPtr device) {
+  std::string guid = device->guid;
+  devices_[guid] = std::move(device);
+
+  mojom::HidDeviceInfo* device_info = devices_[guid].get();
+  clients_.ForAllPtrs([device_info](mojom::HidManagerClient* client) {
+    client->DeviceAdded(device_info->Clone());
+  });
+}
+
+void FakeHidManager::RemoveDevice(const std::string& guid) {
+  if (base::ContainsKey(devices_, guid)) {
+    mojom::HidDeviceInfo* device_info = devices_[guid].get();
+    clients_.ForAllPtrs([device_info](mojom::HidManagerClient* client) {
+      client->DeviceRemoved(device_info->Clone());
+    });
+    devices_.erase(guid);
+  }
+}
+
+}  // namespace device
diff --git a/services/device/public/cpp/hid/fake_hid_manager.h b/services/device/public/cpp/hid/fake_hid_manager.h
new file mode 100644
index 0000000..a94eb69
--- /dev/null
+++ b/services/device/public/cpp/hid/fake_hid_manager.h
@@ -0,0 +1,67 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_DEVICE_PUBLIC_CPP_HID_FAKE_HID_MANAGER_H_
+#define SERVICES_DEVICE_PUBLIC_CPP_HID_FAKE_HID_MANAGER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "services/device/public/mojom/hid.mojom.h"
+
+namespace device {
+
+class FakeHidConnection : public mojom::HidConnection {
+ public:
+  explicit FakeHidConnection(mojom::HidDeviceInfoPtr device);
+  ~FakeHidConnection() override;
+
+  // mojom::HidConnection implementation:
+  void Read(ReadCallback callback) override;
+  void Write(uint8_t report_id,
+             const std::vector<uint8_t>& buffer,
+             WriteCallback callback) override;
+  void GetFeatureReport(uint8_t report_id,
+                        GetFeatureReportCallback callback) override;
+
+  void SendFeatureReport(uint8_t report_id,
+                         const std::vector<uint8_t>& buffer,
+                         SendFeatureReportCallback callback) override;
+
+ private:
+  mojom::HidDeviceInfoPtr device_;
+};
+
+class FakeHidManager : public mojom::HidManager {
+ public:
+  FakeHidManager();
+  ~FakeHidManager() override;
+
+  void Bind(mojom::HidManagerRequest request);
+
+  // mojom::HidManager implementation:
+  void GetDevicesAndSetClient(mojom::HidManagerClientAssociatedPtrInfo client,
+                              GetDevicesCallback callback) override;
+  void GetDevices(GetDevicesCallback callback) override;
+  void Connect(const std::string& device_guid,
+               ConnectCallback callback) override;
+
+  mojom::HidDeviceInfoPtr CreateAndAddDevice(const std::string& product_name,
+                                             const std::string& serial_number,
+                                             mojom::HidBusType bus_type);
+  void AddDevice(mojom::HidDeviceInfoPtr device);
+  void RemoveDevice(const std::string& guid);
+
+ private:
+  std::map<std::string, mojom::HidDeviceInfoPtr> devices_;
+  mojo::AssociatedInterfacePtrSet<mojom::HidManagerClient> clients_;
+  mojo::BindingSet<mojom::HidManager> bindings_;
+};
+
+}  // namespace device
+
+#endif  // SERVICES_DEVICE_PUBLIC_CPP_HID_FAKE_HID_MANAGER_H_
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index c02b285..c172485b 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -99,13 +99,12 @@
     const ResourceRequest& resource_request,
     mojom::URLLoaderClientPtr client,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
-  if (!IsSane(context_, resource_request)) {
+  if (!IsSane(resource_request)) {
     client->OnComplete(URLLoaderCompletionStatus(net::ERR_INVALID_ARGUMENT));
     return;
   }
 
-  if (base::FeatureList::IsEnabled(features::kOutOfBlinkCors) &&
-      !disable_web_security_) {
+  if (features::ShouldEnableOutOfBlinkCors() && !disable_web_security_) {
     auto loader = std::make_unique<CorsURLLoader>(
         std::move(request), routing_id, request_id, options,
         base::BindOnce(&CorsURLLoaderFactory::DestroyURLLoader,
@@ -140,8 +139,7 @@
     context_->DestroyURLLoaderFactory(this);
 }
 
-bool CorsURLLoaderFactory::IsSane(const NetworkContext* context,
-                                  const ResourceRequest& request) {
+bool CorsURLLoaderFactory::IsSane(const ResourceRequest& request) {
   // CORS needs a proper origin (including a unique opaque origin). If the
   // request doesn't have one, CORS cannot work.
   if (!request.request_initiator &&
@@ -163,21 +161,6 @@
     return false;
   }
 
-  if (context) {
-    net::HttpRequestHeaders::Iterator header_iterator(
-        request.cors_exempt_headers);
-    const auto& allowed_exempt_headers = context->cors_exempt_header_list();
-    while (header_iterator.GetNext()) {
-      if (allowed_exempt_headers.find(header_iterator.name()) !=
-          allowed_exempt_headers.end()) {
-        continue;
-      }
-      LOG(WARNING) << "|cors_exempt_headers| contains unexpected key: "
-                   << header_iterator.name();
-      return false;
-    }
-  }
-
   // TODO(yhirano): If the request mode is "no-cors", the redirect mode should
   // be "follow".
   return true;
diff --git a/services/network/cors/cors_url_loader_factory.h b/services/network/cors/cors_url_loader_factory.h
index a072867..490a05db 100644
--- a/services/network/cors/cors_url_loader_factory.h
+++ b/services/network/cors/cors_url_loader_factory.h
@@ -76,8 +76,7 @@
 
   void DeleteIfNeeded();
 
-  static bool IsSane(const NetworkContext* context,
-                     const ResourceRequest& request);
+  static bool IsSane(const ResourceRequest& request);
 
   mojo::BindingSet<mojom::URLLoaderFactory> bindings_;
 
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc
index 92903bb..e1b60cf 100644
--- a/services/network/cors/cors_url_loader_unittest.cc
+++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -143,7 +143,8 @@
  protected:
   // testing::Test implementation.
   void SetUp() override {
-    feature_list_.InitAndEnableFeature(features::kOutOfBlinkCors);
+    feature_list_.InitWithFeatures(
+        {features::kOutOfBlinkCors, features::kNetworkService}, {});
 
     network_service_ = NetworkService::CreateForTesting();
 
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index c9cd180..4e825fc8 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -549,7 +549,7 @@
   resource_scheduler_ =
       std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
 
-  InitializeCorsParams();
+  InitializeCorsOriginAccessList();
 }
 
 // TODO(mmenke): Share URLRequestContextBulder configuration between two
@@ -578,14 +578,12 @@
   resource_scheduler_ =
       std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
 
-  InitializeCorsParams();
+  InitializeCorsOriginAccessList();
 }
 
-NetworkContext::NetworkContext(
-    NetworkService* network_service,
-    mojom::NetworkContextRequest request,
-    net::URLRequestContext* url_request_context,
-    const std::vector<std::string>& cors_exempt_header_list)
+NetworkContext::NetworkContext(NetworkService* network_service,
+                               mojom::NetworkContextRequest request,
+                               net::URLRequestContext* url_request_context)
     : network_service_(network_service),
       url_request_context_(url_request_context),
 #if defined(OS_ANDROID)
@@ -607,9 +605,6 @@
     network_service_->RegisterNetworkContext(this);
   resource_scheduler_ =
       std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
-
-  for (const auto& key : cors_exempt_header_list)
-    cors_exempt_header_list_.insert(key);
 }
 
 NetworkContext::~NetworkContext() {
@@ -2321,7 +2316,7 @@
 }
 #endif
 
-void NetworkContext::InitializeCorsParams() {
+void NetworkContext::InitializeCorsOriginAccessList() {
   for (const auto& pattern : params_->cors_origin_access_list) {
     url::Origin origin = url::Origin::Create(GURL(pattern->source_origin));
     cors_origin_access_list_.SetAllowListForOrigin(origin,
@@ -2329,8 +2324,6 @@
     cors_origin_access_list_.SetBlockListForOrigin(origin,
                                                    pattern->block_patterns);
   }
-  for (const auto& key : params_->cors_exempt_header_list)
-    cors_exempt_header_list_.insert(key);
 }
 
 }  // namespace network
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 8cfa0be9..ad9e10f 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -11,7 +11,6 @@
 #include <memory>
 #include <set>
 #include <string>
-#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -128,8 +127,7 @@
   // TODO(mmenke):  Remove this constructor when the network service ships.
   NetworkContext(NetworkService* network_service,
                  mojom::NetworkContextRequest request,
-                 net::URLRequestContext* url_request_context,
-                 const std::vector<std::string>& cors_exempt_header_list);
+                 net::URLRequestContext* url_request_context);
 
   ~NetworkContext() override;
 
@@ -153,10 +151,6 @@
 
   CookieManager* cookie_manager() { return cookie_manager_.get(); }
 
-  const std::unordered_set<std::string>& cors_exempt_header_list() const {
-    return cors_exempt_header_list_;
-  }
-
 #if defined(OS_ANDROID)
   base::android::ApplicationStatusListener* app_status_listener() const {
     return app_status_listener_.get();
@@ -445,7 +439,7 @@
   void OnSetExpectCTTestReportFailure();
 #endif  // BUILDFLAG(IS_CT_SUPPORTED)
 
-  void InitializeCorsParams();
+  void InitializeCorsOriginAccessList();
 
   NetworkService* const network_service_;
 
@@ -582,10 +576,6 @@
   // Manages allowed origin access lists.
   cors::OriginAccessList cors_origin_access_list_;
 
-  // Manages header keys that are allowed to be used in
-  // ResourceRequest::cors_exempt_headers.
-  std::unordered_set<std::string> cors_exempt_header_list_;
-
   // Manages CORS preflight requests and its cache.
   cors::PreflightController cors_preflight_controller_;
 
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 72e96fb..5276ed9 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -59,5 +59,13 @@
 const base::Feature kEnforceRequestInitiatorLockForCorb{
     "EnforceRequestInitiatorLockForCorb", base::FEATURE_ENABLED_BY_DEFAULT};
 
+bool ShouldEnableOutOfBlinkCors() {
+  // OOR-CORS requires NetworkService.
+  if (!base::FeatureList::IsEnabled(features::kNetworkService))
+    return false;
+
+  return base::FeatureList::IsEnabled(features::kOutOfBlinkCors);
+}
+
 }  // namespace features
 }  // namespace network
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 72618b3..cbf53f1f 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -28,6 +28,8 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kEnforceRequestInitiatorLockForCorb;
 
+COMPONENT_EXPORT(NETWORK_CPP) bool ShouldEnableOutOfBlinkCors();
+
 }  // namespace features
 }  // namespace network
 
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc
index 454d425..5ac1cf9 100644
--- a/services/network/public/cpp/resource_request.cc
+++ b/services/network/public/cpp/resource_request.cc
@@ -22,8 +22,8 @@
          referrer_policy == request.referrer_policy &&
          is_prerendering == request.is_prerendering &&
          headers.ToString() == request.headers.ToString() &&
-         cors_exempt_headers.ToString() ==
-             request.cors_exempt_headers.ToString() &&
+         requested_with_header == request.requested_with_header &&
+         client_data_header == request.client_data_header &&
          load_flags == request.load_flags &&
          allow_credentials == request.allow_credentials &&
          plugin_child_id == request.plugin_child_id &&
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h
index 11df12af..346344d0 100644
--- a/services/network/public/cpp/resource_request.h
+++ b/services/network/public/cpp/resource_request.h
@@ -47,7 +47,8 @@
       net::URLRequest::NEVER_CLEAR_REFERRER;
   bool is_prerendering = false;
   net::HttpRequestHeaders headers;
-  net::HttpRequestHeaders cors_exempt_headers;
+  std::string requested_with_header;
+  std::string client_data_header;
   int load_flags = 0;
   bool allow_credentials = true;
   int plugin_child_id = -1;
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
index be488ca..f67fb04 100644
--- a/services/network/public/cpp/url_request_mojom_traits.cc
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -162,7 +162,8 @@
       !data.ReadReferrer(&out->referrer) ||
       !data.ReadReferrerPolicy(&out->referrer_policy) ||
       !data.ReadHeaders(&out->headers) ||
-      !data.ReadCorsExemptHeaders(&out->cors_exempt_headers) ||
+      !data.ReadRequestedWithHeader(&out->requested_with_header) ||
+      !data.ReadClientDataHeader(&out->client_data_header) ||
       !data.ReadPriority(&out->priority) ||
       !data.ReadCorsPreflightPolicy(&out->cors_preflight_policy) ||
       !data.ReadFetchRequestMode(&out->fetch_request_mode) ||
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h
index 276e03b4..20dd802 100644
--- a/services/network/public/cpp/url_request_mojom_traits.h
+++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -85,9 +85,13 @@
       const network::ResourceRequest& request) {
     return request.headers;
   }
-  static const net::HttpRequestHeaders& cors_exempt_headers(
+  static const std::string& requested_with_header(
       const network::ResourceRequest& request) {
-    return request.cors_exempt_headers;
+    return request.requested_with_header;
+  }
+  static const std::string& client_data_header(
+      const network::ResourceRequest& request) {
+    return request.client_data_header;
   }
   static int32_t load_flags(const network::ResourceRequest& request) {
     return request.load_flags;
diff --git a/services/network/public/cpp/url_request_mojom_traits_unittest.cc b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
index bd41643..246a2c3 100644
--- a/services/network/public/cpp/url_request_mojom_traits_unittest.cc
+++ b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
@@ -57,7 +57,8 @@
       net::URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN;
   original.is_prerendering = false;
   original.headers.SetHeader("Accept", "text/xml");
-  original.cors_exempt_headers.SetHeader("X-Requested-With", "ForTesting");
+  original.requested_with_header = "dummy_requested_with_header";
+  original.client_data_header = "dummy_client_data_header";
   original.load_flags = 3;
   original.allow_credentials = true;
   original.plugin_child_id = 5;
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 541496e..b994ea5b 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -347,10 +347,6 @@
   // Specifies the initial set of allowed and blocked origins for the
   // URLLoaderFactory consumers to access beyond the same-origin-policy.
   array<CorsOriginAccessPatterns> cors_origin_access_list;
-
-  // Specifies header keys that are allowed to be used in
-  // network::url_request.cors_exempt_headers.
-  array<string> cors_exempt_header_list;
 };
 
 struct NetworkConditions {
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom
index a269edda..049da805 100644
--- a/services/network/public/mojom/url_loader.mojom
+++ b/services/network/public/mojom/url_loader.mojom
@@ -118,21 +118,19 @@
   // Additional HTTP request headers.
   HttpRequestHeaders headers;
 
-  // HTTP request headers that has been internally added. Some consumers want to
-  // set additional HTTP headers, but such internal headers must be ignored by
-  // CORS check (which run inside Network Service), so the values are stored
-  // here (rather than in |headers|) and later merged into the |headers| after
-  // CORS check.
-  //
-  // *Warning*: Adding new headers to this list is strongly discouraged. What
-  // usually you need is to update the fetch spec, and add your custom headers
-  // to the CORS-safelisted header so to pass proper CORS checks. 'Proxy-' or
-  // 'Sec-' prefixes are also available. See cors::IsCORSSafelistedHeader and
-  // cors::IsForbiddenHeader for details.
-  //
-  // You should ask Loading and CORS OWNERS when you need to add your own
-  // headers to the list.
-  HttpRequestHeaders cors_exempt_headers;  // See Note above before using.
+  // 'X-Requested-With' header value. Some consumers want to set this header,
+  // but such internal headers must be ignored by CORS checks (which run inside
+  // Network Service), so the value is stored here (rather than in |headers|)
+  // and later populated in the headers after CORS check.
+  // TODO(toyoshim): Remove it once PPAPI is deprecated.
+  string requested_with_header;
+
+  // 'X-Client-Data' header value. See comments for |requested_with_header|
+  // above, too.
+  // TODO(toyoshim): Consider to rename this to have a chrome specific prefix
+  // such as 'Chrome-' instead of 'X-', and to add 'Chrome-' prefixed header
+  // names into the forbidden header name list.
+  string client_data_header;
 
   // net::URLRequest load flags.
   int32 load_flags;
diff --git a/services/network/test/test_shared_url_loader_factory.cc b/services/network/test/test_shared_url_loader_factory.cc
index a6ab2c2..acfec46 100644
--- a/services/network/test/test_shared_url_loader_factory.cc
+++ b/services/network/test/test_shared_url_loader_factory.cc
@@ -17,8 +17,7 @@
   mojom::NetworkContextPtr network_context;
   network_context_ = std::make_unique<NetworkContext>(
       network_service, mojo::MakeRequest(&network_context),
-      url_request_context_.get(),
-      /*cors_exempt_header_list=*/std::vector<std::string>());
+      url_request_context_.get());
   mojom::URLLoaderFactoryParamsPtr params =
       mojom::URLLoaderFactoryParams::New();
   params->process_id = mojom::kBrowserProcessId;
diff --git a/services/network/transitional_url_loader_factory_owner.cc b/services/network/transitional_url_loader_factory_owner.cc
index 0964d62..29316057 100644
--- a/services/network/transitional_url_loader_factory_owner.cc
+++ b/services/network/transitional_url_loader_factory_owner.cc
@@ -60,8 +60,7 @@
       mojom::NetworkContextRequest request) {
     network_context_ = std::make_unique<network::NetworkContext>(
         nullptr /* network_service */, std::move(request),
-        url_request_context_getter_->GetURLRequestContext(),
-        /*cors_exempt_header_list=*/std::vector<std::string>());
+        url_request_context_getter_->GetURLRequestContext());
   }
 
   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 7f1d8e13..a867be6 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -376,15 +376,20 @@
   url_request_->set_attach_same_site_cookies(request.attach_same_site_cookies);
   url_request_->SetReferrer(ComputeReferrer(request.referrer));
   url_request_->set_referrer_policy(request.referrer_policy);
+  url_request_->SetExtraRequestHeaders(request.headers);
+  // X-Requested-With and X-Client-Data header must be set here to avoid
+  // breaking CORS checks. They are non-empty when the values are given by the
+  // UA code, therefore they should be ignored by CORS checks.
+  if (!request.requested_with_header.empty()) {
+    url_request_->SetExtraRequestHeaderByName(
+        "X-Requested-With", request.requested_with_header, true);
+  }
+  if (!request.client_data_header.empty()) {
+    url_request_->SetExtraRequestHeaderByName("X-Client-Data",
+                                              request.client_data_header, true);
+  }
   url_request_->set_upgrade_if_insecure(request.upgrade_if_insecure);
 
-  // |cors_excempt_headers| must be merged here to avoid breaking CORS checks.
-  // They are non-empty when the values are given by the UA code, therefore
-  // they should be ignored by CORS checks.
-  net::HttpRequestHeaders merged_headers = request.headers;
-  merged_headers.MergeFrom(request.cors_exempt_headers);
-  url_request_->SetExtraRequestHeaders(merged_headers);
-
   url_request_->SetUserData(kUserDataKey,
                             std::make_unique<UnownedPointer>(this));
 
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index fac4e27..aab42463 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -3740,6 +3740,25 @@
   "chromeos-vm-code-coverage": {
     "gtest_tests": [
       {
+        "args": [
+          "--ozone-platform=headless"
+        ],
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "aura_unittests"
+      },
+      {
         "isolate_coverage_data": true,
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -3754,6 +3773,379 @@
           "io_timeout": 3600
         },
         "test": "base_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "cacheinvalidation_unittests"
+      },
+      {
+        "args": [
+          "--test-launcher-jobs=1",
+          "--gtest_filter=-*UsingRealWebcam_CaptureMjpeg*"
+        ],
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "capture_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "cc_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "chrome_all_tast_tests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "cros_vm_sanity_test"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "crypto_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "display_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "google_apis_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "ipc_tests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "jingle_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "latency_unittests"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.media_unittests.filter"
+        ],
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "media_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "midi_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "mojo_unittests"
+      },
+      {
+        "args": [
+          "--vpython-dir=../../vpython_dir_linux_amd64"
+        ],
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/vpython/linux-amd64",
+              "location": "vpython_dir_linux_amd64",
+              "revision": "git_revision:9a931a5307c46b16b1c12e01e8239d4a73830b89"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600,
+          "shards": 3
+        },
+        "test": "net_unittests"
+      },
+      {
+        "args": [
+          "--ozone-platform=headless"
+        ],
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "ozone_gl_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "ozone_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "pdf_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "printing_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "sandbox_linux_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "sql_unittests"
+      },
+      {
+        "isolate_coverage_data": true,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-CrOS-VM"
+            }
+          ],
+          "hard_timeout": 3600,
+          "io_timeout": 3600
+        },
+        "test": "url_unittests"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 1c72ffe..0b82616 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -693,6 +693,48 @@
             }
           ]
         },
+        "test": "blink_common_unittests"
+      },
+      {
+        "args": [
+          "--qemu-require-kvm"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1"
+            }
+          ]
+        },
+        "test": "blink_heap_unittests"
+      },
+      {
+        "args": [
+          "--qemu-require-kvm"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1"
+            }
+          ]
+        },
+        "test": "blink_platform_unittests"
+      },
+      {
+        "args": [
+          "--qemu-require-kvm"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1"
+            }
+          ]
+        },
         "test": "cast_runner_browsertests"
       },
       {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index e7c24922..14541c14 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -5334,7 +5334,7 @@
               "os": "Ubuntu-14.04"
             }
           ],
-          "shards": 20
+          "shards": 30
         },
         "test": "browser_tests"
       },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 6853b698..938bd9f 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -55,24 +55,6 @@
       },
     },
   },
-  'blink_common_unittests': {
-    'remove_from': [
-      # chromium.linux
-      'Fuchsia x64',
-    ],
-  },
-  'blink_heap_unittests': {
-    'remove_from': [
-      # chromium.linux
-      'Fuchsia x64',
-    ],
-  },
-  'blink_platform_unittests': {
-    'remove_from': [
-      # chromium.linux
-      'Fuchsia x64',
-    ],
-  },
   'browser_tests': {
     'remove_from': [
       # chromium.clang
@@ -1321,7 +1303,7 @@
         # These are very slow on the Chrome OS MSAN trybot for some reason.
         # crbug.com/865455
         'swarming': {
-          'shards': 20,
+          'shards': 30,
         },
       },
       'Linux Chromium OS ASan LSan Tests (1)': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 12c2dc3..d8908b1 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -370,10 +370,6 @@
     # NOTE: We only want a small subset of test suites here, because most
     # suites assume that they stub out the underlying device hardware.
     # https://crbug.com/865693
-    'chromeos_coverage_gtests_experimental': {
-      'base_unittests': {},
-    },
-
     'chromeos_device_friendly_gtests': {
       'aura_unittests': {
         'args': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 840723cd..24821c6 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -1399,7 +1399,7 @@
             'code-coverage',
         ],
         'test_suites': {
-          'gtest_tests': 'chromeos_coverage_gtests_experimental',
+          'gtest_tests': 'chromeos_device_friendly_gtests',
         },
         'swarming': {
           'dimension_sets': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index bac03ce..499217d 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2108,7 +2108,10 @@
             ],
             "experiments": [
                 {
-                    "name": "branded"
+                    "name": "Enabled",
+                    "enable_features": [
+                        "GoogleBrandedContextMenu"
+                    ]
                 }
             ]
         }
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom
index 5fbcafd..1d02f34 100644
--- a/third_party/blink/public/mojom/web_feature/web_feature.mojom
+++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2260,6 +2260,9 @@
   kAdClickNavigation = 2826,
   kRTCStatsRelativePacketArrivalDelay = 2827,
 
+  // The above items are available in M74 branch.
+  kFlexboxWithOverflowFlexItemIntrinsicSize = 2828,
+
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
   // Also, run update_use_counter_feature_enum.py in
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index 07dbad1..9c8e768 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -296,14 +296,13 @@
 
   // Returns the hash for the given canonicalized URL for use in visited
   // link coloring.
-  virtual unsigned long long VisitedLinkHash(const char* canonical_url,
-                                             size_t length) {
+  virtual uint64_t VisitedLinkHash(const char* canonical_url, size_t length) {
     return 0;
   }
 
   // Returns whether the given link hash is in the user's history. The
   // hash must have been generated by calling VisitedLinkHash().
-  virtual bool IsLinkVisited(unsigned long long link_hash) { return false; }
+  virtual bool IsLinkVisited(uint64_t link_hash) { return false; }
 
   static const size_t kNoDecodedImageByteLimit = static_cast<size_t>(-1);
 
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h
index 1820058..3aba024 100644
--- a/third_party/blink/public/platform/web_url_request.h
+++ b/third_party/blink/public/platform/web_url_request.h
@@ -318,6 +318,12 @@
   BLINK_PLATFORM_EXPORT const WebString GetRequestedWithHeader() const;
   BLINK_PLATFORM_EXPORT void SetRequestedWithHeader(const WebString&);
 
+  // Remembers 'X-Client-Data' header value. Blink should not set this header
+  // value until CORS checks are done to avoid running checks even against
+  // headers that are internally set.
+  BLINK_PLATFORM_EXPORT const WebString GetClientDataHeader() const;
+  BLINK_PLATFORM_EXPORT void SetClientDataHeader(const WebString&);
+
   // https://fetch.spec.whatwg.org/#concept-request-window
   // See network::ResourceRequest::fetch_window_id for details.
   BLINK_PLATFORM_EXPORT const base::UnguessableToken& GetFetchWindowId() const;
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h
index 61ea5ce4..73f44bb 100644
--- a/third_party/blink/public/web/web_view.h
+++ b/third_party/blink/public/web/web_view.h
@@ -369,7 +369,7 @@
 
   // Tells all WebView instances to update the visited link state for the
   // specified hash.
-  BLINK_EXPORT static void UpdateVisitedLinkState(unsigned long long hash);
+  BLINK_EXPORT static void UpdateVisitedLinkState(uint64_t hash);
 
   // Tells all WebView instances to update the visited state for all
   // their links. Use invalidateVisitedLinkHashes to inform that the visitedlink
diff --git a/third_party/blink/renderer/bindings/scripts/v8_interface.py b/third_party/blink/renderer/bindings/scripts/v8_interface.py
index 65160189e..5bdeb1c1 100644
--- a/third_party/blink/renderer/bindings/scripts/v8_interface.py
+++ b/third_party/blink/renderer/bindings/scripts/v8_interface.py
@@ -71,6 +71,7 @@
     'base/memory/scoped_refptr.h',
     'bindings/core/v8/v8_dom_configuration.h',
     'core/execution_context/execution_context.h',
+    'platform/scheduler/public/cooperative_scheduling_manager.h',
     'platform/bindings/exception_messages.h',
     'platform/bindings/exception_state.h',
     'platform/bindings/v8_object_constructor.h',
diff --git a/third_party/blink/renderer/bindings/templates/methods.cc.tmpl b/third_party/blink/renderer/bindings/templates/methods.cc.tmpl
index 2da8418..a71634e1 100644
--- a/third_party/blink/renderer/bindings/templates/methods.cc.tmpl
+++ b/third_party/blink/renderer/bindings/templates/methods.cc.tmpl
@@ -365,6 +365,8 @@
 {##############################################################################}
 {% macro overload_resolution_method(overloads, world_suffix) %}
 static void {{overloads.camel_case_name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   {% set fall_through_to_partial_overloads = not is_partial and overloads.has_partial_overloads %}
 
   {% if overloads.measure_all_as %}
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.cc
index 984b5ab..2eba168 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.cc
index 908abaf..1555e248 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.cc
@@ -34,6 +34,7 @@
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_data_view.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_data_view.cc
index bbf42fb..42b8494 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_data_view.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_data_view.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.cc
index ecdc18f..5bf35fa 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_attributes.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_attributes.cc
index ccfffa4..b84ba2ee 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_attributes.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_attributes.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.cc
index b52a3c7..35765b7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.cc
index 334c642..b85ad5f 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.cc
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.cc
index 668a766..a80a13f 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.cc
@@ -24,6 +24,7 @@
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.cc
index 7622c041..6e58680 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.cc
index 9cb8629..2fa79e44 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.cc
@@ -40,6 +40,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
@@ -1811,6 +1812,8 @@
 }
 
 static void OverloadMethodWithExposedAndRuntimeEnabledFlagMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -1953,6 +1956,8 @@
 }
 
 static void OverloadMethodWithUnionTypeWithStringMemberMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -2280,6 +2285,8 @@
 }
 
 static void VoidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   switch (std::min(1, info.Length())) {
     case 0:
       if (true) {
@@ -2304,6 +2311,8 @@
 }
 
 static void StaticVoidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   switch (std::min(1, info.Length())) {
     case 0:
       if (true) {
@@ -2320,6 +2329,8 @@
 }
 
 static void PromiseMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   switch (std::min(1, info.Length())) {
     case 0:
       if (true) {
@@ -2340,6 +2351,8 @@
 }
 
 static void StaticPromiseMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   switch (std::min(1, info.Length())) {
     case 0:
       if (true) {
@@ -2356,6 +2369,8 @@
 }
 
 static void Partial2VoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   switch (std::min(1, info.Length())) {
     case 0:
       if (true) {
@@ -2372,6 +2387,8 @@
 }
 
 static void Partial2StaticVoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   switch (std::min(1, info.Length())) {
     case 0:
       if (true) {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.cc
index 22dfb2768..d8d2a6b 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc
index 09f91b9..8e2907a5 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_cross_origin_setter_info.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
@@ -407,6 +408,8 @@
 }
 
 static void DoNotCheckSecurityVoidOverloadMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(2, info.Length())) {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.cc
index 7fd987b8..931f0b3 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.cc
index 1a2e02e..d5313903 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
 #include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.cc
index 24acebc..49616a0 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.cc
index c21ba3e..fa1f218 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.cc
index b8e22a3b..00442e0 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.cc
index 67da084..eb6c346 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.cc
@@ -17,6 +17,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.cc
index c9420eb..91bd931 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.cc
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.cc
index ed6edc91..9c1e665e 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.cc
index d4393e0..51eee84d 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.cc
index 592a9bf..28b9b16 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
 #include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.cc
index 6b8923b..32a91d7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
 #include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.cc
index b1f8321..c3af467 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
 #include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.cc
index bf81dfb..0131d22 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.cc
index fdfc0729..cef580d 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
@@ -195,6 +196,8 @@
 }
 
 static void VoidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.cc
index 27cf0ef..819d07a5 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_node.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_node.cc
index c07e326..5c3968f 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_node.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_node.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
index a413aca..70f7978 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
@@ -72,6 +72,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
 #include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
@@ -6695,6 +6696,8 @@
 }
 
 static void OverloadedMethodAMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(2, info.Length())) {
@@ -6766,6 +6769,8 @@
 }
 
 static void OverloadedMethodBMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(2, info.Length())) {
@@ -6830,6 +6835,8 @@
 }
 
 static void OverloadedMethodCMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -6888,6 +6895,8 @@
 }
 
 static void OverloadedMethodDMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -6958,6 +6967,8 @@
 }
 
 static void OverloadedMethodEMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7028,6 +7039,8 @@
 }
 
 static void OverloadedMethodFMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7096,6 +7109,8 @@
 }
 
 static void OverloadedMethodGMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7164,6 +7179,8 @@
 }
 
 static void OverloadedMethodHMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7216,6 +7233,8 @@
 }
 
 static void OverloadedMethodIMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7276,6 +7295,8 @@
 }
 
 static void OverloadedMethodJMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7333,6 +7354,8 @@
 }
 
 static void OverloadedMethodKMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7397,6 +7420,8 @@
 }
 
 static void OverloadedMethodLMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(2, info.Length())) {
@@ -7470,6 +7495,8 @@
 }
 
 static void OverloadedMethodNMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7567,6 +7594,8 @@
 }
 
 static void PromiseOverloadMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(2, info.Length())) {
@@ -7627,6 +7656,8 @@
 }
 
 static void OverloadedPerWorldBindingsMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7666,6 +7697,8 @@
 }
 
 static void OverloadedPerWorldBindingsMethodMethodForMainWorld(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -7719,6 +7752,8 @@
 }
 
 static void OverloadedStaticMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(2, info.Length())) {
@@ -8005,6 +8040,8 @@
 }
 
 static void MeasureOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -8054,6 +8091,8 @@
 }
 
 static void DeprecateAsOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -8101,6 +8140,8 @@
 }
 
 static void DeprecateAsSameValueOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::kTestFeature);
 
   bool is_arity_error = false;
@@ -8148,6 +8189,8 @@
 }
 
 static void MeasureAsOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -8197,6 +8240,8 @@
 }
 
 static void MeasureAsSameValueOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -8278,6 +8323,8 @@
 }
 
 static void CeReactionsOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -8323,6 +8370,8 @@
 }
 
 static void DeprecateAsMeasureAsSameValueOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -8374,6 +8423,8 @@
 }
 
 static void DeprecateAsSameValueMeasureAsOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::kTestFeature);
 
   bool is_arity_error = false;
@@ -8425,6 +8476,8 @@
 }
 
 static void DeprecateAsSameValueMeasureAsSameValueOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::kTestFeatureA);
 
   bool is_arity_error = false;
@@ -8738,6 +8791,8 @@
 }
 
 static void RuntimeEnabledOverloadedVoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -8854,6 +8909,8 @@
 }
 
 static void PartiallyRuntimeEnabledOverloadedVoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(test_object_v8_internal::PartiallyRuntimeEnabledOverloadedVoidMethodMethodMaxArg(), info.Length())) {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.cc
index c847495..f7300ab 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.cc
index e31e102..01a351ac 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.cc
index 0f065b4..d294fb1 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.cc
index 39a9413..ca56b9b7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.cc
index d1a1b1eff..e5fc808a 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.cc
index c9cba77a..93aef88c 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.cc
index ec9328cc..77451f90 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.cc
index 70d1c28d..902c2f8 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.cc
index f631680f..1ab0914 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.cc
@@ -30,6 +30,7 @@
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
@@ -98,6 +99,8 @@
 }
 
 static void VoidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -129,6 +132,8 @@
 }
 
 static void StaticVoidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -173,6 +178,8 @@
 }
 
 static void PromiseMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -208,6 +215,8 @@
 }
 
 static void StaticPromiseMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -255,6 +264,8 @@
 }
 
 static void Partial2VoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
@@ -315,6 +326,8 @@
 }
 
 static void Partial2StaticVoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();
+
   bool is_arity_error = false;
 
   switch (std::min(1, info.Length())) {
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.cc
index 3cd1b59..b6688d8 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.cc
index a8ad53f..9c3d0a8 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 #include "third_party/blink/renderer/platform/wtf/get_ptr.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl b/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl
index 86d48b87..1c7ab588 100644
--- a/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl
@@ -9,7 +9,6 @@
 #define {{header_guard}}
 
 #include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
 {% for include in config["settings"]["includes"] %}
 #include "{{include}}"
 {% endfor %}
diff --git a/third_party/blink/renderer/core/animation/document_animations.h b/third_party/blink/renderer/core/animation/document_animations.h
index 024c5c4..12f52b2 100644
--- a/third_party/blink/renderer/core/animation/document_animations.h
+++ b/third_party/blink/renderer/core/animation/document_animations.h
@@ -35,12 +35,15 @@
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/dom/document_lifecycle.h"
 #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace blink {
 
 class Document;
 
 class DocumentAnimations {
+  STATIC_ONLY(DocumentAnimations);
+
  public:
   static void UpdateAnimationTimingForAnimationFrame(Document&);
   static bool NeedsAnimationTimingUpdate(const Document&);
@@ -53,9 +56,6 @@
       Document&,
       DocumentLifecycle::LifecycleState required_lifecycle_state,
       const base::Optional<CompositorElementIdSet>&);
-
- private:
-  DocumentAnimations() = default;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/image_slice_property_functions.h b/third_party/blink/renderer/core/animation/image_slice_property_functions.h
index ca090999..02cd55c 100644
--- a/third_party/blink/renderer/core/animation/image_slice_property_functions.h
+++ b/third_party/blink/renderer/core/animation/image_slice_property_functions.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace blink {
 
@@ -20,6 +21,8 @@
 };
 
 class ImageSlicePropertyFunctions {
+  STATIC_ONLY(ImageSlicePropertyFunctions);
+
  public:
   static ImageSlice GetInitialImageSlice(const CSSProperty& property) {
     return GetImageSlice(property, ComputedStyle::InitialStyle());
diff --git a/third_party/blink/renderer/core/animation/list_interpolation_functions.h b/third_party/blink/renderer/core/animation/list_interpolation_functions.h
index a263b94..3cca4332 100644
--- a/third_party/blink/renderer/core/animation/list_interpolation_functions.h
+++ b/third_party/blink/renderer/core/animation/list_interpolation_functions.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include "third_party/blink/renderer/core/animation/interpolation_value.h"
 #include "third_party/blink/renderer/core/animation/pairwise_interpolation_value.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
@@ -16,6 +17,8 @@
 class InterpolationType;
 
 class CORE_EXPORT ListInterpolationFunctions {
+  STACK_ALLOCATED();
+
  public:
   template <typename CreateItemCallback>
   static InterpolationValue CreateList(wtf_size_t length, CreateItemCallback);
diff --git a/third_party/blink/renderer/core/animation/number_property_functions.h b/third_party/blink/renderer/core/animation/number_property_functions.h
index 4b32e30..7596581 100644
--- a/third_party/blink/renderer/core/animation/number_property_functions.h
+++ b/third_party/blink/renderer/core/animation/number_property_functions.h
@@ -7,6 +7,7 @@
 
 #include "base/optional.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace blink {
 
@@ -14,6 +15,8 @@
 class CSSProperty;
 
 class NumberPropertyFunctions {
+  STATIC_ONLY(NumberPropertyFunctions);
+
  public:
   static base::Optional<double> GetInitialNumber(const CSSProperty&);
   static base::Optional<double> GetNumber(const CSSProperty&,
diff --git a/third_party/blink/renderer/core/animation/path_interpolation_functions.h b/third_party/blink/renderer/core/animation/path_interpolation_functions.h
index 93f8752..96b91cc 100644
--- a/third_party/blink/renderer/core/animation/path_interpolation_functions.h
+++ b/third_party/blink/renderer/core/animation/path_interpolation_functions.h
@@ -8,12 +8,15 @@
 #include <memory>
 #include "third_party/blink/renderer/core/animation/interpolation_type.h"
 #include "third_party/blink/renderer/core/svg/svg_path_byte_stream.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace blink {
 
 class StylePath;
 
 class PathInterpolationFunctions {
+  STATIC_ONLY(PathInterpolationFunctions);
+
  public:
   enum CoordinateConversion { PreserveCoordinates, ForceAbsolute };
 
diff --git a/third_party/blink/renderer/core/animation/typed_interpolation_value.h b/third_party/blink/renderer/core/animation/typed_interpolation_value.h
index d9702ea..1b4014c 100644
--- a/third_party/blink/renderer/core/animation/typed_interpolation_value.h
+++ b/third_party/blink/renderer/core/animation/typed_interpolation_value.h
@@ -10,6 +10,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "third_party/blink/renderer/core/animation/interpolation_value.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace blink {
 
@@ -18,6 +19,8 @@
 // Represents an interpolated value between an adjacent pair of
 // PropertySpecificKeyframes.
 class TypedInterpolationValue {
+  USING_FAST_MALLOC(TypedInterpolationValue);
+
  public:
   static std::unique_ptr<TypedInterpolationValue> Create(
       const InterpolationType& type,
diff --git a/third_party/blink/renderer/core/content_capture/content_capture_test.cc b/third_party/blink/renderer/core/content_capture/content_capture_test.cc
index 513a76d..36cbf93 100644
--- a/third_party/blink/renderer/core/content_capture/content_capture_test.cc
+++ b/third_party/blink/renderer/core/content_capture/content_capture_test.cc
@@ -613,7 +613,7 @@
     auto* child_frame =
         ToHTMLIFrameElement(GetDocument().getElementById("frame"));
     child_document_ = child_frame->contentDocument();
-    child_document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    child_document_->UpdateStyleAndLayout();
     Compositor().BeginFrame();
     InitMainFrameNodeHolders();
     InitChildFrameNodeHolders(*child_document_);
diff --git a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
index 38db457..16a25287 100644
--- a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
+++ b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
@@ -245,7 +245,7 @@
   if (!node_)
     return nullptr;
 
-  node_->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  node_->GetDocument().UpdateStyleAndLayout();
 
   const ComputedStyle* style =
       node_->EnsureComputedStyle(pseudo_element_specifier_);
@@ -357,7 +357,7 @@
   const ComputedStyle* style = ComputeComputedStyle();
 
   if (property_class.IsLayoutDependent(style, layout_object)) {
-    document.UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(styled_node);
+    document.UpdateStyleAndLayoutForNode(styled_node);
     styled_node = StyledNode();
     style = ComputeComputedStyle();
     layout_object = StyledLayoutObject();
@@ -409,7 +409,7 @@
       (property_value.IsPrimitiveValue() ||
        property_value.IsIdentifierValue()) &&
       node_) {
-    node_->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    node_->GetDocument().UpdateStyleAndLayout();
     const ComputedStyle* style =
         node_->EnsureComputedStyle(pseudo_element_specifier_);
     if (style && style->GetFontDescription().KeywordSize()) {
diff --git a/third_party/blink/renderer/core/css/css_image_generator_value.h b/third_party/blink/renderer/core/css/css_image_generator_value.h
index 9d9c789..f0321cd 100644
--- a/third_party/blink/renderer/core/css/css_image_generator_value.h
+++ b/third_party/blink/renderer/core/css/css_image_generator_value.h
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/core/css/css_value.h"
 #include "third_party/blink/renderer/platform/geometry/float_size.h"
 #include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 
 namespace blink {
@@ -61,6 +62,8 @@
     std::map<FloatSize, scoped_refptr<Image>, FloatSizeCompare>;
 
 class GeneratedImageCache {
+  DISALLOW_NEW();
+
  public:
   void AddSize(const FloatSize&);
   void RemoveSize(const FloatSize&);
diff --git a/third_party/blink/renderer/core/css/css_syntax_component.h b/third_party/blink/renderer/core/css/css_syntax_component.h
index a828a13..bda4962 100644
--- a/third_party/blink/renderer/core/css/css_syntax_component.h
+++ b/third_party/blink/renderer/core/css/css_syntax_component.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/css/css_value.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
@@ -35,6 +36,8 @@
 enum class CSSSyntaxRepeat { kNone, kSpaceSeparated, kCommaSeparated };
 
 class CSSSyntaxComponent {
+  DISALLOW_NEW();
+
  public:
   CSSSyntaxComponent(CSSSyntaxType type,
                      const String& string,
diff --git a/third_party/blink/renderer/core/css/css_syntax_string_parser.h b/third_party/blink/renderer/core/css/css_syntax_string_parser.h
index d9739ed..d681a907e5 100644
--- a/third_party/blink/renderer/core/css/css_syntax_string_parser.h
+++ b/third_party/blink/renderer/core/css/css_syntax_string_parser.h
@@ -8,6 +8,7 @@
 #include "base/optional.h"
 #include "third_party/blink/renderer/core/css/css_syntax_descriptor.h"
 #include "third_party/blink/renderer/core/css/parser/css_tokenizer_input_stream.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace blink {
 
@@ -17,6 +18,8 @@
 //
 // https://drafts.css-houdini.org/css-properties-values-api-1/#parsing-syntax
 class CORE_EXPORT CSSSyntaxStringParser {
+  STACK_ALLOCATED();
+
  public:
   explicit CSSSyntaxStringParser(const String&);
 
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_token_stream.h b/third_party/blink/renderer/core/css/parser/css_parser_token_stream.h
index fbc17152..d348ad0d 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_token_stream.h
+++ b/third_party/blink/renderer/core/css/parser/css_parser_token_stream.h
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
 #include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace blink {
 
@@ -40,6 +41,8 @@
   // Instantiate this to start reading from a block. When the guard is out of
   // scope, the rest of the block is consumed.
   class BlockGuard {
+    STACK_ALLOCATED();
+
    public:
     explicit BlockGuard(CSSParserTokenStream& stream) : stream_(stream) {
       const CSSParserToken next = stream.ConsumeInternal();
diff --git a/third_party/blink/renderer/core/css/parser/css_proto_converter.h b/third_party/blink/renderer/core/css/parser/css_proto_converter.h
index c369955..c650b3c9 100644
--- a/third_party/blink/renderer/core/css/parser/css_proto_converter.h
+++ b/third_party/blink/renderer/core/css/parser/css_proto_converter.h
@@ -8,10 +8,13 @@
 #include <string>
 
 #include "third_party/blink/renderer/core/css/parser/css.pb.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace css_proto_converter {
 
 class Converter {
+  STACK_ALLOCATED();
+
  public:
   Converter();
   std::string Convert(const StyleSheet&);
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index 3f244abe..fc15e32 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -1360,8 +1360,7 @@
   if (tree_scope.GetDocument().HasPendingForcedStyleRecalc())
     return;
 
-  if (!tree_scope.GetDocument().body() ||
-      tree_scope.GetDocument().HasNodesWithPlaceholderStyle()) {
+  if (!tree_scope.GetDocument().body()) {
     tree_scope.GetDocument().SetNeedsStyleRecalc(
         kSubtreeStyleChange,
         StyleChangeReasonForTracing::Create(
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
index 78e6761..73e4431 100644
--- a/third_party/blink/renderer/core/css/style_engine.h
+++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -87,18 +87,6 @@
   USING_GARBAGE_COLLECTED_MIXIN(StyleEngine);
 
  public:
-  class IgnoringPendingStylesheet {
-    STACK_ALLOCATED();
-
-   public:
-    IgnoringPendingStylesheet(StyleEngine& engine)
-        : scope_(&engine.ignore_pending_stylesheets_,
-                 !RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) {
-    }
-
-   private:
-    base::AutoReset<bool> scope_;
-  };
 
   class DOMRemovalScope {
     STACK_ALLOCATED();
@@ -196,9 +184,6 @@
   bool HaveRenderBlockingStylesheetsLoaded() const {
     return !HasPendingRenderBlockingSheets();
   }
-  bool IgnoringPendingStylesheets() const {
-    return ignore_pending_stylesheets_;
-  }
 
   unsigned MaxDirectAdjacentSelectors() const {
     return GetRuleFeatureSet().MaxDirectAdjacentSelectors();
@@ -494,7 +479,6 @@
   String preferred_stylesheet_set_name_;
 
   bool uses_rem_units_ = false;
-  bool ignore_pending_stylesheets_ = false;
   bool in_layout_tree_rebuild_ = false;
   bool in_dom_removal_ = false;
 
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
index b89523c..c8f9c71 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -657,7 +657,7 @@
   EXPECT_FALSE(element->NeedsReattachLayoutTree());
   EXPECT_FALSE(element->ChildNeedsReattachLayoutTree());
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   EXPECT_FALSE(element->NeedsStyleRecalc());
   EXPECT_FALSE(element->ChildNeedsStyleRecalc());
@@ -672,7 +672,7 @@
   EXPECT_FALSE(element->NeedsReattachLayoutTree());
   EXPECT_FALSE(element->ChildNeedsReattachLayoutTree());
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   EXPECT_FALSE(element->NeedsStyleRecalc());
   EXPECT_TRUE(element->ChildNeedsStyleRecalc());
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 2a763d8f..bd276f3 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -607,7 +607,6 @@
     : ContainerNode(nullptr, kCreateDocument),
       TreeScope(*this),
       ExecutionContext(V8PerIsolateData::MainThreadIsolate()),
-      has_nodes_with_placeholder_style_(false),
       evaluate_media_queries_on_style_recalc_(false),
       pending_sheet_layout_(kNoLayoutWithPendingSheets),
       frame_(initializer.GetFrame()),
@@ -2298,7 +2297,6 @@
   if (GetStyleChangeType() == kSubtreeStyleChange) {
     change = change.ForceRecalcDescendants();
 
-    has_nodes_with_placeholder_style_ = false;
     // TODO(futhark@chromium.org): Cannot access the EnsureStyleResolver()
     // before calling StyleForViewport() below because apparently the
     // StyleResolver's constructor has side effects. We should fix it. See
@@ -2457,8 +2455,7 @@
   UpdateStyleAndLayoutTree();
 }
 
-void Document::UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(
-    const Node* node) {
+void Document::UpdateStyleAndLayoutForNode(const Node* node) {
   DCHECK(node);
   if (!node->InActiveDocument())
     return;
@@ -2476,16 +2473,19 @@
     }
   }
 
-  UpdateStyleAndLayoutIgnorePendingStylesheets();
+  UpdateStyleAndLayout();
 }
 
-void Document::UpdateStyleAndLayout() {
+void Document::UpdateStyleAndLayout(ForcedLayoutStatus status) {
   DCHECK(IsMainThread());
+  LocalFrameView* frame_view = View();
+
+  if (status == IsForcedLayout && frame_view)
+    frame_view->WillStartForcedLayout();
 
   HTMLFrameOwnerElement::PluginDisposeSuspendScope suspend_plugin_dispose;
   ScriptForbiddenScope forbid_script;
 
-  LocalFrameView* frame_view = View();
   DCHECK(!frame_view || !frame_view->IsInPerformLayout())
       << "View layout should not be re-entrant";
 
@@ -2508,6 +2508,9 @@
 
   if (LocalFrameView* frame_view_anchored = View())
     frame_view_anchored->PerformScrollAnchoringAdjustments();
+
+  if (status == IsForcedLayout && frame_view)
+    frame_view->DidFinishForcedLayout();
 }
 
 void Document::LayoutUpdated() {
@@ -2552,71 +2555,6 @@
     focused_element_->blur();
 }
 
-// FIXME: This is a bad idea and needs to be removed eventually.
-// Other browsers load stylesheets before they continue parsing the web page.
-// Since we don't, we can run JavaScript code that needs answers before the
-// stylesheets are loaded. Doing a layout ignoring the pending stylesheets
-// lets us get reasonable answers. The long term solution to this problem is
-// to instead suspend JavaScript execution.
-void Document::UpdateStyleAndLayoutTreeIgnorePendingStylesheets() {
-  if (RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) {
-    UpdateStyleAndLayoutTree();
-    return;
-  }
-  if (Lifecycle().LifecyclePostponed())
-    return;
-  // See comment for equivalent CHECK in Document::UpdateStyleAndLayoutTree.
-  // Updating style and layout can dirty state that must remain clean during
-  // lifecycle updates.
-  CHECK(Lifecycle().StateAllowsTreeMutations());
-  StyleEngine::IgnoringPendingStylesheet ignoring(GetStyleEngine());
-
-  if (!HaveRenderBlockingResourcesLoaded()) {
-    // FIXME: We are willing to attempt to suppress painting with outdated style
-    // info only once.  Our assumption is that it would be dangerous to try to
-    // stop it a second time, after page content has already been loaded and
-    // displayed with accurate style information. (Our suppression involves
-    // blanking the whole page at the moment. If it were more refined, we might
-    // be able to do something better.) It's worth noting though that this
-    // entire method is a hack, since what we really want to do is suspend JS
-    // instead of doing a layout with inaccurate information.
-    HTMLElement* body_element = body();
-    if (body_element && !body_element->GetLayoutObject() &&
-        pending_sheet_layout_ == kNoLayoutWithPendingSheets) {
-      pending_sheet_layout_ = kDidLayoutWithPendingSheets;
-      GetStyleEngine().MarkAllTreeScopesDirty();
-    }
-    if (has_nodes_with_placeholder_style_) {
-      // If new nodes have been added or style recalc has been done with style
-      // sheets still pending, some nodes may not have had their real style
-      // calculated yet.  Normally this gets cleaned when style sheets arrive
-      // but here we need up-to-date style immediately.
-      SetNeedsStyleRecalc(kSubtreeStyleChange,
-                          StyleChangeReasonForTracing::Create(
-                              style_change_reason::kCleanupPlaceholderStyles));
-    }
-  }
-  UpdateStyleAndLayoutTree();
-}
-
-void Document::UpdateStyleAndLayoutIgnorePendingStylesheets() {
-  DCHECK(!find_in_page_root_);
-  UpdateStyleAndLayoutIgnorePendingStylesheetsConsideringInvisibleNodes();
-}
-
-void Document::
-    UpdateStyleAndLayoutIgnorePendingStylesheetsConsideringInvisibleNodes() {
-  LocalFrameView* local_view = View();
-  if (local_view)
-    local_view->WillStartForcedLayout();
-  if (!RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled())
-    UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
-  UpdateStyleAndLayout();
-
-  if (local_view)
-    local_view->DidFinishForcedLayout();
-}
-
 scoped_refptr<ComputedStyle> Document::StyleForPage(int page_index) {
   UpdateDistributionForUnknownReasons();
   return EnsureStyleResolver().StyleForPage(page_index);
@@ -2650,7 +2588,7 @@
 
   // For all nodes we must have up-to-date style and have performed layout to do
   // any location-based calculation.
-  UpdateStyleAndLayoutIgnorePendingStylesheets();
+  UpdateStyleAndLayout();
 
   // The location of elements that are position: sticky is not known until
   // compositing inputs are cleaned. Therefore, for any elements that are either
@@ -4228,8 +4166,6 @@
 void Document::DidLoadAllImports() {
   if (!HaveScriptBlockingStylesheetsLoaded())
     return;
-  if (!ImportLoader())
-    StyleResolverMayHaveChanged();
   DidLoadAllScriptBlockingResources();
 }
 
@@ -4239,8 +4175,6 @@
 }
 
 void Document::DidRemoveAllPendingStylesheet() {
-  StyleResolverMayHaveChanged();
-
   // Only imports on master documents can trigger rendering.
   if (HTMLImportLoader* import = ImportLoader())
     import->DidRemoveAllPendingStylesheet();
@@ -4638,25 +4572,6 @@
   EnsureStyleResolver().ClearResizedForViewportUnits();
 }
 
-void Document::StyleResolverMayHaveChanged() {
-  if (HasNodesWithPlaceholderStyle()) {
-    SetNeedsStyleRecalc(kSubtreeStyleChange,
-                        StyleChangeReasonForTracing::Create(
-                            style_change_reason::kCleanupPlaceholderStyles));
-  }
-
-  if (DidLayoutWithPendingStylesheets() &&
-      HaveRenderBlockingResourcesLoaded()) {
-    // We need to manually repaint because we avoid doing all repaints in layout
-    // or style recalc while sheets are still loading to avoid FOUC.
-    pending_sheet_layout_ = kIgnoreLayoutWithPendingSheets;
-
-    DCHECK(GetLayoutView() || ImportsController());
-    if (GetLayoutView())
-      GetLayoutView()->InvalidatePaintForViewAndCompositedLayers();
-  }
-}
-
 void Document::SetHoverElement(Element* new_hover_element) {
   hover_element_ = new_hover_element;
 }
@@ -6741,8 +6656,7 @@
 }
 
 bool Document::IsRenderingReady() const {
-  return style_engine_->IgnoringPendingStylesheets() ||
-         HaveRenderBlockingResourcesLoaded();
+  return HaveRenderBlockingResourcesLoaded();
 }
 
 bool Document::AllowInlineEventHandler(Node* node,
@@ -7308,12 +7222,8 @@
 }
 
 bool Document::HaveRenderBlockingResourcesLoaded() const {
-  if (RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) {
-    return HaveImportsLoaded() &&
-           style_engine_->HaveRenderBlockingStylesheetsLoaded();
-  }
   return HaveImportsLoaded() &&
-         style_engine_->HaveScriptBlockingStylesheetsLoaded();
+         style_engine_->HaveRenderBlockingStylesheetsLoaded();
 }
 
 Locale& Document::GetCachedLocale(const AtomicString& locale) {
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 9cbc69b..5fe53d6 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -512,20 +512,16 @@
   // Update ComputedStyles and attach LayoutObjects if necessary, but don't
   // lay out.
   void UpdateStyleAndLayoutTree();
-  // Same as updateStyleAndLayoutTree() except ignoring pending stylesheets.
-  void UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
   void UpdateStyleAndLayoutTreeForNode(const Node*);
-  void UpdateStyleAndLayout();
+
+  enum ForcedLayoutStatus { IsForcedLayout, IsNotForcedLayout };
+  void UpdateStyleAndLayout(ForcedLayoutStatus = IsForcedLayout);
   void LayoutUpdated();
   enum RunPostLayoutTasks {
     kRunPostLayoutTasksAsynchronously,
     kRunPostLayoutTasksSynchronously,
   };
-  void UpdateStyleAndLayoutIgnorePendingStylesheets();
-  // Same as UpdateStyleAndLayoutIgnorePendingStyleSheets()
-  // but allows style & layout tree calculation for invisible nodes.
-  void UpdateStyleAndLayoutIgnorePendingStylesheetsConsideringInvisibleNodes();
-  void UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(const Node*);
+  void UpdateStyleAndLayoutForNode(const Node*);
   scoped_refptr<ComputedStyle> StyleForPage(int page_index);
 
   // Ensures that location-based data will be valid for a given node.
@@ -1033,20 +1029,6 @@
     kIgnoreLayoutWithPendingSheets
   };
 
-  bool DidLayoutWithPendingStylesheets() const {
-    return pending_sheet_layout_ == kDidLayoutWithPendingSheets;
-  }
-  bool IgnoreLayoutWithPendingStylesheets() const {
-    return pending_sheet_layout_ == kIgnoreLayoutWithPendingSheets;
-  }
-
-  bool HasNodesWithPlaceholderStyle() const {
-    return has_nodes_with_placeholder_style_;
-  }
-  void SetHasNodesWithPlaceholderStyle() {
-    has_nodes_with_placeholder_style_ = true;
-  }
-
   Vector<IconURL> IconURLs(int icon_types_mask);
 
   Color ThemeColor() const;
@@ -1639,7 +1621,6 @@
 
   bool HaveScriptBlockingStylesheetsLoaded() const;
   bool HaveRenderBlockingResourcesLoaded() const;
-  void StyleResolverMayHaveChanged();
 
   void SetHoverElement(Element*);
 
@@ -1684,7 +1665,6 @@
 
   DocumentLifecycle lifecycle_;
 
-  bool has_nodes_with_placeholder_style_;
   bool evaluate_media_queries_on_style_recalc_;
 
   // If we do ignore the pending stylesheet count, then we need to add a boolean
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc
index 54cb23d..3acf495b 100644
--- a/third_party/blink/renderer/core/dom/document_test.cc
+++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -1076,6 +1076,11 @@
 TEST_F(DocumentTest, CanExecuteScriptsWithSandboxAndIsolatedWorld) {
   constexpr SandboxFlags kSandboxMask = kSandboxScripts;
   GetDocument().EnforceSandboxFlags(kSandboxMask);
+  // With FeaturePolicyForSandbox, all the sandbox flags must be explicitly
+  // converted to equivalent feature policies. Since sandbox is enforced above,
+  // the feature policies have to be reset; setting an empty header policy will
+  // internally convert the newly set sandbox flags to policies.
+  GetDocument().ApplyFeaturePolicyFromHeader("");
 
   LocalFrame* frame = GetDocument().GetFrame();
   frame->GetSettings()->SetScriptEnabled(true);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 0c28a9f4..e84ee06 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -672,14 +672,14 @@
 }
 
 Element* Element::OffsetParent() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   LayoutObject* layout_object = GetLayoutObject();
   return layout_object ? layout_object->OffsetParent() : nullptr;
 }
 
 int Element::clientLeft() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (LayoutBox* layout_object = GetLayoutBox())
     return AdjustForAbsoluteZoom::AdjustLayoutUnit(layout_object->ClientLeft(),
@@ -689,7 +689,7 @@
 }
 
 int Element::clientTop() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (LayoutBox* layout_object = GetLayoutBox())
     return AdjustForAbsoluteZoom::AdjustLayoutUnit(layout_object->ClientTop(),
@@ -710,7 +710,7 @@
     if (layout_view) {
       if (!RuntimeEnabledFeatures::OverlayScrollbarsEnabled() ||
           !GetDocument().GetFrame()->IsLocalRoot())
-        GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+        GetDocument().UpdateStyleAndLayoutForNode(this);
       if (GetDocument().GetPage()->GetSettings().GetForceZeroLayoutHeight())
         return AdjustForAbsoluteZoom::AdjustLayoutUnit(
                    layout_view->OverflowClipRect(LayoutPoint()).Width(),
@@ -723,7 +723,7 @@
     }
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (LayoutBox* layout_object = GetLayoutBox())
     return AdjustForAbsoluteZoom::AdjustLayoutUnit(
@@ -746,7 +746,7 @@
     if (layout_view) {
       if (!RuntimeEnabledFeatures::OverlayScrollbarsEnabled() ||
           !GetDocument().GetFrame()->IsLocalRoot())
-        GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+        GetDocument().UpdateStyleAndLayoutForNode(this);
       if (GetDocument().GetPage()->GetSettings().GetForceZeroLayoutHeight())
         return AdjustForAbsoluteZoom::AdjustLayoutUnit(
                    layout_view->OverflowClipRect(LayoutPoint()).Height(),
@@ -759,7 +759,7 @@
     }
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (LayoutBox* layout_object = GetLayoutBox())
     return AdjustForAbsoluteZoom::AdjustLayoutUnit(
@@ -773,7 +773,7 @@
   if (!InActiveDocument())
     return 0;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (GetDocument().ScrollingElementNoLayout() == this) {
     if (GetDocument().domWindow())
@@ -792,7 +792,7 @@
   if (!InActiveDocument())
     return 0;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (GetDocument().ScrollingElementNoLayout() == this) {
     if (GetDocument().domWindow())
@@ -811,7 +811,7 @@
   if (!InActiveDocument())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   new_left = ScrollableArea::NormalizeNonFiniteScroll(new_left);
 
@@ -843,7 +843,7 @@
   if (!InActiveDocument())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   new_top = ScrollableArea::NormalizeNonFiniteScroll(new_top);
 
@@ -875,7 +875,7 @@
   if (!InActiveDocument())
     return 0;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (GetDocument().ScrollingElementNoLayout() == this) {
     if (GetDocument().View()) {
@@ -897,7 +897,7 @@
   if (!InActiveDocument())
     return 0;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (GetDocument().ScrollingElementNoLayout() == this) {
     if (GetDocument().View()) {
@@ -928,7 +928,7 @@
 
   // FIXME: This should be removed once scroll updates are processed only after
   // the compositing update. See http://crbug.com/420741.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (GetDocument().ScrollingElementNoLayout() == this) {
     ScrollFrameBy(scroll_to_options);
@@ -950,7 +950,7 @@
 
   // FIXME: This should be removed once scroll updates are processed only after
   // the compositing update. See http://crbug.com/420741.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (GetDocument().ScrollingElementNoLayout() == this) {
     ScrollFrameTo(scroll_to_options);
@@ -1102,7 +1102,7 @@
 }
 
 bool Element::HasNonEmptyLayoutSize() const {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   if (LayoutBoxModelObject* box = GetLayoutBoxModelObject())
     return box->HasNonEmptyLayoutSize();
@@ -1246,7 +1246,7 @@
   Document& document = GetDocument();
   if (!document.IsActive())
     return g_null_atom;
-  document.UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  document.UpdateStyleAndLayoutForNode(this);
   AXContext ax_context(document);
   return ax_context.GetAXObjectCache().ComputedRoleForNode(this);
 }
@@ -1255,7 +1255,7 @@
   Document& document = GetDocument();
   if (!document.IsActive())
     return String();
-  document.UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  document.UpdateStyleAndLayoutForNode(this);
   AXContext ax_context(document);
   return ax_context.GetAXObjectCache().ComputedNameForNode(this);
 }
@@ -3192,7 +3192,7 @@
       frame_owner_element->contentDocument()->UnloadStarted())
     return;
 
-  GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayoutTree();
   if (!IsFocusable())
     return;
 
@@ -3868,8 +3868,6 @@
   // values returned for the ":selection" pseudo-element will be correct.
   ComputedStyle* element_style = MutableComputedStyle();
   if (!element_style) {
-    StyleEngine::IgnoringPendingStylesheet ignoring(
-        GetDocument().GetStyleEngine());
     if (CanParticipateInFlatTree()) {
       ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*this);
       if (parent)
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index 255acae..f7e1f8b 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -529,8 +529,8 @@
     return;
 
   // TODO(esprehn): This should use
-  // updateStyleAndLayoutIgnorePendingStylesheetsForNode.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  // updateStyleAndLayoutForNode.
+  GetDocument().UpdateStyleAndLayout();
 
   LayoutBox* box_to_scroll = ToLayoutBox(GetLayoutObject());
 
@@ -2699,7 +2699,7 @@
       // FIXME: We should avoid synchronous layout if possible. We can
       // remove this synchronous layout if we avoid synchronous layout in
       // LayoutTextControlSingleLine::scrollHeight
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
       LayoutObject* layout_object = GetLayoutObject();
       while (
           layout_object &&
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc
index 911fa657..cc19b21 100644
--- a/third_party/blink/renderer/core/dom/range.cc
+++ b/third_party/blink/renderer/core/dom/range.cc
@@ -1610,7 +1610,7 @@
 void Range::expand(const String& unit, ExceptionState& exception_state) {
   if (!StartPosition().IsConnected() || !EndPosition().IsConnected())
     return;
-  owner_document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  owner_document_->UpdateStyleAndLayout();
   VisiblePosition start = CreateVisiblePosition(StartPosition());
   VisiblePosition end = CreateVisiblePosition(EndPosition());
   if (unit == "word") {
@@ -1637,7 +1637,7 @@
 }
 
 DOMRectList* Range::getClientRects() const {
-  owner_document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  owner_document_->UpdateStyleAndLayout();
 
   Vector<FloatQuad> quads;
   GetBorderAndTextQuads(quads);
@@ -1756,7 +1756,7 @@
 }
 
 FloatRect Range::BoundingRect() const {
-  owner_document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  owner_document_->UpdateStyleAndLayout();
 
   Vector<FloatQuad> quads;
   GetBorderAndTextQuads(quads);
diff --git a/third_party/blink/renderer/core/dom/tree_scope.cc b/third_party/blink/renderer/core/dom/tree_scope.cc
index 5bd853d..3f6c670 100644
--- a/third_party/blink/renderer/core/dom/tree_scope.cc
+++ b/third_party/blink/renderer/core/dom/tree_scope.cc
@@ -208,7 +208,7 @@
     return false;
 
   // The VisibleContentRect check below requires that scrollbars are up-to-date.
-  document.UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document.UpdateStyleAndLayout();
 
   auto* scrollable_area = frame_view->LayoutViewport();
   IntRect visible_frame_rect(IntPoint(),
diff --git a/third_party/blink/renderer/core/editing/BUILD.gn b/third_party/blink/renderer/core/editing/BUILD.gn
index d2c777f6..c7ab9a5a 100644
--- a/third_party/blink/renderer/core/editing/BUILD.gn
+++ b/third_party/blink/renderer/core/editing/BUILD.gn
@@ -157,20 +157,14 @@
     "inline_box_traversal.h",
     "iterators/backwards_character_iterator.cc",
     "iterators/backwards_character_iterator.h",
-    "iterators/backwards_text_buffer.cc",
-    "iterators/backwards_text_buffer.h",
     "iterators/bit_stack.cc",
     "iterators/bit_stack.h",
     "iterators/character_iterator.cc",
     "iterators/character_iterator.h",
-    "iterators/forwards_text_buffer.cc",
-    "iterators/forwards_text_buffer.h",
     "iterators/fully_clipped_state_stack.cc",
     "iterators/fully_clipped_state_stack.h",
     "iterators/simplified_backwards_text_iterator.cc",
     "iterators/simplified_backwards_text_iterator.h",
-    "iterators/text_buffer_base.cc",
-    "iterators/text_buffer_base.h",
     "iterators/text_iterator.cc",
     "iterators/text_iterator.h",
     "iterators/text_iterator_behavior.cc",
@@ -369,9 +363,7 @@
     "ime/ime_text_span_test.cc",
     "ime/input_method_controller_test.cc",
     "inline_box_position_test.cc",
-    "iterators/backwards_text_buffer_test.cc",
     "iterators/character_iterator_test.cc",
-    "iterators/forwards_text_buffer_test.cc",
     "iterators/simplified_backwards_text_iterator_test.cc",
     "iterators/text_iterator_behavior_test.cc",
     "iterators/text_iterator_test.cc",
diff --git a/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc b/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc
index 0f7d916..a616b4c6 100644
--- a/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc
@@ -108,7 +108,7 @@
   if (editing_state->IsAborted())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   DCHECK_EQ(start_scope, end_scope);
   DCHECK_GE(start_index, 0);
@@ -212,7 +212,7 @@
         !end_of_next_paragraph.IsConnected())
       return;
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     end_of_current_paragraph = CreateVisiblePosition(end_of_next_paragraph);
   }
 }
@@ -373,7 +373,7 @@
   // pointing at this same text node, endOfNextParagraph will be shifted by one
   // paragraph. Avoid this by splitting "\n"
   SplitTextNode(end_of_next_paragraph_text, 1);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   Text* const previous_text =
       end_of_next_paragraph_text->previousSibling() &&
               end_of_next_paragraph_text->previousSibling()->IsTextNode()
diff --git a/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc b/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc
index 930b54b2..2e56f25 100644
--- a/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc
+++ b/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc
@@ -36,7 +36,7 @@
 
   GetDocument().body()->setContentEditable("false", ASSERT_NO_EXCEPTION);
   GetDocument().setDesignMode("on");
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   Selection().SetSelection(
       SelectionInDOMTree::Builder()
           .SetBaseAndExtent(
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
index 3e03449..c413fd12 100644
--- a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
@@ -180,7 +180,7 @@
   if (!use_ending_selection_ &&
       (range.StartPosition() != start_ || range.EndPosition() != end_))
     use_ending_selection_ = true;
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   const bool was_base_first =
       StartingSelection().IsBaseFirst() || !SelectionIsDirectional();
   SelectionInDOMTree::Builder builder;
@@ -250,7 +250,7 @@
   // update document layout once before removing styles
   // so that we avoid the expense of updating before each and every call
   // to check a computed style
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // get positions we want to use for applying style
   Position start = StartPosition();
@@ -312,7 +312,7 @@
         if (new_block) {
           block = new_block;
           if (paragraph_start.IsOrphan()) {
-            GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+            GetDocument().UpdateStyleAndLayout();
             paragraph_start = CreateVisiblePosition(
                 Position::FirstPositionInNode(*new_block));
           }
@@ -330,7 +330,7 @@
         }
       }
 
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
 
       // Make the VisiblePositions valid again after style changes.
       // TODO(editing-dev): We shouldn't store VisiblePositions and inspect
@@ -355,7 +355,7 @@
   // Update style and layout again, since added or removed styles could have
   // affected the layout. We need clean layout in order to compute
   // plain-text ranges below.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   EphemeralRange start_ephemeral_range =
       PlainTextRange(start_index)
@@ -687,7 +687,7 @@
   // update document layout once before removing styles
   // so that we avoid the expense of updating before each and every call
   // to check a computed style
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // adjust to the positions we want to use for applying style
   Position start = StartPosition();
@@ -819,7 +819,7 @@
   // update document layout once before running the rest of the function
   // so that we avoid the expense of updating before each and every call
   // to check a computed style
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   EditingStyle* style_to_apply = style;
   if (has_text_direction) {
@@ -857,7 +857,7 @@
     }
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   FixRangeAndApplyInlineStyle(style_to_apply, start, end, editing_state);
   if (editing_state->IsAborted())
     return;
@@ -974,7 +974,7 @@
   if (remove_only_)
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   HeapVector<InlineRunToApplyStyle> runs;
   Node* node = start_node;
@@ -1049,7 +1049,7 @@
     }
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   for (auto& run : runs) {
     if (run.position_for_style_computation.IsNotNull())
@@ -1428,9 +1428,9 @@
   // FIXME: We should assert that start/end are not in the middle of a text
   // node.
 
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   Position push_down_start = MostForwardCaretPosition(start);
   // If the pushDownStart is at the end of a text node, then this node is not
@@ -1446,9 +1446,9 @@
           ToText(push_down_start_container)->length())
     push_down_start = NextVisuallyDistinctCandidate(push_down_start);
 
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   Position push_down_end = MostBackwardCaretPosition(end);
   // If pushDownEnd is at the start of a text node, then this node is not fully
@@ -1552,7 +1552,7 @@
                                              const Position& end) const {
   // The tree may have changed and Position::upstream() relies on an up-to-date
   // layout.
-  element.GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  element.GetDocument().UpdateStyleAndLayout();
 
   return ComparePositions(FirstPositionInOrBeforeNode(element), start) >= 0 &&
          ComparePositions(
diff --git a/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc b/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
index ae91516..046a84b 100644
--- a/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
@@ -152,7 +152,7 @@
   if (editing_state->IsAborted())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // If we're inserting the break at the end of the quoted content, we don't
   // need to break the quote.
diff --git a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
index a2540da5..4062685 100644
--- a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
+++ b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
@@ -132,9 +132,9 @@
 bool ClipboardCommands::DispatchCopyOrCutEvent(LocalFrame& frame,
                                                EditorCommandSource source,
                                                const AtomicString& event_type) {
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   if (IsInPasswordField(
           frame.Selection().ComputeVisibleSelectionInDOMTree().Start()))
     return true;
@@ -229,11 +229,11 @@
 
   Document* const document = frame.GetDocument();
 
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
   // A 'copy' event handler might have dirtied the layout so we need to update
   // before we obtain the selection.
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
 
   if (HTMLImageElement* image_element =
           ImageElementFromImageDocument(document)) {
@@ -285,11 +285,11 @@
   if (!frame.GetEditor().CanCut())
     return true;
 
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
   // A 'cut' event handler might have dirtied the layout so we need to update
   // before we obtain the selection.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
@@ -369,11 +369,11 @@
   if (text.IsEmpty())
     return std::make_pair(fragment, false);
 
-  // TODO(editing-dev): Use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited. See http://crbug.com/590369 for more details.
   // |SelectedRange| requires clean layout for visible selection
   // normalization.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   fragment = CreateFragmentFromText(frame.GetEditor().SelectedRange(), text);
   return std::make_pair(fragment, true);
 }
@@ -398,11 +398,11 @@
   if (!frame.GetEditor().CanPaste())
     return;
 
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
   // A 'paste' event handler might have dirtied the layout so we need to update
   // before we obtain the selection.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
@@ -470,11 +470,11 @@
   if (!frame.GetEditor().CanPaste())
     return false;
 
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
   // A 'paste' event handler might have dirtied the layout so we need to update
   // before we obtain the selection.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
diff --git a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
index 4f52566c..1561665 100644
--- a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
@@ -103,9 +103,9 @@
 
 VisibleSelection CompositeEditCommand::EndingVisibleSelection() const {
   // TODO(editing-dev): The use of
-  // |Document::UpdateStyleAndLayoutIgnorePendingStylesheets()|
+  // |Document::UpdateStyleAndLayout()|
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   return CreateVisibleSelection(ending_selection_);
 }
 
@@ -145,7 +145,7 @@
   // operations, like RemoveNodeCommand, don't require a layout because the high
   // level operations that use them perform one if one is necessary (like for
   // the creation of VisiblePositions).
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   LocalFrame* frame = GetDocument().GetFrame();
   DCHECK(frame);
@@ -288,9 +288,9 @@
         should_assume_content_is_always_editable) {
   ABORT_EDITING_COMMAND_IF(GetDocument().body() == ref_child);
   ABORT_EDITING_COMMAND_IF(!ref_child->parentNode());
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   ABORT_EDITING_COMMAND_IF(!HasEditableStyle(*ref_child->parentNode()) &&
                            ref_child->parentNode()->InActiveDocument());
   ApplyCommandToComposite(
@@ -320,7 +320,7 @@
 void CompositeEditCommand::InsertNodeAt(Node* insert_child,
                                         const Position& editing_position,
                                         EditingState* editing_state) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   ABORT_EDITING_COMMAND_IF(!IsEditablePosition(editing_position));
   // For editing positions like [table, 0], insert before the table,
   // likewise for replaced elements, brs, etc.
@@ -590,9 +590,9 @@
   HTMLSpanElement* tab_span = TabSpanElement(pos.ComputeContainerNode());
   DCHECK(tab_span);
 
-  // TODO(editing-dev): Hoist this UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Hoist this UpdateStyleAndLayout
   // to the callers. See crbug.com/590369 for details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   if (pos.OffsetInContainerNode() <= CaretMinOffset(pos.ComputeContainerNode()))
     return Position::InParentBeforeNode(*tab_span);
@@ -655,9 +655,9 @@
 }
 
 bool CompositeEditCommand::CanRebalance(const Position& position) const {
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets()
+  // TODO(editing-dev): Use of UpdateStyleAndLayout()
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   Node* node = position.ComputeContainerNode();
   if (!position.IsOffsetInAnchor() || !node || !node->IsTextNode() ||
@@ -717,7 +717,7 @@
   if (!length)
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   VisiblePosition visible_upstream_pos =
       CreateVisiblePosition(Position(text_node, upstream));
   VisiblePosition visible_downstream_pos =
@@ -765,14 +765,14 @@
   Position upstream_pos = MostBackwardCaretPosition(position);
   DeleteInsignificantText(upstream_pos, MostForwardCaretPosition(position));
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   position = MostForwardCaretPosition(upstream_pos);
   VisiblePosition visible_pos = CreateVisiblePosition(position);
   VisiblePosition previous_visible_pos = PreviousPositionOf(visible_pos);
   ReplaceCollapsibleWhitespaceWithNonBreakingSpaceIfNeeded(
       previous_visible_pos);
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   ReplaceCollapsibleWhitespaceWithNonBreakingSpaceIfNeeded(
       CreateVisiblePosition(position));
 }
@@ -927,7 +927,7 @@
   if (!container)
     return nullptr;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. See
   // 4244964.
@@ -963,7 +963,7 @@
   if (!container)
     return nullptr;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   LayoutObject* layout_object = container->GetLayoutObject();
   if (!layout_object || !layout_object->IsLayoutBlockFlow())
@@ -1078,7 +1078,7 @@
 
   // Inserting default paragraph element can change visible position. We
   // should update visible positions before use them.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   const VisiblePosition& destination =
       VisiblePosition::FirstPositionInNode(*new_block);
   if (destination.IsNull()) {
@@ -1234,7 +1234,7 @@
 
 void CompositeEditCommand::CleanupAfterDeletion(EditingState* editing_state,
                                                 VisiblePosition destination) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   VisiblePosition caret_after_delete = EndingVisibleSelection().VisibleStart();
   Node* destination_node = destination.DeepEquivalent().AnchorNode();
@@ -1336,7 +1336,7 @@
   if (editing_state->IsAborted())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Add a br if pruning an empty block level element caused a collapse.  For
   // example:
@@ -1516,7 +1516,7 @@
     return;
   DCHECK(destination.DeepEquivalent().IsConnected()) << destination;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Add a br if pruning an empty block level element caused a collapse. For
   // example:
@@ -1544,7 +1544,7 @@
   }
 
   // TextIterator::rangeLength requires clean layout.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   destination_index = TextIterator::RangeLength(
       Position::FirstPositionInNode(*GetDocument().documentElement()),
@@ -1574,7 +1574,7 @@
     return;
   ABORT_EDITING_COMMAND_IF(!EndingSelection().IsValidFor(GetDocument()));
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // If the selection is in an empty paragraph, restore styles from the old
   // empty paragraph to the new empty paragraph.
@@ -1595,7 +1595,7 @@
     return;
 
   // We need clean layout in order to compute plain-text ranges below.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Fragment creation (using createMarkup) incorrectly uses regular spaces
   // instead of nbsps for some spaces that were rendered (11475), which causes
@@ -1743,7 +1743,7 @@
   if (!EndingSelection().IsCaret())
     return false;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   VisiblePosition caret = EndingVisibleSelection().VisibleStart();
   HTMLQuoteElement* highest_blockquote =
@@ -1770,7 +1770,7 @@
   if (editing_state->IsAborted())
     return false;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   VisiblePosition at_br = VisiblePosition::BeforeNode(*br);
   // If the br we inserted collapsed, for example:
@@ -1780,7 +1780,7 @@
     InsertNodeBefore(HTMLBRElement::Create(GetDocument()), br, editing_state);
     if (editing_state->IsAborted())
       return false;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
   }
   SetEndingSelection(SelectionForUndoStep::From(
       SelectionInDOMTree::Builder()
@@ -1829,7 +1829,7 @@
   if (original.IsNull())
     return original;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   VisiblePosition visible_pos = CreateVisiblePosition(original);
   Element* enclosing_anchor = EnclosingAnchorElement(original);
   Position result = original;
@@ -1859,7 +1859,7 @@
           return original;
       }
 
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
 
       // Don't insert outside an anchor if doing so would skip over a line
       // break.  It would probably be safe to move the line break so that we
@@ -1921,7 +1921,7 @@
     if (!parent_element)
       break;
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     // Do not split a node when doing so introduces an empty node.
     VisiblePosition position_in_parent =
diff --git a/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc b/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc
index 8ec83ae2..1a891d0f 100644
--- a/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc
@@ -60,7 +60,7 @@
   if (!IsHTMLTableRowElement(row))
     return false;
 
-  row->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  row->GetDocument().UpdateStyleAndLayout();
   for (Node* child = row->firstChild(); child; child = child->nextSibling()) {
     if (IsTableCell(child) && !IsTableCellEmpty(child))
       return false;
@@ -440,7 +440,7 @@
   // We detect the case where the start is an empty line consisting of BR not
   // wrapped in a block element.
   if (upstream_start_is_br && downstream_start_is_br) {
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     if (!(IsStartOfBlock(
               VisiblePosition::BeforeNode(*node_after_upstream_start)) &&
           IsEndOfBlock(
@@ -511,7 +511,7 @@
     }
 
     // Make sure empty cell has some height, if a placeholder can be inserted.
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     LayoutObject* r = node->GetLayoutObject();
     if (r && r->IsTableCell() && ToLayoutTableCell(r)->ContentHeight() <= 0) {
       Position first_editable_position = FirstEditablePositionInNode(node);
@@ -521,7 +521,7 @@
     return;
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (node == start_block_) {
     VisiblePosition previous = PreviousPositionOf(
         VisiblePosition::FirstPositionInNode(*start_block_.Get()));
@@ -619,7 +619,7 @@
       return;
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (start_offset >= CaretMaxOffset(start_node) && start_node->IsTextNode()) {
     Text* text = ToText(start_node);
     if (text->length() > (unsigned)CaretMaxOffset(start_node))
@@ -653,7 +653,7 @@
         ending_position_ = upstream_start_;
       }
       // We should update layout to associate |start_node| to layout object.
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
     }
 
     // The selection to delete is all in one node.
@@ -702,7 +702,7 @@
           return;
         node = next_node;
       } else {
-        GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+        GetDocument().UpdateStyleAndLayout();
         Node& n = NodeTraversal::LastWithinOrSelf(*node);
         if (downstream_end_.AnchorNode() == n &&
             downstream_end_.ComputeEditingOffset() >= CaretMaxOffset(&n)) {
@@ -716,9 +716,9 @@
       }
     }
 
-    // TODO(editing-dev): Hoist updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Hoist UpdateStyleAndLayout
     // to caller. See http://crbug.com/590369 for more details.
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     if (downstream_end_.AnchorNode() != start_node &&
         !upstream_start_.AnchorNode()->IsDescendantOf(
@@ -769,7 +769,7 @@
 }
 
 void DeleteSelectionCommand::FixupWhitespace() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (leading_whitespace_.IsNotNull() &&
       !IsRenderedCharacter(leading_whitespace_) &&
       leading_whitespace_.AnchorNode()->IsTextNode()) {
@@ -828,7 +828,7 @@
   if (upstream_start_ == downstream_end_)
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   VisiblePosition start_of_paragraph_to_move =
       CreateVisiblePosition(downstream_end_);
@@ -862,7 +862,7 @@
                  editing_state);
     if (editing_state->IsAborted())
       return;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     merge_destination = CreateVisiblePosition(upstream_start_);
     start_of_paragraph_to_move =
         CreateVisiblePosition(relocatable_start.GetPosition());
@@ -1088,7 +1088,7 @@
   // save this to later make the selection with
   TextAffinity affinity = selection_to_delete_.Affinity();
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   Position downstream_end =
       MostForwardCaretPosition(selection_to_delete_.End());
@@ -1138,7 +1138,7 @@
     return;
   if (br_result) {
     CalculateTypingStyleAfterDelete();
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     SelectionInDOMTree::Builder builder;
     builder.SetAffinity(affinity);
     if (ending_position_.IsNotNull())
@@ -1152,7 +1152,7 @@
     return;
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   HandleGeneralDelete(editing_state);
   if (editing_state->IsAborted())
@@ -1169,7 +1169,7 @@
     return;
 
   if (!need_placeholder_ && root_will_stay_open_without_placeholder) {
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     VisiblePosition visual_ending = CreateVisiblePosition(ending_position_);
     bool has_placeholder =
         LineBreakExistsAtVisiblePosition(visual_ending) &&
@@ -1200,7 +1200,7 @@
 
   CalculateTypingStyleAfterDelete();
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   SelectionInDOMTree::Builder builder;
   builder.SetAffinity(affinity);
diff --git a/third_party/blink/renderer/core/editing/commands/editor_command.cc b/third_party/blink/renderer/core/editing/commands/editor_command.cc
index 12a1440..942a266 100644
--- a/third_party/blink/renderer/core/editing/commands/editor_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/editor_command.cc
@@ -68,6 +68,7 @@
 #include "third_party/blink/renderer/core/scroll/scrollbar.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
 
 #include <iterator>
@@ -195,7 +196,7 @@
     const LocalFrame& frame,
     SelectionModifyDirection direction,
     TextGranularity granularity) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   SelectionModifier selection_modifier(
       frame, frame.Selection().GetSelectionInDOMTree());
   selection_modifier.SetSelectionIsDirectional(
@@ -234,6 +235,8 @@
 }  // anonymous namespace
 
 class EditorInternalCommand {
+  STACK_ALLOCATED();
+
  public:
   WebEditingCommandType command_type;
   bool (*execute)(LocalFrame&, Event*, EditorCommandSource, const String&);
@@ -373,10 +376,10 @@
   if (!frame.GetEditor().CanDelete())
     return;
 
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
   // |SelectedRange| requires clean layout for visible selection normalization.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   frame.GetEditor().AddToKillRing(frame.GetEditor().SelectedRange());
   // TODO(editing-dev): |Editor::performDelete()| has no direction.
@@ -565,9 +568,9 @@
   }
   PerformDelete(frame);
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   frame.GetEditor().SetMark();
   return true;
 }
@@ -886,9 +889,9 @@
 
   Document* const document = frame.GetDocument();
 
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
 
   const EphemeralRange& range = ComputeRangeForTranspose(frame);
   if (range.IsNull())
@@ -912,9 +915,9 @@
   if (frame.GetDocument() != document)
     return false;
 
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
 
   // 'beforeinput' event handler may change selection, we need to re-calculate
   // range.
@@ -980,9 +983,9 @@
   if (frame.GetDocument()->GetFrame() != &frame)
     return false;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   frame.GetEditor().InsertTextWithoutSendingTextEvent(
       yank_string, false, nullptr, InputEvent::InputType::kInsertFromYank);
@@ -1005,9 +1008,9 @@
   if (frame.GetDocument()->GetFrame() != &frame)
     return false;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   frame.GetEditor().InsertTextWithoutSendingTextEvent(
       frame.GetEditor().GetKillRing().Yank(), true, nullptr,
@@ -1035,7 +1038,7 @@
 static bool EnabledVisibleSelection(LocalFrame& frame,
                                     Event* event,
                                     EditorCommandSource source) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
@@ -1052,7 +1055,7 @@
 static bool EnabledVisibleSelectionAndMark(LocalFrame& frame,
                                            Event* event,
                                            EditorCommandSource source) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
@@ -1068,7 +1071,7 @@
 static bool EnableCaretInEditableText(LocalFrame& frame,
                                       Event* event,
                                       EditorCommandSource source) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
@@ -1081,7 +1084,7 @@
 static bool EnabledInEditableText(LocalFrame& frame,
                                   Event* event,
                                   EditorCommandSource source) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
     return false;
@@ -1110,7 +1113,7 @@
 static bool EnabledInRichlyEditableText(LocalFrame& frame,
                                         Event*,
                                         EditorCommandSource source) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
     return false;
@@ -1123,7 +1126,7 @@
 static bool EnabledRangeInEditableText(LocalFrame& frame,
                                        Event*,
                                        EditorCommandSource source) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
     return false;
@@ -1138,7 +1141,7 @@
 static bool EnabledRangeInRichlyEditableText(LocalFrame& frame,
                                              Event*,
                                              EditorCommandSource source) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   if (source == EditorCommandSource::kMenuOrKeyBinding &&
       !frame.Selection().SelectionHasFocus())
     return false;
@@ -1158,7 +1161,7 @@
 static bool EnabledUnselect(LocalFrame& frame,
                             Event* event,
                             EditorCommandSource) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   // The term "visible" here includes a caret in editable text or a range in any
   // text.
@@ -1171,9 +1174,9 @@
 static bool EnabledSelectAll(LocalFrame& frame,
                              Event*,
                              EditorCommandSource source) {
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   const VisibleSelection& selection =
       frame.Selection().ComputeVisibleSelectionInDOMTree();
   if (selection.IsNone())
@@ -1830,9 +1833,9 @@
   if (command_name == "DeleteForward")
     return CreateCommand(AtomicString("ForwardDelete")).Execute();
   if (command_name == "AdvanceToNextMisspelling") {
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited. see http://crbug.com/590369 for more details.
-    GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetFrame().GetDocument()->UpdateStyleAndLayout();
 
     // We need to pass false here or else the currently selected word will never
     // be skipped.
@@ -1840,10 +1843,10 @@
     return true;
   }
   if (command_name == "ToggleSpellPanel") {
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited.
     // see http://crbug.com/590369 for more details.
-    GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetFrame().GetDocument()->UpdateStyleAndLayout();
 
     GetSpellChecker().ShowSpellingGuessPanel();
     return true;
@@ -1864,9 +1867,9 @@
         kScrollDownIgnoringWritingMode, kScrollByDocument);
 
   if (command_name == "ToggleSpellPanel") {
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited. see http://crbug.com/590369 for more details.
-    GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetFrame().GetDocument()->UpdateStyleAndLayout();
 
     GetSpellChecker().ShowSpellingGuessPanel();
     return true;
@@ -1917,7 +1920,7 @@
     }
   }
 
-  GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame().GetDocument()->UpdateStyleAndLayout();
   DEFINE_STATIC_LOCAL(SparseHistogram, command_histogram,
                       ("WebCore.Editing.Commands"));
   command_histogram.Sample(static_cast<int>(command_->command_type));
diff --git a/third_party/blink/renderer/core/editing/commands/format_block_command.cc b/third_party/blink/renderer/core/editing/commands/format_block_command.cc
index 60373750..274fa4f 100644
--- a/third_party/blink/renderer/core/editing/commands/format_block_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/format_block_command.cc
@@ -91,7 +91,7 @@
   Node* node_after_insertion_position = outer_block;
   const EphemeralRange range(start, end_of_selection);
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (IsElementForFormatBlock(ref_element->TagQName()) &&
       CreateVisiblePosition(start).DeepEquivalent() ==
           StartOfBlock(CreateVisiblePosition(start)).DeepEquivalent() &&
@@ -114,7 +114,7 @@
                      editing_state);
     if (editing_state->IsAborted())
       return;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
   }
 
   Position last_paragraph_in_block_node =
@@ -147,7 +147,7 @@
         ToHTMLElement(node_after_insertion_position)->getAttribute(kStyleAttr));
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   if (was_end_of_paragraph &&
       !IsEndOfParagraph(CreateVisiblePosition(last_paragraph_in_block_node)) &&
diff --git a/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc b/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
index 4c13994..57e2c2c 100644
--- a/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
@@ -99,7 +99,7 @@
   if (editing_state->IsAborted())
     return false;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // We should clone all the children of the list item for indenting purposes.
   // However, in case the current selection does not encompass all its children,
@@ -135,7 +135,7 @@
       return false;
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   DCHECK(new_list);
   if (previous_list && CanMergeLists(*previous_list, *new_list)) {
     MergeIdenticalElements(previous_list, new_list, editing_state);
@@ -143,7 +143,7 @@
       return false;
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (next_list && CanMergeLists(*new_list, *next_list)) {
     MergeIdenticalElements(new_list, next_list, editing_state);
     if (editing_state->IsAborted())
@@ -174,7 +174,7 @@
           ? start.ComputeContainerNode()
           : SplitTreeToNode(start.ComputeContainerNode(), element_to_split_to);
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   VisiblePosition start_of_contents = CreateVisiblePosition(start);
   if (!target_blockquote) {
     // Create a new blockquote and insert it as a child of the root editable
@@ -192,7 +192,7 @@
       InsertNodeBefore(target_blockquote, outer_block, editing_state);
     if (editing_state->IsAborted())
       return;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     start_of_contents = VisiblePosition::InParentAfterNode(*target_blockquote);
   }
 
@@ -269,7 +269,7 @@
       }
     }
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     visible_start_of_paragraph =
         CreateVisiblePosition(visible_start_of_paragraph.DeepEquivalent());
     if (visible_start_of_paragraph.IsNotNull() &&
@@ -280,7 +280,7 @@
         return;
     }
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     visible_end_of_paragraph =
         CreateVisiblePosition(visible_end_of_paragraph.DeepEquivalent());
     if (visible_end_of_paragraph.IsNotNull() &&
@@ -325,7 +325,7 @@
               : visible_start_of_paragraph.DeepEquivalent().AnchorNode());
     }
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     // Re-canonicalize visible{Start,End}OfParagraph, make them valid again
     // after DOM change.
@@ -352,7 +352,7 @@
   if (editing_state->IsAborted())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   start_of_paragraph_to_move = CreateVisiblePosition(
       start_of_paragraph_to_move.ToPositionWithAffinity());
   end_of_paragraph_to_move =
@@ -408,7 +408,7 @@
     if (end_after_selection.IsNotNull() && !end_after_selection.IsConnected())
       break;
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     if (end_of_next_paragraph.IsNotNull() &&
         !end_of_next_paragraph.IsConnected()) {
       end_of_current_paragraph =
diff --git a/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc b/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc
index 7dc560f..4969f95 100644
--- a/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc
@@ -51,7 +51,7 @@
       GetDocument().GetSettings() &&
       GetDocument().GetSettings()->GetPasswordEchoEnabled();
   if (password_echo_enabled)
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
   if (!HasEditableStyle(*node_))
     return;
diff --git a/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc b/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc
index e049830..60ed97f 100644
--- a/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc
@@ -67,7 +67,7 @@
   if (!DeleteSelection(editing_state, DeleteSelectionOptions::NormalDelete()))
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   VisibleSelection selection = EndingVisibleSelection();
   if (selection.IsNone() || selection.Start().IsOrphan() ||
@@ -97,7 +97,7 @@
   else
     node_to_insert = GetDocument().createTextNode("\n");
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // FIXME: Need to merge text nodes when inserting just after or before text.
 
@@ -136,7 +136,7 @@
     InsertNodeAt(node_to_insert, pos, editing_state);
     if (editing_state->IsAborted())
       return;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     // Insert an extra br or '\n' if the just inserted one collapsed.
     if (!IsStartOfParagraph(VisiblePosition::BeforeNode(*node_to_insert))) {
@@ -172,7 +172,7 @@
     Position ending_position = Position::FirstPositionInNode(*text_node);
 
     // Handle whitespace that occurs after the split
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     if (!IsRenderedCharacter(ending_position)) {
       Position position_before_text_node(
           Position::InParentBeforeNode(*text_node));
diff --git a/third_party/blink/renderer/core/editing/commands/insert_list_command.cc b/third_party/blink/renderer/core/editing/commands/insert_list_command.cc
index e156df7..0b324dec 100644
--- a/third_party/blink/renderer/core/editing/commands/insert_list_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/insert_list_command.cc
@@ -76,7 +76,7 @@
   DCHECK(passed_list);
   HTMLElement* list = passed_list;
   Element* previous_list = ElementTraversal::PreviousSibling(*list);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (previous_list && CanMergeLists(*previous_list, *list)) {
     MergeIdenticalElements(previous_list, list, editing_state);
     if (editing_state->IsAborted())
@@ -91,7 +91,7 @@
     return list;
 
   HTMLElement* next_list = ToHTMLElement(next_sibling);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (CanMergeLists(*list, *next_list)) {
     MergeIdenticalElements(list, next_list, editing_state);
     if (editing_state->IsAborted())
@@ -244,7 +244,7 @@
         if (!single_paragraph_result)
           break;
 
-        GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+        GetDocument().UpdateStyleAndLayout();
 
         // Make |visibleEndOfSelection| valid again.
         if (!end_of_selection.IsConnected() ||
@@ -280,7 +280,7 @@
     if (editing_state->IsAborted())
       return;
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     // Fetch the end of the selection, for the reason mentioned above.
     if (!end_of_selection.IsConnected()) {
@@ -358,7 +358,7 @@
       list_element = MergeWithNeighboringLists(list_element, editing_state);
       if (editing_state->IsAborted())
         return false;
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
     }
     DCHECK(HasEditableStyle(*list_element));
     DCHECK(HasEditableStyle(*list_element->parentNode()));
@@ -393,7 +393,7 @@
       if (editing_state->IsAborted())
         return false;
 
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
       Node* first_child_in_list =
           EnclosingListChild(VisiblePosition::FirstPositionInNode(*list_element)
                                  .DeepEquivalent()
@@ -449,7 +449,7 @@
                        list_child_node, editing_state);
     if (editing_state->IsAborted())
       return false;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
   }
 
   if (!list_child_node || switch_list_type || force_create_list) {
@@ -538,7 +538,7 @@
   if (editing_state->IsAborted())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Make |start| and |end| valid again.
   start = CreateVisiblePosition(start_position);
@@ -603,7 +603,7 @@
     if (editing_state->IsAborted())
       return;
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     if (previous_list && next_list && CanMergeLists(*previous_list, *next_list))
       MergeIdenticalElements(previous_list, next_list, editing_state);
 
@@ -625,7 +625,7 @@
     start_pos = Position::BeforeNode(*placeholder);
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Insert the list at a position visually equivalent to start of the
   // paragraph that is being moved into the list.
@@ -668,7 +668,7 @@
     MoveParagraphOverPositionIntoEmptyListItem(
         original_start, list_item_element, editing_state);
   } else {
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     MoveParagraphOverPositionIntoEmptyListItem(
         CreateVisiblePosition(start_pos), list_item_element, editing_state);
   }
@@ -691,7 +691,7 @@
     return;
   // Inserting list element and list item list may change start of pargraph
   // to move. We calculate start of paragraph again.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   const VisiblePosition& valid_pos =
       CreateVisiblePosition(pos.ToPositionWithAffinity());
   const VisiblePosition& start =
diff --git a/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc b/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc
index 4f6cc13f..a6b1419 100644
--- a/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc
@@ -194,7 +194,7 @@
 
   // Delete the current selection.
   if (EndingSelection().IsRange()) {
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     CalculateStyleBeforeInsertion(insertion_position);
     if (!DeleteSelection(editing_state, DeleteSelectionOptions::NormalDelete()))
       return;
@@ -204,7 +204,7 @@
     affinity = visble_selection_after_delete.Affinity();
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // FIXME: The parentAnchoredEquivalent conversion needs to be moved into
   // enclosingBlock.
@@ -254,7 +254,7 @@
         ToHTMLElement(EnclosingAnchorElement(original_insertion_position));
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   CalculateStyleBeforeInsertion(insertion_position);
 
   //---------------------------------------------------------------------
@@ -389,7 +389,7 @@
       ref_node = insertion_position.AnchorNode();
     }
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     // find ending selection position easily before inserting the paragraph
     insertion_position = MostForwardCaretPosition(insertion_position);
@@ -438,7 +438,7 @@
     InsertNodeAt(br, insertion_position, editing_state);
     if (editing_state->IsAborted())
       return;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     insertion_position = Position::InParentAfterNode(*br);
     visible_pos = CreateVisiblePosition(insertion_position);
@@ -496,7 +496,7 @@
     ReplaceTextInNode(text_node,
                       leading_whitespace.ComputeOffsetInContainerNode(), 1,
                       NonBreakingSpaceString());
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
   }
 
   // Split at pos if in the middle of a text node.
@@ -508,7 +508,7 @@
     bool at_end = static_cast<unsigned>(text_offset) >= text_node->length();
     if (text_offset > 0 && !at_end) {
       SplitTextNode(text_node, text_offset);
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
 
       position_after_split = Position::FirstPositionInNode(*text_node);
       insertion_position = Position(text_node->previousSibling(), text_offset);
@@ -534,7 +534,7 @@
   if (editing_state->IsAborted())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   visible_pos = CreateVisiblePosition(insertion_position);
 
   // If the paragraph separator was inserted at the end of a paragraph, an empty
@@ -547,7 +547,7 @@
                editing_state);
     if (editing_state->IsAborted())
       return;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
   }
 
   // Move the start node and the siblings of the start node.
@@ -565,7 +565,7 @@
       if (split_to)
         SplitTreeToNode(split_to, start_block);
 
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
 
       for (n = start_block->firstChild(); n; n = n->nextSibling()) {
         VisiblePosition before_node_position = VisiblePosition::BeforeNode(*n);
@@ -584,7 +584,7 @@
 
   // Handle whitespace that occurs after the split
   if (position_after_split.IsNotNull()) {
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     if (!IsRenderedCharacter(position_after_split)) {
       // Clear out all whitespace and insert one non-breaking space
       DCHECK(!position_after_split.ComputeContainerNode()->GetLayoutObject() ||
diff --git a/third_party/blink/renderer/core/editing/commands/insert_text_command.cc b/third_party/blink/renderer/core/editing/commands/insert_text_command.cc
index 73d5250b..a7c2b33 100644
--- a/third_party/blink/renderer/core/editing/commands/insert_text_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/insert_text_command.cc
@@ -160,7 +160,7 @@
   if (EndingSelection().IsRange()) {
     if (PerformTrivialReplace(text_))
       return;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     bool end_of_selection_was_at_start_of_block =
         IsStartOfBlock(EndingVisibleSelection().VisibleEnd());
     if (!DeleteSelection(editing_state, DeleteSelectionOptions::Builder()
@@ -184,7 +184,7 @@
       return;
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Reached by InsertTextCommandTest.NoVisibleSelectionAfterDeletingSelection
   ABORT_EDITING_COMMAND_IF(EndingVisibleSelection().IsNone());
@@ -223,9 +223,9 @@
   DeleteInsignificantText(start_position,
                           MostForwardCaretPosition(start_position));
 
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets()
+  // TODO(editing-dev): Use of UpdateStyleAndLayout()
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   if (!start_position.IsConnected())
     start_position = position_before_start_node;
@@ -305,7 +305,7 @@
 
 Position InsertTextCommand::InsertTab(const Position& pos,
                                       EditingState* editing_state) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   Position insert_pos = CreateVisiblePosition(pos).DeepEquivalent();
   if (insert_pos.IsNull())
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
index 0dd9e2c3..1e66d9b 100644
--- a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
@@ -173,7 +173,7 @@
   if (!editable_root)
     return;
 
-  document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document_->UpdateStyleAndLayout();
 
   Element* shadow_ancestor_element;
   if (editable_root->IsInShadowTree())
@@ -246,9 +246,9 @@
   if (text != evt->GetText() || !HasRichlyEditableStyle(*editable_root)) {
     RestoreAndRemoveTestRenderingNodesToFragment(holder);
 
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited.  See http://crbug.com/590369 for more details.
-    document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    document->UpdateStyleAndLayout();
 
     fragment_ = CreateFragmentFromText(selection.ToNormalizedEphemeralRange(),
                                        evt->GetText());
@@ -318,7 +318,7 @@
   root_editable_element->AppendChild(holder);
 
   // TODO(editing-dev): Hoist this call to the call sites.
-  document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document_->UpdateStyleAndLayout();
 
   return holder;
 }
@@ -604,7 +604,7 @@
       // TODO(editing-dev): There is currently no way to update style without
       // updating layout. We might want to have updateLifcycleToStyleClean()
       // similar to FrameView::updateLifecylceToLayoutClean() in Document.
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
 
       if (blockquote_element)
         new_inline_style->RemoveStyleFromRulesAndContext(
@@ -629,7 +629,7 @@
                        AtomicString(new_inline_style->Style()->AsText()));
     }
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     // FIXME: Tolerate differences in id, class, and style attributes.
     if (element->parentNode() && IsNonTableCellHTMLBlockElement(element) &&
@@ -737,7 +737,7 @@
   if (!HasEditableStyle(*ancestor->parentNode()))
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   VisiblePosition position_at_end_of_node =
       CreateVisiblePosition(LastPositionInOrAfterNode(*element));
   VisiblePosition last_position_in_paragraph =
@@ -773,7 +773,7 @@
 
 void ReplaceSelectionCommand::RemoveUnrenderedTextNodesAtEnds(
     InsertedNodes& inserted_nodes) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   Node* last_leaf_inserted = inserted_nodes.LastLeafInserted();
   if (last_leaf_inserted && last_leaf_inserted->IsTextNode() &&
@@ -802,7 +802,7 @@
 VisiblePosition ReplaceSelectionCommand::PositionAtEndOfInsertedContent()
     const {
   // TODO(editing-dev): Hoist the call and change it into a DCHECK.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   // TODO(yosin): We should set |end_of_inserted_content_| not in SELECT
   // element, since contents of SELECT elements, e.g. OPTION, OPTGROUP, are
   // not editable, or SELECT element is an atomic on editing.
@@ -819,7 +819,7 @@
 VisiblePosition ReplaceSelectionCommand::PositionAtStartOfInsertedContent()
     const {
   // TODO(editing-dev): Hoist the call and change it into a DCHECK.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (start_of_inserted_content_.IsOrphan())
     return VisiblePosition();
   return CreateVisiblePosition(start_of_inserted_content_);
@@ -938,9 +938,9 @@
     if (editing_state->IsAborted())
       return;
 
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets()
+    // TODO(editing-dev): Use of UpdateStyleAndLayout()
     // needs to be audited.  See http://crbug.com/590369 for more details.
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     destination = VisiblePosition::BeforeNode(*placeholder);
     start_of_paragraph_to_move = CreateVisiblePosition(
@@ -953,7 +953,7 @@
   if (editing_state->IsAborted())
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Merging forward will remove end_of_inserted_content from the document.
   if (merge_forward) {
@@ -1077,7 +1077,7 @@
                                             .Build()))
       return;
     if (fragment.HasInterchangeNewlineAtStart()) {
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
       VisiblePosition start_after_delete =
           EndingVisibleSelection().VisibleStart();
       if (IsEndOfParagraph(start_after_delete) &&
@@ -1108,7 +1108,7 @@
         InsertParagraphSeparator(editing_state);
         if (editing_state->IsAborted())
           return;
-        GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+        GetDocument().UpdateStyleAndLayout();
       }
     }
     // We split the current paragraph in two to avoid nesting the blocks from
@@ -1133,7 +1133,7 @@
       InsertParagraphSeparator(editing_state);
       if (editing_state->IsAborted())
         return;
-      GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      GetDocument().UpdateStyleAndLayout();
       SetEndingSelection(SelectionForUndoStep::From(
           SelectionInDOMTree::Builder()
               .Collapse(
@@ -1164,7 +1164,7 @@
   if (trivial_replace_result)
     return;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   SetUpStyle(selection);
   Element* const current_root = selection.RootEditableElement();
@@ -1208,7 +1208,7 @@
   // <div>foo</div> into hello^ world.
   PrepareWhitespaceAtPositionForSplit(insertion_pos);
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // If the downstream node has been removed there's no point in continuing.
   if (!MostForwardCaretPosition(insertion_pos).AnchorNode())
@@ -1263,7 +1263,7 @@
 
   RemoveHeadContents(fragment);
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // We don't want the destination to end up inside nodes that weren't selected.
   // To avoid that, we move the position forward without changing the visible
@@ -1380,7 +1380,7 @@
     ABORT_EDITING_COMMAND_IF(!inserted_nodes.RefNode());
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Mutation events (bug 20161) may have already removed the inserted content
   if (!inserted_nodes.FirstNodeInserted() ||
@@ -1413,7 +1413,7 @@
       return;
   }
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (end_br &&
       (plain_text_fragment ||
        (ShouldRemoveEndBR(end_br, original_vis_pos_before_end_br) &&
@@ -1529,7 +1529,7 @@
         return;
     }
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     // Making the two VisiblePositions valid again.
     start_of_paragraph_to_move =
@@ -1545,7 +1545,7 @@
     if (editing_state->IsAborted())
       return;
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     const VisibleSelection& visible_selection_of_insterted_content =
         EndingVisibleSelection();
     start_of_inserted_content_ = MostForwardCaretPosition(
@@ -1612,7 +1612,7 @@
             return;
         }
 
-        GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+        GetDocument().UpdateStyleAndLayout();
 
         // Select up to the paragraph separator that was added.
         last_position_to_select =
@@ -1943,7 +1943,7 @@
          IsHTMLListElement(list_element->firstChild()))
     list_element = ToHTMLElement(list_element->firstChild());
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   bool is_start = IsStartOfParagraph(CreateVisiblePosition(insert_pos));
   bool is_end = IsEndOfParagraph(CreateVisiblePosition(insert_pos));
   bool is_middle = !is_start && !is_end;
@@ -2017,9 +2017,9 @@
           EndingVisibleSelection().Start()))
     return false;
 
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   Node* node_after_insertion_pos =
       MostForwardCaretPosition(EndingSelection().End()).AnchorNode();
@@ -2032,7 +2032,7 @@
   if (end.IsNull())
     return false;
 
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   if (node_after_insertion_pos && node_after_insertion_pos->parentNode() &&
       IsHTMLBRElement(*node_after_insertion_pos) &&
diff --git a/third_party/blink/renderer/core/editing/commands/style_commands.cc b/third_party/blink/renderer/core/editing/commands/style_commands.cc
index 2c278620..3ac4dfb 100644
--- a/third_party/blink/renderer/core/editing/commands/style_commands.cc
+++ b/third_party/blink/renderer/core/editing/commands/style_commands.cc
@@ -365,7 +365,7 @@
 EditingTriState StyleCommands::StateStyle(LocalFrame& frame,
                                           CSSPropertyID property_id,
                                           const char* desired_value) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
   if (frame.GetEditor().Behavior().ShouldToggleStyleBasedOnStartOfSelection()) {
     return SelectionStartHasStyle(frame, property_id, desired_value)
                ? EditingTriState::kTrue
@@ -516,7 +516,7 @@
 EditingTriState StyleCommands::StateTextWritingDirection(
     LocalFrame& frame,
     WritingDirection direction) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   bool has_nested_or_multiple_embeddings;
   WritingDirection selection_direction = TextDirectionForSelection(
@@ -570,7 +570,7 @@
 }
 
 String StyleCommands::ValueStyle(LocalFrame& frame, CSSPropertyID property_id) {
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   // TODO(editnig-dev): Rather than retrieving the style at the start of the
   // current selection, we should retrieve the style present throughout the
diff --git a/third_party/blink/renderer/core/editing/commands/typing_command.cc b/third_party/blink/renderer/core/editing/commands/typing_command.cc
index 17f5fb5..9e51460 100644
--- a/third_party/blink/renderer/core/editing/commands/typing_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/typing_command.cc
@@ -311,9 +311,9 @@
   if (!IsIncrementalInsertion())
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame->GetDocument()->UpdateStyleAndLayout();
 
   Element* element = frame->Selection()
                          .ComputeVisibleSelectionInDOMTreeDeprecated()
@@ -378,9 +378,9 @@
   if (selection_for_insertion.IsCaret() && new_text.IsEmpty())
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  document.UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document.UpdateStyleAndLayout();
 
   const PlainTextRange selection_offsets =
       GetSelectionOffsets(selection_for_insertion.AsSelection());
@@ -799,7 +799,7 @@
     TypingAddedToOpenCommand(kDeleteKey);
 
   smart_delete_ = false;
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   SelectionModifier selection_modifier(*frame, EndingSelection().AsSelection());
   selection_modifier.SetSelectionIsDirectional(SelectionIsDirectional());
@@ -973,7 +973,7 @@
   }
 
   smart_delete_ = false;
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Handle delete at beginning-of-block case.
   // Do nothing in the case that the caret is at the start of a
diff --git a/third_party/blink/renderer/core/editing/commands/undo_step.cc b/third_party/blink/renderer/core/editing/commands/undo_step.cc
index ddf8979c..ec73c17da 100644
--- a/third_party/blink/renderer/core/editing/commands/undo_step.cc
+++ b/third_party/blink/renderer/core/editing/commands/undo_step.cc
@@ -52,7 +52,7 @@
   // operations, like RemoveNodeCommand, don't require a layout because the high
   // level operations that use them perform one if one is necessary (like for
   // the creation of VisiblePositions).
-  document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document_->UpdateStyleAndLayout();
 
   {
     wtf_size_t size = commands_.size();
@@ -94,7 +94,7 @@
   // operations, like RemoveNodeCommand, don't require a layout because the high
   // level operations that use them perform one if one is necessary (like for
   // the creation of VisiblePositions).
-  document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document_->UpdateStyleAndLayout();
 
   {
     for (const auto& command : commands_)
diff --git a/third_party/blink/renderer/core/editing/dom_selection.cc b/third_party/blink/renderer/core/editing/dom_selection.cc
index 4a3011a..dd45826e 100644
--- a/third_party/blink/renderer/core/editing/dom_selection.cc
+++ b/third_party/blink/renderer/core/editing/dom_selection.cc
@@ -452,9 +452,9 @@
   else
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   Element* focused_element = GetFrame()->GetDocument()->FocusedElement();
   GetFrame()->Selection().Modify(alter, direction, granularity,
@@ -686,9 +686,9 @@
     return;
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   // The following code is necessary for
   // editing/selection/deleteFromDocument-crash.html, which assumes
@@ -721,10 +721,10 @@
 
   unsigned node_index = n->NodeIndex();
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
   // |VisibleSelection::toNormalizedEphemeralRange| requires clean layout.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   FrameSelection& selection = GetFrame()->Selection();
   const EphemeralRange selected_range =
@@ -782,9 +782,9 @@
   if (!IsAvailable())
     return String();
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   DocumentLifecycle::DisallowTransitionScope disallow_transition(
       GetFrame()->GetDocument()->Lifecycle());
diff --git a/third_party/blink/renderer/core/editing/editing_strategy.cc b/third_party/blink/renderer/core/editing/editing_strategy.cc
index 2995371..59967488 100644
--- a/third_party/blink/renderer/core/editing/editing_strategy.cc
+++ b/third_party/blink/renderer/core/editing/editing_strategy.cc
@@ -7,6 +7,23 @@
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
 
+namespace {
+
+blink::EUserSelect UsedValueOfUserSelect(const blink::Node& node) {
+  if (node.IsHTMLElement() && ToHTMLElement(node).IsTextControl())
+    return blink::EUserSelect::kText;
+  if (!node.GetLayoutObject())
+    return blink::EUserSelect::kNone;
+
+  const blink::ComputedStyle* style = node.GetLayoutObject()->Style();
+  if (style->UserModify() != blink::EUserModify::kReadOnly)
+    return blink::EUserSelect::kText;
+
+  return style->UserSelect();
+}
+
+}  // namespace
+
 namespace blink {
 
 // If a node can contain candidates for VisiblePositions, return the offset of
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc
index 0483f31..db45a64e6 100644
--- a/third_party/blink/renderer/core/editing/editing_utilities.cc
+++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -985,19 +985,6 @@
   return nullptr;
 }
 
-EUserSelect UsedValueOfUserSelect(const Node& node) {
-  if (node.IsHTMLElement() && ToHTMLElement(node).IsTextControl())
-    return EUserSelect::kText;
-  if (!node.GetLayoutObject())
-    return EUserSelect::kNone;
-
-  const ComputedStyle* style = node.GetLayoutObject()->Style();
-  if (style->UserModify() != EUserModify::kReadOnly)
-    return EUserSelect::kText;
-
-  return style->UserSelect();
-}
-
 template <typename Strategy>
 TextDirection DirectionOfEnclosingBlockOfAlgorithm(
     const PositionTemplate<Strategy>& position) {
@@ -1561,9 +1548,9 @@
 }
 
 const StaticRangeVector* TargetRangesForInputEvent(const Node& node) {
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  node.GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  node.GetDocument().UpdateStyleAndLayout();
   if (!HasRichlyEditableStyle(node))
     return nullptr;
   const EphemeralRange& range =
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.h b/third_party/blink/renderer/core/editing/editing_utilities.h
index 1249b03..48e6f83 100644
--- a/third_party/blink/renderer/core/editing/editing_utilities.h
+++ b/third_party/blink/renderer/core/editing/editing_utilities.h
@@ -167,7 +167,6 @@
 bool IsRenderedAsNonInlineTableImageOrHR(const Node*);
 bool IsNonTableCellHTMLBlockElement(const Node*);
 bool IsBlockFlowElement(const Node&);
-EUserSelect UsedValueOfUserSelect(const Node&);
 bool IsInPasswordField(const Position&);
 CORE_EXPORT TextDirection DirectionOfEnclosingBlockOf(const Position&);
 CORE_EXPORT TextDirection
diff --git a/third_party/blink/renderer/core/editing/editor.cc b/third_party/blink/renderer/core/editing/editor.cc
index 565c36971..aba7b71 100644
--- a/third_party/blink/renderer/core/editing/editor.cc
+++ b/third_party/blink/renderer/core/editing/editor.cc
@@ -174,9 +174,9 @@
   if (event->IsIncrementalInsertion())
     return false;
 
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
 
   if (event->IsPaste()) {
     if (event->PastingFragment()) {
@@ -237,7 +237,7 @@
   FrameSelection& selection = GetFrameSelection();
   if (!selection.IsAvailable())
     return false;
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
   const VisibleSelectionInFlatTree& visible_selection =
       selection.ComputeVisibleSelectionInFlatTree();
   return visible_selection.IsRange() &&
diff --git a/third_party/blink/renderer/core/editing/element_inner_text.cc b/third_party/blink/renderer/core/editing/element_inner_text.cc
index a15aa12..2d176eeb 100644
--- a/third_party/blink/renderer/core/editing/element_inner_text.cc
+++ b/third_party/blink/renderer/core/editing/element_inner_text.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/text/character_names.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -37,6 +38,8 @@
 // [1]
 // https://html.spec.whatwg.org/C/#the-innertext-idl-attribute
 class ElementInnerTextCollector final {
+  STACK_ALLOCATED();
+
  public:
   ElementInnerTextCollector() = default;
 
@@ -443,7 +446,7 @@
 String Element::innerText() {
   // We need to update layout, since |ElementInnerTextCollector()| uses line
   // boxes in the layout tree.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
   return ElementInnerTextCollector().RunOn(*this);
 }
 
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer.cc b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
index c150176..e55cf8a 100644
--- a/third_party/blink/renderer/core/editing/finder/find_buffer.cc
+++ b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
@@ -120,8 +120,7 @@
   // TODO(rakina): This currently does layout too and might be expensive. In the
   // future, we might to figure out a way to make NGOffsetMapping work with only
   // style & layout tree so that we don't have to do layout here.
-  invisible_root_->GetDocument()
-      .UpdateStyleAndLayoutIgnorePendingStylesheetsConsideringInvisibleNodes();
+  invisible_root_->GetDocument().UpdateStyleAndLayout();
 }
 
 FindBuffer::InvisibleLayoutScope::~InvisibleLayoutScope() {
@@ -133,7 +132,7 @@
   invisible_root_->SetNeedsStyleRecalc(
       kSubtreeStyleChange,
       StyleChangeReasonForTracing::Create(style_change_reason::kFindInvisible));
-  invisible_root_->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  invisible_root_->GetDocument().UpdateStyleAndLayout();
 }
 
 bool ShouldIgnoreContents(const Node& node) {
@@ -345,7 +344,7 @@
   if (node) {
     CollectScopedForcedUpdates(*node, end_node, just_after_block);
     if (!scoped_forced_update_list_.IsEmpty())
-      node->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      node->GetDocument().UpdateStyleAndLayout();
   }
 
   while (node && node != just_after_block) {
diff --git a/third_party/blink/renderer/core/editing/finder/find_task_controller.cc b/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
index 80b67e7..e8e6f29 100644
--- a/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
+++ b/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
@@ -106,9 +106,9 @@
         return;
     }
 
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited.  see http://crbug.com/590369 for more details.
-    search_start.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    search_start.GetDocument()->UpdateStyleAndLayout();
 
     int match_count = 0;
     bool full_range_searched = false;
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.cc b/third_party/blink/renderer/core/editing/finder/text_finder.cc
index fc71904..e3f83ba 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.cc
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -80,7 +80,7 @@
     const EphemeralRangeInFlatTree range(match);
     if (InvisibleDOM::ActivateRangeIfNeeded(range) ||
         DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(range))
-      first_node.GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+      first_node.GetDocument().UpdateStyleAndLayout();
   }
   Settings* settings = first_node.GetDocument().GetSettings();
   bool smooth_find_enabled =
@@ -242,7 +242,7 @@
 
   // Need to clean out style and layout state before querying
   // Element::isFocusable().
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   // Try to find the first focusable node up the chain, which will, for
   // example, focus links if we have found text within the link.
diff --git a/third_party/blink/renderer/core/editing/frame_selection.cc b/third_party/blink/renderer/core/editing/frame_selection.cc
index b06d1a0..19a63c59 100644
--- a/third_party/blink/renderer/core/editing/frame_selection.cc
+++ b/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -148,9 +148,9 @@
 
 VisibleSelection FrameSelection::ComputeVisibleSelectionInDOMTreeDeprecated()
     const {
-  // TODO(editing-dev): Hoist updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Hoist UpdateStyleAndLayout
   // to caller. See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   return ComputeVisibleSelectionInDOMTree();
 }
 
@@ -422,9 +422,9 @@
 }
 
 bool FrameSelection::SelectionHasFocus() const {
-  // TODO(editing-dev): Hoist UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Hoist UpdateStyleAndLayout
   // to caller. See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (ComputeVisibleSelectionInFlatTree().IsNone())
     return false;
   const Node* current =
@@ -536,9 +536,9 @@
   if (!IsAvailable() || GetSelectionInDOMTree().IsNone())
     return false;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
   if (ComputeVisibleSelectionInDOMTree().IsNone()) {
     // plugins/mouse-capture-inside-shadow.html reaches here.
     return false;
@@ -633,9 +633,9 @@
     return;
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   if (!IsStartOfDocument(ComputeVisibleSelectionInDOMTree().VisibleStart()))
     return;
@@ -657,10 +657,9 @@
   if (!owner_element_parent)
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
-  // needs to be audited.  See http://crbug.com/590369 for more details.
-  owner_element_parent->GetDocument()
-      .UpdateStyleAndLayoutIgnorePendingStylesheets();
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
+  // needs to be audited. See http://crbug.com/590369 for more details.
+  owner_element_parent->GetDocument().UpdateStyleAndLayout();
 
   // This method's purpose is it to make it easier to select iframes (in order
   // to delete them).  Don't do anything if the iframe isn't deletable.
@@ -900,7 +899,7 @@
   if (Element* target =
           ComputeVisibleSelectionInDOMTreeDeprecated().RootEditableElement()) {
     // Walk up the DOM tree to search for a node to focus.
-    GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayoutTree();
     while (target) {
       // We don't want to set focus on a subframe when selecting in a parent
       // frame, so add the !isFrameElement check here. There's probably a better
@@ -988,10 +987,10 @@
                                      RevealExtentOption reveal_extent_option) {
   DCHECK(IsAvailable());
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
   // Calculation of absolute caret bounds requires clean layout.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   const VisibleSelection& selection = ComputeVisibleSelectionInDOMTree();
   if (selection.IsNone())
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
index c8c3df2..930f404 100644
--- a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
+++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -160,9 +160,9 @@
   if (!frame.GetDocument())
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame.GetDocument()->UpdateStyleAndLayout();
 
   const bool is_incremental_insertion = NeedsIncrementalInsertion(frame, text);
 
@@ -174,7 +174,7 @@
       // https://crbug.com/693481
       if (text.IsEmpty())
         TypingCommand::DeleteSelection(*frame.GetDocument(), 0);
-      frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+      frame.GetDocument()->UpdateStyleAndLayout();
       TypingCommand::InsertText(*frame.GetDocument(), text, options,
                                 composition_type, is_incremental_insertion);
       break;
@@ -296,9 +296,9 @@
   // element as editable[1]
   // [1] http://crbug.com/712761
 
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  frameSelection.GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frameSelection.GetDocument().UpdateStyleAndLayout();
   const VisibleSelection& visibleSeleciton =
       frameSelection.ComputeVisibleSelectionInDOMTree();
   return RootEditableElementOf(visibleSeleciton.Start());
@@ -453,7 +453,7 @@
 
   // TODO(editing-dev): Use of UpdateStyleAndLayoutIgnorePendingStylesheets
   // needs to be audited. see http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   const String& composing = ComposingText();
 
   // Suppress input event (if we hit the is_too_long case) and compositionend
@@ -478,7 +478,7 @@
 
     // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
     // needs to be audited. see http://crbug.com/590369 for more details.
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     const EphemeralRange& old_selection_range =
         EphemeralRangeForOffsets(old_offsets);
@@ -654,9 +654,9 @@
   if (!ReplaceComposition(text))
     return false;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   AddImeTextSpans(ime_text_spans, root_editable_element, text_start);
 
@@ -770,9 +770,9 @@
   if (!target)
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   PlainTextRange selected_range = CreateSelectionRangeForSetComposition(
       selection_start, selection_end, text.length());
@@ -810,9 +810,9 @@
         return;
     }
 
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited. see http://crbug.com/590369 for more details.
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     SetEditableSelectionOffsets(selected_range);
     return;
@@ -839,9 +839,9 @@
   if (!IsAvailable())
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // The undo stack could become empty if a JavaScript event handler calls
   // execCommand('undo') to pop elements off the stack. Or, the top element of
@@ -878,9 +878,9 @@
   if (base_node->GetLayoutObject())
     base_node->GetLayoutObject()->SetShouldDoFullPaintInvalidation();
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited. see http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // We shouldn't close typing in the middle of setComposition.
   SetEditableSelectionOffsets(selected_range, TypingContinuation::kContinue);
@@ -1124,7 +1124,7 @@
 }
 
 bool InputMethodController::MoveCaret(int new_caret_position) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   PlainTextRange selected_range =
       CreateRangeForSelection(new_caret_position, new_caret_position, 0);
   if (selected_range.IsNull())
@@ -1303,9 +1303,9 @@
   if (!GetFrame().GetEditor().CanEdit())
     return info;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   DocumentLifecycle::DisallowTransitionScope disallow_transition(
       GetDocument().Lifecycle());
diff --git a/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.cc b/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.cc
deleted file mode 100644
index cac653f..0000000
--- a/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h"
-
-namespace blink {
-
-const UChar* BackwardsTextBuffer::Data() const {
-  return BufferEnd() - Size();
-}
-
-UChar* BackwardsTextBuffer::CalcDestination(wtf_size_t length) {
-  DCHECK_LE(Size() + length, Capacity());
-  return BufferEnd() - Size() - length;
-}
-
-void BackwardsTextBuffer::ShiftData(wtf_size_t old_capacity) {
-  DCHECK_LE(old_capacity, Capacity());
-  DCHECK_LE(Size(), old_capacity);
-  std::copy_backward(BufferBegin() + old_capacity - Size(),
-                     BufferBegin() + old_capacity, BufferEnd());
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h b/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h
deleted file mode 100644
index bced1da..0000000
--- a/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_BACKWARDS_TEXT_BUFFER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_BACKWARDS_TEXT_BUFFER_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/core/editing/iterators/text_buffer_base.h"
-
-namespace blink {
-
-class CORE_EXPORT BackwardsTextBuffer final : public TextBufferBase {
-  STACK_ALLOCATED();
-
- public:
-  BackwardsTextBuffer() = default;
-  const UChar* Data() const override;
-
- private:
-  UChar* CalcDestination(wtf_size_t length) override;
-  void ShiftData(wtf_size_t old_capacity) override;
-
-  DISALLOW_COPY_AND_ASSIGN(BackwardsTextBuffer);
-};
-
-}  // namespace blink
-
-#endif  // TextBuffer_h
diff --git a/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer_test.cc b/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer_test.cc
deleted file mode 100644
index 7111929..0000000
--- a/third_party/blink/renderer/core/editing/iterators/backwards_text_buffer_test.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h"
-
-#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
-
-namespace blink {
-
-class BackwardsTextBufferTest : public EditingTestBase {};
-
-TEST_F(BackwardsTextBufferTest, pushCharacters) {
-  BackwardsTextBuffer buffer;
-
-  // Basic tests.
-  buffer.PushCharacters('a', 1);
-  buffer.PushCharacters(1u, 0);
-  buffer.PushCharacters('#', 2);
-  buffer.PushCharacters('\0', 1);
-  EXPECT_EQ('\0', buffer[0]);
-  EXPECT_EQ('#', buffer[1]);
-  EXPECT_EQ('#', buffer[2]);
-  EXPECT_EQ('a', buffer[3]);
-
-  // Tests with buffer reallocation.
-  buffer.PushCharacters('A', 4096);
-  EXPECT_EQ('A', buffer[0]);
-  EXPECT_EQ('A', buffer[4095]);
-  EXPECT_EQ('\0', buffer[4096]);
-  EXPECT_EQ('#', buffer[4097]);
-  EXPECT_EQ('#', buffer[4098]);
-  EXPECT_EQ('a', buffer[4099]);
-}
-
-TEST_F(BackwardsTextBufferTest, pushRange) {
-  BackwardsTextBuffer buffer;
-
-  // Basic tests.
-  buffer.PushRange("ababc", 1);
-  buffer.PushRange((UChar*)nullptr, 0);
-  buffer.PushRange("#@", 2);
-  UChar ch = 'x';
-  buffer.PushRange(&ch, 1);
-  EXPECT_EQ('x', buffer[0]);
-  EXPECT_EQ('#', buffer[1]);
-  EXPECT_EQ('@', buffer[2]);
-  EXPECT_EQ('a', buffer[3]);
-
-  // Tests with buffer reallocation.
-  Vector<UChar> chunk(4096);
-  for (unsigned i = 0; i < chunk.size(); ++i)
-    chunk[i] = i % 256;
-  buffer.PushRange(chunk.data(), chunk.size());
-  EXPECT_EQ(0, buffer[0]);
-  EXPECT_EQ(1111 % 256, buffer[1111]);
-  EXPECT_EQ(255, buffer[4095]);
-  EXPECT_EQ('x', buffer[4096]);
-  EXPECT_EQ('#', buffer[4097]);
-  EXPECT_EQ('@', buffer[4098]);
-  EXPECT_EQ('a', buffer[4099]);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/character_iterator.cc b/third_party/blink/renderer/core/editing/iterators/character_iterator.cc
index cfff0d204..2144ff65 100644
--- a/third_party/blink/renderer/core/editing/iterators/character_iterator.cc
+++ b/third_party/blink/renderer/core/editing/iterators/character_iterator.cc
@@ -175,12 +175,6 @@
 }
 
 template <typename Strategy>
-void CharacterIteratorAlgorithm<Strategy>::CopyTextTo(
-    ForwardsTextBuffer* output) {
-  text_iterator_.CopyTextTo(output, run_offset_);
-}
-
-template <typename Strategy>
 EphemeralRangeTemplate<Strategy>
 CharacterIteratorAlgorithm<Strategy>::CalculateCharacterSubrange(int offset,
                                                                  int length) {
diff --git a/third_party/blink/renderer/core/editing/iterators/character_iterator.h b/third_party/blink/renderer/core/editing/iterators/character_iterator.h
index ec82b455..c9a3e14 100644
--- a/third_party/blink/renderer/core/editing/iterators/character_iterator.h
+++ b/third_party/blink/renderer/core/editing/iterators/character_iterator.h
@@ -60,8 +60,6 @@
     return text_iterator_.CharacterAt(run_offset_ + index);
   }
 
-  void CopyTextTo(ForwardsTextBuffer* output);
-
   int CharacterOffset() const { return offset_; }
 
   const Document& OwnerDocument() const;
diff --git a/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.cc b/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.cc
deleted file mode 100644
index 59a6f27..0000000
--- a/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.h"
-
-namespace blink {
-
-const UChar* ForwardsTextBuffer::Data() const {
-  return BufferBegin();
-}
-
-UChar* ForwardsTextBuffer::CalcDestination(wtf_size_t length) {
-  DCHECK_LE(Size() + length, Capacity());
-  return BufferBegin() + Size();
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.h b/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.h
deleted file mode 100644
index 0131fd86..0000000
--- a/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_FORWARDS_TEXT_BUFFER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_FORWARDS_TEXT_BUFFER_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/core/editing/iterators/text_buffer_base.h"
-
-namespace blink {
-
-class CORE_EXPORT ForwardsTextBuffer final : public TextBufferBase {
-  STACK_ALLOCATED();
-
- public:
-  ForwardsTextBuffer() = default;
-  const UChar* Data() const override;
-
- private:
-  UChar* CalcDestination(wtf_size_t length) override;
-
-  DISALLOW_COPY_AND_ASSIGN(ForwardsTextBuffer);
-};
-
-}  // namespace blink
-
-#endif  // TextBuffer_h
diff --git a/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer_test.cc b/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer_test.cc
deleted file mode 100644
index 0700242..0000000
--- a/third_party/blink/renderer/core/editing/iterators/forwards_text_buffer_test.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.h"
-
-#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
-
-namespace blink {
-
-class ForwardsTextBufferTest : public EditingTestBase {};
-
-TEST_F(ForwardsTextBufferTest, pushCharacters) {
-  ForwardsTextBuffer buffer;
-
-  // Basic tests.
-  buffer.PushCharacters('a', 1);
-  buffer.PushCharacters(1u, 0);
-  buffer.PushCharacters('#', 2);
-  buffer.PushCharacters('\0', 1);
-  EXPECT_EQ('a', buffer[0]);
-  EXPECT_EQ('#', buffer[1]);
-  EXPECT_EQ('#', buffer[2]);
-  EXPECT_EQ('\0', buffer[3]);
-
-  // Tests with buffer reallocation.
-  buffer.PushCharacters('A', 4096);
-  EXPECT_EQ('a', buffer[0]);
-  EXPECT_EQ('#', buffer[1]);
-  EXPECT_EQ('#', buffer[2]);
-  EXPECT_EQ('\0', buffer[3]);
-  EXPECT_EQ('A', buffer[4]);
-  EXPECT_EQ('A', buffer[4 + 4095]);
-}
-
-TEST_F(ForwardsTextBufferTest, pushRange) {
-  ForwardsTextBuffer buffer;
-
-  // Basic tests.
-  buffer.PushRange("ababc", 1);
-  buffer.PushRange((UChar*)nullptr, 0);
-  buffer.PushRange("#@", 2);
-  UChar ch = 'x';
-  buffer.PushRange(&ch, 1);
-  EXPECT_EQ('a', buffer[0]);
-  EXPECT_EQ('#', buffer[1]);
-  EXPECT_EQ('@', buffer[2]);
-  EXPECT_EQ('x', buffer[3]);
-
-  // Tests with buffer reallocation.
-  Vector<UChar> chunk(4096);
-  for (unsigned i = 0; i < chunk.size(); ++i)
-    chunk[i] = i % 256;
-  buffer.PushRange(chunk.data(), chunk.size());
-  EXPECT_EQ('a', buffer[0]);
-  EXPECT_EQ('#', buffer[1]);
-  EXPECT_EQ('@', buffer[2]);
-  EXPECT_EQ('x', buffer[3]);
-  EXPECT_EQ(0, buffer[4]);
-  EXPECT_EQ(1111 % 256, buffer[4 + 1111]);
-  EXPECT_EQ(255, buffer[4 + 4095]);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc
index 2590c93..f589536 100644
--- a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc
+++ b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc
@@ -413,35 +413,6 @@
   return text_state_.CharacterAt(text_state_.length() - index - 1);
 }
 
-template <typename Strategy>
-bool SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::IsBetweenSurrogatePair(
-    int position) const {
-  DCHECK_GE(position, 0);
-  return position > 0 && position < length() &&
-         U16_IS_TRAIL(CharacterAt(position - 1)) &&
-         U16_IS_LEAD(CharacterAt(position));
-}
-
-template <typename Strategy>
-int SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::CopyTextTo(
-    BackwardsTextBuffer* output,
-    int position,
-    int min_length) const {
-  int end = std::min(length(), position + min_length);
-  if (IsBetweenSurrogatePair(end))
-    ++end;
-  int copied_length = end - position;
-  text_state_.PrependTextTo(output, position, copied_length);
-  return copied_length;
-}
-
-template <typename Strategy>
-int SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::CopyTextTo(
-    BackwardsTextBuffer* output,
-    int position) const {
-  return CopyTextTo(output, position, text_state_.length() - position);
-}
-
 template class CORE_TEMPLATE_EXPORT
     SimplifiedBackwardsTextIteratorAlgorithm<EditingStrategy>;
 template class CORE_TEMPLATE_EXPORT
diff --git a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h
index f3d72ea..4d41206 100644
--- a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h
+++ b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h
@@ -27,7 +27,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_SIMPLIFIED_BACKWARDS_TEXT_ITERATOR_H_
 
 #include "third_party/blink/renderer/core/editing/forward.h"
-#include "third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h"
 #include "third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.h"
 #include "third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h"
 #include "third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h"
@@ -57,6 +56,7 @@
   void Advance();
 
   int length() const { return text_state_.length(); }
+  const TextIteratorTextState& GetTextState() const { return text_state_; }
 
   // Note: |characterAt()| returns characters in the reversed order, since
   // the iterator is backwards. For example, if the current text is "abc",
@@ -65,14 +65,6 @@
 
   const Node* GetNode() const { return node_; }
 
-  // Calculate the minimum |actualLength >= minLength| such that code units
-  // with offset range [position, position + actualLength) are whole code
-  // points. Prepend these code points to |output| and return |actualLength|.
-  int CopyTextTo(BackwardsTextBuffer* output,
-                 int position,
-                 int min_length) const;
-  int CopyTextTo(BackwardsTextBuffer* output, int position = 0) const;
-
   // TODO(editing-dev): We should consider code sharing between |TextIterator|
   // and |SimplifiedBackwardsTextIterator| for
   //  - StartContainer()
@@ -98,8 +90,6 @@
   bool HandleNonTextNode();
   bool AdvanceRespectingRange(const Node*);
 
-  bool IsBetweenSurrogatePair(int position) const;
-
   // TODO(editing-dev): We should consider code sharing between |TextIterator|
   // and |SimplifiedBackwardsTextIterator| for
   //  - EnsurePositionContainer()
diff --git a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator_test.cc b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator_test.cc
index 37a2316..58ae10e 100644
--- a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator_test.cc
+++ b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator_test.cc
@@ -30,12 +30,10 @@
     for (SimplifiedBackwardsTextIterator iterator(selection.ComputeRange(),
                                                   behavior);
          !iterator.AtEnd(); iterator.Advance()) {
-      BackwardsTextBuffer buffer;
-      iterator.CopyTextTo(&buffer);
       if (!is_first)
         builder.Append(", ", 2);
       is_first = false;
-      builder.Append(buffer.Data(), buffer.Size());
+      builder.Append(iterator.GetTextState().GetTextForTesting());
     }
     CString utf8 = builder.ToString().Utf8();
     return std::string(utf8.data(), utf8.length());
@@ -46,15 +44,15 @@
 static String ExtractString(const Element& element) {
   const EphemeralRangeTemplate<Strategy> range =
       EphemeralRangeTemplate<Strategy>::RangeOfContents(element);
-  BackwardsTextBuffer buffer;
+  String result;
   for (SimplifiedBackwardsTextIteratorAlgorithm<Strategy> it(range);
        !it.AtEnd(); it.Advance()) {
-    it.CopyTextTo(&buffer);
+    result = it.GetTextState().GetTextForTesting() + result;
   }
-  return String(buffer.Data(), buffer.Size());
+  return result;
 }
 
-TEST_F(SimplifiedBackwardsTextIteratorTest, CopyTextToWithFirstLetterPart) {
+TEST_F(SimplifiedBackwardsTextIteratorTest, IterateWithFirstLetterPart) {
   InsertStyleElement("p::first-letter {font-size: 200%}");
   // TODO(editing-dev): |SimplifiedBackwardsTextIterator| should not account
   // collapsed whitespace (http://crbug.com/760428)
@@ -229,100 +227,6 @@
   EXPECT_EQ('t', back_iter2.CharacterAt(5)) << message2;
 }
 
-TEST_F(SimplifiedBackwardsTextIteratorTest, copyTextTo) {
-  const char* body_content =
-      "<a id=host><b id=one>one</b> not appeared <b id=two>two</b></a>";
-  const char* shadow_content =
-      "three <content select=#two></content> <content select=#one></content> "
-      "zero";
-  SetBodyContent(body_content);
-  SetShadowContent(shadow_content, "host");
-
-  Element* host = GetDocument().getElementById("host");
-  const char* message =
-      "|backIter%d| should have emitted '%s' in reverse order.";
-
-  EphemeralRangeTemplate<EditingStrategy> range1(
-      EphemeralRangeTemplate<EditingStrategy>::RangeOfContents(*host));
-  SimplifiedBackwardsTextIteratorAlgorithm<EditingStrategy> back_iter1(range1);
-  BackwardsTextBuffer output1;
-  back_iter1.CopyTextTo(&output1, 0, 2);
-  EXPECT_EQ("wo", String(output1.Data(), output1.Size()))
-      << String::Format(message, 1, "wo").Utf8().data();
-  back_iter1.CopyTextTo(&output1, 2, 1);
-  EXPECT_EQ("two", String(output1.Data(), output1.Size()))
-      << String::Format(message, 1, "two").Utf8().data();
-  back_iter1.Advance();
-  back_iter1.CopyTextTo(&output1, 0, 1);
-  EXPECT_EQ("etwo", String(output1.Data(), output1.Size()))
-      << String::Format(message, 1, "etwo").Utf8().data();
-  back_iter1.CopyTextTo(&output1, 1, 2);
-  EXPECT_EQ("onetwo", String(output1.Data(), output1.Size()))
-      << String::Format(message, 1, "onetwo").Utf8().data();
-
-  EphemeralRangeTemplate<EditingInFlatTreeStrategy> range2(
-      EphemeralRangeTemplate<EditingInFlatTreeStrategy>::RangeOfContents(
-          *host));
-  SimplifiedBackwardsTextIteratorAlgorithm<EditingInFlatTreeStrategy>
-      back_iter2(range2);
-  BackwardsTextBuffer output2;
-  back_iter2.CopyTextTo(&output2, 0, 2);
-  EXPECT_EQ("ro", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "ro").Utf8().data();
-  back_iter2.CopyTextTo(&output2, 2, 3);
-  EXPECT_EQ(" zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, " zero").Utf8().data();
-  back_iter2.Advance();
-  back_iter2.CopyTextTo(&output2, 0, 1);
-  EXPECT_EQ("e zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "e zero").Utf8().data();
-  back_iter2.CopyTextTo(&output2, 1, 2);
-  EXPECT_EQ("one zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "one zero").Utf8().data();
-  back_iter2.Advance();
-  back_iter2.CopyTextTo(&output2, 0, 1);
-  EXPECT_EQ(" one zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, " one zero").Utf8().data();
-  back_iter2.Advance();
-  back_iter2.CopyTextTo(&output2, 0, 2);
-  EXPECT_EQ("wo one zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "wo one zero").Utf8().data();
-  back_iter2.CopyTextTo(&output2, 2, 1);
-  EXPECT_EQ("two one zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "two one zero").Utf8().data();
-  back_iter2.Advance();
-  back_iter2.CopyTextTo(&output2, 0, 3);
-  EXPECT_EQ("ee two one zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "ee two one zero").Utf8().data();
-  back_iter2.CopyTextTo(&output2, 3, 3);
-  EXPECT_EQ("three two one zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three two one zero").Utf8().data();
-}
-
-TEST_F(SimplifiedBackwardsTextIteratorTest, CopyWholeCodePoints) {
-  const char* body_content = "&#x13000;&#x13001;&#x13002; &#x13140;&#x13141;.";
-  SetBodyContent(body_content);
-
-  const UChar kExpected[] = {0xD80C, 0xDC00, 0xD80C, 0xDC01, 0xD80C, 0xDC02,
-                             ' ',    0xD80C, 0xDD40, 0xD80C, 0xDD41, '.'};
-
-  EphemeralRange range(EphemeralRange::RangeOfContents(GetDocument()));
-  SimplifiedBackwardsTextIterator iter(range);
-  BackwardsTextBuffer buffer;
-  EXPECT_EQ(1, iter.CopyTextTo(&buffer, 0, 1))
-      << "Should emit 1 UChar for '.'.";
-  EXPECT_EQ(2, iter.CopyTextTo(&buffer, 1, 1))
-      << "Should emit 2 UChars for 'U+13141'.";
-  EXPECT_EQ(2, iter.CopyTextTo(&buffer, 3, 2))
-      << "Should emit 2 UChars for 'U+13140'.";
-  EXPECT_EQ(5, iter.CopyTextTo(&buffer, 5, 4))
-      << "Should emit 5 UChars for 'U+13001U+13002 '.";
-  EXPECT_EQ(2, iter.CopyTextTo(&buffer, 10, 2))
-      << "Should emit 2 UChars for 'U+13000'.";
-  for (int i = 0; i < 12; i++)
-    EXPECT_EQ(kExpected[i], buffer[i]);
-}
-
 TEST_F(SimplifiedBackwardsTextIteratorTest, TextSecurity) {
   InsertStyleElement("s {-webkit-text-security:disc;}");
   EXPECT_EQ("baz, xxx, abc",
diff --git a/third_party/blink/renderer/core/editing/iterators/text_buffer_base.cc b/third_party/blink/renderer/core/editing/iterators/text_buffer_base.cc
deleted file mode 100644
index f0e8c888..0000000
--- a/third_party/blink/renderer/core/editing/iterators/text_buffer_base.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/editing/iterators/text_buffer_base.h"
-
-namespace blink {
-
-TextBufferBase::TextBufferBase() {
-  buffer_.ReserveCapacity(1024);
-  buffer_.resize(Capacity());
-}
-
-void TextBufferBase::ShiftData(wtf_size_t) {}
-
-void TextBufferBase::PushCharacters(UChar ch, wtf_size_t length) {
-  if (length == 0)
-    return;
-  std::fill_n(EnsureDestination(length), length, ch);
-}
-
-UChar* TextBufferBase::EnsureDestination(wtf_size_t length) {
-  if (size_ + length > Capacity())
-    Grow(size_ + length);
-  UChar* ans = CalcDestination(length);
-  size_ += length;
-  return ans;
-}
-
-void TextBufferBase::Grow(wtf_size_t demand) {
-  wtf_size_t old_capacity = Capacity();
-  buffer_.resize(demand);
-  buffer_.resize(Capacity());
-  ShiftData(old_capacity);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/text_buffer_base.h b/third_party/blink/renderer/core/editing/iterators/text_buffer_base.h
deleted file mode 100644
index 7fc9eed8..0000000
--- a/third_party/blink/renderer/core/editing/iterators/text_buffer_base.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_TEXT_BUFFER_BASE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_TEXT_BUFFER_BASE_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-class CORE_EXPORT TextBufferBase {
-  STACK_ALLOCATED();
-
- public:
-  void Clear() { size_ = 0; }
-  wtf_size_t Size() const { return size_; }
-  bool IsEmpty() const { return size_ == 0; }
-  wtf_size_t Capacity() const { return buffer_.capacity(); }
-  const UChar& operator[](wtf_size_t index) const {
-    DCHECK_LT(index, size_);
-    return Data()[index];
-  }
-  virtual const UChar* Data() const = 0;
-
-  void PushCharacters(UChar, wtf_size_t length);
-
-  template <typename T>
-  void PushRange(const T* other, wtf_size_t length) {
-    if (length == 0)
-      return;
-    std::copy(other, other + length, EnsureDestination(length));
-  }
-
-  void Shrink(wtf_size_t delta) {
-    DCHECK_LE(delta, size_);
-    size_ -= delta;
-  }
-
- protected:
-  TextBufferBase();
-  UChar* EnsureDestination(wtf_size_t length);
-  void Grow(wtf_size_t demand);
-
-  virtual UChar* CalcDestination(wtf_size_t length) = 0;
-  virtual void ShiftData(wtf_size_t old_capacity);
-
-  const UChar* BufferBegin() const { return buffer_.begin(); }
-  const UChar* BufferEnd() const { return buffer_.end(); }
-  UChar* BufferBegin() { return buffer_.begin(); }
-  UChar* BufferEnd() { return buffer_.end(); }
-
- private:
-  wtf_size_t size_ = 0;
-  Vector<UChar, 1024> buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(TextBufferBase);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_TEXT_BUFFER_BASE_H_
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
index fe63db5..447d7c83 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
@@ -999,40 +999,6 @@
   return RangeLength(range.StartPosition(), range.EndPosition(), behavior);
 }
 
-template <typename Strategy>
-bool TextIteratorAlgorithm<Strategy>::IsBetweenSurrogatePair(
-    unsigned position) const {
-  return position > 0 && position < static_cast<unsigned>(length()) &&
-         U16_IS_LEAD(CharacterAt(position - 1)) &&
-         U16_IS_TRAIL(CharacterAt(position));
-}
-
-template <typename Strategy>
-int TextIteratorAlgorithm<Strategy>::CopyTextTo(ForwardsTextBuffer* output,
-                                                int position,
-                                                int min_length) const {
-  unsigned end = std::min(length(), position + min_length);
-  if (IsBetweenSurrogatePair(end))
-    ++end;
-  unsigned copied_length = end - position;
-  CopyCodeUnitsTo(output, position, copied_length);
-  return copied_length;
-}
-
-template <typename Strategy>
-int TextIteratorAlgorithm<Strategy>::CopyTextTo(ForwardsTextBuffer* output,
-                                                int position) const {
-  return CopyTextTo(output, position, length() - position);
-}
-
-template <typename Strategy>
-void TextIteratorAlgorithm<Strategy>::CopyCodeUnitsTo(
-    ForwardsTextBuffer* output,
-    unsigned position,
-    unsigned copy_length) const {
-  text_state_.AppendTextTo(output, position, copy_length);
-}
-
 // --------
 
 template <typename Strategy>
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.h b/third_party/blink/renderer/core/editing/iterators/text_iterator.h
index b2c2091ec..1f6e69d 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator.h
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.h
@@ -87,6 +87,7 @@
   // Returns the position after |char16_offset| in current text run.
   PositionTemplate<Strategy> GetPositionAfter(int char16_offset) const;
 
+  // TODO(xiaochengh): Rename to |GetTextState()|.
   const TextIteratorTextState& GetText() const { return text_state_; }
   int length() const { return text_state_.length(); }
   UChar CharacterAt(unsigned index) const {
@@ -97,14 +98,6 @@
     return !behavior_.DoesNotBreakAtReplacedElement();
   }
 
-  // Calculate the minimum |actualLength >= minLength| such that code units
-  // with offset range [position, position + actualLength) are whole code
-  // points. Append these code points to |output| and return |actualLength|.
-  int CopyTextTo(ForwardsTextBuffer* output,
-                 int position,
-                 int min_length) const;
-  int CopyTextTo(ForwardsTextBuffer* output, int position = 0) const;
-
   // Computes the length of the given range using a text iterator according to
   // the specified iteration behavior. The default iteration behavior is to
   // always emit object replacement characters for replaced elements.
@@ -201,12 +194,6 @@
 
   bool IsBetweenSurrogatePair(unsigned position) const;
 
-  // Append code units with offset range [position, position + copyLength)
-  // to the output buffer.
-  void CopyCodeUnitsTo(ForwardsTextBuffer* output,
-                       unsigned position,
-                       unsigned copy_length) const;
-
   // Ensure container node of current text run for computing position.
   void EnsurePositionContainer() const;
 
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc
index 4b0148a6..75330a8 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc
@@ -552,76 +552,6 @@
             Iterate<FlatTree>(CollapseTrailingSpaceBehavior()));
 }
 
-TEST_P(TextIteratorTest, copyTextTo) {
-  const char* body_content =
-      "<a id=host><b id=one>one</b> not appeared <b id=two>two</b></a>";
-  const char* shadow_content =
-      "three <content select=#two></content> <content select=#one></content> "
-      "zero";
-  SetBodyContent(body_content);
-  SetShadowContent(shadow_content, "host");
-
-  Element* host = GetDocument().getElementById("host");
-  const char* message = "|iter%d| should have emitted '%s'.";
-
-  EphemeralRangeTemplate<EditingStrategy> range1(
-      EphemeralRangeTemplate<EditingStrategy>::RangeOfContents(*host));
-  TextIteratorAlgorithm<EditingStrategy> iter1(range1.StartPosition(),
-                                               range1.EndPosition());
-  ForwardsTextBuffer output1;
-  iter1.CopyTextTo(&output1, 0, 2);
-  EXPECT_EQ("on", String(output1.Data(), output1.Size()))
-      << String::Format(message, 1, "on").Utf8().data();
-  iter1.CopyTextTo(&output1, 2, 1);
-  EXPECT_EQ("one", String(output1.Data(), output1.Size()))
-      << String::Format(message, 1, "one").Utf8().data();
-  iter1.Advance();
-  iter1.CopyTextTo(&output1, 0, 1);
-  EXPECT_EQ("onet", String(output1.Data(), output1.Size()))
-      << String::Format(message, 1, "onet").Utf8().data();
-  iter1.CopyTextTo(&output1, 1, 2);
-  EXPECT_EQ("onetwo", String(output1.Data(), output1.Size()))
-      << String::Format(message, 1, "onetwo").Utf8().data();
-
-  EphemeralRangeTemplate<EditingInFlatTreeStrategy> range2(
-      EphemeralRangeTemplate<EditingInFlatTreeStrategy>::RangeOfContents(
-          *host));
-  TextIteratorAlgorithm<EditingInFlatTreeStrategy> iter2(range2.StartPosition(),
-                                                         range2.EndPosition());
-  ForwardsTextBuffer output2;
-  iter2.CopyTextTo(&output2, 0, 3);
-  EXPECT_EQ("thr", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "thr").Utf8().data();
-  iter2.CopyTextTo(&output2, 3, 3);
-  EXPECT_EQ("three ", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three ").Utf8().data();
-  iter2.Advance();
-  iter2.CopyTextTo(&output2, 0, 2);
-  EXPECT_EQ("three tw", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three tw").Utf8().data();
-  iter2.CopyTextTo(&output2, 2, 1);
-  EXPECT_EQ("three two", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three two").Utf8().data();
-  iter2.Advance();
-  iter2.CopyTextTo(&output2, 0, 1);
-  EXPECT_EQ("three two ", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three two ").Utf8().data();
-  iter2.Advance();
-  iter2.CopyTextTo(&output2, 0, 1);
-  EXPECT_EQ("three two o", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three two o").Utf8().data();
-  iter2.CopyTextTo(&output2, 1, 2);
-  EXPECT_EQ("three two one", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three two one").Utf8().data();
-  iter2.Advance();
-  iter2.CopyTextTo(&output2, 0, 2);
-  EXPECT_EQ("three two one z", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three two one z").Utf8().data();
-  iter2.CopyTextTo(&output2, 2, 3);
-  EXPECT_EQ("three two one zero", String(output2.Data(), output2.Size()))
-      << String::Format(message, 2, "three two one zero").Utf8().data();
-}
-
 TEST_P(TextIteratorTest, characterAt) {
   const char* body_content =
       "<a id=host><b id=one>one</b> not appeared <b id=two>two</b></a>";
@@ -677,30 +607,6 @@
   EXPECT_EQ('o', iter2.CharacterAt(4)) << message2;
 }
 
-TEST_P(TextIteratorTest, CopyWholeCodePoints) {
-  const char* body_content = "&#x13000;&#x13001;&#x13002; &#x13140;&#x13141;.";
-  SetBodyContent(body_content);
-
-  const UChar kExpected[] = {0xD80C, 0xDC00, 0xD80C, 0xDC01, 0xD80C, 0xDC02,
-                             ' ',    0xD80C, 0xDD40, 0xD80C, 0xDD41, '.'};
-
-  EphemeralRange range(EphemeralRange::RangeOfContents(GetDocument()));
-  TextIterator iter(range.StartPosition(), range.EndPosition());
-  ForwardsTextBuffer buffer;
-  EXPECT_EQ(2, iter.CopyTextTo(&buffer, 0, 1))
-      << "Should emit 2 UChars for 'U+13000'.";
-  EXPECT_EQ(4, iter.CopyTextTo(&buffer, 2, 3))
-      << "Should emit 4 UChars for 'U+13001U+13002'.";
-  EXPECT_EQ(3, iter.CopyTextTo(&buffer, 6, 2))
-      << "Should emit 3 UChars for ' U+13140'.";
-  EXPECT_EQ(2, iter.CopyTextTo(&buffer, 9, 2))
-      << "Should emit 2 UChars for 'U+13141'.";
-  EXPECT_EQ(1, iter.CopyTextTo(&buffer, 11, 1))
-      << "Should emit 1 UChar for '.'.";
-  for (int i = 0; i < 12; i++)
-    EXPECT_EQ(kExpected[i], buffer[i]);
-}
-
 // Regression test for crbug.com/630921
 TEST_P(TextIteratorTest, EndingConditionWithDisplayNone) {
   SetBodyContent(
@@ -768,27 +674,22 @@
   Position start(text, 0);
   Position end(text, 4);
   TextIterator iter(start, end);
-  ForwardsTextBuffer buffer;
 
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(1, iter.length());
-  EXPECT_EQ(1, iter.CopyTextTo(&buffer, 0)) << "Should emit 'A'.";
+  EXPECT_EQ("A", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 0), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 1), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(3, iter.length());
-  EXPECT_EQ(3, iter.CopyTextTo(&buffer, 0)) << "Should emit 'xyz'.";
+  EXPECT_EQ("xyz", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 1), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 4), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_TRUE(iter.AtEnd());
-
-  EXPECT_EQ("Axyz", String(buffer.Data()));
 }
 
 TEST_P(TextIteratorTest, StartInMultiCharFirstLetterWithCollapsedSpace) {
@@ -800,35 +701,29 @@
   Position start(text, 3);
   Position end(text, 10);
   TextIterator iter(start, end);
-  ForwardsTextBuffer buffer;
 
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(2, iter.length());
-  EXPECT_EQ(2, iter.CopyTextTo(&buffer, 0)) << "Should emit 'A)'.";
+  EXPECT_EQ("A)", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 3), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 5), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(1, iter.length());
-  EXPECT_EQ(1, iter.CopyTextTo(&buffer, 0)) << "Should emit ' '.";
+  EXPECT_EQ(" ", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 5), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 6), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(3, iter.length());
-  EXPECT_EQ(3, iter.CopyTextTo(&buffer, 0)) << "Should emit 'xyz'.";
+  EXPECT_EQ("xyz", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 7), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 10), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_TRUE(iter.AtEnd());
-
-  EXPECT_EQ("A) xyz", String(buffer.Data()));
 }
 
 TEST_P(TextIteratorTest, StartAndEndInMultiCharFirstLetterWithCollapsedSpace) {
@@ -840,19 +735,15 @@
   Position start(text, 3);
   Position end(text, 4);
   TextIterator iter(start, end);
-  ForwardsTextBuffer buffer;
 
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(1, iter.length());
-  EXPECT_EQ(1, iter.CopyTextTo(&buffer, 0)) << "Should emit 'A'.";
+  EXPECT_EQ("A", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 3), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 4), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_TRUE(iter.AtEnd());
-
-  EXPECT_EQ("A", String(buffer.Data()));
 }
 
 TEST_P(TextIteratorTest, StartAtRemainingText) {
@@ -863,19 +754,15 @@
   Position start(text, 1);
   Position end(text, 4);
   TextIterator iter(start, end);
-  ForwardsTextBuffer buffer;
 
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(3, iter.length());
-  EXPECT_EQ(3, iter.CopyTextTo(&buffer, 0)) << "Should emit 'xyz'.";
+  EXPECT_EQ("xyz", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 1), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 4), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_TRUE(iter.AtEnd());
-
-  EXPECT_EQ("xyz", String(buffer.Data()));
 }
 
 TEST_P(TextIteratorTest, StartAtFirstLetterInPre) {
@@ -886,27 +773,22 @@
   Position start(text, 0);
   Position end(text, 4);
   TextIterator iter(start, end);
-  ForwardsTextBuffer buffer;
 
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(1, iter.length());
-  EXPECT_EQ(1, iter.CopyTextTo(&buffer, 0)) << "Should emit 'A'.";
+  EXPECT_EQ("A", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 0), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 1), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(3, iter.length());
-  EXPECT_EQ(3, iter.CopyTextTo(&buffer, 0)) << "Should emit 'xyz'.";
+  EXPECT_EQ("xyz", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 1), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 4), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_TRUE(iter.AtEnd());
-
-  EXPECT_EQ("Axyz", String(buffer.Data()));
 }
 
 TEST_P(TextIteratorTest, StartInMultiCharFirstLetterInPre) {
@@ -918,27 +800,22 @@
   Position start(text, 1);
   Position end(text, 6);
   TextIterator iter(start, end);
-  ForwardsTextBuffer buffer;
 
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(2, iter.length());
-  EXPECT_EQ(2, iter.CopyTextTo(&buffer, 0)) << "Should emit 'A)'.";
+  EXPECT_EQ("A)", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 1), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 3), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(3, iter.length());
-  EXPECT_EQ(3, iter.CopyTextTo(&buffer, 0)) << "Should emit 'xyz'.";
+  EXPECT_EQ("xyz", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 3), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 6), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_TRUE(iter.AtEnd());
-
-  EXPECT_EQ("A)xyz", String(buffer.Data()));
 }
 
 TEST_P(TextIteratorTest, StartAndEndInMultiCharFirstLetterInPre) {
@@ -950,19 +827,15 @@
   Position start(text, 1);
   Position end(text, 2);
   TextIterator iter(start, end);
-  ForwardsTextBuffer buffer;
 
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(1, iter.length());
-  EXPECT_EQ(1, iter.CopyTextTo(&buffer, 0)) << "Should emit 'A'.";
+  EXPECT_EQ("A", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 1), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 2), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_TRUE(iter.AtEnd());
-
-  EXPECT_EQ("A", String(buffer.Data()));
 }
 
 TEST_P(TextIteratorTest, StartAtRemainingTextInPre) {
@@ -973,19 +846,15 @@
   Position start(text, 1);
   Position end(text, 4);
   TextIterator iter(start, end);
-  ForwardsTextBuffer buffer;
 
   EXPECT_FALSE(iter.AtEnd());
-  EXPECT_EQ(3, iter.length());
-  EXPECT_EQ(3, iter.CopyTextTo(&buffer, 0)) << "Should emit 'xyz'.";
+  EXPECT_EQ("xyz", iter.GetText().GetTextForTesting());
   EXPECT_EQ(text, iter.CurrentContainer());
   EXPECT_EQ(Position(text, 1), iter.StartPositionInCurrentContainer());
   EXPECT_EQ(Position(text, 4), iter.EndPositionInCurrentContainer());
 
   iter.Advance();
   EXPECT_TRUE(iter.AtEnd());
-
-  EXPECT_EQ("xyz", String(buffer.Data()));
 }
 
 TEST_P(TextIteratorTest, VisitsDisplayContentsChildren) {
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
index 494c141..156f67c 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
@@ -29,7 +29,6 @@
 
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
-#include "third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -265,55 +264,4 @@
   position_end_offset_ = position_end_offset;
 }
 
-void TextIteratorTextState::AppendTextTo(ForwardsTextBuffer* output,
-                                         unsigned position,
-                                         unsigned length_to_append) const {
-  SECURITY_DCHECK(position + length_to_append <= length());
-  // Make sure there's no integer overflow.
-  SECURITY_DCHECK(position + length_to_append >= position);
-  if (!length_to_append)
-    return;
-  DCHECK(output);
-  if (single_character_buffer_) {
-    DCHECK_EQ(position, 0u);
-    DCHECK_EQ(length(), 1u);
-    output->PushCharacters(single_character_buffer_, 1);
-    return;
-  }
-  unsigned offset = text_start_offset_ + position;
-  // Any failure is a security bug (buffer overflow) and must be captured.
-  CHECK_LE(offset, text_.length());
-  CHECK_LE(offset + length_to_append, text_.length());
-  if (text_.Is8Bit())
-    output->PushRange(text_.Characters8() + offset, length_to_append);
-  else
-    output->PushRange(text_.Characters16() + offset, length_to_append);
-}
-
-void TextIteratorTextState::PrependTextTo(BackwardsTextBuffer* output,
-                                          unsigned position,
-                                          unsigned length_to_prepend) const {
-  SECURITY_DCHECK(position + length_to_prepend <= length());
-  // Make sure there's no integer overflow.
-  SECURITY_DCHECK(position + length_to_prepend >= position);
-  if (!length_to_prepend)
-    return;
-  DCHECK(output);
-  if (single_character_buffer_) {
-    DCHECK_EQ(position, 0u);
-    DCHECK_EQ(length(), 1u);
-    output->PushCharacters(single_character_buffer_, 1);
-    return;
-  }
-  const unsigned offset =
-      text_start_offset_ + length() - position - length_to_prepend;
-  // Any failure is a security bug (buffer overflow) and must be captured.
-  CHECK_LE(offset, text_.length());
-  CHECK_LE(offset + length_to_prepend, text_.length());
-  if (text_.Is8Bit())
-    output->PushRange(text_.Characters8() + offset, length_to_prepend);
-  else
-    output->PushRange(text_.Characters16() + offset, length_to_prepend);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h
index 9b880d5..dce6a06 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h
@@ -28,14 +28,12 @@
 
 #include "base/optional.h"
 #include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.h"
 #include "third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
 
-class BackwardsTextBuffer;
 class ContainerNode;
 class HTMLElement;
 class Text;
@@ -49,16 +47,11 @@
   // Return properties of the current text.
   unsigned length() const { return text_length_; }
   UChar CharacterAt(unsigned index) const;
+  // TODO(xiaochengh): Rename to |GetText()| as it's used in production code.
   String GetTextForTesting() const;
   void AppendTextToStringBuilder(StringBuilder&,
                                  unsigned position = 0,
                                  unsigned max_length = UINT_MAX) const;
-  void AppendTextTo(ForwardsTextBuffer* output,
-                    unsigned position,
-                    unsigned length_to_append) const;
-  void PrependTextTo(BackwardsTextBuffer* output,
-                     unsigned position,
-                     unsigned length_to_prepend) const;
 
   // Emits code unit relative to |node|.
   void EmitChar16AfterNode(UChar code_unit, const Node& node);
diff --git a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.cc b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.cc
index f4f6724e..ccb0531 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.cc
@@ -33,6 +33,7 @@
 #include "third_party/blink/renderer/platform/text/text_boundaries.h"
 #include "third_party/blink/renderer/platform/text/text_break_iterator_internal_icu.h"
 #include "third_party/blink/renderer/platform/text/unicode_utilities.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/text/character_names.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
@@ -57,6 +58,8 @@
 }
 
 class ICULockableSearcher {
+  STACK_ALLOCATED();
+
  public:
   static UStringSearch* AcquireSearcher() {
     Instance().lock();
diff --git a/third_party/blink/renderer/core/editing/layout_selection_test.cc b/third_party/blink/renderer/core/editing/layout_selection_test.cc
index fb78d31..21510f6d 100644
--- a/third_party/blink/renderer/core/editing/layout_selection_test.cc
+++ b/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -777,7 +777,7 @@
 
   Node* baz = GetDocument().body()->lastChild();
   baz->remove();
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   Selection().CommitAppearanceIfNeeded();
   EXPECT_EQ(
       "BODY, Contain, NotInvalidate \n"
@@ -810,7 +810,7 @@
 
   Element* span_baz = ToElement(GetDocument().body()->lastChild());
   span_baz->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   Selection().CommitAppearanceIfNeeded();
   EXPECT_EQ(
       "BODY, Contain, NotInvalidate \n"
@@ -854,7 +854,7 @@
       GetDocument().body()->firstChild()->GetShadowRoot()->QuerySelector(
           "slot");
   slot->setAttribute("name", "s2");
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   Selection().CommitAppearanceIfNeeded();
   EXPECT_EQ(
       "BODY, Contain, NotInvalidate \n"
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker.h b/third_party/blink/renderer/core/editing/markers/document_marker.h
index 7ac48cc..97d05a10 100644
--- a/third_party/blink/renderer/core/editing/markers/document_marker.h
+++ b/third_party/blink/renderer/core/editing/markers/document_marker.h
@@ -27,6 +27,7 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/graphics/color.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/blink/renderer/platform/wtf/vector_traits.h"
 
@@ -98,6 +99,8 @@
   };
 
   class MarkerTypes {
+    DISALLOW_NEW();
+
    public:
     explicit MarkerTypes(unsigned mask = 0) : mask_(mask) {}
 
diff --git a/third_party/blink/renderer/core/editing/selection_controller.cc b/third_party/blink/renderer/core/editing/selection_controller.cc
index acf54cc..a4f17ec 100644
--- a/third_party/blink/renderer/core/editing/selection_controller.cc
+++ b/third_party/blink/renderer/core/editing/selection_controller.cc
@@ -484,9 +484,9 @@
   if (!target)
     return;
 
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
 
   const PositionWithAffinity& raw_target_position =
       Selection().SelectionHasFocus()
@@ -582,9 +582,9 @@
   if (!this->Selection().IsAvailable())
     return false;
 
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   const SelectionInFlatTree visible_selection =
       CreateVisibleSelection(selection).AsSelection();
 
@@ -1074,9 +1074,9 @@
       drag_start_pos == FlooredIntPoint(event.Event().PositionInRootFrame()) &&
       Selection().ComputeVisibleSelectionInDOMTreeDeprecated().IsRange() &&
       event.Event().button != WebPointerProperties::Button::kRight) {
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited.  See http://crbug.com/590369 for more details.
-    frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    frame_->GetDocument()->UpdateStyleAndLayout();
 
     SelectionInFlatTree::Builder builder;
     Node* node = event.InnerNode();
@@ -1237,9 +1237,9 @@
 
 void SelectionController::PassMousePressEventToSubframe(
     const MouseEventWithHitTestResults& mev) {
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
 
   // If we're clicking into a frame that is selected, the frame will appear
   // greyed out even though we're clicking on the selection.  This looks
diff --git a/third_party/blink/renderer/core/editing/selection_editor.cc b/third_party/blink/renderer/core/editing/selection_editor.cc
index a047b9e..63349454 100644
--- a/third_party/blink/renderer/core/editing/selection_editor.cc
+++ b/third_party/blink/renderer/core/editing/selection_editor.cc
@@ -171,9 +171,17 @@
   if (!node)
     return position;
 #endif
-  if (container.ContainsIncludingHostElements(*node))
-    return Position::FirstPositionInNode(container);
-  return position;
+  if (!container.ContainsIncludingHostElements(*node))
+    return position;
+  if (auto* element = ToElementOrNull(container)) {
+    if (auto* shadow_root = element->GetShadowRoot()) {
+      // Removal of light children does not affect position in the
+      // shadow tree.
+      if (shadow_root->ContainsIncludingHostElements(*node))
+        return position;
+    }
+  }
+  return Position::FirstPositionInNode(container);
 }
 
 void SelectionEditor::NodeChildrenWillBeRemoved(ContainerNode& container) {
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
index 8ef6c30e..2c595d1 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
+++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
@@ -301,9 +301,9 @@
     return;
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame().GetDocument()->UpdateStyleAndLayout();
 
   DocumentLifecycle::DisallowTransitionScope disallow_transition(
       GetFrame().GetDocument()->Lifecycle());
@@ -487,9 +487,9 @@
 
   Document& current_document = *GetFrame().GetDocument();
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  current_document.UpdateStyleAndLayoutIgnorePendingStylesheets();
+  current_document.UpdateStyleAndLayout();
 
   // Dispatch 'beforeinput'.
   Element* const target = FindEventTargetFrom(
@@ -507,9 +507,9 @@
   if (current_document != GetFrame().GetDocument())
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame().GetDocument()->UpdateStyleAndLayout();
 
   if (cancel)
     return;
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
index 56bbb3e..372c3166 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
+++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
@@ -35,7 +35,7 @@
   frame_rect.SetWidth(frame_rect.Width() + 1);
   frame_rect.SetHeight(frame_rect.Height() + 1);
   Page().GetFrameView().SetFrameRect(frame_rect);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 }
 
 TEST_F(SpellCheckerTest, AdvanceToNextMisspellingWithEmptyInputNoCrash) {
diff --git a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
index a0028e4f..aec06ae68 100644
--- a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
+++ b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc
@@ -615,9 +615,9 @@
 
   // TODO(editing-dev): We should check whether |TextSuggestionController| is
   // available or not.
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame().GetDocument()->UpdateStyleAndLayout();
 
   // Dispatch 'beforeinput'.
   Element* const target = FindEventTargetFrom(
@@ -637,9 +637,9 @@
   if (!IsAvailable())
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame().GetDocument()->UpdateStyleAndLayout();
 
   if (is_canceled)
     return;
diff --git a/third_party/blink/renderer/core/editing/web_substring_util.mm b/third_party/blink/renderer/core/editing/web_substring_util.mm
index 0bfeeba..327b82a 100644
--- a/third_party/blink/renderer/core/editing/web_substring_util.mm
+++ b/third_party/blink/renderer/core/editing/web_substring_util.mm
@@ -75,11 +75,9 @@
 
   unsigned position = 0;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of updateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
-  range.StartPosition()
-      .GetDocument()
-      ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  range.StartPosition().GetDocument()->UpdateStyleAndLayout();
 
   for (TextIterator it(range.StartPosition(), range.EndPosition());
        !it.AtEnd() && [string length] < length; it.Advance()) {
@@ -127,11 +125,11 @@
     else
       [attrs removeObjectForKey:NSBackgroundColorAttributeName];
 
-    ForwardsTextBuffer characters;
-    it.CopyTextTo(&characters);
+    String characters = it.GetText().GetTextForTesting();
+    characters.Ensure16Bit();
     NSString* substring =
-        [[[NSString alloc] initWithCharacters:characters.Data()
-                                       length:characters.Size()] autorelease];
+        [[[NSString alloc] initWithCharacters:characters.Characters16()
+                                       length:characters.length()] autorelease];
     [string replaceCharactersInRange:NSMakeRange(position, 0)
                           withString:substring];
     [string setAttributes:attrs range:NSMakeRange(position, num_characters)];
diff --git a/third_party/blink/renderer/core/events/mouse_event.cc b/third_party/blink/renderer/core/events/mouse_event.cc
index 5710cc0..a5bf081 100644
--- a/third_party/blink/renderer/core/events/mouse_event.cc
+++ b/third_party/blink/renderer/core/events/mouse_event.cc
@@ -469,7 +469,7 @@
   float inverse_zoom_factor = 1 / PageZoomFactor(this);
 
   // Must have an updated layout tree for this math to work correctly.
-  target_node->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  target_node->GetDocument().UpdateStyleAndLayout();
 
   // Adjust offsetLocation to be relative to the target's padding box.
   if (const LayoutObject* layout_object = FindTargetLayoutObject(target_node)) {
diff --git a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
index 57c2ad0..f502778 100644
--- a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
@@ -98,9 +98,9 @@
   if (WebPlugin* plugin = FocusedPluginIfInputMethodSupported())
     return plugin->FinishComposingText(selection_behavior);
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return GetInputMethodController().FinishComposingText(
       selection_behavior == WebInputMethodController::kKeepSelection
@@ -129,9 +129,9 @@
                             blink::mojom::SelectionMenuBehavior::kHide);
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return GetInputMethodController().CommitText(
       text, ImeTextSpanVectorBuilder::Build(ime_text_spans),
@@ -162,7 +162,7 @@
   Element* editable =
       GetFrame()->Selection().RootEditableElementOrDocumentElement();
 
-  editable->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  editable->GetDocument().UpdateStyleAndLayout();
 
   return PlainTextRange::Create(*editable, range);
 }
@@ -190,9 +190,9 @@
 }
 
 WebRange WebInputMethodControllerImpl::GetSelectionOffsets() const {
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return GetFrame()->GetInputMethodController().GetSelectionOffsets();
 }
diff --git a/third_party/blink/renderer/core/exported/web_meaningful_layouts_test.cc b/third_party/blink/renderer/core/exported/web_meaningful_layouts_test.cc
index b296e44d..e407156 100644
--- a/third_party/blink/renderer/core/exported/web_meaningful_layouts_test.cc
+++ b/third_party/blink/renderer/core/exported/web_meaningful_layouts_test.cc
@@ -213,26 +213,6 @@
   EXPECT_TRUE(GetDocument().IsRenderingReady());
 }
 
-// A pending stylesheet in the body is not render-blocking and should not
-// be considered a pending stylesheet if a layout is triggered before it loads.
-TEST_F(WebMeaningfulLayoutsTest, LayoutWithPendingScriptBlockingStylesheet) {
-  SimRequest main_resource("https://example.com/index.html", "text/html");
-  SimSubresourceRequest style_resource("https://example.com/style.css",
-                                       "text/css");
-
-  LoadURL("https://example.com/index.html");
-
-  main_resource.Complete(
-      "<html><head></head><body>"
-      "<link rel=\"stylesheet\" href=\"style.css\">"
-      "</body></html>");
-
-  GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
-  EXPECT_FALSE(GetDocument().DidLayoutWithPendingStylesheets());
-
-  style_resource.Complete("");
-}
-
 // A pending import in the head is render-blocking and will be treated like
 // a pending stylesheet if a layout is triggered before it loads.
 TEST_F(WebMeaningfulLayoutsTest, LayoutWithPendingImportInHead) {
diff --git a/third_party/blink/renderer/core/exported/web_node_test.cc b/third_party/blink/renderer/core/exported/web_node_test.cc
index 0e034621..641e40a 100644
--- a/third_party/blink/renderer/core/exported/web_node_test.cc
+++ b/third_party/blink/renderer/core/exported/web_node_test.cc
@@ -80,7 +80,6 @@
 
   WebNode input_node(GetDocument().getElementById("focusable"));
   EXPECT_FALSE(input_node.IsFocusable());
-  EXPECT_FALSE(GetDocument().HasNodesWithPlaceholderStyle());
 
   main_resource.Finish();
   css_resource.Complete("dummy {}");
diff --git a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
index 2de0484..33688e3 100644
--- a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
@@ -348,8 +348,6 @@
     // worker script fetch on the worker thread.
     // TODO(nhiroki): Currently |address_space| and |origin_trial_tokens| are
     // not updated after worker script fetch. Update them.
-    // TODO(crbug.com/937191): Make SharedWorkerGlobalScope use CSP list from
-    // the response of the main script.
     auto creation_params = std::make_unique<GlobalScopeCreationParams>(
         script_request_url_, script_type,
         OffMainThreadWorkerScriptFetchOption::kEnabled, name_,
@@ -361,7 +359,9 @@
         nullptr /* origin_trial_tokens */, devtools_worker_token_,
         std::make_unique<WorkerSettings>(document->GetFrame()->GetSettings()),
         kV8CacheOptionsDefault, nullptr /* worklet_module_response_map */,
-        std::move(pending_interface_provider_));
+        std::move(pending_interface_provider_), BeginFrameProviderParams(),
+        nullptr /* parent_feature_policy */, base::UnguessableToken(),
+        GlobalScopeCSPApplyMode::kUseResponseCSP);
     StartWorkerThread(std::move(creation_params), script_request_url_,
                       String() /* source_code */, *outside_settings_object);
     return;
diff --git a/third_party/blink/renderer/core/exported/web_surrounding_text.cc b/third_party/blink/renderer/core/exported/web_surrounding_text.cc
index 7533776..37f1698 100644
--- a/third_party/blink/renderer/core/exported/web_surrounding_text.cc
+++ b/third_party/blink/renderer/core/exported/web_surrounding_text.cc
@@ -43,9 +43,9 @@
 EphemeralRange ComputeRangeFromFrameSelection(WebLocalFrame* frame) {
   LocalFrame* web_frame = To<WebLocalFrameImpl>(frame)->GetFrame();
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  web_frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  web_frame->GetDocument()->UpdateStyleAndLayout();
 
   return web_frame->Selection()
       .ComputeVisibleSelectionInDOMTree()
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 8dd8d5e..33d211b 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -273,7 +273,7 @@
   return web_view.get();
 }
 
-void WebView::UpdateVisitedLinkState(unsigned long long link_hash) {
+void WebView::UpdateVisitedLinkState(uint64_t link_hash) {
   Page::VisitedStateChanged(link_hash);
 }
 
@@ -1875,10 +1875,9 @@
       // Finish an ongoing composition to delete the composition node.
       if (focused_frame->GetInputMethodController().HasComposition()) {
         // TODO(editing-dev): The use of
-        // updateStyleAndLayoutIgnorePendingStylesheets needs to be audited.
+        // UpdateStyleAndLayout needs to be audited.
         // See http://crbug.com/590369 for more details.
-        focused_frame->GetDocument()
-            ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+        focused_frame->GetDocument()->UpdateStyleAndLayout();
 
         focused_frame->GetInputMethodController().FinishComposingText(
             InputMethodController::kKeepSelection);
@@ -2087,7 +2086,7 @@
   if (!element || !IsElementEditable(element))
     return false;
 
-  element->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  element->GetDocument().UpdateStyleAndLayout();
 
   LayoutObject* layout_object = element->GetLayoutObject();
   if (!layout_object)
diff --git a/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc b/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
index 2b4e3f2..e4f83c6 100644
--- a/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
+++ b/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
@@ -256,8 +256,7 @@
   // script that touched offsetTop in the child frame.
   auto* child_frame =
       ToHTMLIFrameElement(GetDocument().getElementById("frame"));
-  child_frame->contentDocument()
-      ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  child_frame->contentDocument()->UpdateStyleAndLayout();
 
   auto frame2 = Compositor().BeginFrame();
 
diff --git a/third_party/blink/renderer/core/frame/dom_visual_viewport.cc b/third_party/blink/renderer/core/frame/dom_visual_viewport.cc
index f1fbd9ac..3193bcc 100644
--- a/third_party/blink/renderer/core/frame/dom_visual_viewport.cc
+++ b/third_party/blink/renderer/core/frame/dom_visual_viewport.cc
@@ -91,7 +91,7 @@
   if (!view || !view->LayoutViewport())
     return 0;
 
-  frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame->GetDocument()->UpdateStyleAndLayout();
   float viewport_x = page->GetVisualViewport().GetScrollOffset().Width() +
                      view->LayoutViewport()->GetScrollOffset().Width();
   return AdjustForAbsoluteZoom::AdjustScroll(viewport_x,
@@ -111,7 +111,7 @@
   if (!view || !view->LayoutViewport())
     return 0;
 
-  frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame->GetDocument()->UpdateStyleAndLayout();
   float viewport_y = page->GetVisualViewport().GetScrollOffset().Height() +
                      view->LayoutViewport()->GetScrollOffset().Height();
   return AdjustForAbsoluteZoom::AdjustScroll(viewport_y,
@@ -125,7 +125,7 @@
 
   if (!frame->IsMainFrame()) {
     // Update layout to ensure scrollbars are up-to-date.
-    frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    frame->GetDocument()->UpdateStyleAndLayout();
     auto* scrollable_area = frame->View()->LayoutViewport();
     float width =
         scrollable_area->VisibleContentRect(kExcludeScrollbars).Width();
@@ -146,7 +146,7 @@
 
   if (!frame->IsMainFrame()) {
     // Update layout to ensure scrollbars are up-to-date.
-    frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    frame->GetDocument()->UpdateStyleAndLayout();
     auto* scrollable_area = frame->View()->LayoutViewport();
     float height =
         scrollable_area->VisibleContentRect(kExcludeScrollbars).Height();
diff --git a/third_party/blink/renderer/core/frame/find_in_page.cc b/third_party/blink/renderer/core/frame/find_in_page.cc
index cbebae1..7f842f2 100644
--- a/third_party/blink/renderer/core/frame/find_in_page.cc
+++ b/third_party/blink/renderer/core/frame/find_in_page.cc
@@ -166,9 +166,7 @@
 
   // Up-to-date, clean tree is required for finding text in page, since it
   // relies on TextIterator to look over the text.
-  frame_->GetFrame()
-      ->GetDocument()
-      ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return EnsureTextFinder().Find(identifier, search_text, options,
                                  wrap_within_frame, active_now);
diff --git a/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc b/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc
index fbb4717..c9fef790 100644
--- a/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc
+++ b/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc
@@ -63,7 +63,7 @@
   // second iteration.
   for (int i = 0; i < 2; i++) {
     // Update various sizes including contentsSize, scrollHeight, etc.
-    document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    document->UpdateStyleAndLayout();
 
     auto* layout_view = document->GetLayoutView();
     if (!layout_view)
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index de8d95f..c9d47e3 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -759,7 +759,7 @@
 
   // Up-to-date, clean tree is required for finding text in page, since it
   // relies on TextIterator to look over the text.
-  document()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document()->UpdateStyleAndLayout();
 
   // FIXME (13016): Support searchInFrames and showDialog
   FindOptions options =
@@ -822,14 +822,13 @@
   // after a layout, perform one now so queries during page load will use the
   // up to date viewport.
   if (page->GetSettings().GetViewportEnabled() && GetFrame()->IsMainFrame())
-    document()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    document()->UpdateStyleAndLayout();
 
   // FIXME: This is potentially too much work. We really only need to know the
   // dimensions of the parent frame's layoutObject.
   if (Frame* parent = GetFrame()->Tree().Parent()) {
     if (auto* parent_local_frame = DynamicTo<LocalFrame>(parent))
-      parent_local_frame->GetDocument()
-          ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+      parent_local_frame->GetDocument()->UpdateStyleAndLayout();
   }
 
   return document()->View()->Size();
@@ -895,7 +894,7 @@
   if (!view)
     return 0;
 
-  document()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document()->UpdateStyleAndLayout();
 
   // TODO(bokan): This is wrong when the document.rootScroller is non-default.
   // crbug.com/505516.
@@ -912,7 +911,7 @@
   if (!view)
     return 0;
 
-  document()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document()->UpdateStyleAndLayout();
 
   // TODO(bokan): This is wrong when the document.rootScroller is non-default.
   // crbug.com/505516.
@@ -1004,7 +1003,7 @@
   if (!IsCurrentlyDisplayedInFrame())
     return;
 
-  document()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document()->UpdateStyleAndLayout();
 
   LocalFrameView* view = GetFrame()->View();
   if (!view)
@@ -1067,7 +1066,7 @@
   // clamped, which is never the case for (0, 0).
   if (!scroll_to_options->hasLeft() || !scroll_to_options->hasTop() ||
       scroll_to_options->left() || scroll_to_options->top()) {
-    document()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    document()->UpdateStyleAndLayout();
   }
 
   double scaled_x = 0.0;
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index c6cc53b..b338366 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -832,7 +832,7 @@
       kSubtreeStyleChange,
       StyleChangeReasonForTracing::Create(style_change_reason::kZoom));
   if (View() && View()->DidFirstLayout())
-    document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    document->UpdateStyleAndLayout();
 }
 
 void LocalFrame::DeviceScaleFactorChanged() {
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index a9fd51b..eac5b899 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2096,7 +2096,7 @@
        min_depth != ResizeObserverController::kDepthBottom;
        min_depth = resize_controller.GatherObservations(min_depth)) {
     resize_controller.DeliverObservations();
-    GetFrame().GetDocument()->UpdateStyleAndLayout();
+    GetFrame().GetDocument()->UpdateStyleAndLayout(Document::IsNotForcedLayout);
   }
 
   if (resize_controller.SkippedObservations()) {
diff --git a/third_party/blink/renderer/core/frame/local_frame_view_test.cc b/third_party/blink/renderer/core/frame/local_frame_view_test.cc
index eec1190..a5b9786 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view_test.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view_test.cc
@@ -309,7 +309,7 @@
   // Force a layout.
   anchor->style()->setProperty(&GetDocument(), "display", "block", String(),
                                ASSERT_NO_EXCEPTION);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   EXPECT_EQ(GetDocument().body(), GetDocument().ActiveElement())
       << "Active element changed due to layout while rendering is blocked";
@@ -349,7 +349,7 @@
   // Mark the top-level document for layout and then force layout. This will
   // cause the layout tree in the <object> object to be built.
   GetDocument().View()->SetNeedsLayout();
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   svg_resource.Finish();
 }
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc
index 0f69691..acbb8f2d 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport.cc
+++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -127,8 +127,7 @@
     const auto& device_emulation_transform =
         GetChromeClient()->GetDeviceEmulationTransform();
     if (!device_emulation_transform.IsIdentity()) {
-      TransformPaintPropertyNode::State state;
-      state.matrix = device_emulation_transform;
+      TransformPaintPropertyNode::State state{device_emulation_transform};
       if (!device_emulation_transform_node_) {
         device_emulation_transform_node_ = TransformPaintPropertyNode::Create(
             *transform_parent, std::move(state));
@@ -164,8 +163,8 @@
   }
 
   {
-    TransformPaintPropertyNode::State state;
-    state.matrix.Scale(Scale());
+    TransformPaintPropertyNode::State state{
+        TransformationMatrix().Scale(Scale())};
     state.compositor_element_id = GetCompositorElementId();
 
     if (!scale_transform_node_) {
@@ -210,11 +209,10 @@
   }
 
   {
-    TransformPaintPropertyNode::State state;
     ScrollOffset scroll_position = GetScrollOffset();
-    state.matrix.Translate(-scroll_position.Width(), -scroll_position.Height());
+    TransformPaintPropertyNode::State state{
+        FloatSize(-scroll_position.Width(), -scroll_position.Height())};
     state.scroll = scroll_node_;
-    state.is_identity_or_2d_translation = true;
     if (!translation_transform_node_) {
       translation_transform_node_ = TransformPaintPropertyNode::Create(
           *scale_transform_node_, std::move(state));
@@ -282,12 +280,12 @@
   ScrollableArea::Trace(visitor);
 }
 
-void VisualViewport::UpdateStyleAndLayoutIgnorePendingStylesheets() const {
+void VisualViewport::UpdateStyleAndLayout() const {
   if (!MainFrame())
     return;
 
   if (Document* document = MainFrame()->GetDocument())
-    document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    document->UpdateStyleAndLayout();
 }
 
 void VisualViewport::EnqueueScrollEvent() {
@@ -403,7 +401,7 @@
   if (!MainFrame())
     return 0;
 
-  UpdateStyleAndLayoutIgnorePendingStylesheets();
+  UpdateStyleAndLayout();
 
   return VisibleRect().X() / MainFrame()->PageZoomFactor();
 }
@@ -412,18 +410,18 @@
   if (!MainFrame())
     return 0;
 
-  UpdateStyleAndLayoutIgnorePendingStylesheets();
+  UpdateStyleAndLayout();
 
   return VisibleRect().Y() / MainFrame()->PageZoomFactor();
 }
 
 double VisualViewport::Width() const {
-  UpdateStyleAndLayoutIgnorePendingStylesheets();
+  UpdateStyleAndLayout();
   return VisibleWidthCSSPx();
 }
 
 double VisualViewport::Height() const {
-  UpdateStyleAndLayoutIgnorePendingStylesheets();
+  UpdateStyleAndLayout();
   return VisibleHeightCSSPx();
 }
 
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.h b/third_party/blink/renderer/core/frame/visual_viewport.h
index 92597c1..174d7524 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport.h
+++ b/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -282,8 +282,7 @@
  private:
   bool DidSetScaleOrLocation(float scale, const FloatPoint& location);
 
-
-  void UpdateStyleAndLayoutIgnorePendingStylesheets() const;
+  void UpdateStyleAndLayout() const;
 
   void EnqueueScrollEvent();
   void EnqueueResizeEvent();
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
index 5bd7181..53ee997 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc
+++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -376,8 +376,8 @@
     UpdateAllLifecyclePhases();
     EXPECT_EQ(TransformationMatrix().Scale(2),
               visual_viewport.GetPageScaleNode()->Matrix());
-    EXPECT_EQ(TransformationMatrix().Translate(0, -300),
-              visual_viewport.GetScrollTranslationNode()->Matrix());
+    EXPECT_EQ(FloatSize(0, -300),
+              visual_viewport.GetScrollTranslationNode()->Translation2D());
     EXPECT_EQ(TransformationMatrix().Scale(2).Translate(0, -300),
               GeometryMapper::SourceToDestinationProjection(
                   *visual_viewport.GetScrollTranslationNode(),
@@ -401,8 +401,8 @@
     UpdateAllLifecyclePhases();
     EXPECT_EQ(TransformationMatrix().Scale(4),
               visual_viewport.GetPageScaleNode()->Matrix());
-    EXPECT_EQ(TransformationMatrix().Translate(0, -75),
-              visual_viewport.GetScrollTranslationNode()->Matrix());
+    EXPECT_EQ(FloatSize(0, -75),
+              visual_viewport.GetScrollTranslationNode()->Translation2D());
     EXPECT_EQ(TransformationMatrix().Scale(4).Translate(0, -75),
               GeometryMapper::SourceToDestinationProjection(
                   *visual_viewport.GetScrollTranslationNode(),
@@ -466,8 +466,8 @@
     UpdateAllLifecyclePhases();
     EXPECT_EQ(TransformationMatrix().Scale(2),
               visual_viewport.GetPageScaleNode()->Matrix());
-    EXPECT_EQ(TransformationMatrix().Translate(-150, 0),
-              visual_viewport.GetScrollTranslationNode()->Matrix());
+    EXPECT_EQ(FloatSize(-150, 0),
+              visual_viewport.GetScrollTranslationNode()->Translation2D());
     EXPECT_EQ(TransformationMatrix().Scale(2).Translate(-150, 0),
               GeometryMapper::SourceToDestinationProjection(
                   *visual_viewport.GetScrollTranslationNode(),
@@ -490,8 +490,8 @@
     UpdateAllLifecyclePhases();
     EXPECT_EQ(TransformationMatrix().Scale(4),
               visual_viewport.GetPageScaleNode()->Matrix());
-    EXPECT_EQ(TransformationMatrix().Translate(-150, 0),
-              visual_viewport.GetScrollTranslationNode()->Matrix());
+    EXPECT_EQ(FloatSize(-150, 0),
+              visual_viewport.GetScrollTranslationNode()->Translation2D());
     EXPECT_EQ(TransformationMatrix().Scale(4).Translate(-150, 0),
               GeometryMapper::SourceToDestinationProjection(
                   *visual_viewport.GetScrollTranslationNode(),
@@ -2557,8 +2557,8 @@
   UpdateAllLifecyclePhases();
 
   VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
-  EXPECT_EQ(visual_viewport.GetDeviceEmulationTransformNode()->Matrix(),
-            emulation_transform);
+  EXPECT_EQ(visual_viewport.GetDeviceEmulationTransformNode()->Translation2D(),
+            emulation_transform.To2DTranslation());
 
   // Set an identity device emulation transform and ensure the transform
   // paint property node is cleared.
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index 9ef2f75..d11eed3 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -574,10 +574,9 @@
       // Finish an ongoing composition to delete the composition node.
       if (focused_frame->GetInputMethodController().HasComposition()) {
         // TODO(editing-dev): The use of
-        // updateStyleAndLayoutIgnorePendingStylesheets needs to be audited.
+        // UpdateStyleAndLayout needs to be audited.
         // See http://crbug.com/590369 for more details.
-        focused_frame->GetDocument()
-            ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+        focused_frame->GetDocument()->UpdateStyleAndLayout();
 
         focused_frame->GetInputMethodController().FinishComposingText(
             InputMethodController::kKeepSelection);
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 6f19b08f..fc72259 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -970,9 +970,9 @@
 }
 
 void WebLocalFrameImpl::ReplaceSelection(const WebString& text) {
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   GetFrame()->GetEditor().ReplaceSelection(text);
 }
@@ -1009,9 +1009,9 @@
   if (!editable)
     return false;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
-  editable->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  editable->GetDocument().UpdateStyleAndLayout();
 
   const EphemeralRange range =
       PlainTextRange(location, location + length).CreateRange(*editable);
@@ -1098,9 +1098,9 @@
     return false;
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
 
   if (selection.ComputeVisibleSelectionInDOMTree()
           .ToNormalizedEphemeralRange()
@@ -1158,9 +1158,9 @@
   if (GetFrame()->GetWebPluginContainer())
     return;
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   GetFrame()->GetSpellChecker().ReplaceMisspelledRange(text);
 }
@@ -1190,9 +1190,9 @@
 }
 
 WebRange WebLocalFrameImpl::SelectionRange() const {
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return GetFrame()
       ->Selection()
@@ -1207,9 +1207,9 @@
   if (plugin_container)
     return plugin_container->Plugin()->SelectionAsText();
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   String text = GetFrame()->Selection().SelectedText(
       TextIteratorBehavior::EmitsObjectReplacementCharacterBehavior());
@@ -1226,10 +1226,10 @@
   if (plugin_container)
     return plugin_container->Plugin()->SelectionAsMarkup();
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
   // Selection normalization and markup generation require clean layout.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return GetFrame()->Selection().SelectedHTMLForClipboard();
 }
@@ -1237,9 +1237,9 @@
 bool WebLocalFrameImpl::SelectWordAroundCaret() {
   TRACE_EVENT0("blink", "WebLocalFrameImpl::selectWordAroundCaret");
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
   return GetFrame()->Selection().SelectWordAroundCaret();
 }
 
@@ -1254,9 +1254,9 @@
     blink::mojom::SelectionMenuBehavior selection_menu_behavior) {
   TRACE_EVENT0("blink", "WebLocalFrameImpl::selectRange");
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   const EphemeralRange& range = web_range.CreateEphemeralRange(GetFrame());
   if (range.IsNull())
@@ -1287,9 +1287,9 @@
 }
 
 WebString WebLocalFrameImpl::RangeAsText(const WebRange& web_range) {
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   DocumentLifecycle::DisallowTransitionScope disallow_transition(
       GetFrame()->GetDocument()->Lifecycle());
@@ -1302,9 +1302,9 @@
 void WebLocalFrameImpl::MoveRangeSelectionExtent(const WebPoint& point) {
   TRACE_EVENT0("blink", "WebLocalFrameImpl::moveRangeSelectionExtent");
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   GetFrame()->Selection().MoveRangeSelectionExtent(
       GetFrame()->View()->ViewportToFrame(point));
@@ -1316,9 +1316,9 @@
     WebFrame::TextGranularity granularity) {
   TRACE_EVENT0("blink", "WebLocalFrameImpl::moveRangeSelection");
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   blink::TextGranularity blink_granularity = blink::TextGranularity::kCharacter;
   if (granularity == WebFrame::kWordGranularity)
@@ -1332,9 +1332,9 @@
 void WebLocalFrameImpl::MoveCaretSelection(const WebPoint& point_in_viewport) {
   TRACE_EVENT0("blink", "WebLocalFrameImpl::moveCaretSelection");
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
   const IntPoint point_in_contents =
       GetFrame()->View()->ViewportToFrame(point_in_viewport);
   GetFrame()->Selection().MoveCaretSelection(point_in_contents);
@@ -1343,9 +1343,9 @@
 bool WebLocalFrameImpl::SetEditableSelectionOffsets(int start, int end) {
   TRACE_EVENT0("blink", "WebLocalFrameImpl::setEditableSelectionOffsets");
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return GetFrame()->GetInputMethodController().SetEditableSelectionOffsets(
       PlainTextRange(start, end));
@@ -1362,9 +1362,9 @@
   InputMethodController& input_method_controller =
       GetFrame()->GetInputMethodController();
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   input_method_controller.SetCompositionFromExistingText(
       ImeTextSpanVectorBuilder::Build(ime_text_spans), composition_start,
@@ -1380,9 +1380,9 @@
     return;
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   GetFrame()->GetInputMethodController().ExtendSelectionAndDelete(before,
                                                                   after);
@@ -1395,9 +1395,9 @@
     return;
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   GetFrame()->GetInputMethodController().DeleteSurroundingText(before, after);
 }
@@ -1410,9 +1410,9 @@
     return;
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   GetFrame()->GetInputMethodController().DeleteSurroundingTextInCodePoints(
       before, after);
@@ -2321,9 +2321,9 @@
     return;
   }
 
-  // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   GetFrame()->GetEditor().CopyImage(result);
 }
diff --git a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
index b25f10d..b47b0d1 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
@@ -659,7 +659,7 @@
 }
 
 bool DateTimeEditElement::FocusOnNextFocusableField(wtf_size_t start_index) {
-  GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayoutTree();
   for (wtf_size_t field_index = start_index; field_index < fields_.size();
        ++field_index) {
     if (fields_[field_index]->IsFocusable()) {
@@ -682,7 +682,7 @@
   const wtf_size_t start_field_index = FieldIndexOf(field);
   if (start_field_index == kInvalidFieldIndex)
     return false;
-  GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayoutTree();
   wtf_size_t field_index = start_field_index;
   while (field_index > 0) {
     --field_index;
diff --git a/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc b/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc
index 4b3b9b8..4c521c3a 100644
--- a/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc
+++ b/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc
@@ -39,7 +39,7 @@
         "style='display:none;'><option><option>");
     GetDocument().body()->AppendChild(element, ASSERT_NO_EXCEPTION);
     owner_element_ = element;
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
   }
 
   Persistent<HTMLSelectElement> owner_element_;
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.cc b/third_party/blink/renderer/core/html/forms/html_form_element.cc
index 87acaea..1d0d6ea 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_element.cc
@@ -232,7 +232,7 @@
 
   // Needs to update layout now because we'd like to call isFocusable(), which
   // has !layoutObject()->needsLayout() assertion.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // Focus on the first focusable control and show a validation message.
   for (const auto& unhandled : unhandled_invalid_controls) {
diff --git a/third_party/blink/renderer/core/html/forms/html_label_element.cc b/third_party/blink/renderer/core/html/forms/html_label_element.cc
index 0c286917..7500247 100644
--- a/third_party/blink/renderer/core/html/forms/html_label_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_label_element.cc
@@ -195,7 +195,7 @@
 
     processing_click_ = true;
 
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
     if (element->IsMouseFocusable()) {
       // If the label is *not* selected, or if the click happened on
       // selection of label, only then focus the control element.
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc
index 53de70b..244e066 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -908,7 +908,7 @@
   // OptionRemoved() makes sure option_to_scroll_to_ doesn't have an option with
   // another owner.
   DCHECK_EQ(option->OwnerSelectElement(), this);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (!GetLayoutObject() || !GetLayoutObject()->IsListBox())
     return;
   LayoutRect bounds = option->BoundingBoxForScrollIntoView();
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
index ae617bb..cc07317 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -332,9 +332,9 @@
   // that case, and nothing in the text field will be removed.
   unsigned selection_length = 0;
   if (IsFocused()) {
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited.  See http://crbug.com/590369 for more details.
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
     selection_length = ComputeLengthForAPIValue(
         GetDocument().GetFrame()->Selection().SelectedText());
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.cc b/third_party/blink/renderer/core/html/forms/listed_element.cc
index 0de55bc..00728ae 100644
--- a/third_party/blink/renderer/core/html/forms/listed_element.cc
+++ b/third_party/blink/renderer/core/html/forms/listed_element.cc
@@ -480,7 +480,7 @@
   // Update layout now before calling IsFocusable(), which has
   // !LayoutObject()->NeedsLayout() assertion.
   HTMLElement& element = ToHTMLElement(*this);
-  element.GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  element.GetDocument().UpdateStyleAndLayout();
   if (element.IsFocusable()) {
     ShowValidationMessage();
     return false;
diff --git a/third_party/blink/renderer/core/html/forms/radio_input_type.cc b/third_party/blink/renderer/core/html/forms/radio_input_type.cc
index f2653bd1..9ff420db 100644
--- a/third_party/blink/renderer/core/html/forms/radio_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/radio_input_type.cc
@@ -109,7 +109,7 @@
                      : (key == "ArrowDown" || key == "ArrowRight");
 
   // Force layout for isFocusable() in findNextFocusableRadioButtonInGroup().
-  document.UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document.UpdateStyleAndLayout();
 
   // We can only stay within the form's children if the form hasn't been demoted
   // to a leaf because of malformed HTML.
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
index 73b0dc5d..26b1e5b 100644
--- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -420,9 +420,9 @@
   // that case, and nothing in the text field will be removed.
   unsigned selection_length = 0;
   if (GetElement().IsFocused()) {
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited.  See http://crbug.com/590369 for more details.
-    GetElement().GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetElement().GetDocument().UpdateStyleAndLayout();
 
     selection_length = GetElement()
                            .GetDocument()
diff --git a/third_party/blink/renderer/core/html/html_dialog_element.cc b/third_party/blink/renderer/core/html/html_dialog_element.cc
index 4a604879..71fc70b 100644
--- a/third_party/blink/renderer/core/html/html_dialog_element.cc
+++ b/third_party/blink/renderer/core/html/html_dialog_element.cc
@@ -125,7 +125,7 @@
 
 void HTMLDialogElement::ForceLayoutForCentering() {
   centering_mode_ = kNeedsCentering;
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   if (centering_mode_ == kNeedsCentering)
     SetNotCentered();
 }
@@ -143,7 +143,7 @@
 
   // The layout must be updated here because setFocusForDialog calls
   // Element::isFocusable, which requires an up-to-date layout.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   SetFocusForDialog(this);
 }
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc
index 63ecb28d..1210e66 100644
--- a/third_party/blink/renderer/core/html/html_element.cc
+++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -1398,7 +1398,7 @@
 }
 
 Element* HTMLElement::unclosedOffsetParent() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   LayoutObject* layout_object = GetLayoutObject();
   if (!layout_object)
diff --git a/third_party/blink/renderer/core/html/html_iframe_element_test.cc b/third_party/blink/renderer/core/html/html_iframe_element_test.cc
index f445107..caf0d967 100644
--- a/third_party/blink/renderer/core/html/html_iframe_element_test.cc
+++ b/third_party/blink/renderer/core/html/html_iframe_element_test.cc
@@ -230,10 +230,7 @@
 // Sandboxing an iframe should result in a container policy with an item for
 // each sandbox feature
 TEST_F(HTMLIFrameElementTest, SandboxAttributeContainerPolicy) {
-  // TODO(iclelland): Remove the runtime feature override when this feature
-  // becomes experimental or stable.
-  ASSERT_FALSE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled());
-  RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(true);
+  ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled());
 
   Document* document = Document::CreateForTest();
   const KURL document_url("http://example.com");
@@ -249,17 +246,12 @@
       frame_element->ContainerPolicy();
 
   EXPECT_EQ(expected_number_of_sandbox_features, container_policy.size());
-  // TODO: Check that each item is present.
-  RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(false);
 }
 
 // Test that the allow attribute on a sandboxed frame results in a container
 // policy which is restricted to a unique origin.
 TEST_F(HTMLIFrameElementTest, CrossOriginSandboxAttributeContainerPolicy) {
-  // TODO(iclelland): Remove the runtime feature override when this feature
-  // becomes experimental or stable.
-  ASSERT_FALSE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled());
-  RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(true);
+  ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled());
   Document* document = Document::CreateForTest();
   const KURL document_url("http://example.com");
   document->SetURL(document_url);
@@ -289,17 +281,13 @@
   EXPECT_GE(min_value, item.fallback_value);
   EXPECT_LE(max_value, item.opaque_value);
   EXPECT_EQ(0UL, item.values.size());
-  RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(false);
 }
 
 // Test that the allow attribute on a sandboxed frame with the allow-same-origin
 // flag results in a container policy which is restricted to the origin of the
 // containing document.
 TEST_F(HTMLIFrameElementTest, SameOriginSandboxAttributeContainerPolicy) {
-  // TODO(iclelland): Remove the runtime feature override when this feature
-  // becomes experimental or stable.
-  ASSERT_FALSE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled());
-  RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(true);
+  ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled());
   Document* document = Document::CreateForTest();
   const KURL document_url("http://example.com");
   document->SetURL(document_url);
@@ -331,7 +319,6 @@
   EXPECT_EQ(1UL, item.values.size());
   EXPECT_FALSE(item.values.begin()->first.opaque());
   EXPECT_EQ("http://example.net", item.values.begin()->first.Serialize());
-  RuntimeEnabledFeatures::SetFeaturePolicyForSandboxEnabled(false);
 }
 
 // Test the ConstructContainerPolicy method when no attributes are set on the
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc
index b21dbf7..027123a 100644
--- a/third_party/blink/renderer/core/html/html_image_element.cc
+++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -480,7 +480,7 @@
 
 unsigned HTMLImageElement::width() {
   if (InActiveDocument())
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
   if (!GetLayoutObject()) {
     // check the attribute first for an explicit pixel value
@@ -501,7 +501,7 @@
 
 unsigned HTMLImageElement::height() {
   if (InActiveDocument())
-    GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+    GetDocument().UpdateStyleAndLayout();
 
   if (!GetLayoutObject()) {
     // check the attribute first for an explicit pixel value
@@ -638,7 +638,7 @@
 }
 
 int HTMLImageElement::x() const {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   LayoutObject* r = GetLayoutObject();
   if (!r)
     return 0;
@@ -649,7 +649,7 @@
 }
 
 int HTMLImageElement::y() const {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   LayoutObject* r = GetLayoutObject();
   if (!r)
     return 0;
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc
index e9312233..8a2a3140 100644
--- a/third_party/blink/renderer/core/html/html_plugin_element.cc
+++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -483,7 +483,7 @@
   // Needs to load the plugin immediatedly because this function is called
   // when JavaScript code accesses the plugin.
   // FIXME: Check if dispatching events here is safe.
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
   GetDocument().View()->FlushAnyPendingPostLayoutTasks();
 
   return ExistingLayoutEmbeddedContent();
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
index a002311d..39b39d81 100644
--- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc
+++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -1120,14 +1120,13 @@
 }
 
 void HTMLDocumentParser::DidAddPendingStylesheetInBody() {
-  // When in-body CSS doesn't block painting, the parser needs to pause so that
+  // In-body CSS doesn't block painting. The parser needs to pause so that
   // the DOM doesn't include any elements that may depend on the CSS for style.
   // The stylesheet can be added and removed during the parsing of a single
   // token so don't actually set the bit to block parsing here, just track
   // the state of the added sheet in case it does persist beyond a single
   // token.
-  if (RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled())
-    added_pending_stylesheet_in_body_ = true;
+  added_pending_stylesheet_in_body_ = true;
 }
 
 void HTMLDocumentParser::DidLoadAllBodyStylesheets() {
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc
index 0ffee8d..f8e606d 100644
--- a/third_party/blink/renderer/core/input/event_handler.cc
+++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -1855,7 +1855,7 @@
   // Since |Document::performMouseEventHitTest()| modifies layout tree for
   // setting hover element, we need to update layout tree for requirement of
   // |SelectionController::sendContextMenuEvent()|.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
 
   GetSelectionController().SendContextMenuEvent(mev, position_in_contents);
 
@@ -1868,9 +1868,9 @@
 }
 
 static bool ShouldShowContextMenuAtSelection(const FrameSelection& selection) {
-  // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): The use of UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  selection.GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  selection.GetDocument().UpdateStyleAndLayout();
 
   const VisibleSelection& visible_selection =
       selection.ComputeVisibleSelectionInDOMTree();
diff --git a/third_party/blink/renderer/core/input/event_handler_test.cc b/third_party/blink/renderer/core/input/event_handler_test.cc
index 94f14ed..1651195 100644
--- a/third_party/blink/renderer/core/input/event_handler_test.cc
+++ b/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -1123,8 +1123,7 @@
       GetDocument().GetFrame()->GetEventHandler().IsMousePositionUnknown());
   auto* child_frame =
       ToHTMLIFrameElement(GetDocument().getElementById("frame"));
-  child_frame->contentDocument()
-      ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  child_frame->contentDocument()->UpdateStyleAndLayout();
   EXPECT_TRUE(GetDocument().GetFrame()->Tree().FirstChild());
   EXPECT_FALSE(To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild())
                    ->GetEventHandler()
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc
index 93ebf4d..8bb8c4a 100644
--- a/third_party/blink/renderer/core/input/mouse_event_manager.cc
+++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -487,10 +487,10 @@
   }
 
   // The layout needs to be up to date to determine if an element is focusable.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
 
   Element* element = element_under_mouse_;
-  for (; element; element = FlatTreeTraversal::ParentElement(*element)) {
+  for (; element; element = element->ParentOrShadowHostElement()) {
     if (element->IsFocusable() && element->IsFocusedElementInDocument())
       return WebInputEventResult::kNotHandled;
     if (element->IsMouseFocusable())
@@ -674,7 +674,7 @@
   ResetDragSource();
   CancelFakeMouseMoveEvent();
 
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
 
   bool single_click = event.Event().click_count <= 1;
 
@@ -994,7 +994,7 @@
   // TODO(editing-dev): The use of
   // updateStyleAndLayoutIgnorePendingStylesheets needs to be audited.  See
   // http://crbug.com/590369 for more details.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
   if (IsInPasswordField(
           frame_->Selection().ComputeVisibleSelectionInDOMTree().Start()))
     return false;
diff --git a/third_party/blink/renderer/core/input/scroll_manager.cc b/third_party/blink/renderer/core/input/scroll_manager.cc
index a87e8ae..1424472 100644
--- a/third_party/blink/renderer/core/input/scroll_manager.cc
+++ b/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -242,7 +242,7 @@
 
   Document& document = node->GetDocument();
 
-  document.UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document.UpdateStyleAndLayout();
 
   std::deque<DOMNodeId> scroll_chain;
   std::unique_ptr<ScrollStateData> scroll_state_data =
@@ -332,7 +332,7 @@
   // The layout needs to be up to date to determine if we can scroll. We may be
   // here because of an onLoad event, in which case the final layout hasn't been
   // performed yet.
-  frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_->GetDocument()->UpdateStyleAndLayout();
   // FIXME: enable scroll customization in this case. See crbug.com/410974.
   if (LogicalScroll(direction, granularity, starting_node, mouse_press_node))
     return true;
@@ -351,7 +351,7 @@
     return;
 
   if (scroll_state.deltaX() || scroll_state.deltaY())
-    frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    frame_->GetDocument()->UpdateStyleAndLayout();
 
   DCHECK(!current_scroll_chain_.empty());
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
index 4553a958..be1d26e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -1251,7 +1251,7 @@
   if (!node->IsElementNode())
     return Response::Error("Node is not an Element");
   Element* element = ToElement(node);
-  element->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  element->GetDocument().UpdateStyleAndLayout();
   if (!element->IsFocusable())
     return Response::Error("Element is not focusable");
   element->focus();
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index 58f53f4..39c6aac 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -1146,7 +1146,7 @@
   LocalFrame* main_frame = inspected_frames_->Root();
   VisualViewport& visual_viewport = main_frame->GetPage()->GetVisualViewport();
 
-  main_frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  main_frame->GetDocument()->UpdateStyleAndLayout();
 
   IntRect visible_contents =
       main_frame->View()->LayoutViewport()->VisibleContentRect();
diff --git a/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc b/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc
index 6f87c32..d2b8e76 100644
--- a/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc
+++ b/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc
@@ -25,7 +25,7 @@
   document.View()->ViewportSizeChanged(true, true);
   document.View()->UpdateAllLifecyclePhases(
       DocumentLifecycle::LifecycleUpdateReason::kTest);
-  document.UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document.UpdateStyleAndLayout();
   document.UpdateStyleAndLayoutTree();
 
   postponed_transition_scope.reset();
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
index 8d304c2ac..4ec1641 100644
--- a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
@@ -75,6 +75,12 @@
     return;
   }
 
+  if (!layout_ctor->IsConstructor()) {
+    exception_state.ThrowTypeError(
+        "The provided callback is not a constructor.");
+    return;
+  }
+
   v8::Local<v8::Context> current_context =
       layout_ctor->GetIsolate()->GetCurrentContext();
 
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.h b/third_party/blink/renderer/core/layout/layout_block_flow.h
index 9f500a39..d757b3f1 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.h
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.h
@@ -64,7 +64,6 @@
 class NGConstraintSpace;
 class NGLayoutResult;
 class NGOffsetMapping;
-class NGPaintFragment;
 class NGPhysicalFragment;
 
 struct NGInlineNodeData;
@@ -457,7 +456,6 @@
   virtual void ResetNGInlineNodeData() {}
   virtual void ClearNGInlineNodeData() {}
   virtual bool HasNGInlineNodeData() const { return false; }
-  virtual NGPaintFragment* PaintFragment() const { return nullptr; }
   virtual scoped_refptr<const NGLayoutResult> CachedLayoutResult(
       const NGConstraintSpace&,
       const NGBreakToken*);
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
index 11827668..44e5bda 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -94,6 +94,31 @@
     max_preferred_logical_width += margin;
     if (!IsColumnFlow()) {
       max_logical_width += max_preferred_logical_width;
+
+      EOverflow overflow = StyleRef().IsHorizontalWritingMode()
+                               ? child->StyleRef().OverflowX()
+                               : child->StyleRef().OverflowY();
+      const Length& main_axis_length = IsHorizontalFlow()
+                                           ? child->StyleRef().Width()
+                                           : child->StyleRef().Height();
+      // This code experimentally implements the proposal in
+      // https://github.com/w3c/csswg-drafts/issues/1865
+      // to see if it is web-compatible.
+      if (overflow != EOverflow::kVisible && !main_axis_length.IsFixed()) {
+        LayoutUnit border_and_padding =
+            StyleRef().IsHorizontalWritingMode()
+                ? child->BorderAndPaddingWidth() +
+                      child->VerticalScrollbarWidth()
+                : child->BorderAndPaddingHeight() +
+                      child->HorizontalScrollbarHeight();
+        if (min_preferred_logical_width != margin + border_and_padding) {
+          min_preferred_logical_width = margin + border_and_padding;
+          UseCounter::Count(
+              GetDocument(),
+              WebFeature::kFlexboxWithOverflowFlexItemIntrinsicSize);
+        }
+      }
+
       if (IsMultiline()) {
         // For multiline, the min preferred width is if you put a break between
         // each item.
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.h b/third_party/blink/renderer/core/layout/layout_flexible_box.h
index 3df70c5..e8565c9 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.h
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.h
@@ -162,7 +162,6 @@
                                  const Length& flex_basis) const;
   bool NeedToStretchChildLogicalHeight(const LayoutBox& child) const;
   bool ChildHasIntrinsicMainAxisSize(const LayoutBox& child) const;
-  EOverflow MainAxisOverflowForChild(const LayoutBox& child) const;
   EOverflow CrossAxisOverflowForChild(const LayoutBox& child) const;
   void CacheChildMainSize(const LayoutBox& child);
   bool CanAvoidLayoutForNGChild(const LayoutBox& child) const;
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 376712e..96baa17 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -4187,9 +4187,8 @@
       // This mapping happens for inline box whose LayoutObject is a LayoutBlock
       // whose VisualRect is not in the same transform space as the inline box.
       // For now this happens for EllipsisBox only.
-      DCHECK(scroll_translation->IsIdentityOr2DTranslation());
       auto float_visual_rect = FloatRect(visual_rect);
-      float_visual_rect.Move(-scroll_translation->Matrix().To2DTranslation());
+      float_visual_rect.Move(-scroll_translation->Translation2D());
       return EnclosingLayoutRect(float_visual_rect);
     }
   }
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 705157a..1368cd3 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1222,6 +1222,10 @@
   void SetFloating(bool is_floating) { bitfields_.SetFloating(is_floating); }
   void SetInline(bool is_inline) { bitfields_.SetIsInline(is_inline); }
 
+  // Returns the associated |NGPaintFragment|. When this is not a |nullptr|,
+  // this is the root of an inline formatting context, laid out by LayoutNG.
+  virtual NGPaintFragment* PaintFragment() const { return nullptr; }
+
   void SetIsInLayoutNGInlineFormattingContext(bool);
   virtual NGPaintFragment* FirstInlineFragment() const { return nullptr; }
   virtual void SetFirstInlineFragment(NGPaintFragment*) {}
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index d629d04..33f5dfad 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -290,8 +290,6 @@
       // produces one fragment but legacy produces multiple text boxes broken at
       // collapsed whitespaces. We break the fragment at collapsed whitespaces
       // to match the legacy output.
-      // TODO(xiaochengh): We need to report boxes of ::before/after text, which
-      // |NGOffsetMapping| doesn't support.
       for (const NGOffsetMappingUnit& unit :
            mapping->GetMappingUnitsForTextContentOffsetRange(
                text_fragment.StartOffset(), text_fragment.EndOffset())) {
@@ -311,10 +309,21 @@
         rect.MoveBy(fragment->InlineOffsetToContainerBox().ToLayoutPoint());
 
         // Compute start of the legacy text box.
-        const base::Optional<unsigned> box_start =
-            CaretOffsetForPosition(mapping->GetLastPosition(clamped_start));
-        DCHECK(box_start.has_value());
-        results.push_back(TextBoxInfo{rect, box_start.value(), box_length});
+        if (unit.AssociatedNode()) {
+          // In case of |text_| comes from DOM node.
+          const base::Optional<unsigned> box_start =
+              CaretOffsetForPosition(mapping->GetLastPosition(clamped_start));
+          DCHECK(box_start.has_value());
+          results.push_back(TextBoxInfo{rect, *box_start, box_length});
+          continue;
+        }
+        // Handle CSS generated content, e.g. ::before/::after
+        const NGOffsetMappingUnit* const mapping_unit =
+            mapping->GetLastMappingUnit(clamped_start);
+        DCHECK(mapping_unit) << this << " at " << clamped_start;
+        const unsigned dom_offset =
+            mapping_unit->ConvertTextContentToLastDOMOffset(clamped_start);
+        results.push_back(TextBoxInfo{rect, dom_offset, box_length});
       }
     }
     return results;
diff --git a/third_party/blink/renderer/core/layout/layout_text_test.cc b/third_party/blink/renderer/core/layout/layout_text_test.cc
index 5755b39..324f7e9 100644
--- a/third_party/blink/renderer/core/layout/layout_text_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_test.cc
@@ -6,6 +6,7 @@
 
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/pseudo_element.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/editing/selection_template.h"
 #include "third_party/blink/renderer/core/editing/testing/selection_sample.h"
@@ -360,6 +361,84 @@
   EXPECT_TRUE(GetBasicText()->ContainsCaretOffset(7));  // "foo\nbar|"
 }
 
+TEST_P(ParameterizedLayoutTextTest, GetTextBoxInfoWithCollapsedWhiteSpace) {
+  LoadAhem();
+  SetBodyInnerHTML(R"HTML(
+    <style>pre { font: 10px/1 Ahem; white-space: pre-line; }</style>
+    <pre id=target> abc  def
+    xyz   </pre>)HTML");
+  const LayoutText& layout_text = *GetLayoutTextById("target");
+
+  const auto& results = layout_text.GetTextBoxInfo();
+
+  ASSERT_EQ(4u, results.size());
+
+  EXPECT_EQ(1u, results[0].dom_start_offset);
+  EXPECT_EQ(4u, results[0].dom_length);
+  EXPECT_EQ(LayoutRect(LayoutPoint(0, 0), LayoutSize(40, 10)),
+            results[0].local_rect);
+
+  EXPECT_EQ(6u, results[1].dom_start_offset);
+  EXPECT_EQ(3u, results[1].dom_length);
+  EXPECT_EQ(LayoutRect(LayoutPoint(40, 0), LayoutSize(30, 10)),
+            results[1].local_rect);
+
+  EXPECT_EQ(9u, results[2].dom_start_offset);
+  EXPECT_EQ(1u, results[2].dom_length);
+  EXPECT_EQ(LayoutRect(LayoutPoint(70, 0), LayoutSize(0, 10)),
+            results[2].local_rect);
+
+  EXPECT_EQ(14u, results[3].dom_start_offset);
+  EXPECT_EQ(3u, results[3].dom_length);
+  EXPECT_EQ(LayoutRect(LayoutPoint(0, 10), LayoutSize(30, 10)),
+            results[3].local_rect);
+}
+
+TEST_P(ParameterizedLayoutTextTest, GetTextBoxInfoWithGeneratedContent) {
+  LoadAhem();
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      div::before { content: '  a   bc'; }
+      div::first-letter { font-weight: bold; }
+      div { font: 10px/1 Ahem; }
+    </style>
+    <div id="target">XYZ</div>)HTML");
+  const Element& target = *GetElementById("target");
+  const Element& before =
+      *GetElementById("target")->GetPseudoElement(kPseudoIdBefore);
+  const LayoutText& layout_text_xyz =
+      *ToLayoutText(target.firstChild()->GetLayoutObject());
+  const LayoutText& layout_text_remaining =
+      ToLayoutText(*before.GetLayoutObject()->SlowLastChild());
+  const LayoutText& layout_text_first_letter =
+      *layout_text_remaining.GetFirstLetterPart();
+
+  auto boxes_xyz = layout_text_xyz.GetTextBoxInfo();
+  EXPECT_EQ(1u, boxes_xyz.size());
+  EXPECT_EQ(0u, boxes_xyz[0].dom_start_offset);
+  EXPECT_EQ(3u, boxes_xyz[0].dom_length);
+  EXPECT_EQ(LayoutRect(LayoutPoint(40, 0), LayoutSize(30, 10)),
+            boxes_xyz[0].local_rect);
+
+  auto boxes_first_letter = layout_text_first_letter.GetTextBoxInfo();
+  EXPECT_EQ(1u, boxes_first_letter.size());
+  EXPECT_EQ(2u, boxes_first_letter[0].dom_start_offset);
+  EXPECT_EQ(1u, boxes_first_letter[0].dom_length);
+  EXPECT_EQ(LayoutRect(LayoutPoint(0, 0), LayoutSize(10, 10)),
+            boxes_first_letter[0].local_rect);
+
+  auto boxes_remaining = layout_text_remaining.GetTextBoxInfo();
+  EXPECT_EQ(2u, boxes_remaining.size());
+  EXPECT_EQ(0u, boxes_remaining[0].dom_start_offset);
+  EXPECT_EQ(1u, boxes_remaining[0].dom_length) << "two spaces to one space";
+  EXPECT_EQ(LayoutRect(LayoutPoint(10, 0), LayoutSize(10, 10)),
+            boxes_remaining[0].local_rect);
+  EXPECT_EQ(3u, boxes_remaining[1].dom_start_offset);
+  EXPECT_EQ(2u, boxes_remaining[1].dom_length);
+  EXPECT_EQ(LayoutRect(LayoutPoint(20, 0), LayoutSize(20, 10)),
+            boxes_remaining[1].local_rect);
+}
+
 TEST_P(ParameterizedLayoutTextTest,
        IsBeforeAfterNonCollapsedCharacterNoLineWrap) {
   // Basic tests
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc
index c4152b7..ad2a5ee 100644
--- a/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -539,7 +539,7 @@
     // compute the subpixel offset of painting at this point in a a bottom-up
     // walk, round to the enclosing int rect, which will enclose the actual
     // visible rect.
-    rect = LayoutRect(EnclosingIntRect(rect));
+    rect.ExpandEdgesToPixelBoundaries();
 
     // Adjust for frame border.
     rect.Move(obj->PhysicalContentBoxOffset());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/empty_offset_mapping_builder.h b/third_party/blink/renderer/core/layout/ng/inline/empty_offset_mapping_builder.h
index 0d83ede..b691848 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/empty_offset_mapping_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/empty_offset_mapping_builder.h
@@ -9,8 +9,6 @@
 
 namespace blink {
 
-class LayoutObject;
-
 // A mock class providing all APIs of an offset mapping builder, but not doing
 // anything. For templates functions/classes that can optionally create an
 // offset mapping, this mock class is passed to create an instantiation that
@@ -31,8 +29,6 @@
   void CollapseTrailingSpace(unsigned) {}
   void Composite(const EmptyOffsetMappingBuilder&) {}
   void Concatenate(const EmptyOffsetMappingBuilder&) {}
-  void EnterInline(const LayoutObject&) {}
-  void ExitInline(const LayoutObject&) {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(EmptyOffsetMappingBuilder);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
index f6beb0e..bda9d0b 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -980,8 +980,6 @@
     LayoutObject* node) {
   DCHECK(node);
 
-  mapping_builder_.EnterInline(*node);
-
   // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-table
   const ComputedStyle* style = node->Style();
   if (style->RtlOrdering() == EOrder::kLogical) {
@@ -1056,8 +1054,6 @@
     boxes_.pop_back();
 
   Exit(node);
-
-  mapping_builder_.ExitInline(*node);
 }
 
 template <typename OffsetMappingBuilder>
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
index 9ef582897..8cf5f32 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
@@ -26,14 +26,6 @@
   return object.IsLayoutBlockFlow() && !object.IsLayoutFlowThread();
 }
 
-// Returns true if |node| has style 'display:inline' and can have descendants
-// in the inline layout.
-bool IsNonAtomicInline(const Node& node) {
-  const LayoutObject* layout_object = node.GetLayoutObject();
-  return layout_object && layout_object->IsInline() &&
-         !layout_object->IsText() && !layout_object->IsAtomicInlineLevel();
-}
-
 Position CreatePositionForOffsetMapping(const Node& node, unsigned dom_offset) {
   if (node.IsTextNode()) {
     // 'text-transform' may make the rendered text length longer than the
@@ -97,13 +89,13 @@
 }
 
 NGOffsetMappingUnit::NGOffsetMappingUnit(NGOffsetMappingUnitType type,
-                                         const Node& node,
+                                         const LayoutObject& layout_object,
                                          unsigned dom_start,
                                          unsigned dom_end,
                                          unsigned text_content_start,
                                          unsigned text_content_end)
     : type_(type),
-      owner_(&node),
+      layout_object_(&layout_object),
       dom_start_(dom_start),
       dom_end_(dom_end),
       text_content_start_(text_content_start),
@@ -111,8 +103,20 @@
 
 NGOffsetMappingUnit::~NGOffsetMappingUnit() = default;
 
+const Node* NGOffsetMappingUnit::AssociatedNode() const {
+  if (const auto* text_fragment = ToLayoutTextFragmentOrNull(layout_object_))
+    return text_fragment->AssociatedTextNode();
+  return layout_object_->GetNode();
+}
+
+const Node& NGOffsetMappingUnit::GetOwner() const {
+  const Node* const node = AssociatedNode();
+  DCHECK(node) << layout_object_;
+  return *node;
+}
+
 bool NGOffsetMappingUnit::Concatenate(const NGOffsetMappingUnit& other) {
-  if (owner_ != other.owner_)
+  if (layout_object_ != other.layout_object_)
     return false;
   if (type_ != other.type_ || type_ == NGOffsetMappingUnitType::kExpanded)
     return false;
@@ -122,7 +126,7 @@
     return false;
   // Don't merge first letter and remaining text
   if (const LayoutTextFragment* text_fragment =
-          ToLayoutTextFragmentOrNull(owner_->GetLayoutObject())) {
+          ToLayoutTextFragmentOrNull(layout_object_)) {
     // TODO(layout-dev): Fix offset calculation for text-transform
     if (text_fragment->IsRemainingTextLayoutObject() &&
         other.dom_start_ == text_fragment->TextStartOffset())
@@ -189,7 +193,9 @@
   if (!position.IsBeforeAnchor() && !position.IsAfterAnchor())
     return false;
   const LayoutObject* layout_object = position.AnchorNode()->GetLayoutObject();
-  return layout_object && layout_object->IsInline();
+  if (!layout_object || !layout_object->IsInline())
+    return false;
+  return layout_object->IsText() || layout_object->IsAtomicInlineLevel();
 }
 
 // static
@@ -244,7 +250,6 @@
 const NGOffsetMappingUnit* NGOffsetMapping::GetMappingUnitForPosition(
     const Position& position) const {
   DCHECK(NGOffsetMapping::AcceptsPosition(position));
-  DCHECK(!IsNonAtomicInline(*position.AnchorNode())) << position;
   const auto node_and_offset = ToNodeOffsetPair(position);
   const Node& node = node_and_offset.first;
   const unsigned offset = node_and_offset.second;
@@ -277,16 +282,6 @@
   unsigned range_end;
   std::tie(range_start, range_end) = ranges_.at(&node);
 
-  if (IsNonAtomicInline(node)) {
-    if (start_offset == end_offset)
-      return UnitVector();
-
-    UnitVector result;
-    result.AppendRange(units_.begin() + range_start,
-                       units_.begin() + range_end);
-    return result;
-  }
-
   if (range_start == range_end || units_[range_start].DOMStart() > end_offset ||
       units_[range_end - 1].DOMEnd() < start_offset)
     return UnitVector();
@@ -316,7 +311,7 @@
         unit.ConvertDOMOffsetToTextContent(clamped_start);
     const unsigned clamped_text_content_end =
         unit.ConvertDOMOffsetToTextContent(clamped_end);
-    result.emplace_back(unit.GetType(), unit.GetOwner(), clamped_start,
+    result.emplace_back(unit.GetType(), unit.GetLayoutObject(), clamped_start,
                         clamped_end, clamped_text_content_start,
                         clamped_text_content_end);
   }
@@ -333,6 +328,23 @@
   return {units_.begin() + it->value.first, units_.begin() + it->value.second};
 }
 
+NGMappingUnitRange NGOffsetMapping::GetMappingUnitsForLayoutObject(
+    const LayoutObject& layout_object) const {
+  const auto* begin =
+      std::find_if(units_.begin(), units_.end(),
+                   [&layout_object](const NGOffsetMappingUnit& unit) {
+                     return unit.GetLayoutObject() == layout_object;
+                   });
+  DCHECK_NE(begin, units_.end());
+  const auto* end =
+      std::find_if(std::next(begin), units_.end(),
+                   [&layout_object](const NGOffsetMappingUnit& unit) {
+                     return unit.GetLayoutObject() != layout_object;
+                   });
+  DCHECK_LT(begin, end);
+  return {begin, end};
+}
+
 NGMappingUnitRange NGOffsetMapping::GetMappingUnitsForTextContentOffsetRange(
     unsigned start,
     unsigned end) const {
@@ -362,16 +374,6 @@
 base::Optional<unsigned> NGOffsetMapping::GetTextContentOffset(
     const Position& position) const {
   DCHECK(NGOffsetMapping::AcceptsPosition(position)) << position;
-  if (IsNonAtomicInline(*position.AnchorNode())) {
-    auto iter = ranges_.find(position.AnchorNode());
-    if (iter == ranges_.end())
-      return base::nullopt;
-    DCHECK_NE(iter->value.first, iter->value.second) << position;
-    if (position.IsBeforeAnchor())
-      return units_[iter->value.first].TextContentStart();
-    return units_[iter->value.second - 1].TextContentEnd();
-  }
-
   const NGOffsetMappingUnit* unit = GetMappingUnitForPosition(position);
   if (!unit)
     return base::nullopt;
@@ -381,7 +383,6 @@
 Position NGOffsetMapping::StartOfNextNonCollapsedContent(
     const Position& position) const {
   DCHECK(NGOffsetMapping::AcceptsPosition(position)) << position;
-  DCHECK(!IsNonAtomicInline(*position.AnchorNode())) << position;
   const NGOffsetMappingUnit* unit = GetMappingUnitForPosition(position);
   if (!unit)
     return Position();
@@ -403,7 +404,6 @@
 Position NGOffsetMapping::EndOfLastNonCollapsedContent(
     const Position& position) const {
   DCHECK(NGOffsetMapping::AcceptsPosition(position)) << position;
-  DCHECK(!IsNonAtomicInline(*position.AnchorNode())) << position;
   const NGOffsetMappingUnit* unit = GetMappingUnitForPosition(position);
   if (!unit)
     return Position();
@@ -427,7 +427,6 @@
 bool NGOffsetMapping::IsBeforeNonCollapsedContent(
     const Position& position) const {
   DCHECK(NGOffsetMapping::AcceptsPosition(position));
-  DCHECK(!IsNonAtomicInline(*position.AnchorNode())) << position;
   const NGOffsetMappingUnit* unit = GetMappingUnitForPosition(position);
   const unsigned offset = ToNodeOffsetPair(position).second;
   return unit && offset < unit->DOMEnd() &&
@@ -437,7 +436,6 @@
 bool NGOffsetMapping::IsAfterNonCollapsedContent(
     const Position& position) const {
   DCHECK(NGOffsetMapping::AcceptsPosition(position));
-  DCHECK(!IsNonAtomicInline(*position.AnchorNode())) << position;
   const auto node_and_offset = ToNodeOffsetPair(position);
   const Node& node = node_and_offset.first;
   const unsigned offset = node_and_offset.second;
@@ -454,7 +452,6 @@
 base::Optional<UChar> NGOffsetMapping::GetCharacterBefore(
     const Position& position) const {
   DCHECK(NGOffsetMapping::AcceptsPosition(position));
-  DCHECK(!IsNonAtomicInline(*position.AnchorNode())) << position;
   base::Optional<unsigned> text_content_offset = GetTextContentOffset(position);
   if (!text_content_offset || !*text_content_offset)
     return base::nullopt;
@@ -471,18 +468,23 @@
                          return unit.TextContentEnd() < offset;
                        });
   DCHECK_NE(result, units_.end());
-  if (result->TextContentStart() > offset)
-    return {};
+  // Skip CSS generated content, e.g. "content" property in ::before/::after.
+  while (!result->AssociatedNode()) {
+    result = std::next(result);
+    if (result == units_.end() || result->TextContentStart() > offset)
+      return {};
+  }
   const Node& node = result->GetOwner();
   const unsigned dom_offset =
       result->ConvertTextContentToFirstDOMOffset(offset);
   return CreatePositionForOffsetMapping(node, dom_offset);
 }
 
-Position NGOffsetMapping::GetLastPosition(unsigned offset) const {
+const NGOffsetMappingUnit* NGOffsetMapping::GetLastMappingUnit(
+    unsigned offset) const {
   // Find the last unit where |unit.TextContentStart() <= offset|
   if (units_.IsEmpty() || units_.front().TextContentStart() > offset)
-    return {};
+    return nullptr;
   const NGOffsetMappingUnit* result =
       std::upper_bound(units_.begin(), units_.end(), offset,
                        [](unsigned offset, const NGOffsetMappingUnit& unit) {
@@ -491,7 +493,22 @@
   DCHECK_NE(result, units_.begin());
   result = std::prev(result);
   if (result->TextContentEnd() < offset)
+    return nullptr;
+  return result;
+}
+
+Position NGOffsetMapping::GetLastPosition(unsigned offset) const {
+  const NGOffsetMappingUnit* result = GetLastMappingUnit(offset);
+  if (!result)
     return {};
+  // Skip CSS generated content, e.g. "content" property in ::before/::after.
+  while (!result->AssociatedNode()) {
+    if (result == units_.begin())
+      return {};
+    result = std::prev(result);
+    if (result->TextContentEnd() < offset)
+      return {};
+  }
   const Node& node = result->GetOwner();
   const unsigned dom_offset = result->ConvertTextContentToLastDOMOffset(offset);
   return CreatePositionForOffsetMapping(node, dom_offset);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
index 4b30f2a..05f2b03 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
@@ -43,15 +43,22 @@
 
  public:
   NGOffsetMappingUnit(NGOffsetMappingUnitType,
-                      const Node&,
+                      const LayoutObject&,
                       unsigned dom_start,
                       unsigned dom_end,
                       unsigned text_content_start,
                       unsigned text_content_end);
   ~NGOffsetMappingUnit();
 
+  // Returns associated node for this unit or null if this unit is associated
+  // to generated content.
+  const Node* AssociatedNode() const;
   NGOffsetMappingUnitType GetType() const { return type_; }
-  const Node& GetOwner() const { return *owner_; }
+  const LayoutObject& GetLayoutObject() const { return *layout_object_; }
+  // Returns |Node| for this unit. If this unit comes from CSS generated
+  // content, we can't use this function.
+  // TODO(yosin): We should rename |GetOwner()| to |NonPseudoNode()|.
+  const Node& GetOwner() const;
   unsigned DOMStart() const { return dom_start_; }
   unsigned DOMEnd() const { return dom_end_; }
   unsigned TextContentStart() const { return text_content_start_; }
@@ -69,7 +76,10 @@
  private:
   NGOffsetMappingUnitType type_ = NGOffsetMappingUnitType::kIdentity;
 
-  Persistent<const Node> owner_;
+  const LayoutObject* layout_object_;
+  // TODO(yosin): We should rename |dom_start_| and |dom_end_| to appropriate
+  // names since |layout_object_| is for generated text, these offsets are
+  // offset in |LayoutText::text_| instead of DOM node.
   unsigned dom_start_;
   unsigned dom_end_;
   unsigned text_content_start_;
@@ -122,7 +132,7 @@
 
   // NGOffsetMapping APIs only accept the following positions:
   // 1. Offset-in-anchor in a text node;
-  // 2. Before/After-anchor of an inline-level node.
+  // 2. Before/After-anchor of an atomic inline or a text-like node like <br>.
   static bool AcceptsPosition(const Position&);
 
   // Returns the mapping object of the inline formatting context laying out the
@@ -158,10 +168,20 @@
   // same anchor node.
   UnitVector GetMappingUnitsForDOMRange(const EphemeralRange&) const;
 
-  // Returns all NGOffsetMappingUnits associated to |node|. Note: |node| should
-  // have associated mapping.
+  // Returns all NGOffsetMappingUnits associated to |node|. When |node| is
+  // laid out with ::first-letter, this function returns both first-letter part
+  // and remaining part. Note: |node| should have associated mapping.
   NGMappingUnitRange GetMappingUnitsForNode(const Node& node) const;
 
+  // Returns all NGOffsetMappingUnits associated to |layout_object|. This
+  // function works even if |layout_object| is for CSS generated content
+  // ("content" property in ::before/::after, etc.)
+  // Note: Unlike |GetMappingUnitsForNode()|, this function returns units
+  // for first-letter or remaining part only instead of both parts.
+  // Note: |layout_object| should have associated mapping.
+  NGMappingUnitRange GetMappingUnitsForLayoutObject(
+      const LayoutObject& layout_object) const;
+
   // Returns the text content offset corresponding to the given position.
   // Returns nullopt when the position is not laid out in this context.
   base::Optional<unsigned> GetTextContentOffset(const Position&) const;
@@ -210,11 +230,14 @@
   // Returns all NGOffsetMappingUnits whose text content ranges has non-empty
   // (but possibly collapsed) intersection with (start, end). Note that units
   // that only "touch" |start| or |end| are excluded.
+  // Note: Returned range may include units for generated content.
   NGMappingUnitRange GetMappingUnitsForTextContentOffsetRange(
       unsigned start,
       unsigned end) const;
 
-  // TODO(xiaochengh): Add offset-to-DOM APIs skipping generated contents.
+  // Returns the last |NGOffsetMappingUnit| where |TextContentStart() >= offset|
+  // including unit for generated content.
+  const NGOffsetMappingUnit* GetLastMappingUnit(unsigned offset) const;
 
   // ------ APIs inspecting the text content string ------
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
index a84f879..f04e45d 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h"
 
+#include <utility>
 #include "third_party/blink/renderer/core/layout/layout_text.h"
 #include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h"
@@ -13,23 +14,15 @@
 
 namespace {
 
-// Returns the associated non-pseudo node from |layout_object|, handling
-// first-letter text fragments.
-const Node* GetAssociatedNode(const LayoutObject* layout_object) {
-  if (!layout_object)
-    return nullptr;
-  if (const auto* text_fragment = ToLayoutTextFragmentOrNull(layout_object))
-    return text_fragment->AssociatedTextNode();
-  return layout_object->GetNode();
-}
-
 // Returns 0 unless |layout_object| is the remaining text of a node styled with
 // ::first-letter, in which case it returns the start offset of the remaining
-// text.
+// text. When ::first-letter is applied to generated content, e.g. ::before,
+// remaining part contains text for remaining part only instead of all text.
 unsigned GetAssociatedStartOffset(const LayoutObject* layout_object) {
-  if (const auto* text_fragment = ToLayoutTextFragmentOrNull(layout_object))
-    return text_fragment->Start();
-  return 0;
+  const auto* text_fragment = ToLayoutTextFragmentOrNull(layout_object);
+  if (!text_fragment || !text_fragment->AssociatedTextNode())
+    return 0;
+  return text_fragment->Start();
 }
 
 }  // namespace
@@ -40,13 +33,12 @@
     NGOffsetMappingBuilder* builder,
     const LayoutObject* node)
     : builder_(builder),
-      layout_object_auto_reset_(&builder->current_node_,
-                                GetAssociatedNode(node)),
+      layout_object_auto_reset_(&builder->current_layout_object_, node),
       appended_length_auto_reset_(&builder->current_offset_,
                                   GetAssociatedStartOffset(node)) {
   builder_->has_open_unit_ = false;
 #if DCHECK_IS_ON()
-  if (!builder_->current_node_)
+  if (!builder_->current_layout_object_)
     return;
   // We allow at most one scope with non-null node at any time.
   DCHECK(!builder->has_nonnull_node_scope_);
@@ -57,7 +49,7 @@
 NGOffsetMappingBuilder::SourceNodeScope::~SourceNodeScope() {
   builder_->has_open_unit_ = false;
 #if DCHECK_IS_ON()
-  if (builder_->current_node_)
+  if (builder_->current_layout_object_)
     builder_->has_nonnull_node_scope_ = false;
 #endif
 }
@@ -76,12 +68,12 @@
   current_offset_ += length;
   destination_length_ += length;
 
-  if (!current_node_)
+  if (!current_layout_object_)
     return;
 
   if (has_open_unit_ &&
       mapping_units_.back().GetType() == NGOffsetMappingUnitType::kIdentity) {
-    DCHECK_EQ(mapping_units_.back().GetOwner(), current_node_);
+    DCHECK_EQ(mapping_units_.back().GetLayoutObject(), current_layout_object_);
     DCHECK_EQ(mapping_units_.back().DOMEnd(), dom_start);
     mapping_units_.back().dom_end_ += length;
     mapping_units_.back().text_content_end_ += length;
@@ -89,7 +81,7 @@
   }
 
   mapping_units_.emplace_back(NGOffsetMappingUnitType::kIdentity,
-                              *current_node_, dom_start, dom_end,
+                              *current_layout_object_, dom_start, dom_end,
                               text_content_start, text_content_end);
   has_open_unit_ = true;
 }
@@ -102,19 +94,19 @@
   const unsigned text_content_end = text_content_start;
   current_offset_ += length;
 
-  if (!current_node_)
+  if (!current_layout_object_)
     return;
 
   if (has_open_unit_ &&
       mapping_units_.back().GetType() == NGOffsetMappingUnitType::kCollapsed) {
-    DCHECK_EQ(mapping_units_.back().GetOwner(), current_node_);
+    DCHECK_EQ(mapping_units_.back().GetLayoutObject(), current_layout_object_);
     DCHECK_EQ(mapping_units_.back().DOMEnd(), dom_start);
     mapping_units_.back().dom_end_ += length;
     return;
   }
 
   mapping_units_.emplace_back(NGOffsetMappingUnitType::kCollapsed,
-                              *current_node_, dom_start, dom_end,
+                              *current_layout_object_, dom_start, dom_end,
                               text_content_start, text_content_end);
   has_open_unit_ = true;
 }
@@ -142,26 +134,28 @@
   // <= space_offset <
   // container_unit->TextContentEnd()
   DCHECK_EQ(NGOffsetMappingUnitType::kIdentity, container_unit->GetType());
-  const Node& node = container_unit->GetOwner();
+  const LayoutObject& layout_object = container_unit->GetLayoutObject();
   unsigned dom_offset = container_unit->DOMStart();
   unsigned text_content_offset = container_unit->TextContentStart();
   unsigned offset_to_collapse = space_offset - text_content_offset;
 
   Vector<NGOffsetMappingUnit, 3> new_units;
   if (offset_to_collapse) {
-    new_units.emplace_back(NGOffsetMappingUnitType::kIdentity, node, dom_offset,
-                           dom_offset + offset_to_collapse, text_content_offset,
+    new_units.emplace_back(NGOffsetMappingUnitType::kIdentity, layout_object,
+                           dom_offset, dom_offset + offset_to_collapse,
+                           text_content_offset,
                            text_content_offset + offset_to_collapse);
     dom_offset += offset_to_collapse;
     text_content_offset += offset_to_collapse;
   }
-  new_units.emplace_back(NGOffsetMappingUnitType::kCollapsed, node, dom_offset,
-                         dom_offset + 1, text_content_offset,
+  new_units.emplace_back(NGOffsetMappingUnitType::kCollapsed, layout_object,
+                         dom_offset, dom_offset + 1, text_content_offset,
                          text_content_offset);
   ++dom_offset;
   if (dom_offset < container_unit->DOMEnd()) {
-    new_units.emplace_back(NGOffsetMappingUnitType::kIdentity, node, dom_offset,
-                           container_unit->DOMEnd(), text_content_offset,
+    new_units.emplace_back(NGOffsetMappingUnitType::kIdentity, layout_object,
+                           dom_offset, container_unit->DOMEnd(),
+                           text_content_offset,
                            container_unit->TextContentEnd() - 1);
   }
 
@@ -169,28 +163,15 @@
   unsigned position = std::distance(mapping_units_.begin(), container_unit);
   mapping_units_.EraseAt(position);
   mapping_units_.InsertVector(position, new_units);
-  ShiftRanges(position, new_units.size() - 1);
   unsigned new_unit_end = position + new_units.size();
   while (new_unit_end && new_unit_end < mapping_units_.size() &&
          mapping_units_[new_unit_end - 1].Concatenate(
              mapping_units_[new_unit_end])) {
     mapping_units_.EraseAt(new_unit_end);
-    ShiftRanges(new_unit_end, -1);
   }
   while (position && position < mapping_units_.size() &&
          mapping_units_[position - 1].Concatenate(mapping_units_[position])) {
     mapping_units_.EraseAt(position);
-    ShiftRanges(position, -1);
-  }
-}
-
-void NGOffsetMappingBuilder::ShiftRanges(unsigned position, int delta) {
-  for (auto& range : unit_ranges_) {
-    auto& pair = range.value;
-    if (pair.first > position)
-      pair.first += delta;
-    if (pair.second > position)
-      pair.second += delta;
   }
 }
 
@@ -202,15 +183,23 @@
 NGOffsetMapping NGOffsetMappingBuilder::Build() {
   // All mapping units are already built. Scan them to build mapping ranges.
   for (unsigned range_start = 0; range_start < mapping_units_.size();) {
-    const Node* node = &mapping_units_[range_start].GetOwner();
-    // Units of the same node should be consecutive in the mapping function,
-    // If not, the layout structure should be already broken.
-    DCHECK(!unit_ranges_.Contains(node)) << node;
+    const LayoutObject& layout_object =
+        mapping_units_[range_start].GetLayoutObject();
     unsigned range_end = range_start + 1;
-    while (range_end < mapping_units_.size() &&
-           mapping_units_[range_end].GetOwner() == node)
-      ++range_end;
-    unit_ranges_.insert(node, std::make_pair(range_start, range_end));
+    const Node* node = mapping_units_[range_start].AssociatedNode();
+    if (node) {
+      while (range_end < mapping_units_.size() &&
+             mapping_units_[range_end].AssociatedNode() == node)
+        ++range_end;
+      // Units of the same node should be consecutive in the mapping function,
+      // If not, the layout structure should be already broken.
+      DCHECK(!unit_ranges_.Contains(node)) << node;
+      unit_ranges_.insert(node, std::make_pair(range_start, range_end));
+    } else {
+      while (range_end < mapping_units_.size() &&
+             mapping_units_[range_end].GetLayoutObject() == layout_object)
+        ++range_end;
+    }
     range_start = range_end;
   }
 
@@ -218,20 +207,4 @@
                          destination_string_);
 }
 
-void NGOffsetMappingBuilder::EnterInline(const LayoutObject& layout_object) {
-  if (!layout_object.NonPseudoNode())
-    return;
-  open_inlines_.push_back(mapping_units_.size());
-}
-
-void NGOffsetMappingBuilder::ExitInline(const LayoutObject& layout_object) {
-  if (!layout_object.NonPseudoNode())
-    return;
-  DCHECK(open_inlines_.size());
-  unit_ranges_.insert(
-      layout_object.GetNode(),
-      std::make_pair(open_inlines_.back(), mapping_units_.size()));
-  open_inlines_.pop_back();
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
index b4f04da..d9b95a96 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
@@ -64,7 +64,7 @@
 
    private:
     NGOffsetMappingBuilder* const builder_ = nullptr;
-    base::AutoReset<Persistent<const Node>> layout_object_auto_reset_;
+    base::AutoReset<const LayoutObject*> layout_object_auto_reset_;
     base::AutoReset<unsigned> appended_length_auto_reset_;
 
     DISALLOW_COPY_AND_ASSIGN(SourceNodeScope);
@@ -108,23 +108,12 @@
   // Set the destination string of the offset mapping.
   void SetDestinationString(String);
 
-  // Called when entering a non-atomic inline node (e.g., SPAN), before
-  // collecting any of its inline descendants.
-  void EnterInline(const LayoutObject&);
-
-  // Called when exiting a non-atomic inline node (e.g., SPAN), after having
-  // collected all of its inline descendants.
-  void ExitInline(const LayoutObject&);
-
   // Finalize and return the offset mapping.
   // This method can only be called once, as it can invalidate the stored data.
   NGOffsetMapping Build();
 
  private:
-  // Helper function for CollapseTrailingSpace() to maintain unit ranges.
-  void ShiftRanges(unsigned position, int delta);
-
-  Persistent<const Node> current_node_ = nullptr;
+  const LayoutObject* current_layout_object_ = nullptr;
   unsigned current_offset_ = 0;
   bool has_open_unit_ = false;
 #if DCHECK_IS_ON()
@@ -140,9 +129,6 @@
   // Unit ranges of the current mapping function.
   NGOffsetMapping::RangeMap unit_ranges_;
 
-  // Unit range starts of currently entered inline elements.
-  Vector<unsigned> open_inlines_;
-
   // The destination string of the offset mapping.
   String destination_string_;
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
index 00eebffc..e2c66a41 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
@@ -22,8 +22,77 @@
 // https://github.com/w3c/csswg-drafts/issues/337
 #define SEGMENT_BREAK_TRANSFORMATION_FOR_EAST_ASIAN_WIDTH 0
 
+// Helper functions to use |EXPECT_EQ()| for |NGOffsetMappingUnit| and
+// |NGMappingUnitRange|.
+Vector<NGOffsetMappingUnit> ToVector(const NGMappingUnitRange& range) {
+  Vector<NGOffsetMappingUnit> units;
+  for (const auto& unit : range)
+    units.push_back(unit);
+  return units;
+}
+
+bool operator==(const NGOffsetMappingUnit& unit,
+                const NGOffsetMappingUnit& other) {
+  return unit.GetType() == other.GetType() &&
+         unit.GetLayoutObject() == other.GetLayoutObject() &&
+         unit.DOMStart() == other.DOMStart() &&
+         unit.DOMEnd() == other.DOMEnd() &&
+         unit.TextContentStart() == other.TextContentStart() &&
+         unit.TextContentEnd() == other.TextContentEnd();
+}
+
+bool operator!=(const NGOffsetMappingUnit& unit,
+                const NGOffsetMappingUnit& other) {
+  return !operator==(unit, other);
+}
+
+void PrintTo(const NGOffsetMappingUnit& unit, std::ostream& ostream) {
+  static const char* kTypeNames[] = {"Identity", "Collapsed", "Expanded"};
+  ostream << "{" << kTypeNames[static_cast<unsigned>(unit.GetType())] << " "
+          << unit.GetLayoutObject() << " dom=" << unit.DOMStart() << "-"
+          << unit.DOMEnd() << " tc=" << unit.TextContentStart() << "-"
+          << unit.TextContentEnd() << "}";
+}
+
+bool operator==(const Vector<NGOffsetMappingUnit>& units1,
+                const Vector<NGOffsetMappingUnit>& units2) {
+  if (units1.size() != units2.size())
+    return false;
+  auto* it2 = units2.begin();
+  for (const auto& unit1 : units1) {
+    if (unit1 != *it2)
+      return false;
+    ++it2;
+  }
+  return true;
+}
+
+bool operator==(const Vector<NGOffsetMappingUnit>& units,
+                const NGMappingUnitRange& range) {
+  return units == ToVector(range);
+}
+
+void PrintTo(const Vector<NGOffsetMappingUnit>& units, std::ostream& ostream) {
+  ostream << "[";
+  const char* comma = "";
+  for (const auto& unit : units) {
+    ostream << comma;
+    PrintTo(unit, ostream);
+    comma = ", ";
+  }
+  ostream << "]";
+}
+
+void PrintTo(const NGMappingUnitRange& range, std::ostream& ostream) {
+  PrintTo(ToVector(range), ostream);
+}
+
 class NGOffsetMappingTest : public NGLayoutTest {
  protected:
+  static const auto kCollapsed = NGOffsetMappingUnitType::kCollapsed;
+  static const auto kIdentity = NGOffsetMappingUnitType::kIdentity;
+  static const auto kExpanded = NGOffsetMappingUnitType::kExpanded;
+
   void SetUp() override {
     NGLayoutTest::SetUp();
     style_ = ComputedStyle::Create();
@@ -372,10 +441,6 @@
             NGInlineFormattingContextOf(Position::BeforeNode(*inline_block)));
   EXPECT_EQ(container_object,
             NGInlineFormattingContextOf(Position::AfterNode(*inline_block)));
-  EXPECT_EQ(container_object,
-            NGInlineFormattingContextOf(Position::BeforeNode(*inline_span)));
-  EXPECT_EQ(container_object,
-            NGInlineFormattingContextOf(Position::AfterNode(*inline_span)));
 
   const LayoutObject* inline_block_object = inline_block->GetLayoutObject();
   EXPECT_EQ(inline_block_object,
@@ -451,7 +516,6 @@
   const LayoutText* bar = GetLayoutTextUnder("s");
   const Node* foo_node = foo->GetNode();
   const Node* bar_node = bar->GetNode();
-  const Node* span = GetElementById("s");
   const NGOffsetMapping& result = GetOffsetMapping();
 
   EXPECT_EQ("foobar", result.GetText());
@@ -462,10 +526,9 @@
   TEST_UNIT(result.GetUnits()[1], NGOffsetMappingUnitType::kIdentity, bar_node,
             0u, 3u, 3u, 6u);
 
-  ASSERT_EQ(3u, result.GetRanges().size());
+  ASSERT_EQ(2u, result.GetRanges().size());
   TEST_RANGE(result.GetRanges(), foo_node, 0u, 1u);
   TEST_RANGE(result.GetRanges(), bar_node, 1u, 2u);
-  TEST_RANGE(result.GetRanges(), span, 1u, 2u);
 
   EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0)));
   EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1)));
@@ -654,8 +717,6 @@
   const Node* foo_node = foo->GetNode();
   const Node* bar_node = bar->GetNode();
   const Node* space_node = space->GetNode();
-  const Node* span1 = GetElementById("s1");
-  const Node* span2 = GetElementById("s2");
   const NGOffsetMapping& result = GetOffsetMapping();
 
   EXPECT_EQ("foo bar", result.GetText());
@@ -668,12 +729,10 @@
   TEST_UNIT(result.GetUnits()[2], NGOffsetMappingUnitType::kIdentity, bar_node,
             0u, 3u, 4u, 7u);
 
-  ASSERT_EQ(5u, result.GetRanges().size());
+  ASSERT_EQ(3u, result.GetRanges().size());
   TEST_RANGE(result.GetRanges(), foo_node, 0u, 1u);
-  TEST_RANGE(result.GetRanges(), span1, 0u, 1u);
   TEST_RANGE(result.GetRanges(), space_node, 1u, 2u);
   TEST_RANGE(result.GetRanges(), bar_node, 2u, 3u);
-  TEST_RANGE(result.GetRanges(), span2, 2u, 3u);
 
   EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 0)));
   EXPECT_EQ(&result.GetUnits()[0], GetUnitForPosition(Position(foo_node, 1)));
@@ -934,48 +993,75 @@
   EXPECT_TRUE(StartOfNextNonCollapsedContent(Position(text_node, 0u)).IsNull());
 }
 
-TEST_F(NGOffsetMappingTest, OneContainerWithLeadingAndTrailingSpaces) {
-  SetupHtml("t", "<div id=t><span id=s>  foo  </span></div>");
-  const Node* span = GetElementById("s");
-  const Node* text = span->firstChild();
-  const NGOffsetMapping& result = GetOffsetMapping();
-
-  // 3 units in total:
-  // - collapsed unit for leading spaces
-  // - identity unit for "foo"
-  // - collapsed unit for trailing spaces
-
-  ASSERT_EQ(2u, result.GetRanges().size());
-  TEST_RANGE(result.GetRanges(), span, 0u, 3u);
-  TEST_RANGE(result.GetRanges(), text, 0u, 3u);
-
-  auto unit_range = result.GetMappingUnitsForDOMRange(
-      EphemeralRange(Position::BeforeNode(*span), Position::AfterNode(*span)));
-  EXPECT_EQ(result.GetUnits().size(), unit_range.size());
-
-  EXPECT_EQ(0u, *GetTextContentOffset(Position::BeforeNode(*span)));
-  EXPECT_EQ(3u, *GetTextContentOffset(Position::AfterNode(*span)));
-}
-
 TEST_F(NGOffsetMappingTest, ContainerWithGeneratedContent) {
   SetupHtml("t",
             "<style>#s::before{content:'bar'} #s::after{content:'baz'}</style>"
             "<div id=t><span id=s>foo</span></div>");
-  const Node* span = GetElementById("s");
+  const Element* span = GetElementById("s");
   const Node* text = span->firstChild();
+  const LayoutObject& before = *span->GetPseudoElement(kPseudoIdBefore)
+                                    ->GetLayoutObject()
+                                    ->SlowFirstChild();
+  const LayoutObject& after = *span->GetPseudoElement(kPseudoIdAfter)
+                                   ->GetLayoutObject()
+                                   ->SlowFirstChild();
   const NGOffsetMapping& result = GetOffsetMapping();
 
-  ASSERT_EQ(2u, result.GetRanges().size());
-  TEST_RANGE(result.GetRanges(), span, 0u, 1u);
-  TEST_RANGE(result.GetRanges(), text, 0u, 1u);
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
+                NGOffsetMappingUnit(kIdentity, before, 0u, 3u, 0u, 3u),
+                NGOffsetMappingUnit(kIdentity, *text->GetLayoutObject(), 0u, 3u,
+                                    3u, 6u),
+                NGOffsetMappingUnit(kIdentity, after, 0u, 3u, 6u, 9u)}),
+            result.GetUnits());
 
-  auto unit_range = result.GetMappingUnitsForDOMRange(
-      EphemeralRange(Position::BeforeNode(*span), Position::AfterNode(*span)));
-  EXPECT_EQ(result.GetUnits().size(), unit_range.size());
+  // Verify |GetMappingUnitsForLayoutObject()| for ::before and ::after
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
+                NGOffsetMappingUnit(kIdentity, before, 0u, 3u, 0u, 3u)}),
+            result.GetMappingUnitsForLayoutObject(before));
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
+                NGOffsetMappingUnit(kIdentity, after, 0u, 3u, 6u, 9u)}),
+            result.GetMappingUnitsForLayoutObject(after));
+}
 
-  // Offset mapping for inline containers skips generated content.
-  EXPECT_EQ(3u, *GetTextContentOffset(Position::BeforeNode(*span)));
-  EXPECT_EQ(6u, *GetTextContentOffset(Position::AfterNode(*span)));
+TEST_F(NGOffsetMappingTest,
+       ContainerWithGeneratedContentWithCollapsedWhitespace) {
+  SetupHtml("t",
+            "<style>"
+            "#t::before { content: '  a   bc'; }"
+            "#t::first-letter { font-weight: bold; }"
+            "</style><div id=t>def</div>");
+  const Element& target = *GetElementById("t");
+  const LayoutText& remaining_part =
+      *ToLayoutText(target.GetPseudoElement(kPseudoIdBefore)
+                        ->GetLayoutObject()
+                        ->SlowLastChild());
+  const LayoutObject& first_letter_part = *remaining_part.GetFirstLetterPart();
+  const NGOffsetMapping& result = GetOffsetMapping();
+  const LayoutText& target_text =
+      ToLayoutText(*target.firstChild()->GetLayoutObject());
+
+  EXPECT_EQ(
+      (Vector<NGOffsetMappingUnit>{
+          NGOffsetMappingUnit(kCollapsed, first_letter_part, 0u, 2u, 0u, 0u),
+          NGOffsetMappingUnit(kIdentity, first_letter_part, 2u, 3u, 0u, 1u),
+          NGOffsetMappingUnit(kIdentity, remaining_part, 0u, 1u, 1u, 2u),
+          NGOffsetMappingUnit(kCollapsed, remaining_part, 1u, 3u, 2u, 2u),
+          NGOffsetMappingUnit(kIdentity, remaining_part, 3u, 5u, 2u, 4u),
+          NGOffsetMappingUnit(kIdentity, target_text, 0u, 3u, 4u, 7u)}),
+      result.GetUnits());
+
+  // Verify |GetMappingUnitsForLayoutObject()| for ::first-letter
+  EXPECT_EQ(
+      (Vector<NGOffsetMappingUnit>{
+          NGOffsetMappingUnit(kCollapsed, first_letter_part, 0u, 2u, 0u, 0u),
+          NGOffsetMappingUnit(kIdentity, first_letter_part, 2u, 3u, 0u, 1u)}),
+      result.GetMappingUnitsForLayoutObject(first_letter_part));
+  EXPECT_EQ(
+      (Vector<NGOffsetMappingUnit>{
+          NGOffsetMappingUnit(kIdentity, remaining_part, 0u, 1u, 1u, 2u),
+          NGOffsetMappingUnit(kCollapsed, remaining_part, 1u, 3u, 2u, 2u),
+          NGOffsetMappingUnit(kIdentity, remaining_part, 3u, 5u, 2u, 4u)}),
+      result.GetMappingUnitsForLayoutObject(remaining_part));
 }
 
 TEST_F(NGOffsetMappingTest, Table) {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
index 5836b64..4ce2a71f 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
@@ -267,7 +267,7 @@
     ink_overflow.Expand(text_shadow_logical_outsets);
   }
 
-  ink_overflow = LayoutRect(EnclosingIntRect(ink_overflow));
+  ink_overflow.ExpandEdgesToPixelBoundaries();
 
   // Uniting the frame rect ensures that non-ink spaces such side bearings, or
   // even space characters, are included in the visual rect for decorations.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
index 434e661..e7022f7 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
@@ -125,9 +125,7 @@
 }
 
 const NGPaintFragment* NGLayoutInputNode::PaintFragment() const {
-  if (LayoutBlockFlow* block_flow = ToLayoutBlockFlowOrNull(GetLayoutBox()))
-    return block_flow->PaintFragment();
-  return nullptr;
+  return GetLayoutBox()->PaintFragment();
 }
 
 String NGLayoutInputNode::ToString() const {
diff --git a/third_party/blink/renderer/core/page/drag_controller.cc b/third_party/blink/renderer/core/page/drag_controller.cc
index 68dbbe3..bfc3ec6 100644
--- a/third_party/blink/renderer/core/page/drag_controller.cc
+++ b/third_party/blink/renderer/core/page/drag_controller.cc
@@ -487,9 +487,9 @@
                                     const LayoutPoint& point) {
   frame->Selection().SetSelectionAndEndTyping(drag_caret);
   // TODO(editing-dev): The use of
-  // UpdateStyleAndLayoutIgnorePendingStylesheets
+  // UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame->GetDocument()->UpdateStyleAndLayout();
   if (!frame->Selection().ComputeVisibleSelectionInDOMTree().IsNone()) {
     return frame->Selection()
         .ComputeVisibleSelectionInDOMTree()
@@ -503,9 +503,9 @@
   frame->Selection().SetSelectionAndEndTyping(
       SelectionInDOMTree::Builder().Collapse(position).Build());
   // TODO(editing-dev): The use of
-  // UpdateStyleAndLayoutIgnorePendingStylesheets
+  // UpdateStyleAndLayout
   // needs to be audited.  See http://crbug.com/590369 for more details.
-  frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame->GetDocument()->UpdateStyleAndLayout();
   const VisibleSelection& visible_selection =
       frame->Selection().ComputeVisibleSelectionInDOMTree();
   range = CreateRange(visible_selection.ToNormalizedEphemeralRange());
@@ -576,13 +576,13 @@
   }
 
   if (page_->GetDragCaret().HasCaret()) {
-    // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+    // TODO(editing-dev): Use of UpdateStyleAndLayout
     // needs to be audited.  See http://crbug.com/590369 for more details.
     page_->GetDragCaret()
         .CaretPosition()
         .GetPosition()
         .GetDocument()
-        ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+        ->UpdateStyleAndLayout();
   }
 
   const PositionWithAffinity& caret_position =
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc
index 225c345..04b897d 100644
--- a/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -680,8 +680,7 @@
     auto* container_local_frame = DynamicTo<LocalFrame>(owner.ContentFrame());
     if (!container_local_frame)
       break;
-    container_local_frame->GetDocument()
-        ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+    container_local_frame->GetDocument()->UpdateStyleAndLayout();
     ScopedFocusNavigation scope =
         ScopedFocusNavigation::OwnedByIFrame(owner, owner_map);
     Element* found_element =
@@ -1018,7 +1017,7 @@
   if (!current && !initial_focus)
     current = document->SequentialFocusNavigationStartingPoint(type);
 
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
   ScopedFocusNavigation scope =
       current ? ScopedFocusNavigation::CreateFor(*current, owner_map)
               : ScopedFocusNavigation::CreateForDocument(*document, owner_map);
@@ -1127,7 +1126,7 @@
   // from current element in terms of tabindex, then it's signalling CPU load.
   // Will nvestigate further for a proper solution later.
   static const int kFocusTraversalThreshold = 50;
-  element->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  element->GetDocument().UpdateStyleAndLayout();
   if (!element->IsHTMLElement())
     return nullptr;
 
@@ -1187,7 +1186,7 @@
                                                     WebFocusType type) {
   if (type != kWebFocusTypeForward && type != kWebFocusTypeBackward)
     return nullptr;
-  element.GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  element.GetDocument().UpdateStyleAndLayout();
 
   OwnerMap owner_map;
   return FindFocusableElement(type, element, owner_map);
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
index 7a61f26..126877a 100644
--- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
+++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -212,7 +212,7 @@
   if (!interest_node)
     return false;
 
-  interest_node->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  interest_node->GetDocument().UpdateStyleAndLayout();
 
   Node* container = ScrollableAreaOrDocumentOf(interest_node);
 
@@ -249,7 +249,7 @@
     // Currently this will fail if we're going from an inner document to a
     // sub-scroller in a parent document.
     if (auto* document = DynamicTo<Document>(container))
-      document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+      document->UpdateStyleAndLayout();
   }
 
   return false;
diff --git a/third_party/blink/renderer/core/paint/block_painter.cc b/third_party/blink/renderer/core/paint/block_painter.cc
index e6c78757..dfaa4c8 100644
--- a/third_party/blink/renderer/core/paint/block_painter.cc
+++ b/third_party/blink/renderer/core/paint/block_painter.cc
@@ -287,16 +287,13 @@
 void BlockPainter::PaintBlockFlowContents(const PaintInfo& paint_info,
                                           const LayoutPoint& paint_offset) {
   DCHECK(layout_block_.IsLayoutBlockFlow());
-  if (layout_block_.IsLayoutView() ||
-      !paint_info.SuppressPaintingDescendants()) {
-    if (!layout_block_.ChildrenInline()) {
-      PaintContents(paint_info, paint_offset);
-    } else if (ShouldPaintDescendantOutlines(paint_info.phase)) {
-      ObjectPainter(layout_block_).PaintInlineChildrenOutlines(paint_info);
-    } else {
-      LineBoxListPainter(ToLayoutBlockFlow(layout_block_).LineBoxes())
-          .Paint(layout_block_, paint_info, paint_offset);
-    }
+  if (!layout_block_.ChildrenInline()) {
+    PaintContents(paint_info, paint_offset);
+  } else if (ShouldPaintDescendantOutlines(paint_info.phase)) {
+    ObjectPainter(layout_block_).PaintInlineChildrenOutlines(paint_info);
+  } else {
+    LineBoxListPainter(ToLayoutBlockFlow(layout_block_).LineBoxes())
+        .Paint(layout_block_, paint_info, paint_offset);
   }
 
   // If we don't have any floats to paint, or we're in the wrong paint phase,
diff --git a/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h b/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h
index 260c627..7058bbe 100644
--- a/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h
+++ b/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h
@@ -37,7 +37,7 @@
     if (const auto* properties = fragment_data.PaintProperties()) {
       if (const auto* translation = properties->PaintOffsetTranslation()) {
         old_parent_ = translation->Parent();
-        old_translation_ = translation->Matrix();
+        old_translation_ = translation->Translation2D();
       }
     }
   }
@@ -49,11 +49,11 @@
     DCHECK_EQ(old_paint_offset_, paint_offset) << object_.DebugName();
 
     const TransformPaintPropertyNode* new_parent = nullptr;
-    base::Optional<TransformationMatrix> new_translation;
+    base::Optional<FloatSize> new_translation;
     if (const auto* properties = fragment_data_.PaintProperties()) {
       if (const auto* translation = properties->PaintOffsetTranslation()) {
         new_parent = translation->Parent();
-        new_translation = translation->Matrix();
+        new_translation = translation->Translation2D();
       }
     }
     DCHECK_EQ(!!old_translation_, !!new_translation) << object_.DebugName();
@@ -68,7 +68,7 @@
   const bool& is_actually_needed_;
   LayoutPoint old_paint_offset_;
   const TransformPaintPropertyNode* old_parent_ = nullptr;
-  base::Optional<TransformationMatrix> old_translation_;
+  base::Optional<FloatSize> old_translation_;
 };
 
 class FindVisualRectNeedingUpdateScopeBase {
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index a3db57d..1d1e12d 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -330,10 +330,6 @@
   // TODO(layout-dev): Handle without delegating to LayoutObject.
   const NGPhysicalBoxFragment& fragment = PhysicalFragment();
   LayoutObject* layout_object = fragment.GetLayoutObject();
-  if (layout_object->GetDocument().DidLayoutWithPendingStylesheets() &&
-      !layout_object->IsLayoutView()) {
-    return;
-  }
 
   DCHECK(fragment.ChildrenInline());
 
@@ -349,15 +345,12 @@
 
   DCHECK(layout_object->IsLayoutBlockFlow());
   const LayoutBlock& layout_block = ToLayoutBlock(*layout_object);
-  if (layout_block.IsLayoutView() ||
-      !paint_info.SuppressPaintingDescendants()) {
-    DCHECK(layout_block.ChildrenInline());
-    if (ShouldPaintDescendantOutlines(paint_info.phase)) {
-      ObjectPainter(layout_block).PaintInlineChildrenOutlines(paint_info);
-    } else {
-      PaintLineBoxChildren(box_fragment_.Children(),
-                           paint_info.ForDescendants(), paint_offset);
-    }
+  DCHECK(layout_block.ChildrenInline());
+  if (ShouldPaintDescendantOutlines(paint_info.phase)) {
+    ObjectPainter(layout_block).PaintInlineChildrenOutlines(paint_info);
+  } else {
+    PaintLineBoxChildren(box_fragment_.Children(), paint_info.ForDescendants(),
+                         paint_offset);
   }
 }
 
@@ -572,7 +565,7 @@
   GraphicsContextStateSaver state_saver(paint_info.context, false);
 
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-      LayoutRect(EnclosingIntRect(paint_rect)) == paint_rect &&
+      paint_rect.EdgesOnPixelBoundaries() &&
       BackgroundIsKnownToBeOpaque(paint_info))
     recorder.SetKnownToBeOpaque();
 
@@ -678,8 +671,7 @@
     const PaintInfo& paint_info) {
   LayoutObject* child_layout_object = fragment.GetLayoutObject();
   DCHECK(child_layout_object);
-  if (child_layout_object->IsLayoutNGMixin() &&
-      ToLayoutBlockFlow(child_layout_object)->PaintFragment()) {
+  if (child_layout_object->PaintFragment()) {
     // This object will use NGBoxFragmentPainter.
     child_layout_object->Paint(paint_info);
     return;
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index 96e6edba..6a0d726a 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -448,7 +448,7 @@
     // This needs cleanup.
     if (block_flow->IsLayoutFlowThread()) {
       DCHECK(block_flow->Parent() && block_flow->Parent()->IsLayoutBlockFlow());
-      return ToLayoutBlockFlow(block_flow->Parent())->PaintFragment();
+      return block_flow->Parent()->PaintFragment();
     }
   }
   return nullptr;
@@ -617,13 +617,10 @@
 
   // The |layout_object| is inserted into an empty block.
   // Mark the first line box dirty.
-  if (parent.IsLayoutNGMixin()) {
-    const LayoutBlockFlow& block = ToLayoutBlockFlow(parent);
-    if (NGPaintFragment* paint_fragment = block.PaintFragment()) {
-      if (NGPaintFragment* first_line = paint_fragment->FirstLineBox()) {
-        first_line->is_dirty_inline_ = true;
-        return;
-      }
+  if (NGPaintFragment* paint_fragment = parent.PaintFragment()) {
+    if (NGPaintFragment* first_line = paint_fragment->FirstLineBox()) {
+      first_line->is_dirty_inline_ = true;
+      return;
     }
   }
 }
diff --git a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
index 74e97b0..8507dfa 100644
--- a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
+++ b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
@@ -180,8 +180,7 @@
   // TODO(crbug.com/880519): This hack only makes current invalidation tracking
   // web tests pass with LayoutNG. More work is needed if we want to launch
   // the invalidation tracking feature.
-  return object.IsLayoutBlockFlow() &&
-         &client == ToLayoutBlockFlow(object).PaintFragment();
+  return &client == object.PaintFragment();
 }
 }  // namespace
 
diff --git a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
index 4307a7a9..94fffe6 100644
--- a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
@@ -1021,9 +1021,10 @@
   const auto* sticky = GetLayoutObjectByElementId("sticky");
   EXPECT_TRUE(sticky->NeedsPaintPropertyUpdate());
   EXPECT_EQ(LayoutPoint(0, 0), sticky->FirstFragment().PaintOffset());
-  EXPECT_EQ(
-      TransformationMatrix().Translate(0.f, 50.f),
-      sticky->FirstFragment().PaintProperties()->StickyTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, 50), sticky->FirstFragment()
+                                  .PaintProperties()
+                                  ->StickyTranslation()
+                                  ->Translation2D());
   const auto* inner = GetLayoutObjectByElementId("inner");
   EXPECT_EQ(LayoutPoint(0, 0), inner->FirstFragment().PaintOffset());
 
@@ -1031,9 +1032,10 @@
 
   EXPECT_FALSE(sticky->NeedsPaintPropertyUpdate());
   EXPECT_EQ(LayoutPoint(0, 0), sticky->FirstFragment().PaintOffset());
-  EXPECT_EQ(
-      TransformationMatrix().Translate(0.f, 150.f),
-      sticky->FirstFragment().PaintProperties()->StickyTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, 150), sticky->FirstFragment()
+                                   .PaintProperties()
+                                   ->StickyTranslation()
+                                   ->Translation2D());
   EXPECT_EQ(LayoutPoint(0, 0), inner->FirstFragment().PaintOffset());
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_info.h b/third_party/blink/renderer/core/paint/paint_info.h
index c3d7dc7..f5a5330 100644
--- a/third_party/blink/renderer/core/paint/paint_info.h
+++ b/third_party/blink/renderer/core/paint/paint_info.h
@@ -61,8 +61,7 @@
             GlobalPaintFlags global_paint_flags,
             PaintLayerFlags paint_flags,
             const LayoutBoxModelObject* paint_container = nullptr,
-            LayoutUnit fragment_logical_top_in_flow_thread = LayoutUnit(),
-            bool suppress_painting_descendants = false)
+            LayoutUnit fragment_logical_top_in_flow_thread = LayoutUnit())
       : context(context),
         phase(phase),
         cull_rect_(cull_rect),
@@ -71,7 +70,6 @@
             fragment_logical_top_in_flow_thread),
         paint_flags_(paint_flags),
         global_paint_flags_(global_paint_flags),
-        suppress_painting_descendants_(suppress_painting_descendants),
         is_painting_scrolling_background_(false) {}
 
   PaintInfo(GraphicsContext& new_context,
@@ -84,8 +82,6 @@
             copy_other_fields_from.fragment_logical_top_in_flow_thread_),
         paint_flags_(copy_other_fields_from.paint_flags_),
         global_paint_flags_(copy_other_fields_from.global_paint_flags_),
-        suppress_painting_descendants_(
-            copy_other_fields_from.suppress_painting_descendants_),
         is_painting_scrolling_background_(false) {
     // We should never pass is_painting_scrolling_background_ other PaintInfo.
     DCHECK(!copy_other_fields_from.is_painting_scrolling_background_);
@@ -127,10 +123,6 @@
 
   bool IsPrinting() const { return global_paint_flags_ & kGlobalPaintPrinting; }
 
-  bool SuppressPaintingDescendants() const {
-    return suppress_painting_descendants_;
-  }
-
   DisplayItem::Type DisplayItemTypeForClipping() const {
     return DisplayItem::PaintPhaseToClipType(phase);
   }
@@ -195,7 +187,6 @@
 
   PaintLayerFlags paint_flags_;
   const GlobalPaintFlags global_paint_flags_;
-  const bool suppress_painting_descendants_;
 
   // For CAP only.
   bool is_painting_scrolling_background_;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
index 4be3c35..affe4e84 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -25,19 +25,6 @@
 
 namespace blink {
 
-static inline bool ShouldSuppressPaintingLayer(const PaintLayer& layer) {
-  // Avoid painting descendants of the root layer when stylesheets haven't
-  // loaded. This avoids some FOUC.  It's ok not to draw, because later on, when
-  // all the stylesheets do load, Document::styleResolverMayHaveChanged() will
-  // invalidate all painted output via a call to
-  // LayoutView::invalidatePaintForViewAndCompositedLayers().  We also avoid
-  // caching subsequences in this mode; see shouldCreateSubsequence().
-  return layer.GetLayoutObject()
-             .GetDocument()
-             .DidLayoutWithPendingStylesheets() &&
-         !layer.IsRootLayer() && !layer.GetLayoutObject().IsDocumentElement();
-}
-
 void PaintLayerPainter::Paint(GraphicsContext& context,
                               const CullRect& cull_rect,
                               const GlobalPaintFlags global_paint_flags,
@@ -114,9 +101,6 @@
       !paint_layer_.HasSelfPaintingLayerDescendant())
     return kFullyPainted;
 
-  if (ShouldSuppressPaintingLayer(paint_layer_))
-    return kFullyPainted;
-
   // If this layer is totally invisible then there is nothing to paint. In CAP
   // we simplify this optimization by painting even when effectively invisible
   // but skipping the painted content during layerization in
@@ -172,15 +156,6 @@
       (kPaintLayerPaintingOverlayScrollbars | kPaintLayerUncachedClipRects))
     return false;
 
-  // When in FOUC-avoidance mode, don't cache any subsequences, to avoid having
-  // to invalidate all of them when leaving this mode. There is an early-out in
-  // BlockPainter::paintContents that may result in nothing getting painted in
-  // this mode, in addition to early-out logic in PaintLayerPainter.
-  if (paint_layer.GetLayoutObject()
-          .GetDocument()
-          .DidLayoutWithPendingStylesheets())
-    return false;
-
   return true;
 }
 
@@ -791,18 +766,12 @@
   new_cull_rect.MoveBy(
       RoundedIntPoint(fragment.root_fragment_data->PaintOffset()));
 
-  // If we had pending stylesheets, we should avoid painting descendants of
-  // layout view to avoid FOUC.
-  bool suppress_painting_descendants = paint_layer_.GetLayoutObject()
-                                           .GetDocument()
-                                           .DidLayoutWithPendingStylesheets();
   PaintInfo paint_info(context, PixelSnappedIntRect(new_cull_rect), phase,
                        painting_info.GetGlobalPaintFlags(), paint_flags,
                        &painting_info.root_layer->GetLayoutObject(),
                        fragment.fragment_data
                            ? fragment.fragment_data->LogicalTopInFlowThread()
-                           : LayoutUnit(),
-                       suppress_painting_descendants);
+                           : LayoutUnit());
   paint_layer_.GetLayoutObject().Paint(paint_info);
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
index 80a89676c..5a6711e 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -1020,11 +1020,10 @@
     EXPECT_EQ(kPaintsIntoOwnBacking, scroller->Layer()->GetCompositingState());
   auto* sticky = ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky"));
 
-  EXPECT_EQ(FloatSize(0, 0), sticky->FirstFragment()
-                                 .LocalBorderBoxProperties()
-                                 .Transform()
-                                 .Matrix()
-                                 .To2DTranslation());
+  EXPECT_TRUE(sticky->FirstFragment()
+                  .LocalBorderBoxProperties()
+                  .Transform()
+                  .IsIdentity());
 
   scrollable_area->SetScrollOffset(ScrollOffset(0, 50), kUserScroll);
   UpdateAllLifecyclePhasesForTest();
@@ -1032,8 +1031,7 @@
   EXPECT_EQ(FloatSize(0, 50), sticky->FirstFragment()
                                   .LocalBorderBoxProperties()
                                   .Transform()
-                                  .Matrix()
-                                  .To2DTranslation());
+                                  .Translation2D());
 }
 
 // Delayed scroll offset clamping should not crash. https://crbug.com/842495
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index f2976ad2..de7bb34 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -477,12 +477,10 @@
   DCHECK(properties_);
 
   if (paint_offset_translation) {
-    TransformPaintPropertyNode::State state;
-    state.matrix.Translate(paint_offset_translation->X(),
-                           paint_offset_translation->Y());
+    TransformPaintPropertyNode::State state{
+        FloatSize(ToIntSize(*paint_offset_translation))};
     state.flattens_inherited_transform =
         context_.current.should_flatten_inherited_transform;
-    state.is_identity_or_2d_translation = true;
 
     state.affected_by_outer_viewport_bounds_delta =
         object_.StyleRef().GetPosition() == EPosition::kFixed &&
@@ -510,10 +508,8 @@
   if (NeedsPaintPropertyUpdate()) {
     if (NeedsStickyTranslation(object_)) {
       const auto& box_model = ToLayoutBoxModelObject(object_);
-      FloatSize sticky_offset(box_model.StickyPositionOffset());
-      TransformPaintPropertyNode::State state{AffineTransform::Translation(
-          sticky_offset.Width(), sticky_offset.Height())};
-      state.is_identity_or_2d_translation = true;
+      TransformPaintPropertyNode::State state{
+          FloatSize(box_model.StickyPositionOffset())};
       state.compositor_element_id = CompositorElementIdFromUniqueObjectId(
           box_model.UniqueId(),
           CompositorElementIdNamespace::kStickyTranslation);
@@ -611,9 +607,9 @@
     AffineTransform transform = object_.LocalToSVGParentTransform();
     if (NeedsTransformForNonRootSVG(object_)) {
       // The origin is included in the local transform, so leave origin empty.
-      OnUpdate(properties_->UpdateTransform(
-          *context_.current.transform,
-          TransformPaintPropertyNode::State{transform}));
+      TransformPaintPropertyNode::State state{TransformationMatrix(transform)};
+      OnUpdate(properties_->UpdateTransform(*context_.current.transform,
+                                            std::move(state)));
     } else {
       OnClear(properties_->ClearTransform());
     }
@@ -677,11 +673,21 @@
 
       if (object_.IsBox()) {
         auto& box = ToLayoutBox(object_);
-        state.origin = TransformOrigin(box);
+        TransformationMatrix matrix;
         style.ApplyTransform(
-            state.matrix, box.Size(), ComputedStyle::kExcludeTransformOrigin,
+            matrix, box.Size(), ComputedStyle::kExcludeTransformOrigin,
             ComputedStyle::kIncludeMotionPath,
             ComputedStyle::kIncludeIndependentTransformProperties);
+        // If we are running transform animation on compositor, we should
+        // disable 2d translation optimization to ensure that the compositor
+        // gets the correct origin (which might be omitted by the optimization)
+        // to the compositor, in case later animated values will use the origin.
+        bool disable_2d_translation_optimization =
+            style.IsRunningTransformAnimationOnCompositor();
+        state.transform_and_origin =
+            TransformPaintPropertyNode::TransformAndOrigin(
+                matrix, TransformOrigin(box),
+                disable_2d_translation_optimization);
 
         if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
             RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
@@ -1343,10 +1349,8 @@
   // Convert the result into the space of the scrolling contents space.
   if (const auto* properties =
           paint_offset_root->FirstFragment().PaintProperties()) {
-    if (const auto* scroll_translation = properties->ScrollTranslation()) {
-      DCHECK(scroll_translation->Matrix().IsIdentityOr2DTranslation());
-      result += -LayoutSize(scroll_translation->Matrix().To2DTranslation());
-    }
+    if (const auto* scroll_translation = properties->ScrollTranslation())
+      result += -LayoutSize(scroll_translation->Translation2D());
   }
   return result;
 }
@@ -1518,10 +1522,11 @@
       // The perspective node must not flatten (else nothing will get
       // perspective), but it should still extend the rendering context as
       // most transform nodes do.
-      TransformPaintPropertyNode::State state;
-      state.matrix.ApplyPerspective(style.Perspective());
-      state.origin = PerspectiveOrigin(ToLayoutBox(object_)) +
-                     ToLayoutSize(context_.current.paint_offset);
+      TransformPaintPropertyNode::State state{
+          TransformPaintPropertyNode::TransformAndOrigin(
+              TransformationMatrix().ApplyPerspective(style.Perspective()),
+              PerspectiveOrigin(ToLayoutBox(object_)) +
+                  ToLayoutSize(context_.current.paint_offset))};
       state.flattens_inherited_transform =
           context_.current.should_flatten_inherited_transform;
       if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
@@ -1586,9 +1591,10 @@
       NOTREACHED();
     }
     if (!content_to_parent_space.IsIdentity()) {
+      TransformPaintPropertyNode::State state{
+          TransformationMatrix(content_to_parent_space)};
       OnUpdate(properties_->UpdateReplacedContentTransform(
-          *context_.current.transform,
-          TransformPaintPropertyNode::State{content_to_parent_space}));
+          *context_.current.transform, std::move(state)));
     } else {
       OnClear(properties_->ClearReplacedContentTransform());
     }
@@ -1757,14 +1763,13 @@
     // hidden with scroll offset) or cases that scroll and have a scroll node.
     if (NeedsScrollOrScrollTranslation(object_)) {
       const auto& box = ToLayoutBox(object_);
-      TransformPaintPropertyNode::State state;
       // Bake ScrollOrigin into ScrollTranslation. See comments for
       // ScrollTranslation in object_paint_properties.h for details.
       auto scroll_position = box.ScrollOrigin() + box.ScrolledContentOffset();
-      state.matrix.Translate(-scroll_position.X(), -scroll_position.Y());
+      TransformPaintPropertyNode::State state{
+          -FloatSize(ToIntSize(scroll_position))};
       state.flattens_inherited_transform =
           context_.current.should_flatten_inherited_transform;
-      state.is_identity_or_2d_translation = true;
       state.direct_compositing_reasons = CompositingReasonsForScroll(box);
       if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
           RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
index 6258f370..03722e9 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -159,8 +159,7 @@
   } else {
     EXPECT_EQ(DocScroll(), positioned_scroll_node->Parent());
   }
-  EXPECT_EQ(TransformationMatrix().Translate(0, -3),
-            positioned_scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -3), positioned_scroll_translation->Translation2D());
   EXPECT_EQ(nullptr, target1_properties->ScrollTranslation());
   CHECK_EXACT_VISUAL_RECT(LayoutRect(200, 150, 100, 100),
                           target1->GetLayoutObject(),
@@ -197,8 +196,7 @@
   } else {
     EXPECT_EQ(DocScroll(), transformed_scroll_node->Parent());
   }
-  EXPECT_EQ(TransformationMatrix().Translate(0, -5),
-            transformed_scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -5), transformed_scroll_translation->Translation2D());
   EXPECT_EQ(nullptr, target2_properties->ScrollTranslation());
 
   CHECK_EXACT_VISUAL_RECT(LayoutRect(208, 153, 200, 100),
@@ -217,8 +215,8 @@
       DocumentLifecycle::LifecycleUpdateReason::kTest);
   const ObjectPaintProperties* scroller_properties =
       scroller->GetLayoutObject()->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(0, -100),
-            scroller_properties->ScrollTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, -100),
+            scroller_properties->ScrollTranslation()->Translation2D());
   EXPECT_EQ(scroller_properties->PaintOffsetTranslation(),
             scroller_properties->ScrollTranslation()->Parent());
   EXPECT_EQ(DocScrollTranslation(),
@@ -231,9 +229,8 @@
   EXPECT_EQ(IntSize(660, 10200), scroll->ContentsSize());
   EXPECT_FALSE(scroll->UserScrollableHorizontal());
   EXPECT_TRUE(scroll->UserScrollableVertical());
-  EXPECT_EQ(FloatSize(120, 340), scroller_properties->PaintOffsetTranslation()
-                                     ->Matrix()
-                                     .To2DTranslation());
+  EXPECT_EQ(FloatSize(120, 340),
+            scroller_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(FloatRoundedRect(0, 0, 413, 317),
             scroller_properties->OverflowClip()->ClipRect());
   EXPECT_EQ(DocContentClip(), scroller_properties->OverflowClip()->Parent());
@@ -246,8 +243,8 @@
   Element* rel_pos = GetDocument().getElementById("rel-pos");
   const ObjectPaintProperties* rel_pos_properties =
       rel_pos->GetLayoutObject()->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(560, 780),
-            rel_pos_properties->PaintOffsetTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(560, 780),
+            rel_pos_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(scroller_properties->ScrollTranslation(),
             rel_pos_properties->PaintOffsetTranslation()->Parent());
   EXPECT_EQ(rel_pos_properties->Transform(),
@@ -264,8 +261,8 @@
   Element* abs_pos = GetDocument().getElementById("abs-pos");
   const ObjectPaintProperties* abs_pos_properties =
       abs_pos->GetLayoutObject()->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(123, 456),
-            abs_pos_properties->PaintOffsetTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(123, 456),
+            abs_pos_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(DocScrollTranslation(),
             abs_pos_properties->PaintOffsetTranslation()->Parent());
   EXPECT_EQ(abs_pos_properties->Transform(),
@@ -352,8 +349,7 @@
   const auto* scroll = properties->Scroll();
 
   // -315: container_width (100) - contents_width (400) - scrollber_width
-  EXPECT_EQ(TransformationMatrix().Translate(-315, 0),
-            scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(-315, 0), scroll_translation->Translation2D());
   EXPECT_EQ(scroll, scroll_translation->ScrollNode());
   // 10: border width. 85: container client size (== 100 - scrollbar width).
   EXPECT_EQ(IntRect(10, 10, 85, 85), scroll->ContainerRect());
@@ -371,8 +367,7 @@
   UpdateAllLifecyclePhasesForTest();
 
   // Only scroll_translation is affected by scrolling.
-  EXPECT_EQ(TransformationMatrix().Translate(-215, 0),
-            scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(-215, 0), scroll_translation->Translation2D());
   // Other properties are the same as before.
   EXPECT_EQ(scroll, scroll_translation->ScrollNode());
   EXPECT_EQ(IntRect(10, 10, 85, 85), scroll->ContainerRect());
@@ -405,8 +400,7 @@
   const auto* scroll = properties->Scroll();
 
   // -315: container_width (100) - contents_width (400) - scrollbar width (15).
-  EXPECT_EQ(TransformationMatrix().Translate(-315, 0),
-            scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(-315, 0), scroll_translation->Translation2D());
   EXPECT_EQ(scroll, scroll_translation->ScrollNode());
   // 25: border width (10) + scrollbar (on the left) width (15).
   // 85: container client size (== 100 - scrollbar width).
@@ -425,8 +419,7 @@
   UpdateAllLifecyclePhasesForTest();
 
   // Only scroll_translation is affected by scrolling.
-  EXPECT_EQ(TransformationMatrix().Translate(-215, 0),
-            scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(-215, 0), scroll_translation->Translation2D());
   // Other properties are the same as before.
   EXPECT_EQ(scroll, scroll_translation->ScrollNode());
   EXPECT_EQ(IntRect(25, 10, 85, 85), scroll->ContainerRect());
@@ -492,12 +485,11 @@
   LocalFrameView* frame_view = GetDocument().View();
   frame_view->UpdateAllLifecyclePhases(
       DocumentLifecycle::LifecycleUpdateReason::kTest);
-  EXPECT_EQ(TransformationMatrix(), DocPreTranslation()->Matrix());
+  EXPECT_TRUE(DocPreTranslation()->IsIdentity());
   EXPECT_EQ(
       GetDocument().GetPage()->GetVisualViewport().GetScrollTranslationNode(),
       DocPreTranslation()->Parent());
-  EXPECT_EQ(TransformationMatrix().Translate(0, -100),
-            DocScrollTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, -100), DocScrollTranslation()->Translation2D());
   EXPECT_EQ(DocPreTranslation(), DocScrollTranslation()->Parent());
   EXPECT_EQ(DocPreTranslation(), &DocContentClip()->LocalTransformSpace());
   EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), DocContentClip()->ClipRect());
@@ -553,8 +545,8 @@
   Element* inner = GetDocument().getElementById("inner");
   const ObjectPaintProperties* inner_properties =
       inner->GetLayoutObject()->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(50, 100),
-            inner_properties->PaintOffsetTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(50, 100),
+            inner_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(perspective_properties->Perspective(),
             inner_properties->PaintOffsetTranslation()->Parent());
   CHECK_EXACT_VISUAL_RECT(LayoutRect(50, 100, 100, 200),
@@ -614,8 +606,8 @@
             transform_properties->Transform()->Origin());
   EXPECT_EQ(transform_properties->PaintOffsetTranslation(),
             transform_properties->Transform()->Parent());
-  EXPECT_EQ(TransformationMatrix().Translate(50, 100),
-            transform_properties->PaintOffsetTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(50, 100),
+            transform_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(DocScrollTranslation(),
             transform_properties->PaintOffsetTranslation()->Parent());
 
@@ -737,14 +729,11 @@
   const ObjectPaintProperties* transform_properties =
       transform->GetLayoutObject()->FirstFragment().PaintProperties();
 
-  EXPECT_EQ(TransformationMatrix(),
-            transform_properties->Transform()->Matrix());
-  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
-            transform_properties->Transform()->Matrix());
-  // The value is zero without a transform property that needs transform-offset.
-  EXPECT_EQ(FloatPoint3D(0, 0, 0), transform_properties->Transform()->Origin());
-  EXPECT_EQ(TransformationMatrix().Translate(50, 100),
-            transform_properties->PaintOffsetTranslation()->Matrix());
+  EXPECT_TRUE(transform_properties->Transform()->IsIdentity());
+  EXPECT_EQ(FloatSize(), transform_properties->Transform()->Translation2D());
+  EXPECT_EQ(FloatPoint3D(), transform_properties->Transform()->Origin());
+  EXPECT_EQ(FloatSize(50, 100),
+            transform_properties->PaintOffsetTranslation()->Translation2D());
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
     EXPECT_TRUE(
         transform_properties->Transform()->HasDirectCompositingReasons());
@@ -766,11 +755,11 @@
       "margin-left: 50px; margin-top: 100px; width: 400px; height: 300px; "
       "will-change: transform");
   UpdateAllLifecyclePhasesForTest();
-  EXPECT_EQ(TransformationMatrix(), transform->GetLayoutObject()
-                                        ->FirstFragment()
-                                        .PaintProperties()
-                                        ->Transform()
-                                        ->Matrix());
+  EXPECT_TRUE(transform->GetLayoutObject()
+                  ->FirstFragment()
+                  .PaintProperties()
+                  ->Transform()
+                  ->IsIdentity());
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, WillChangeContents) {
@@ -796,8 +785,8 @@
   Element* inline_block = GetDocument().getElementById("inline-block");
   const ObjectPaintProperties* inline_block_properties =
       inline_block->GetLayoutObject()->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(135, 490),
-            inline_block_properties->PaintOffsetTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(135, 490),
+            inline_block_properties->PaintOffsetTranslation()->Translation2D());
   // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
   // scrolling.
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
@@ -911,8 +900,8 @@
   const ObjectPaintProperties* child_with_transform_properties =
       child_with_transform->FirstFragment().PaintProperties();
   EXPECT_EQ(nullptr, child_with_transform_properties->Effect());
-  EXPECT_EQ(TransformationMatrix().Translate(10, 10),
-            child_with_transform_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(10, 10),
+            child_with_transform_properties->Transform()->Translation2D());
   CHECK_EXACT_VISUAL_RECT(LayoutRect(18, 18, 50, 60), child_with_transform,
                           GetDocument().View()->GetLayoutView());
 
@@ -1131,9 +1120,9 @@
             svg_root_with3d_transform_properties->Transform()->Origin());
   EXPECT_EQ(svg_root_with3d_transform_properties->PaintOffsetTranslation(),
             svg_root_with3d_transform_properties->Transform()->Parent());
-  EXPECT_EQ(
-      TransformationMatrix().Translate(70, 25),
-      svg_root_with3d_transform_properties->PaintOffsetTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(70, 25),
+            svg_root_with3d_transform_properties->PaintOffsetTranslation()
+                ->Translation2D());
   // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
   // scrolling.
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
@@ -1191,16 +1180,16 @@
       svg_with_view_box.FirstFragment().PaintProperties();
   EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
             svg_with_view_box_properties->Transform()->Matrix());
-  EXPECT_EQ(TransformationMatrix().Translate(-50, -50),
-            svg_with_view_box_properties->ReplacedContentTransform()->Matrix());
+  EXPECT_EQ(FloatSize(-50, -50),
+            svg_with_view_box_properties->ReplacedContentTransform()
+                ->Translation2D());
   EXPECT_EQ(svg_with_view_box_properties->ReplacedContentTransform()->Parent(),
             svg_with_view_box_properties->Transform());
 
   LayoutObject& rect = *GetLayoutObjectByElementId("rect");
   const ObjectPaintProperties* rect_properties =
       rect.FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(100, 100),
-            rect_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(100, 100), rect_properties->Transform()->Translation2D());
   EXPECT_EQ(svg_with_view_box_properties->ReplacedContentTransform(),
             rect_properties->Transform()->Parent());
 }
@@ -1223,9 +1212,8 @@
   const ObjectPaintProperties* svg_properties =
       svg.FirstFragment().PaintProperties();
   EXPECT_TRUE(svg_properties->PaintOffsetTranslation());
-  EXPECT_EQ(
-      FloatSize(50, 25),
-      svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(50, 25),
+            svg_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(nullptr, svg_properties->ReplacedContentTransform());
   // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
   // scrolling.
@@ -1257,10 +1245,9 @@
   LayoutObject& svg = *GetLayoutObjectByElementId("svg");
   const ObjectPaintProperties* svg_properties =
       svg.FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(2, 3),
-            svg_properties->PaintOffsetTranslation()->Matrix());
-  EXPECT_EQ(TransformationMatrix().Translate(5, 7),
-            svg_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(2, 3),
+            svg_properties->PaintOffsetTranslation()->Translation2D());
+  EXPECT_EQ(FloatSize(5, 7), svg_properties->Transform()->Translation2D());
   EXPECT_EQ(TransformationMatrix().Translate(11, 11).Scale(100.0 / 13.0),
             svg_properties->ReplacedContentTransform()->Matrix());
   EXPECT_EQ(svg_properties->PaintOffsetTranslation(),
@@ -1273,8 +1260,7 @@
   LayoutObject& rect = *GetLayoutObjectByElementId("rect");
   const ObjectPaintProperties* rect_properties =
       rect.FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(17, 19),
-            rect_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(17, 19), rect_properties->Transform()->Translation2D());
   EXPECT_EQ(svg_properties->ReplacedContentTransform(),
             rect_properties->Transform()->Parent());
 }
@@ -1293,8 +1279,7 @@
   LayoutObject& svg = *GetLayoutObjectByElementId("svg");
   const ObjectPaintProperties* svg_properties =
       svg.FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(11, 11),
-            svg_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(11, 11), svg_properties->Transform()->Translation2D());
   EXPECT_EQ(TransformationMatrix().Scale(2),
             svg_properties->ReplacedContentTransform()->Matrix());
 
@@ -1310,8 +1295,7 @@
   LayoutObject& rect = *GetLayoutObjectByElementId("rect");
   const ObjectPaintProperties* rect_properties =
       rect.FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(13, 13),
-            rect_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(13, 13), rect_properties->Transform()->Translation2D());
   EXPECT_EQ(nested_svg_properties->Transform(),
             rect_properties->Transform()->Parent());
 }
@@ -1409,9 +1393,8 @@
   LayoutObject& svg = *GetLayoutObjectByElementId("svg");
   const ObjectPaintProperties* svg_properties =
       svg.FirstFragment().PaintProperties();
-  EXPECT_EQ(
-      FloatSize(8, 8),
-      svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(8, 8),
+            svg_properties->PaintOffsetTranslation()->Translation2D());
 
   LayoutObject& div_with_transform =
       *GetLayoutObjectByElementId("divWithTransform");
@@ -1419,10 +1402,9 @@
       div_with_transform.FirstFragment().PaintProperties();
   EXPECT_EQ(TransformationMatrix().Translate3d(3, 4, 5),
             div_with_transform_properties->Transform()->Matrix());
-  EXPECT_EQ(FloatSize(8, 158),
-            div_with_transform_properties->PaintOffsetTranslation()
-                ->Matrix()
-                .To2DTranslation());
+  EXPECT_EQ(
+      FloatSize(8, 158),
+      div_with_transform_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(div_with_transform_properties->PaintOffsetTranslation(),
             div_with_transform_properties->Transform()->Parent());
 }
@@ -1483,7 +1465,7 @@
   transform = properties4->Transform();
   EXPECT_EQ(nullptr, clip);
   ASSERT_NE(nullptr, transform);
-  EXPECT_EQ(TransformationMatrix().Translate(20, 30), transform->Matrix());
+  EXPECT_EQ(FloatSize(20, 30), transform->Translation2D());
   EXPECT_EQ(parent_transform, transform->Parent());
 }
 
@@ -1553,9 +1535,8 @@
   LayoutObject& svg = *GetLayoutObjectByElementId("svg");
   const ObjectPaintProperties* svg_properties =
       svg.FirstFragment().PaintProperties();
-  EXPECT_EQ(
-      FloatSize(8, 8),
-      svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(8, 8),
+            svg_properties->PaintOffsetTranslation()->Translation2D());
   LayoutObject& div_with_columns =
       *GetLayoutObjectByElementId("divWithColumns")->SlowFirstChild();
   EXPECT_EQ(LayoutPoint(0, 0), div_with_columns.FirstFragment().PaintOffset());
@@ -1586,8 +1567,8 @@
   LayoutObject& container = *GetLayoutObjectByElementId("container");
   const ObjectPaintProperties* container_properties =
       container.FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(20, 30),
-            container_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(20, 30),
+            container_properties->Transform()->Translation2D());
   EXPECT_EQ(svg_properties->Transform(),
             container_properties->Transform()->Parent());
 
@@ -1739,8 +1720,8 @@
   EXPECT_EQ(
       FloatRoundedRect(
           border_box_minus_border_outset,
-          FloatSize(0, 0),    // (top left) = max((12, 12) - (60, 45), (0, 0))
-          FloatSize(0, 0),    // (top right) = max((34, 34) - (50, 45), (0, 0))
+          FloatSize(),        // (top left) = max((12, 12) - (60, 45), (0, 0))
+          FloatSize(),        // (top right) = max((34, 34) - (50, 45), (0, 0))
           FloatSize(18, 23),  // (bot left) = max((78, 78) - (60, 55), (0, 0))
           FloatSize(6, 1)),   // (bot right) = max((56, 56) - (50, 55), (0, 0))
       border_radius_clip->ClipRect());
@@ -1809,14 +1790,12 @@
   //         ScrollTranslation transform=translation=0.000000,0.000000,0.000000
   //           Transform transform=translation=4.000000,5.000000,6.000000
   auto* inner_document_scroll_translation = inner_div_transform->Parent();
-  EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0),
-            inner_document_scroll_translation->Matrix());
+  EXPECT_TRUE(inner_document_scroll_translation->IsIdentity());
   auto* paint_offset_translation = inner_document_scroll_translation->Parent();
   auto* iframe_pre_translation =
       inner_document_scroll_translation->Parent()->Unalias().Parent();
-  EXPECT_EQ(FloatSize(), paint_offset_translation->Matrix().To2DTranslation());
-  EXPECT_EQ(TransformationMatrix().Translate3d(7, 7, 0),
-            iframe_pre_translation->Matrix());
+  EXPECT_TRUE(paint_offset_translation->IsIdentity());
+  EXPECT_EQ(FloatSize(7, 7), iframe_pre_translation->Translation2D());
   // SPv1 composited elements always create paint offset translation,
   // where in CAP they don't.
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
@@ -1828,8 +1807,9 @@
         iframe_element->FirstFragment().PaintProperties();
     EXPECT_EQ(iframe_element_properties->PaintOffsetTranslation(),
               iframe_pre_translation->Parent());
-    EXPECT_EQ(TransformationMatrix(),
-              iframe_element_properties->PaintOffsetTranslation()->Matrix());
+    EXPECT_EQ(
+        FloatSize(),
+        iframe_element_properties->PaintOffsetTranslation()->Translation2D());
     EXPECT_EQ(div_with_transform_properties->Transform(),
               iframe_element_properties->PaintOffsetTranslation()->Parent());
   }
@@ -1884,8 +1864,8 @@
   //  - transform isolation node
   //    - paint offset translation
   //      - transform
-  EXPECT_EQ(TransformationMatrix().Translate(50, 0),
-            child_local_border_box_properties.Transform().Matrix());
+  EXPECT_EQ(FloatSize(50, 0),
+            child_local_border_box_properties.Transform().Translation2D());
   EXPECT_EQ(child_local_border_box_properties.Transform().Parent(),
             child_properties->PaintOffsetTranslation());
   EXPECT_EQ(child_local_border_box_properties.Transform().Parent()->Parent(),
@@ -1913,14 +1893,13 @@
 // this only runs if we don't have DCHECKs enabled.
 #if !DCHECK_IS_ON()
   // Now clobber the child transform to something identifiable.
-  TransformPaintPropertyNode::State state{
-      TransformationMatrix().Translate(123, 321)};
+  TransformPaintPropertyNode::State state{FloatSize(123, 321)};
   child_properties->UpdateTransform(
       *child_local_border_box_properties.Transform().Parent(),
       std::move(state));
   // Verify that we clobbered it correctly.
-  EXPECT_EQ(TransformationMatrix().Translate(123, 321),
-            child_local_border_box_properties.Transform().Matrix());
+  EXPECT_EQ(FloatSize(123, 321),
+            child_local_border_box_properties.Transform().Translation2D());
 
   // This causes a tree topology change which forces the subtree to be updated.
   // However, isolation stops this recursion.
@@ -1930,8 +1909,8 @@
       DocumentLifecycle::LifecycleUpdateReason::kTest);
 
   // Verify that our clobbered state is still clobbered.
-  EXPECT_EQ(TransformationMatrix().Translate(123, 321),
-            child_local_border_box_properties.Transform().Matrix());
+  EXPECT_EQ(FloatSize(123, 321),
+            child_local_border_box_properties.Transform().Translation2D());
 #endif  // !DCHECK_IS_ON()
 }
 
@@ -1988,21 +1967,18 @@
                           frame_view->GetLayoutView());
 
   auto* inner_document_paint_offset_translation = inner_div_transform->Parent();
-  EXPECT_EQ(TransformationMatrix().Translate3d(31, 31, 0),
-            inner_document_paint_offset_translation->Matrix());
+  EXPECT_EQ(FloatSize(31, 31),
+            inner_document_paint_offset_translation->Translation2D());
   auto& inner_document_scroll_translation =
       inner_document_paint_offset_translation->Parent()->Unalias();
-  EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0),
-            inner_document_scroll_translation.Matrix());
+  EXPECT_TRUE(inner_document_scroll_translation.IsIdentity());
   auto* iframe_pre_translation = inner_document_scroll_translation.Parent();
-  EXPECT_EQ(TransformationMatrix().Translate3d(42, 42, 0),
-            iframe_pre_translation->Matrix());
+  EXPECT_EQ(FloatSize(42, 42), iframe_pre_translation->Translation2D());
   auto* iframe_transform = iframe_pre_translation->Parent();
   EXPECT_EQ(TransformationMatrix().Translate3d(4, 5, 6),
             iframe_transform->Matrix());
   auto* iframe_paint_offset_translation = iframe_transform->Parent();
-  EXPECT_EQ(TransformationMatrix().Translate3d(7, 7, 0),
-            iframe_paint_offset_translation->Matrix());
+  EXPECT_EQ(FloatSize(7, 7), iframe_paint_offset_translation->Translation2D());
   auto* div_with_transform_transform =
       iframe_paint_offset_translation->Parent();
   EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
@@ -2509,11 +2485,9 @@
   LayoutObject* b = GetLayoutObjectByElementId("b");
   const ObjectPaintProperties* b_properties =
       b->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0),
-            b_properties->Transform()->Matrix());
+  EXPECT_TRUE(b_properties->Transform()->IsIdentity());
   // The paint offset transform should be snapped from (0.3,0.3) to (0,0).
-  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
-            b_properties->Transform()->Parent()->Matrix());
+  EXPECT_TRUE(b_properties->Transform()->Parent()->IsIdentity());
   // The residual subpixel adjustment should be (0.3,0.3) - (0,0) = (0.3,0.3).
   LayoutPoint subpixel_accumulation = LayoutPoint(FloatPoint(0.3, 0.3));
   EXPECT_EQ(subpixel_accumulation, b->FirstFragment().PaintOffset());
@@ -2567,11 +2541,10 @@
   LayoutObject* b = GetLayoutObjectByElementId("b");
   const ObjectPaintProperties* b_properties =
       b->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0),
-            b_properties->Transform()->Matrix());
+  EXPECT_TRUE(b_properties->Transform()->IsIdentity());
   // The paint offset transform should be snapped from (0.7,0.7) to (1,1).
-  EXPECT_EQ(TransformationMatrix().Translate(1, 1),
-            b_properties->Transform()->Parent()->Matrix());
+  EXPECT_EQ(FloatSize(1, 1),
+            b_properties->Transform()->Parent()->Translation2D());
   // The residual subpixel adjustment should be (0.7,0.7) - (1,1) = (-0.3,-0.3).
   LayoutPoint subpixel_accumulation =
       LayoutPoint(LayoutPoint(FloatPoint(0.7, 0.7)) - LayoutPoint(1, 1));
@@ -2633,8 +2606,8 @@
   EXPECT_EQ(TransformationMatrix().Scale(10),
             b_properties->Transform()->Matrix());
   // The paint offset transform should not be snapped.
-  EXPECT_EQ(TransformationMatrix().Translate(1, 1),
-            b_properties->Transform()->Parent()->Matrix());
+  EXPECT_EQ(FloatSize(1, 1),
+            b_properties->Transform()->Parent()->Translation2D());
   EXPECT_EQ(LayoutPoint(), b->FirstFragment().PaintOffset());
   // Visual rects via the non-paint properties system use enclosingIntRect
   // before applying transforms, because they are computed bottom-up and
@@ -2699,11 +2672,10 @@
   LayoutObject* b = GetLayoutObjectByElementId("b");
   const ObjectPaintProperties* b_properties =
       b->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate3d(5, 7, 0),
-            b_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(5, 7), b_properties->Transform()->Translation2D());
   // The paint offset transform should be snapped from (0.7,0.7) to (1,1).
-  EXPECT_EQ(TransformationMatrix().Translate(1, 1),
-            b_properties->Transform()->Parent()->Matrix());
+  EXPECT_EQ(FloatSize(1, 1),
+            b_properties->Transform()->Parent()->Translation2D());
   // The residual subpixel adjustment should be (0.7,0.7) - (1,1) = (-0.3,-0.3).
   LayoutPoint subpixel_accumulation =
       LayoutPoint(LayoutPoint(FloatPoint(0.7, 0.7)) - LayoutPoint(1, 1));
@@ -2715,12 +2687,10 @@
   LayoutObject* c = GetLayoutObjectByElementId("c");
   const ObjectPaintProperties* c_properties =
       c->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate3d(11, 13, 0),
-            c_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(11, 13), c_properties->Transform()->Translation2D());
   // The paint offset should be (-0.3,-0.3) but the paint offset transform
   // should still be at (0,0) because it should be snapped.
-  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
-            c_properties->Transform()->Parent()->Matrix());
+  EXPECT_EQ(FloatSize(), c_properties->Transform()->Parent()->Translation2D());
   // The residual subpixel adjustment should still be (-0.3,-0.3).
   EXPECT_EQ(subpixel_accumulation, c->FirstFragment().PaintOffset());
   CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(16.7), LayoutUnit(20.7),
@@ -2783,11 +2753,10 @@
   LayoutObject* b = GetLayoutObjectByElementId("b");
   const ObjectPaintProperties* b_properties =
       b->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
-            b_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(), b_properties->Transform()->Translation2D());
   // The paint offset transform should be snapped from (0.7,0) to (1,0).
-  EXPECT_EQ(TransformationMatrix().Translate(1, 0),
-            b_properties->Transform()->Parent()->Matrix());
+  EXPECT_EQ(FloatSize(1, 0),
+            b_properties->Transform()->Parent()->Translation2D());
   // The residual subpixel adjustment should be (0.7,0) - (1,0) = (-0.3,0).
   LayoutPoint subpixel_accumulation =
       LayoutPoint(LayoutPoint(FloatPoint(0.7, 0)) - LayoutPoint(1, 0));
@@ -2833,8 +2802,7 @@
   LayoutObject& svg_with_transform = *GetLayoutObjectByElementId("svg");
   const ObjectPaintProperties* svg_with_transform_properties =
       svg_with_transform.FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix(),
-            svg_with_transform_properties->Transform()->Matrix());
+  EXPECT_TRUE(svg_with_transform_properties->Transform()->IsIdentity());
   EXPECT_EQ(LayoutPoint(FloatPoint(0.1, 0)),
             svg_with_transform.FirstFragment().PaintOffset());
   EXPECT_TRUE(svg_with_transform_properties->ReplacedContentTransform() ==
@@ -2843,8 +2811,8 @@
   LayoutObject& rect_with_transform = *GetLayoutObjectByElementId("rect");
   const ObjectPaintProperties* rect_with_transform_properties =
       rect_with_transform.FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(1, 1),
-            rect_with_transform_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(1, 1),
+            rect_with_transform_properties->Transform()->Translation2D());
 
   // Ensure there is no PaintOffset transform between the rect and the svg's
   // transform.
@@ -2866,9 +2834,8 @@
   const auto* svg_properties = svg->FirstFragment().PaintProperties();
   // The paint offset of (8.6, 8.3) is rounded off here. The fractional part
   // remains PaintOffset.
-  EXPECT_EQ(
-      FloatSize(9, 8),
-      svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(9, 8),
+            svg_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(LayoutPoint(LayoutUnit(-0.40625), LayoutUnit(0.3)),
             svg->FirstFragment().PaintOffset());
   EXPECT_EQ(nullptr, svg_properties->ReplacedContentTransform());
@@ -3160,7 +3127,7 @@
   const auto* a_properties = PaintPropertiesForElement("a");
   ASSERT_NE(a_properties, nullptr);
   ASSERT_NE(a_properties->Transform(), nullptr);
-  EXPECT_EQ(TransformationMatrix(), a_properties->Transform()->Matrix());
+  EXPECT_TRUE(a_properties->Transform()->IsIdentity());
   EXPECT_TRUE(a_properties->Transform()->HasRenderingContext());
   EXPECT_TRUE(a_properties->Transform()->FlattensInheritedTransform());
   EXPECT_EQ(a_properties->Effect(), nullptr);
@@ -3249,24 +3216,21 @@
       a->GetLayoutObject()->FirstFragment().PaintProperties();
   const TransformPaintPropertyNode* a_transform_node =
       a_properties->Transform();
-  EXPECT_EQ(TransformationMatrix().Translate(33, 44),
-            a_transform_node->Matrix());
+  EXPECT_EQ(FloatSize(33, 44), a_transform_node->Translation2D());
 
   Element* b = GetDocument().getElementById("b");
   const ObjectPaintProperties* b_properties =
       b->GetLayoutObject()->FirstFragment().PaintProperties();
   const TransformPaintPropertyNode* b_transform_node =
       b_properties->Transform();
-  EXPECT_EQ(TransformationMatrix().Translate(55, 66),
-            b_transform_node->Matrix());
+  EXPECT_EQ(FloatSize(55, 66), b_transform_node->Translation2D());
 
   Element* c = GetDocument().getElementById("c");
   const ObjectPaintProperties* c_properties =
       c->GetLayoutObject()->FirstFragment().PaintProperties();
   const TransformPaintPropertyNode* c_transform_node =
       c_properties->Transform();
-  EXPECT_EQ(TransformationMatrix().Translate(77, 88),
-            c_transform_node->Matrix());
+  EXPECT_EQ(FloatSize(77, 88), c_transform_node->Translation2D());
 
   CHECK_EXACT_VISUAL_RECT(LayoutRect(33, 44, 50, 60), a->GetLayoutObject(),
                           frame_view->GetLayoutView());
@@ -3288,8 +3252,7 @@
   EXPECT_EQ(b_properties,
             b->GetLayoutObject()->FirstFragment().PaintProperties());
   b_transform_node = b_properties->Transform();
-  EXPECT_EQ(TransformationMatrix().Translate(111, 222),
-            b_transform_node->Matrix());
+  EXPECT_EQ(FloatSize(111, 222), b_transform_node->Translation2D());
   EXPECT_EQ(a_transform_node, b_transform_node->Parent()->Parent());
 
   EXPECT_EQ(c_properties,
@@ -3342,7 +3305,7 @@
   EXPECT_EQ(b_properties,
             b->GetLayoutObject()->FirstFragment().PaintProperties());
   b_transform_node = b_properties->Transform();
-  EXPECT_EQ(TransformationMatrix().Translate(4, 5), b_transform_node->Matrix());
+  EXPECT_EQ(FloatSize(4, 5), b_transform_node->Translation2D());
   EXPECT_EQ(a_transform_node, b_transform_node->Parent()->Parent());
 
   EXPECT_EQ(c_properties,
@@ -3499,8 +3462,7 @@
     // Verify transform:
 
     // Isolation transform node should be identity.
-    EXPECT_EQ(clip_properties->TransformIsolationNode()->Matrix(),
-              TransformationMatrix());
+    EXPECT_TRUE(clip_properties->TransformIsolationNode()->IsIdentity());
 
     // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
     // scrolling.
@@ -3593,9 +3555,8 @@
             &clipper->FirstFragment().LocalBorderBoxProperties().Clip());
 
   auto contents_properties = clipper->FirstFragment().ContentsProperties();
-  EXPECT_EQ(
-      FloatSize(30, 20),
-      clip_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(30, 20),
+            clip_properties->PaintOffsetTranslation()->Translation2D());
   EXPECT_EQ(LayoutPoint(0, 0), clipper->FirstFragment().PaintOffset());
   EXPECT_EQ(clip_properties->ScrollTranslation(),
             &contents_properties.Transform());
@@ -3739,8 +3700,7 @@
   } else {
     EXPECT_EQ(DocScrollTranslation(), paint_offset_translation->Parent());
   }
-  EXPECT_EQ(FloatSize(30, 20),
-            paint_offset_translation->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(30, 20), paint_offset_translation->Translation2D());
   EXPECT_EQ(LayoutPoint(0, 0), svg_with_view_box.FirstFragment().PaintOffset());
 
   const auto* replaced_content_transform = svg_with_view_box.FirstFragment()
@@ -3750,8 +3710,7 @@
       replaced_content_transform,
       &svg_with_view_box.FirstFragment().ContentsProperties().Transform());
   EXPECT_EQ(paint_offset_translation, replaced_content_transform->Parent());
-  EXPECT_EQ(FloatSize(-50, -50),
-            replaced_content_transform->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(-50, -50), replaced_content_transform->Translation2D());
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, OverflowHiddenScrollProperties) {
@@ -3786,8 +3745,7 @@
   // offset, there should be a scroll translation node but no scroll node.
   auto* scroll_translation =
       overflow_hidden_scroll_properties->ScrollTranslation();
-  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
-            scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -37), scroll_translation->Translation2D());
   EXPECT_EQ(nullptr, scroll_translation->ScrollNode());
   EXPECT_EQ(nullptr, overflow_hidden_scroll_properties->Scroll());
 }
@@ -3812,8 +3770,7 @@
 
   UpdateAllLifecyclePhasesForTest();
 
-  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
-            DocScrollTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, -37), DocScrollTranslation()->Translation2D());
 
   // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
   // scrolling.
@@ -3880,8 +3837,7 @@
   } else {
     EXPECT_EQ(DocScroll(), overflow_a_scroll_node->Parent());
   }
-  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
-            scroll_a_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -37), scroll_a_translation->Translation2D());
   EXPECT_EQ(IntRect(0, 0, 5, 3), overflow_a_scroll_node->ContainerRect());
   // 107 is the forceScroll element plus the height of the overflow scroll child
   // (overflowB).
@@ -3897,8 +3853,7 @@
       overflow_b_scroll_properties->ScrollTranslation();
   auto* overflow_b_scroll_node = scroll_b_translation->ScrollNode();
   EXPECT_EQ(overflow_a_scroll_node, overflow_b_scroll_node->Parent());
-  EXPECT_EQ(TransformationMatrix().Translate(0, -41),
-            scroll_b_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -41), scroll_b_translation->Translation2D());
   EXPECT_EQ(IntRect(0, 0, 9, 7), overflow_b_scroll_node->ContainerRect());
   EXPECT_EQ(IntSize(9, 100), overflow_b_scroll_node->ContentsSize());
   EXPECT_TRUE(overflow_b_scroll_node->UserScrollableHorizontal());
@@ -3967,8 +3922,7 @@
   EXPECT_EQ(
       DocScroll(),
       overflow_scroll_properties->ScrollTranslation()->ScrollNode()->Parent());
-  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
-            scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -37), scroll_translation->Translation2D());
   EXPECT_EQ(IntRect(0, 0, 5, 3), overflow_scroll_node->ContainerRect());
   // The height should be 4000px because the (dom-order) overflow children are
   // positioned and do not contribute to the height. Only the 4000px
@@ -3983,8 +3937,7 @@
   // The absolute position overflow scroll node is parented under the frame, not
   // the dom-order parent.
   EXPECT_EQ(DocScroll(), abspos_overflow_scroll_node->Parent());
-  EXPECT_EQ(TransformationMatrix().Translate(0, -41),
-            abspos_scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -41), abspos_scroll_translation->Translation2D());
   EXPECT_EQ(IntRect(0, 0, 9, 7), abspos_overflow_scroll_node->ContainerRect());
   EXPECT_EQ(IntSize(9, 4000), abspos_overflow_scroll_node->ContentsSize());
 
@@ -4001,8 +3954,7 @@
                 .GetScrollTranslationNode()
                 ->ScrollNode(),
             fixed_overflow_scroll_node->Parent());
-  EXPECT_EQ(TransformationMatrix().Translate(0, -43),
-            fixed_scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -43), fixed_scroll_translation->Translation2D());
   EXPECT_EQ(IntRect(0, 0, 13, 11), fixed_overflow_scroll_node->ContainerRect());
   EXPECT_EQ(IntSize(13, 4000), fixed_overflow_scroll_node->ContentsSize());
 }
@@ -4067,8 +4019,7 @@
   } else {
     EXPECT_EQ(DocScroll(), overflow_a_scroll_node->Parent());
   }
-  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
-            scroll_a_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -37), scroll_a_translation->Translation2D());
   EXPECT_EQ(IntRect(0, 0, 20, 20), overflow_a_scroll_node->ContainerRect());
   // 100 is the forceScroll element's height because the overflow child does not
   // contribute to the height.
@@ -4084,8 +4035,7 @@
       overflow_b_scroll_properties->ScrollTranslation();
   auto* overflow_b_scroll_node = scroll_b_translation->ScrollNode();
   EXPECT_EQ(overflow_a_scroll_node, overflow_b_scroll_node->Parent());
-  EXPECT_EQ(TransformationMatrix().Translate(0, -41),
-            scroll_b_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -41), scroll_b_translation->Translation2D());
   EXPECT_EQ(IntRect(0, 0, 5, 3), overflow_b_scroll_node->ContainerRect());
   EXPECT_EQ(IntSize(5, 100), overflow_b_scroll_node->ContentsSize());
   EXPECT_TRUE(overflow_b_scroll_node->UserScrollableHorizontal());
@@ -4108,8 +4058,7 @@
                                  ->FirstFragment()
                                  .PaintProperties()
                                  ->PaintOffsetTranslation()
-                                 ->Matrix()
-                                 .To2DTranslation());
+                                 ->Translation2D());
   EXPECT_EQ(FloatRoundedRect(0, 0, 100, 100), clip->ClipRect());
 }
 
@@ -4183,8 +4132,7 @@
   EXPECT_EQ(FloatSize(8, 8), scroller->FirstFragment()
                                  .PaintProperties()
                                  ->PaintOffsetTranslation()
-                                 ->Matrix()
-                                 .To2DTranslation());
+                                 ->Translation2D());
 }
 
 TEST_P(PaintPropertyTreeBuilderTest,
@@ -4807,34 +4755,36 @@
         width: 400px;
         height: 100px;
       }
-      #transform {
+      #translation {
         transform: translate(100px, 200px);
         transform-origin: 75% 75% 0;
       }
+      #scale {
+        transform: scale(2);
+        transform-origin: 75% 75% 0;
+      }
       #willChange {
         will-change: opacity;
         transform-origin: 75% 75% 0;
       }
     </style>
-    <div id='transform'></div>
+    <div id='translation'></div>
+    <div id='scale'></div>
     <div id='willChange'></div>
   )HTML");
 
-  auto* transform = GetLayoutObjectByElementId("transform");
-  EXPECT_EQ(
-      TransformationMatrix().Translate3d(100, 200, 0),
-      transform->FirstFragment().PaintProperties()->Transform()->Matrix());
-  EXPECT_EQ(
-      FloatPoint3D(300, 75, 0),
-      transform->FirstFragment().PaintProperties()->Transform()->Origin());
+  auto* translation = PaintPropertiesForElement("translation")->Transform();
+  EXPECT_EQ(FloatSize(100, 200), translation->Translation2D());
+  // We don't need to store origin for 2d-translation.
+  EXPECT_EQ(FloatPoint3D(), translation->Origin());
 
-  auto* will_change = GetLayoutObjectByElementId("willChange");
-  EXPECT_EQ(
-      TransformationMatrix().Translate3d(0, 0, 0),
-      will_change->FirstFragment().PaintProperties()->Transform()->Matrix());
-  EXPECT_EQ(
-      FloatPoint3D(0, 0, 0),
-      will_change->FirstFragment().PaintProperties()->Transform()->Origin());
+  auto* scale = PaintPropertiesForElement("scale")->Transform();
+  EXPECT_EQ(TransformationMatrix().Scale(2), scale->Matrix());
+  EXPECT_EQ(FloatPoint3D(300, 75, 0), scale->Origin());
+
+  auto* will_change = PaintPropertiesForElement("willChange")->Transform();
+  EXPECT_TRUE(will_change->IsIdentity());
+  EXPECT_EQ(FloatPoint3D(), will_change->Origin());
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, TransformOriginWithAndWithoutMotionPath) {
@@ -4862,19 +4812,22 @@
   )HTML");
 
   auto* motion_path = GetLayoutObjectByElementId("motionPath");
+  EXPECT_EQ(FloatSize(50, 150), motion_path->FirstFragment()
+                                    .PaintProperties()
+                                    ->Transform()
+                                    ->Translation2D());
+  // We don't need to store origin for 2d-translation.
   EXPECT_EQ(
-      TransformationMatrix().Translate3d(50, 150, 0),
-      motion_path->FirstFragment().PaintProperties()->Transform()->Matrix());
-  EXPECT_EQ(
-      FloatPoint3D(50, 50, 0),
+      FloatPoint3D(),
       motion_path->FirstFragment().PaintProperties()->Transform()->Origin());
 
   auto* will_change = GetLayoutObjectByElementId("willChange");
+  EXPECT_TRUE(will_change->FirstFragment()
+                  .PaintProperties()
+                  ->Transform()
+                  ->IsIdentity());
   EXPECT_EQ(
-      TransformationMatrix().Translate3d(0, 0, 0),
-      will_change->FirstFragment().PaintProperties()->Transform()->Matrix());
-  EXPECT_EQ(
-      FloatPoint3D(0, 0, 0),
+      FloatPoint3D(),
       will_change->FirstFragment().PaintProperties()->Transform()->Origin());
 }
 
@@ -5351,19 +5304,16 @@
   } else {
     EXPECT_EQ(DocScroll(), scroll_node->Parent());
   }
-  EXPECT_EQ(TransformationMatrix().Translate(0, -42),
-            scroll_translation->Matrix());
+  EXPECT_EQ(FloatSize(0, -42), scroll_translation->Translation2D());
   // The paint offset node should be offset by the margin.
-  EXPECT_EQ(FloatSize(7, 11),
-            paint_offset_translation->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(7, 11), paint_offset_translation->Translation2D());
   // And the scroll node should not.
   EXPECT_EQ(IntRect(0, 0, 100, 100), scroll_node->ContainerRect());
 
   scroller->setAttribute(html_names::kStyleAttr, "border: 20px solid black;");
   UpdateAllLifecyclePhasesForTest();
   // The paint offset node should be offset by the margin.
-  EXPECT_EQ(FloatSize(7, 11),
-            paint_offset_translation->Matrix().To2DTranslation());
+  EXPECT_EQ(FloatSize(7, 11), paint_offset_translation->Translation2D());
   // The scroll node should be offset by the border.
   EXPECT_EQ(IntRect(20, 20, 100, 100), scroll_node->ContainerRect());
 
@@ -5374,8 +5324,8 @@
   // The scroll node's offset should not include margin if it has already been
   // included in a paint offset node.
   EXPECT_EQ(IntRect(20, 20, 100, 100), scroll_node->ContainerRect());
-  EXPECT_EQ(TransformationMatrix().Translate(7, 11),
-            scroll_properties->PaintOffsetTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(7, 11),
+            scroll_properties->PaintOffsetTranslation()->Translation2D());
 }
 
 
@@ -5396,8 +5346,7 @@
   } else {
     // For SPv1, |target| is composited so we created PaintOffsetTranslation.
     ASSERT_NE(nullptr, paint_offset_translation);
-    EXPECT_EQ(TransformationMatrix().Translate(60, 50),
-              paint_offset_translation->Matrix());
+    EXPECT_EQ(FloatSize(60, 50), paint_offset_translation->Translation2D());
     EXPECT_EQ(TransformPaintPropertyNode::BackfaceVisibility::kInherited,
               paint_offset_translation->GetBackfaceVisibility());
   }
@@ -5406,7 +5355,7 @@
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
       RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
     ASSERT_NE(nullptr, transform);
-    EXPECT_TRUE(transform->Matrix().IsIdentity());
+    EXPECT_TRUE(transform->IsIdentity());
     EXPECT_EQ(TransformPaintPropertyNode::BackfaceVisibility::kHidden,
               transform->GetBackfaceVisibility());
   } else {
@@ -5979,10 +5928,9 @@
     EXPECT_EQ(LayoutPoint(), fragment.PaintOffset());
     EXPECT_EQ(LayoutUnit(i * 400), fragment.LogicalTopInFlowThread());
     const auto* properties = fragment.PaintProperties();
-    EXPECT_EQ(TransformationMatrix().Translate(20, -180 + i * 400),
-              properties->PaintOffsetTranslation()->Matrix());
-    EXPECT_EQ(TransformationMatrix().Translate(10, 0),
-              properties->Transform()->Matrix());
+    EXPECT_EQ(FloatSize(20, -180 + i * 400),
+              properties->PaintOffsetTranslation()->Translation2D());
+    EXPECT_EQ(FloatSize(10, 0), properties->Transform()->Translation2D());
     EXPECT_EQ(properties->PaintOffsetTranslation(),
               properties->Transform()->Parent());
   }
@@ -6246,8 +6194,8 @@
 
   const auto* outer_properties = PaintPropertiesForElement("outer");
   ASSERT_TRUE(outer_properties && outer_properties->StickyTranslation());
-  EXPECT_EQ(TransformationMatrix().Translate(0, 60),
-            outer_properties->StickyTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, 60),
+            outer_properties->StickyTranslation()->Translation2D());
   ASSERT_NE(nullptr,
             outer_properties->StickyTranslation()->GetStickyConstraint());
   EXPECT_TRUE(
@@ -6262,8 +6210,8 @@
 
   const auto* middle_properties = PaintPropertiesForElement("middle");
   ASSERT_TRUE(middle_properties && middle_properties->StickyTranslation());
-  EXPECT_EQ(TransformationMatrix().Translate(0, 15),
-            middle_properties->StickyTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, 15),
+            middle_properties->StickyTranslation()->Translation2D());
   ASSERT_NE(nullptr,
             middle_properties->StickyTranslation()->GetStickyConstraint());
   EXPECT_TRUE(
@@ -6278,8 +6226,8 @@
 
   const auto* inner_properties = PaintPropertiesForElement("inner");
   ASSERT_TRUE(inner_properties && inner_properties->StickyTranslation());
-  EXPECT_EQ(TransformationMatrix().Translate(0, 20),
-            inner_properties->StickyTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, 20),
+            inner_properties->StickyTranslation()->Translation2D());
   ASSERT_NE(nullptr,
             inner_properties->StickyTranslation()->GetStickyConstraint());
   EXPECT_TRUE(
@@ -6315,22 +6263,22 @@
 
   const auto* outer_properties = PaintPropertiesForElement("outer");
   ASSERT_TRUE(outer_properties && outer_properties->StickyTranslation());
-  EXPECT_EQ(TransformationMatrix().Translate(0, 60),
-            outer_properties->StickyTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, 60),
+            outer_properties->StickyTranslation()->Translation2D());
   EXPECT_EQ(nullptr,
             outer_properties->StickyTranslation()->GetStickyConstraint());
 
   const auto* middle_properties = PaintPropertiesForElement("middle");
   ASSERT_TRUE(middle_properties && middle_properties->StickyTranslation());
-  EXPECT_EQ(TransformationMatrix().Translate(0, 15),
-            middle_properties->StickyTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, 15),
+            middle_properties->StickyTranslation()->Translation2D());
   EXPECT_EQ(nullptr,
             middle_properties->StickyTranslation()->GetStickyConstraint());
 
   const auto* inner_properties = PaintPropertiesForElement("inner");
   ASSERT_TRUE(inner_properties && inner_properties->StickyTranslation());
-  EXPECT_EQ(TransformationMatrix().Translate(0, 20),
-            inner_properties->StickyTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, 20),
+            inner_properties->StickyTranslation()->Translation2D());
   EXPECT_EQ(nullptr,
             inner_properties->StickyTranslation()->GetStickyConstraint());
 }
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_printer_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_printer_test.cc
index 6a860a14..a34a4c9 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_printer_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_printer_test.cc
@@ -66,8 +66,8 @@
 
 TEST_P(PaintPropertyTreePrinterTest, SimpleTransformTreePath) {
   SetBodyInnerHTML(
-      "<div id='transform' style='transform: translate3d(10px, 10px, "
-      "0px);'></div>");
+      "<div id='transform' style='transform: translate3d(10px, 10px, 10px);'>"
+      "</div>");
   LayoutObject* transformed_object =
       GetDocument().getElementById("transform")->GetLayoutObject();
   const auto* transformed_object_properties =
@@ -77,7 +77,7 @@
   EXPECT_THAT(transform_path_as_string.Ascii().data(),
               testing::MatchesRegex("root .*\"scroll\".*"
                                     "  .*\"parent\".*"
-                                    "    .*\"matrix\".*"
+                                    "    .*\"translation2d\".*"
                                     "      .*\"matrix\".*"));
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
index 1d2cdf0..78a548bb 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -740,20 +740,18 @@
 
   auto* transform = GetDocument().getElementById("transform");
   auto* transform_object = transform->GetLayoutObject();
-  EXPECT_EQ(TransformationMatrix().Translate3d(50, 100, 0),
-            transform_object->FirstFragment()
-                .PaintProperties()
-                ->Transform()
-                ->Matrix());
+  EXPECT_EQ(FloatSize(50, 100), transform_object->FirstFragment()
+                                    .PaintProperties()
+                                    ->Transform()
+                                    ->Translation2D());
 
   transform->setAttribute(html_names::kStyleAttr,
                           "width: 200px; height: 300px;");
   UpdateAllLifecyclePhasesForTest();
-  EXPECT_EQ(TransformationMatrix().Translate3d(100, 150, 0),
-            transform_object->FirstFragment()
-                .PaintProperties()
-                ->Transform()
-                ->Matrix());
+  EXPECT_EQ(FloatSize(100, 150), transform_object->FirstFragment()
+                                     .PaintProperties()
+                                     ->Transform()
+                                     ->Translation2D());
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, CSSClipDependingOnSize) {
@@ -1594,9 +1592,8 @@
   auto* child = GetLayoutObjectByElementId("child");
   EXPECT_EQ(LayoutPoint(LayoutUnit(10.25), LayoutUnit()),
             parent->FirstFragment().PaintOffset());
-  EXPECT_EQ(FloatSize(10, 0), isolation_properties->PaintOffsetTranslation()
-                                  ->Matrix()
-                                  .To2DTranslation());
+  EXPECT_EQ(FloatSize(10, 0),
+            isolation_properties->PaintOffsetTranslation()->Translation2D());
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
     EXPECT_EQ(LayoutPoint(), child->FirstFragment().PaintOffset());
   } else {
@@ -1609,9 +1606,8 @@
 
   EXPECT_EQ(LayoutPoint(LayoutUnit(12.75), LayoutUnit()),
             parent->FirstFragment().PaintOffset());
-  EXPECT_EQ(FloatSize(13, 0), isolation_properties->PaintOffsetTranslation()
-                                  ->Matrix()
-                                  .To2DTranslation());
+  EXPECT_EQ(FloatSize(13, 0),
+            isolation_properties->PaintOffsetTranslation()->Translation2D());
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
     EXPECT_EQ(LayoutPoint(), child->FirstFragment().PaintOffset());
   } else {
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
index 5d140b5..f4085af 100644
--- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
+++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
@@ -69,8 +69,8 @@
   auto* transformed_element = GetDocument().getElementById("transformed");
   const auto* transformed_properties =
       transformed_element->GetLayoutObject()->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(100, 100),
-            transformed_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(100, 100),
+            transformed_properties->Transform()->Translation2D());
 
   // Artifically change the transform node.
   const_cast<ObjectPaintProperties*>(transformed_properties)->ClearTransform();
@@ -81,21 +81,19 @@
   UpdateAllLifecyclePhasesForTest();
 
   // Should have changed back.
-  EXPECT_EQ(TransformationMatrix().Translate(100, 100),
-            transformed_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(100, 100),
+            transformed_properties->Transform()->Translation2D());
 }
 
 TEST_P(PrePaintTreeWalkTest, PropertyTreesRebuiltWithFrameScroll) {
   SetBodyInnerHTML("<style> body { height: 10000px; } </style>");
-  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
-            FrameScrollTranslation()->Matrix());
+  EXPECT_TRUE(FrameScrollTranslation()->IsIdentity());
 
   // Cause a scroll invalidation and ensure the translation is updated.
   GetDocument().domWindow()->scrollTo(0, 100);
   UpdateAllLifecyclePhasesForTest();
 
-  EXPECT_EQ(TransformationMatrix().Translate(0, -100),
-            FrameScrollTranslation()->Matrix());
+  EXPECT_EQ(FloatSize(0, -100), FrameScrollTranslation()->Translation2D());
 }
 
 TEST_P(PrePaintTreeWalkTest, PropertyTreesRebuiltWithCSSTransformInvalidation) {
@@ -111,16 +109,16 @@
   auto* transformed_element = GetDocument().getElementById("transformed");
   const auto* transformed_properties =
       transformed_element->GetLayoutObject()->FirstFragment().PaintProperties();
-  EXPECT_EQ(TransformationMatrix().Translate(100, 100),
-            transformed_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(100, 100),
+            transformed_properties->Transform()->Translation2D());
 
   // Invalidate the CSS transform property.
   transformed_element->setAttribute(html_names::kClassAttr, "transformB");
   UpdateAllLifecyclePhasesForTest();
 
   // The transform should have changed.
-  EXPECT_EQ(TransformationMatrix().Translate(200, 200),
-            transformed_properties->Transform()->Matrix());
+  EXPECT_EQ(FloatSize(200, 200),
+            transformed_properties->Transform()->Translation2D());
 }
 
 TEST_P(PrePaintTreeWalkTest, PropertyTreesRebuiltWithOpacityInvalidation) {
diff --git a/third_party/blink/renderer/core/paint/scoped_paint_state.cc b/third_party/blink/renderer/core/paint/scoped_paint_state.cc
index 67e86f83..33b485a 100644
--- a/third_party/blink/renderer/core/paint/scoped_paint_state.cc
+++ b/third_party/blink/renderer/core/paint/scoped_paint_state.cc
@@ -19,7 +19,7 @@
     // are painting table row background behind a cell having paint offset
     // translation.
     input_paint_info_.context.Save();
-    FloatSize translation = paint_offset_translation.Matrix().To2DTranslation();
+    FloatSize translation = paint_offset_translation.Translation2D();
     input_paint_info_.context.Translate(translation.Width(),
                                         translation.Height());
     paint_offset_translation_as_drawing_ = true;
diff --git a/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h b/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h
index 67e6f597..479b12c 100644
--- a/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h
+++ b/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h
@@ -58,7 +58,14 @@
       return;
 
     if (const auto* transform_node = properties->Transform()) {
-      DCHECK(transform_node->Matrix() == transform.ToTransformationMatrix());
+#if DCHECK_IS_ON()
+      if (transform_node->IsIdentityOr2DTranslation()) {
+        DCHECK_EQ(transform_node->Translation2D(),
+                  transform.ToTransformationMatrix().To2DTranslation());
+      } else {
+        DCHECK_EQ(transform_node->Matrix(), transform.ToTransformationMatrix());
+      }
+#endif
       transform_property_scope_.emplace(
           paint_info.context.GetPaintController(), *transform_node, object,
           DisplayItem::PaintPhaseToSVGTransformType(paint_info.phase));
diff --git a/third_party/blink/renderer/core/probe/core_probes.json5 b/third_party/blink/renderer/core/probe/core_probes.json5
index 54900d63..d957aa0 100644
--- a/third_party/blink/renderer/core/probe/core_probes.json5
+++ b/third_party/blink/renderer/core/probe/core_probes.json5
@@ -4,6 +4,7 @@
     export_symbol: "CORE_EXPORT",
     include_path: "third_party/blink/renderer/core/inspector",
     includes: [
+      "third_party/blink/renderer/bindings/core/v8/script_source_code.h",
       "third_party/blink/renderer/core/animation/animation.h",
       "third_party/blink/renderer/core/core_probe_sink.h",
       "third_party/blink/renderer/core/dom/character_data.h",
diff --git a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
index bb1910a..e6ad5d4 100644
--- a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
+++ b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
@@ -1220,12 +1220,11 @@
   CompositeFrame();
   CompositeFrame();
   EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
-  EXPECT_EQ(TransformationMatrix().Translate(0, 20),
-            inner_div->GetLayoutObject()
-                ->FirstFragment()
-                .PaintProperties()
-                ->Transform()
-                ->Matrix());
+  EXPECT_EQ(FloatSize(0, 20), inner_div->GetLayoutObject()
+                                  ->FirstFragment()
+                                  .PaintProperties()
+                                  ->Transform()
+                                  ->Translation2D());
 }
 
 TEST_P(FrameThrottlingTest, DisplayNoneNotThrottled) {
@@ -1340,8 +1339,7 @@
   // This simulates a javascript query to layout results, e.g.
   // document.body.offsetTop, which will force style & layout to be computed,
   // whether the frame is throttled or not.
-  frame_element->contentDocument()
-      ->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame_element->contentDocument()->UpdateStyleAndLayout();
   EXPECT_EQ(DocumentLifecycle::kLayoutClean,
             frame_element->contentDocument()->Lifecycle().GetState());
   {
diff --git a/third_party/blink/renderer/core/svg/svg_geometry_element.cc b/third_party/blink/renderer/core/svg/svg_geometry_element.cc
index 8fc1efe..6893a4c 100644
--- a/third_party/blink/renderer/core/svg/svg_geometry_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_geometry_element.cc
@@ -84,7 +84,7 @@
 }
 
 bool SVGGeometryElement::isPointInFill(SVGPointTearOff* point) const {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   // FIXME: Eventually we should support isPointInFill for display:none
   // elements.
@@ -98,7 +98,7 @@
 }
 
 bool SVGGeometryElement::isPointInStroke(SVGPointTearOff* point) const {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   // FIXME: Eventually we should support isPointInStroke for display:none
   // elements.
@@ -135,7 +135,7 @@
 }
 
 float SVGGeometryElement::getTotalLength() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (!GetLayoutObject())
     return 0;
@@ -143,7 +143,7 @@
 }
 
 SVGPointTearOff* SVGGeometryElement::getPointAtLength(float length) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   FloatPoint point;
   if (GetLayoutObject()) {
diff --git a/third_party/blink/renderer/core/svg/svg_graphics_element.cc b/third_party/blink/renderer/core/svg/svg_graphics_element.cc
index bfca480f..79bdae7 100644
--- a/third_party/blink/renderer/core/svg/svg_graphics_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_graphics_element.cc
@@ -88,13 +88,13 @@
 }
 
 SVGMatrixTearOff* SVGGraphicsElement::getCTM() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   return SVGMatrixTearOff::Create(ComputeCTM(kNearestViewportScope));
 }
 
 SVGMatrixTearOff* SVGGraphicsElement::getScreenCTM() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   return SVGMatrixTearOff::Create(ComputeCTM(kScreenScope));
 }
@@ -167,7 +167,7 @@
 }
 
 SVGRectTearOff* SVGGraphicsElement::getBBoxFromJavascript() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetDocument().UpdateStyleAndLayout();
 
   // FIXME: Eventually we should support getBBox for detached elements.
   FloatRect boundingBox;
diff --git a/third_party/blink/renderer/core/svg/svg_path_element.cc b/third_party/blink/renderer/core/svg/svg_path_element.cc
index 0b03e77..8cbca2d92f 100644
--- a/third_party/blink/renderer/core/svg/svg_path_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_path_element.cc
@@ -64,12 +64,12 @@
 }
 
 float SVGPathElement::getTotalLength() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
   return SVGPathQuery(PathByteStream()).GetTotalLength();
 }
 
 SVGPointTearOff* SVGPathElement::getPointAtLength(float length) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
   SVGPathQuery path_query(PathByteStream());
   if (length < 0) {
     length = 0;
diff --git a/third_party/blink/renderer/core/svg/svg_svg_element.cc b/third_party/blink/renderer/core/svg/svg_svg_element.cc
index f9e9d71..3ee6ae0 100644
--- a/third_party/blink/renderer/core/svg/svg_svg_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_svg_element.cc
@@ -373,7 +373,7 @@
 StaticNodeList* SVGSVGElement::getIntersectionList(
     SVGRectTearOff* rect,
     SVGElement* reference_element) const {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   return CollectIntersectionOrEnclosureList(
       rect->Target()->Value(), reference_element, kCheckIntersection);
@@ -382,7 +382,7 @@
 StaticNodeList* SVGSVGElement::getEnclosureList(
     SVGRectTearOff* rect,
     SVGElement* reference_element) const {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   return CollectIntersectionOrEnclosureList(rect->Target()->Value(),
                                             reference_element, kCheckEnclosure);
@@ -391,7 +391,7 @@
 bool SVGSVGElement::checkIntersection(SVGElement* element,
                                       SVGRectTearOff* rect) const {
   DCHECK(element);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   return CheckIntersectionOrEnclosure(*element, rect->Target()->Value(),
                                       kCheckIntersection);
@@ -400,7 +400,7 @@
 bool SVGSVGElement::checkEnclosure(SVGElement* element,
                                    SVGRectTearOff* rect) const {
   DCHECK(element);
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   return CheckIntersectionOrEnclosure(*element, rect->Target()->Value(),
                                       kCheckEnclosure);
diff --git a/third_party/blink/renderer/core/svg/svg_text_content_element.cc b/third_party/blink/renderer/core/svg/svg_text_content_element.cc
index a08ba52..4fef450 100644
--- a/third_party/blink/renderer/core/svg/svg_text_content_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_text_content_element.cc
@@ -94,12 +94,12 @@
 }
 
 unsigned SVGTextContentElement::getNumberOfChars() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
   return SVGTextQuery(GetLayoutObject()).NumberOfCharacters();
 }
 
 float SVGTextContentElement::getComputedTextLength() {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
   return SVGTextQuery(GetLayoutObject()).TextLength();
 }
 
@@ -107,7 +107,7 @@
     unsigned charnum,
     unsigned nchars,
     ExceptionState& exception_state) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   unsigned number_of_chars = getNumberOfChars();
   if (charnum >= number_of_chars) {
@@ -127,7 +127,7 @@
 SVGPointTearOff* SVGTextContentElement::getStartPositionOfChar(
     unsigned charnum,
     ExceptionState& exception_state) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (charnum >= getNumberOfChars()) {
     exception_state.ThrowDOMException(
@@ -145,7 +145,7 @@
 SVGPointTearOff* SVGTextContentElement::getEndPositionOfChar(
     unsigned charnum,
     ExceptionState& exception_state) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (charnum >= getNumberOfChars()) {
     exception_state.ThrowDOMException(
@@ -163,7 +163,7 @@
 SVGRectTearOff* SVGTextContentElement::getExtentOfChar(
     unsigned charnum,
     ExceptionState& exception_state) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (charnum >= getNumberOfChars()) {
     exception_state.ThrowDOMException(
@@ -180,7 +180,7 @@
 float SVGTextContentElement::getRotationOfChar(
     unsigned charnum,
     ExceptionState& exception_state) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
 
   if (charnum >= getNumberOfChars()) {
     exception_state.ThrowDOMException(
@@ -196,7 +196,7 @@
 int SVGTextContentElement::getCharNumAtPosition(
     SVGPointTearOff* point,
     ExceptionState& exception_state) {
-  GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+  GetDocument().UpdateStyleAndLayoutForNode(this);
   return SVGTextQuery(GetLayoutObject())
       .CharacterNumberAtPosition(point->Target()->Value());
 }
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 9c6a8da..83a7394 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -891,7 +891,7 @@
     return nullptr;
   }
 
-  document_->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document_->UpdateStyleAndLayout();
   return DOMRectReadOnly::FromIntRect(
       GetFrame()->Selection().AbsoluteCaretBounds());
 }
@@ -912,7 +912,7 @@
 DOMRectReadOnly* Internals::boundingBox(Element* element) {
   DCHECK(element);
 
-  element->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  element->GetDocument().UpdateStyleAndLayout();
   LayoutObject* layout_object = element->GetLayoutObject();
   if (!layout_object)
     return DOMRectReadOnly::Create(0, 0, 0, 0);
@@ -947,7 +947,7 @@
     return;
   }
 
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
   if (type == DocumentMarker::kSpelling)
     document->Markers().AddSpellingMarker(EphemeralRange(range));
   else
@@ -1079,7 +1079,7 @@
     return;
   }
 
-  range->OwnerDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  range->OwnerDocument().UpdateStyleAndLayout();
   range->OwnerDocument().Markers().AddTextMatchMarker(
       EphemeralRange(range), match_status_enum.value());
 
@@ -1123,7 +1123,7 @@
         void(const EphemeralRange&, Color, ImeTextSpanThickness, Color)>
         create_marker) {
   DCHECK(range);
-  range->OwnerDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  range->OwnerDocument().UpdateStyleAndLayout();
 
   base::Optional<ImeTextSpanThickness> thickness =
       ThicknessFrom(thickness_value);
@@ -1247,7 +1247,7 @@
     return String();
   }
 
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
 
   Page* page = document->GetPage();
 
@@ -1410,7 +1410,7 @@
   DCHECK(scope);
 
   // TextIterator depends on Layout information, make sure layout it up to date.
-  scope->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  scope->GetDocument().UpdateStyleAndLayout();
 
   return CreateRange(
       PlainTextRange(range_location, range_location + range_length)
@@ -1421,7 +1421,7 @@
   DCHECK(scope && range);
   // PlainTextRange depends on Layout information, make sure layout it up to
   // date.
-  scope->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  scope->GetDocument().UpdateStyleAndLayout();
 
   return PlainTextRange::Create(*scope, *range).Start();
 }
@@ -1430,7 +1430,7 @@
   DCHECK(scope && range);
   // PlainTextRange depends on Layout information, make sure layout it up to
   // date.
-  scope->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  scope->GetDocument().UpdateStyleAndLayout();
 
   return PlainTextRange::Create(*scope, *range).length();
 }
@@ -1438,7 +1438,7 @@
 String Internals::rangeAsText(const Range* range) {
   DCHECK(range);
   // Clean layout is required by plain text extraction.
-  range->OwnerDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  range->OwnerDocument().UpdateStyleAndLayout();
 
   return range->GetText();
 }
@@ -2085,7 +2085,7 @@
     return false;
   }
 
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
   return document->GetFrame()->GetSpellChecker().SelectionStartHasMarkerFor(
       DocumentMarker::kSpelling, from, length);
 }
@@ -2100,7 +2100,7 @@
     return;
   }
 
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
   document->GetFrame()->GetSpellChecker().ReplaceMisspelledRange(replacement);
 }
 
@@ -2149,7 +2149,7 @@
     return false;
   }
 
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
   return document->GetFrame()->GetSpellChecker().SelectionStartHasMarkerFor(
       DocumentMarker::kGrammar, from, length);
 }
@@ -2647,7 +2647,7 @@
   frame_view->SetTracksPaintInvalidations(false);
 }
 
-void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(
+void Internals::updateLayoutAndRunPostLayoutTasks(
     Node* node,
     ExceptionState& exception_state) {
   Document* document = nullptr;
@@ -2664,7 +2664,7 @@
         "The node provided is neither a document nor an IFrame.");
     return;
   }
-  document->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document->UpdateStyleAndLayout();
   document->View()->FlushAnyPendingPostLayoutTasks();
 }
 
@@ -3215,11 +3215,6 @@
       reverse ? kWebFocusTypeBackward : kWebFocusTypeForward);
 }
 
-bool Internals::ignoreLayoutWithPendingStylesheets(Document* document) {
-  DCHECK(document);
-  return document->IgnoreLayoutWithPendingStylesheets();
-}
-
 Element* Internals::interestedElement() {
   if (!GetFrame() || !GetFrame()->GetPage())
     return nullptr;
@@ -3268,7 +3263,7 @@
     return String();
 
   // Selection normalization and markup generation require clean layout.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return GetFrame()->Selection().SelectedHTMLForClipboard();
 }
@@ -3278,7 +3273,7 @@
     return String();
 
   // Clean layout is required for extracting plain text from selection.
-  GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  GetFrame()->GetDocument()->UpdateStyleAndLayout();
 
   return GetFrame()->Selection().SelectedTextForClipboard();
 }
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h
index d546f81b..2978b87 100644
--- a/third_party/blink/renderer/core/testing/internals.h
+++ b/third_party/blink/renderer/core/testing/internals.h
@@ -422,9 +422,7 @@
 
   void startTrackingRepaints(Document*, ExceptionState&);
   void stopTrackingRepaints(Document*, ExceptionState&);
-  void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(
-      Node*,
-      ExceptionState&);
+  void updateLayoutAndRunPostLayoutTasks(Node*, ExceptionState&);
   void forceFullRepaint(Document*, ExceptionState&);
 
   DOMRectList* draggableRegions(Document*, ExceptionState&);
@@ -498,8 +496,6 @@
   void setFocused(bool);
   void setInitialFocus(bool);
 
-  bool ignoreLayoutWithPendingStylesheets(Document*);
-
   Element* interestedElement();
 
   unsigned countHitRegions(CanvasRenderingContext*);
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl
index 764185c5..6c2376e 100644
--- a/third_party/blink/renderer/core/testing/internals.idl
+++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -250,7 +250,7 @@
     // |node| should be Document, HTMLIFrameElement, or unspecified.
     // If |node| is an HTMLIFrameElement, it assumes node.contentDocument is
     // specified without security checks. Unspecified means this document.
-    [RaisesException] void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(optional Node? node = null);
+    [RaisesException] void updateLayoutAndRunPostLayoutTasks(optional Node? node = null);
 
     [RaisesException] void forceFullRepaint(Document document);
 
@@ -317,8 +317,6 @@
     void setFocused(boolean focused);
     void setInitialFocus(boolean reverse);
 
-    boolean ignoreLayoutWithPendingStylesheets(Document document);
-
     // When the FocuslessSpatialNavigation feature is enabled, spatial
     // navigation moves "interest" around a page, rather than focus. This
     // attribute returns the currently interested element on the page.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
index 2c095e348..a65910e 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -2507,10 +2507,10 @@
   if (!frame || !frame->Selection().IsAvailable())
     return false;
 
-  // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+  // TODO(editing-dev): Use of UpdateStyleAndLayout
   // needs to be audited.  see http://crbug.com/590369 for more details.
   // This callsite should probably move up the stack.
-  frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+  frame->GetDocument()->UpdateStyleAndLayout();
 
   // Set the selection based on visible positions, because the offsets in
   // accessibility nodes are based on visible indexes, which often skips
diff --git a/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc b/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
index 42c34be..c6630ead 100644
--- a/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
+++ b/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
@@ -528,7 +528,7 @@
     return response;
 
   Document& document = dom_node->GetDocument();
-  document.UpdateStyleAndLayoutIgnorePendingStylesheets();
+  document.UpdateStyleAndLayout();
   DocumentLifecycle::DisallowTransitionScope disallow_transition(
       document.Lifecycle());
   LocalFrame* local_frame = document.GetFrame();
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
index b1c46ed2..c72460c 100644
--- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
+++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
@@ -182,6 +182,12 @@
     return;
   }
 
+  if (!animator_ctor->IsConstructor()) {
+    exception_state.ThrowTypeError(
+        "The provided callback is not a constructor.");
+    return;
+  }
+
   CallbackMethodRetriever retriever(animator_ctor);
   retriever.GetPrototypeObject(exception_state);
   if (exception_state.HadException())
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index 691669f..01418f0 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -341,7 +341,7 @@
   if (!GetState().IsTransformInvertible() || path.IsEmpty())
     return;
 
-  canvas()->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  canvas()->GetDocument().UpdateStyleAndLayout();
 
   LayoutObject* renderer = canvas()->GetLayoutObject();
   LayoutBox* layout_box = canvas()->GetLayoutBox();
@@ -1012,7 +1012,7 @@
 
 void CanvasRenderingContext2D::UpdateElementAccessibility(const Path& path,
                                                           Element* element) {
-  element->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+  element->GetDocument().UpdateStyleAndLayout();
   AXObjectCache* ax_object_cache =
       element->GetDocument().ExistingAXObjectCache();
   LayoutBoxModelObject* lbmo = canvas()->GetLayoutBoxModelObject();
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
index d912c52..1c02c37 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
@@ -171,6 +171,12 @@
     return;
   }
 
+  if (!paint_ctor->IsConstructor()) {
+    exception_state.ThrowTypeError(
+        "The provided callback is not a constructor.");
+    return;
+  }
+
   v8::Local<v8::Context> context = ScriptController()->GetContext();
 
   v8::Local<v8::Object> v8_paint_ctor = paint_ctor->CallbackObject();
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index 125f9c1..d8b49c6 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -441,7 +441,7 @@
       xr_->xrEnvironmentProviderPtr()) {
     environment_error_handler_subscribed_ = true;
     xr_->AddEnvironmentProviderErrorHandler(WTF::Bind(
-        &XRSession::OnEnvironmentProviderError, WrapPersistent(this)));
+        &XRSession::OnEnvironmentProviderError, WrapWeakPersistent(this)));
   }
 }
 
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc
index 99ed366..40bfd45 100644
--- a/third_party/blink/renderer/platform/exported/web_url_request.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -426,6 +426,14 @@
   resource_request_->SetRequestedWithHeader(value);
 }
 
+const WebString WebURLRequest::GetClientDataHeader() const {
+  return resource_request_->GetClientDataHeader();
+}
+
+void WebURLRequest::SetClientDataHeader(const WebString& value) {
+  resource_request_->SetClientDataHeader(value);
+}
+
 const base::UnguessableToken& WebURLRequest::GetFetchWindowId() const {
   return resource_request_->GetFetchWindowId();
 }
diff --git a/third_party/blink/renderer/platform/geometry/layout_rect.h b/third_party/blink/renderer/platform/geometry/layout_rect.h
index 0172626d..d4f62b3 100644
--- a/third_party/blink/renderer/platform/geometry/layout_rect.h
+++ b/third_party/blink/renderer/platform/geometry/layout_rect.h
@@ -173,19 +173,24 @@
     SetHeight((Height() + delta).ClampNegativeToZero());
   }
 
-  constexpr LayoutPoint MinXMinYCorner() const {
-    return location_;
-  }  // typically topLeft
+  // Typically top left.
+  constexpr LayoutPoint MinXMinYCorner() const { return location_; }
+
+  // Typically top right.
   LayoutPoint MaxXMinYCorner() const {
     return LayoutPoint(location_.X() + size_.Width(), location_.Y());
-  }  // typically topRight
+  }
+
+  // Typically bottom left.
   LayoutPoint MinXMaxYCorner() const {
     return LayoutPoint(location_.X(), location_.Y() + size_.Height());
-  }  // typically bottomLeft
+  }
+
+  // Typically bottom right.
   LayoutPoint MaxXMaxYCorner() const {
     return LayoutPoint(location_.X() + size_.Width(),
                        location_.Y() + size_.Height());
-  }  // typically bottomRight
+  }
 
   bool Intersects(const LayoutRect&) const;
   bool Contains(const LayoutRect&) const;
@@ -200,6 +205,26 @@
     return Contains(point.X(), point.Y());
   }
 
+  // Whether all edges of the rect are at full-pixel boundaries.
+  // i.e.: EnclosingIntRect(this)) == this
+  bool EdgesOnPixelBoundaries() const {
+    return !location_.X().HasFraction() && !location_.Y().HasFraction() &&
+           !size_.Width().HasFraction() && !size_.Height().HasFraction();
+  }
+
+  // Expand each edge outwards to the next full-pixel boundary.
+  // i.e.: this = LayoutRect(EnclosingIntRect(this))
+  void ExpandEdgesToPixelBoundaries() {
+    int x = X().Floor();
+    int y = Y().Floor();
+    int max_x = MaxX().Ceil();
+    int max_y = MaxY().Ceil();
+    location_.SetX(LayoutUnit(x));
+    location_.SetY(LayoutUnit(y));
+    size_.SetWidth(LayoutUnit(max_x - x));
+    size_.SetHeight(LayoutUnit(max_y - y));
+  }
+
   void Intersect(const LayoutRect&);
   void Unite(const LayoutRect&);
   void UniteIfNonZero(const LayoutRect&);
diff --git a/third_party/blink/renderer/platform/geometry/layout_rect_test.cc b/third_party/blink/renderer/platform/geometry/layout_rect_test.cc
index 9c73468b..5056feb6 100644
--- a/third_party/blink/renderer/platform/geometry/layout_rect_test.cc
+++ b/third_party/blink/renderer/platform/geometry/layout_rect_test.cc
@@ -182,4 +182,105 @@
             EnclosedIntRect(fractional_negpos_rect3));
 }
 
+TEST(LayoutRectTest, EdgesOnPixelBoundaries) {
+  EXPECT_TRUE(LayoutRect().EdgesOnPixelBoundaries());
+  EXPECT_TRUE(
+      LayoutRect(LayoutUnit(1), LayoutUnit(1), LayoutUnit(1), LayoutUnit(1))
+          .EdgesOnPixelBoundaries());
+  EXPECT_TRUE(
+      LayoutRect(LayoutUnit(1), LayoutUnit(-1), LayoutUnit(1), LayoutUnit(1))
+          .EdgesOnPixelBoundaries());
+  EXPECT_TRUE(
+      LayoutRect(LayoutUnit(-1), LayoutUnit(10), LayoutUnit(10), LayoutUnit(0))
+          .EdgesOnPixelBoundaries());
+  EXPECT_TRUE(
+      LayoutRect(LayoutUnit(-5), LayoutUnit(-7), LayoutUnit(10), LayoutUnit(7))
+          .EdgesOnPixelBoundaries());
+  EXPECT_TRUE(
+      LayoutRect(LayoutUnit(10), LayoutUnit(5), LayoutUnit(-2), LayoutUnit(-3))
+          .EdgesOnPixelBoundaries());
+  EXPECT_TRUE(
+      LayoutRect(LayoutUnit(1.0f), LayoutUnit(5), LayoutUnit(10), LayoutUnit(3))
+          .EdgesOnPixelBoundaries());
+
+  EXPECT_FALSE(
+      LayoutRect(LayoutUnit(9.3f), LayoutUnit(5), LayoutUnit(10), LayoutUnit(3))
+          .EdgesOnPixelBoundaries());
+  EXPECT_FALSE(
+      LayoutRect(LayoutUnit(0.5f), LayoutUnit(5), LayoutUnit(10), LayoutUnit(3))
+          .EdgesOnPixelBoundaries());
+  EXPECT_FALSE(LayoutRect(LayoutUnit(-0.5f), LayoutUnit(-5), LayoutUnit(10),
+                          LayoutUnit(3))
+                   .EdgesOnPixelBoundaries());
+  EXPECT_FALSE(LayoutRect(LayoutUnit(-0.5f), LayoutUnit(-2), LayoutUnit(10),
+                          LayoutUnit(3))
+                   .EdgesOnPixelBoundaries());
+  EXPECT_FALSE(LayoutRect(LayoutUnit(-0.5f), LayoutUnit(5.1f), LayoutUnit(10),
+                          LayoutUnit(3))
+                   .EdgesOnPixelBoundaries());
+  EXPECT_FALSE(
+      LayoutRect(LayoutUnit(3), LayoutUnit(5.1f), LayoutUnit(10), LayoutUnit(3))
+          .EdgesOnPixelBoundaries());
+  EXPECT_FALSE(
+      LayoutRect(LayoutUnit(3), LayoutUnit(5), LayoutUnit(10.2f), LayoutUnit(3))
+          .EdgesOnPixelBoundaries());
+  EXPECT_FALSE(
+      LayoutRect(LayoutUnit(3), LayoutUnit(5), LayoutUnit(10), LayoutUnit(0.3f))
+          .EdgesOnPixelBoundaries());
+}
+
+TEST(LayoutRectTest, ExpandEdgesToPixelBoundaries) {
+  LayoutUnit small;
+  small.SetRawValue(1);
+  LayoutRect small_dimensions_rect(LayoutUnit(42.5f), LayoutUnit(84.5f), small,
+                                   small);
+  small_dimensions_rect.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(42, 84, 1, 1)), small_dimensions_rect);
+
+  LayoutRect integral_rect(IntRect(100, 150, 200, 350));
+  integral_rect.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(100, 150, 200, 350)), integral_rect);
+
+  LayoutRect fractional_pos_rect(LayoutUnit(100.6f), LayoutUnit(150.8f),
+                                 LayoutUnit(200), LayoutUnit(350));
+  fractional_pos_rect.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(100, 150, 201, 351)), fractional_pos_rect);
+
+  LayoutRect fractional_dimensions_rect(LayoutUnit(100), LayoutUnit(150),
+                                        LayoutUnit(200.6f), LayoutUnit(350.4f));
+  fractional_dimensions_rect.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(100, 150, 201, 351)),
+            fractional_dimensions_rect);
+
+  LayoutRect fractional_both_rect1(LayoutUnit(100.6f), LayoutUnit(150.8f),
+                                   LayoutUnit(200.4f), LayoutUnit(350.2f));
+  fractional_both_rect1.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(100, 150, 201, 351)), fractional_both_rect1);
+
+  LayoutRect fractional_both_rect2(LayoutUnit(100.5f), LayoutUnit(150.7f),
+                                   LayoutUnit(200.3f), LayoutUnit(350.3f));
+  fractional_both_rect2.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(100, 150, 201, 351)), fractional_both_rect2);
+
+  LayoutRect fractional_both_rect3(LayoutUnit(100.3f), LayoutUnit(150.2f),
+                                   LayoutUnit(200.8f), LayoutUnit(350.9f));
+  fractional_both_rect3.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(100, 150, 202, 352)), fractional_both_rect3);
+
+  LayoutRect fractional_negpos_rect1(LayoutUnit(-100.4f), LayoutUnit(-150.8f),
+                                     LayoutUnit(200), LayoutUnit(350));
+  fractional_negpos_rect1.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(-101, -151, 201, 351)), fractional_negpos_rect1);
+
+  LayoutRect fractional_negpos_rect2(LayoutUnit(-100.5f), LayoutUnit(-150.7f),
+                                     LayoutUnit(199.4f), LayoutUnit(350.3f));
+  fractional_negpos_rect2.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(-101, -151, 200, 351)), fractional_negpos_rect2);
+
+  LayoutRect fractional_negpos_rect3(LayoutUnit(-100.3f), LayoutUnit(-150.2f),
+                                     LayoutUnit(199.6f), LayoutUnit(350.3f));
+  fractional_negpos_rect3.ExpandEdgesToPixelBoundaries();
+  EXPECT_EQ(LayoutRect(IntRect(-101, -151, 201, 352)), fractional_negpos_rect3);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/geometry/layout_unit.h b/third_party/blink/renderer/platform/geometry/layout_unit.h
index f8ab84b..1c8f3f5 100644
--- a/third_party/blink/renderer/platform/geometry/layout_unit.h
+++ b/third_party/blink/renderer/platform/geometry/layout_unit.h
@@ -177,10 +177,11 @@
     return value_ > 0 ? LayoutUnit() : *this;
   }
 
+  bool HasFraction() const { return RawValue() % kFixedPointDenominator; }
+
   LayoutUnit Fraction() const {
-    // Add the fraction to the size (as opposed to the full location) to avoid
-    // overflows.  Compute fraction using the mod operator to preserve the sign
-    // of the value as it may affect rounding.
+    // Compute fraction using the mod operator to preserve the sign of the value
+    // as it may affect rounding.
     LayoutUnit fraction;
     fraction.SetRawValue(RawValue() % kFixedPointDenominator);
     return fraction;
diff --git a/third_party/blink/renderer/platform/geometry/layout_unit_test.cc b/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
index cf5509f..4a38137 100644
--- a/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
+++ b/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
@@ -320,4 +320,26 @@
             LayoutMod(LayoutUnit(123 + LayoutUnit::Epsilon()), 2));
 }
 
+TEST(LayoutUnitTest, Fraction) {
+  EXPECT_TRUE(LayoutUnit(-1.9f).HasFraction());
+  EXPECT_TRUE(LayoutUnit(-1.6f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(-1.51f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(-1.5f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(-1.49f).HasFraction());
+  EXPECT_FALSE(LayoutUnit(-1.0f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(-0.95f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(-0.51f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(-0.50f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(-0.49f).HasFraction());
+  EXPECT_TRUE(LayoutUnit(-0.1f).HasFraction());
+  EXPECT_FALSE(LayoutUnit(-1.0f).HasFraction());
+  EXPECT_FALSE(LayoutUnit(0.0f).HasFraction());
+  EXPECT_TRUE(LayoutUnit(0.1f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(0.49f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(0.50f).HasFraction());
+  EXPECT_TRUE(LayoutUnit::FromFloatRound(0.51f).HasFraction());
+  EXPECT_TRUE(LayoutUnit(0.95f).HasFraction());
+  EXPECT_FALSE(LayoutUnit(1.0f).HasFraction());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
index ab9ad57..814e669 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
@@ -46,7 +46,7 @@
     return transform_lookup_result->value;
 
   int parent_id = GetTransformId(transform->Parent(), context);
-  if (transform->Matrix().IsIdentity() && !transform->RenderingContextId()) {
+  if (transform->IsIdentity() && !transform->RenderingContextId()) {
     context.transform_id_map.Set(transform, parent_id);
     return parent_id;
   }
@@ -59,10 +59,11 @@
   if (parent_id)
     json->SetInteger("parent", parent_id);
 
-  if (!transform->Matrix().IsIdentity())
-    json->SetArray("transform", TransformAsJSONArray(transform->Matrix()));
+  if (!transform->IsIdentity())
+    json->SetArray("transform", TransformAsJSONArray(transform->SlowMatrix()));
 
-  if (!transform->Matrix().IsIdentityOrTranslation())
+  if (!transform->IsIdentityOr2DTranslation() &&
+      !transform->Matrix().IsIdentityOrTranslation())
     json->SetArray("origin", PointAsJSONArray(transform->Origin()));
 
   if (!transform->FlattensInheritedTransform())
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
index de80a353..3d9eb30 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -491,8 +491,8 @@
     auto transform1 = CreateTransform(t0(), TransformationMatrix());
     auto transform2 =
         CreateTransform(*transform1, TransformationMatrix().Rotate3d(0, 45, 0));
-    TransformPaintPropertyNode::State transform3_state;
-    transform3_state.matrix = TransformationMatrix().Rotate3d(0, 45, 0);
+    TransformPaintPropertyNode::State transform3_state{
+        TransformationMatrix().Rotate3d(0, 45, 0)};
     transform3_state.flattens_inherited_transform = transform_is_flattened;
     auto transform3 = TransformPaintPropertyNode::Create(
         *transform2, std::move(transform3_state));
@@ -544,8 +544,8 @@
     auto real_transform2 =
         CreateTransform(*transform1, TransformationMatrix().Rotate3d(0, 45, 0));
     auto transform2 = TransformPaintPropertyNode::CreateAlias(*real_transform2);
-    TransformPaintPropertyNode::State transform3_state;
-    transform3_state.matrix = TransformationMatrix().Rotate3d(0, 45, 0);
+    TransformPaintPropertyNode::State transform3_state{
+        TransformationMatrix().Rotate3d(0, 45, 0)};
     transform3_state.flattens_inherited_transform = transform_is_flattened;
     auto real_transform3 = TransformPaintPropertyNode::Create(
         *transform2, std::move(transform3_state));
@@ -1961,9 +1961,7 @@
 
 scoped_refptr<TransformPaintPropertyNode>
 CreateSampleTransformNodeWithElementId() {
-  TransformPaintPropertyNode::State state;
-  state.matrix.Rotate(90);
-  state.origin = FloatPoint3D(100, 100, 0);
+  TransformPaintPropertyNode::State state{TransformationMatrix().Rotate(90)};
   state.direct_compositing_reasons = CompositingReason::k3DTransform;
   state.compositor_element_id = CompositorElementIdFromUniqueObjectId(
       3, CompositorElementIdNamespace::kPrimaryTransform);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
index 952d419..966b594 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
@@ -295,7 +295,7 @@
   const auto& parent_transform_space = clip.Parent()->LocalTransformSpace();
   if (&transform_space != &parent_transform_space &&
       (transform_space.Parent() != &parent_transform_space ||
-       !transform_space.Matrix().IsIdentity()))
+       !transform_space.IsIdentity()))
     return false;
 
   // Don't combine two rounded clip rects.
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
index 7bb0263..cbd7b49 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
@@ -267,7 +267,7 @@
            cc::PaintOpType::Restore,                           // </e2_offset>
            cc::PaintOpType::Restore,                           // </e1>
            cc::PaintOpType::Restore}));                        // </t1*t2>
-  EXPECT_TRANSFORM_MATRIX(t1->Matrix() * t2->Matrix(), *output, 1);
+  EXPECT_TRANSFORM_MATRIX(t1->Matrix() * t2->SlowMatrix(), *output, 1);
   // chunk1.bounds + e2(t2^-1(chunk2.bounds))
   EXPECT_EFFECT_BOUNDS(0, 0, 155, 155, *output, 2);
   // e2_offset
@@ -278,8 +278,8 @@
   EXPECT_TRANSLATE(-e2->FiltersOrigin().X(), -e2->FiltersOrigin().Y(), *output,
                    7);
   // t2^1
-  auto translation = t2->Matrix().To2DTranslation();
-  EXPECT_TRANSLATE(-translation.Width(), -translation.Height(), *output, 9);
+  EXPECT_TRANSLATE(-t2->Translation2D().Width(), -t2->Translation2D().Height(),
+                   *output, 9);
 }
 
 TEST_F(PaintChunksToCcLayerTest, InterleavedClipEffect) {
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index 6695213..909d6fc 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -226,7 +226,7 @@
   // sticky node because the sticky offset would be applied twice otherwise.
   if (!transform_node.GetStickyConstraint()) {
     compositor_node.local.matrix() =
-        TransformationMatrix::ToSkMatrix44(transform_node.Matrix());
+        TransformationMatrix::ToSkMatrix44(transform_node.SlowMatrix());
   }
   compositor_node.post_local.matrix().setTranslate(origin.X(), origin.Y(),
                                                    origin.Z());
@@ -289,7 +289,7 @@
     // transform node has a special scroll offset field. To handle this we
     // adjust cc's transform node to remove the 2d scroll translation and
     // instead set the scroll_offset field.
-    auto scroll_offset_size = transform_node.Matrix().To2DTranslation();
+    auto scroll_offset_size = transform_node.Translation2D();
     auto scroll_offset = gfx::ScrollOffset(-scroll_offset_size.Width(),
                                            -scroll_offset_size.Height());
     DCHECK(compositor_node.local.IsIdentityOr2DTranslation());
@@ -329,7 +329,7 @@
   // The page scale node is special because its transform matrix is assumed to
   // be in the post_local matrix by the compositor. There should be no
   // translation from the origin so we clear the other matrices.
-  DCHECK(node.Origin() == FloatPoint3D());
+  DCHECK_EQ(node.Origin(), FloatPoint3D());
   compositor_node.post_local.matrix() = compositor_node.local.matrix();
   compositor_node.pre_local.matrix().setIdentity();
   compositor_node.local.matrix().setIdentity();
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc b/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
index f271c49..c7f8a04b 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
@@ -127,8 +127,7 @@
       });
 
   transform1->Update(transform_root,
-                     TransformPaintPropertyNode::State{
-                         TransformationMatrix().Translate(20, 30)});
+                     TransformPaintPropertyNode::State{FloatSize(20, 30)});
   EXPECT_TRUE(transform1->Changed(transform_root));
   EXPECT_TRUE(transform2->Changed(transform_root));
   layers_.graphics_layer_client().SetNeedsRepaint(true);
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
index 00095a3..a19c8d7 100644
--- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -45,6 +45,17 @@
     rect_.Move(offset);
 }
 
+static void MapRect(const TransformPaintPropertyNode& transform,
+                    IntRect& rect) {
+  if (transform.IsIdentityOr2DTranslation()) {
+    FloatRect float_rect(rect);
+    float_rect.Move(-transform.Translation2D());
+    rect = EnclosingIntRect(float_rect);
+  } else {
+    rect = transform.Matrix().Inverse().MapRect(rect);
+  }
+}
+
 CullRect::ApplyTransformResult CullRect::ApplyTransformInternal(
     const TransformPaintPropertyNode& transform) {
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
@@ -52,7 +63,7 @@
       rect_.Intersect(scroll->ContainerRect());
       if (rect_.IsEmpty())
         return kNotExpanded;
-      rect_ = transform.Matrix().Inverse().MapRect(rect_);
+      MapRect(transform, rect_);
 
       // Expand the cull rect for scrolling contents in case of composited
       // scrolling.
@@ -73,7 +84,7 @@
   }
 
   if (!IsInfinite())
-    rect_ = transform.Matrix().Inverse().MapRect(rect_);
+    MapRect(transform, rect_);
   return kNotExpanded;
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h b/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h
index 2272f762..d51bf53 100644
--- a/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h
+++ b/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h
@@ -92,9 +92,11 @@
     rect_.MoveBy(offset);
   }
 
+  // Assumes that the transform always makes the clip rect not tight. The caller
+  // should use MoveBy() to keep tightness if the transform is known to be
+  // identity or a 2d translation.
   void Map(const TransformationMatrix& matrix) {
-    if (is_tight_ && !matrix.IsIdentityOr2DTranslation())
-      is_tight_ = false;
+    is_tight_ = false;
     if (is_infinite_)
       return;
     rect_ = matrix.MapRect(rect_);
diff --git a/third_party/blink/renderer/platform/graphics/paint/float_clip_rect_test.cc b/third_party/blink/renderer/platform/graphics/paint/float_clip_rect_test.cc
index dd19c4c..35267875 100644
--- a/third_party/blink/renderer/platform/graphics/paint/float_clip_rect_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/float_clip_rect_test.cc
@@ -86,20 +86,16 @@
   EXPECT_TRUE(rect.IsInfinite());
   EXPECT_FALSE(rect.IsTight());
 
+  // FloatClipRect::Map() assumes that the transform always makes the clip rect
+  // not tight. The caller should use MoveBy() to keep tightness if the
+  // transform is known to be identity or a 2d translation.
   FloatClipRect rect2(FloatRect(1, 2, 3, 4));
   rect2.Map(identity);
   EXPECT_EQ(FloatRect(1, 2, 3, 4), rect2.Rect());
-  EXPECT_TRUE(rect2.IsTight());
+  EXPECT_FALSE(rect2.IsTight());
 
   rect2.Map(translation);
   EXPECT_EQ(FloatRect(11, 22, 3, 4), rect2.Rect());
-  EXPECT_TRUE(rect2.IsTight());
-
-  rect2.Map(rotate);
-  EXPECT_EQ(rotate.MapRect(FloatRect(11, 22, 3, 4)), rect2.Rect());
-  EXPECT_FALSE(rect2.IsTight());
-
-  rect2.Map(identity);
   EXPECT_FALSE(rect2.IsTight());
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
index ed340b07..97f7bc51 100644
--- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
@@ -72,7 +72,7 @@
   if (source.Parent() && &destination == &source.Parent()->Unalias()) {
     if (source.IsIdentityOr2DTranslation()) {
       success = true;
-      return Translation2DOrMatrix(source.Matrix().To2DTranslation());
+      return Translation2DOrMatrix(source.Translation2D());
     }
     // The result will be translate(origin)*matrix*translate(-origin) which
     // equals to matrix if the origin is zero or if the matrix is just
@@ -86,7 +86,7 @@
   if (destination.IsIdentityOr2DTranslation() && destination.Parent() &&
       &source == &destination.Parent()->Unalias()) {
     success = true;
-    return Translation2DOrMatrix(-destination.Matrix().To2DTranslation());
+    return Translation2DOrMatrix(-destination.Translation2D());
   }
 
   const auto& source_cache = source.GetTransformCache();
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h
index 73ba9fb..052058bd 100644
--- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h
+++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h
@@ -130,7 +130,7 @@
     // Fast-path optimization for mapping through just |source| when |source| is
     // a 2d translation.
     if (&destination == source.Parent() && source.IsIdentityOr2DTranslation()) {
-      MoveRect(mapping_rect, source.Matrix().To2DTranslation());
+      MoveRect(mapping_rect, source.Translation2D());
       return;
     }
 
@@ -138,7 +138,7 @@
     // |destination| is a 2d translation.
     if (&source == destination.Parent() &&
         destination.IsIdentityOr2DTranslation()) {
-      MoveRect(mapping_rect, -destination.Matrix().To2DTranslation());
+      MoveRect(mapping_rect, -destination.Translation2D());
       return;
     }
 
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
index 57ddb3d..125c5f7 100644
--- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
@@ -698,7 +698,8 @@
 
   input_rect = FloatRect(0, 0, 100, 100);
   // 1. transformBelowEffect
-  auto output = transform_below_effect->Matrix().MapRect(input_rect);
+  auto output = input_rect;
+  output.Move(transform_below_effect->Translation2D());
   // 2. clipBelowEffect
   output.Intersect(clip_below_effect->ClipRect().Rect());
   EXPECT_EQ(FloatRect(20, 30, 90, 80), output);
@@ -709,11 +710,11 @@
   output.Intersect(clip_above_effect->ClipRect().Rect());
   EXPECT_EQ(FloatRect(-40, -30, 140, 130), output);
   // 5. transformAboveEffect
-  output = transform_above_effect->Matrix().MapRect(output);
+  output.Move(transform_above_effect->Translation2D());
   EXPECT_EQ(FloatRect(0, 20, 140, 130), output);
 
-  expected_translation_2d = transform_above_effect->Matrix().To2DTranslation() +
-                            transform_below_effect->Matrix().To2DTranslation();
+  expected_translation_2d = transform_above_effect->Translation2D() +
+                            transform_below_effect->Translation2D();
   expected_transformed_rect = input_rect;
   expected_transformed_rect.Move(expected_translation_2d);
   expected_visual_rect = FloatClipRect(output);
@@ -747,7 +748,8 @@
 
   input_rect = FloatRect(0, 0, 100, 100);
   // 1. transformBelowEffect
-  auto output = transform_below_effect->Matrix().MapRect(input_rect);
+  auto output = input_rect;
+  output.Move(transform_below_effect->Translation2D());
   // 2. clipBelowEffect
   output.Intersect(clip_below_effect->ClipRect().Rect());
   EXPECT_EQ(FloatRect(20, 30, 90, 80), output);
@@ -758,11 +760,11 @@
   output.Intersect(clip_above_effect->ClipRect().Rect());
   EXPECT_EQ(FloatRect(-40, -30, 140, 130), output);
   // 5. transformAboveEffect
-  output = transform_above_effect->Matrix().MapRect(output);
+  output.Move(transform_above_effect->Translation2D());
   EXPECT_EQ(FloatRect(0, 20, 140, 130), output);
 
-  expected_translation_2d = transform_above_effect->Matrix().To2DTranslation() +
-                            transform_below_effect->Matrix().To2DTranslation();
+  expected_translation_2d = transform_above_effect->Translation2D() +
+                            transform_below_effect->Translation2D();
   expected_transformed_rect = input_rect;
   expected_transformed_rect.Move(expected_translation_2d);
   expected_visual_rect = FloatClipRect(output);
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc
index 9a76228..7d153c8 100644
--- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc
@@ -27,7 +27,7 @@
   cache_generation_ = s_global_generation;
 
   if (node.IsRoot()) {
-    DCHECK(node.Matrix().IsIdentity());
+    DCHECK(node.IsIdentity());
     to_2d_translation_root_ = FloatSize();
     root_of_2d_translation_ = &node;
     plane_root_transform_ = nullptr;
@@ -44,7 +44,7 @@
   if (node.IsIdentityOr2DTranslation()) {
     root_of_2d_translation_ = parent.root_of_2d_translation_;
     to_2d_translation_root_ = parent.to_2d_translation_root_;
-    const auto& translation = node.Matrix().To2DTranslation();
+    const auto& translation = node.Translation2D();
     to_2d_translation_root_ += translation;
 
     if (parent.plane_root_transform_) {
@@ -119,7 +119,7 @@
   if (node.FlattensInheritedTransform())
     screen_transform_->to_screen.FlattenTo2d();
   if (node.IsIdentityOr2DTranslation()) {
-    const auto& translation = node.Matrix().To2DTranslation();
+    const auto& translation = node.Translation2D();
     screen_transform_->to_screen.Translate(translation.Width(),
                                            translation.Height());
   } else {
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc
index 38b55ebd..f04c76e 100644
--- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc
@@ -232,8 +232,7 @@
 
   // Change t2 back to a 2d translation.
   GeometryMapperTransformCache::ClearCache();
-  t2->Update(*t1, TransformPaintPropertyNode::State{
-                      TransformationMatrix().Translate(11, 12)});
+  t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(11, 12)});
   Check2dTranslationToRoot(t0(), 0, 0);
   Check2dTranslationToRoot(*t1, 1, 2);
   Check2dTranslationToRoot(*t2, 12, 14);
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc b/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
index 47cf27b..17f7b59 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
@@ -152,9 +152,8 @@
 TEST_F(PaintPropertyNodeTest, TransformChangeAncestor) {
   ResetAllChanged();
   ExpectUnchangedState();
-  transform.ancestor->Update(*transform.root,
-                             TransformPaintPropertyNode::State{
-                                 TransformationMatrix().Translate(1, 2)});
+  transform.ancestor->Update(
+      *transform.root, TransformPaintPropertyNode::State{FloatSize(1, 2)});
 
   // Test descendant->Changed(ancestor).
   EXPECT_TRUE(transform.ancestor->Changed(*transform.root));
@@ -226,8 +225,7 @@
   ResetAllChanged();
   ExpectUnchangedState();
   transform.child1->Update(*transform.ancestor,
-                           TransformPaintPropertyNode::State{
-                               TransformationMatrix().Translate(1, 2)});
+                           TransformPaintPropertyNode::State{FloatSize(1, 2)});
 
   // Test descendant->Changed(ancestor).
   EXPECT_FALSE(transform.ancestor->Changed(*transform.root));
@@ -323,8 +321,7 @@
   ResetAllChanged();
   ExpectUnchangedState();
   transform.child1->Update(*transform.child2,
-                           TransformPaintPropertyNode::State{
-                               TransformationMatrix().Translate(1, 2)});
+                           TransformPaintPropertyNode::State{FloatSize(1, 2)});
   EXPECT_FALSE(transform.ancestor->Changed(*transform.root));
   EXPECT_TRUE(transform.child1->Changed(*transform.ancestor));
   EXPECT_TRUE(transform.child1->Changed(*transform.child2));
@@ -341,8 +338,7 @@
   ResetAllChanged();
   ExpectUnchangedState();
   transform.child1->Update(*transform.ancestor,
-                           TransformPaintPropertyNode::State{
-                               TransformationMatrix().Translate(1, 2)});
+                           TransformPaintPropertyNode::State{FloatSize(1, 2)});
 
   EXPECT_FALSE(clip.ancestor->Changed(STATE(root), nullptr));
   EXPECT_FALSE(clip.ancestor->Changed(STATE(ancestor), nullptr));
@@ -374,9 +370,8 @@
 
   ResetAllChanged();
   ExpectUnchangedState();
-  transform.ancestor->Update(*transform.root,
-                             TransformPaintPropertyNode::State{
-                                 TransformationMatrix().Translate(1, 2)});
+  transform.ancestor->Update(
+      *transform.root, TransformPaintPropertyNode::State{FloatSize(1, 2)});
 
   EXPECT_FALSE(effect.ancestor->Changed(STATE(root), nullptr));
   EXPECT_FALSE(effect.ancestor->Changed(STATE(ancestor), nullptr));
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
index 151b0288..23424ae 100644
--- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h"
 
+#include <utility>
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
 #include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
@@ -415,10 +416,8 @@
   // Change both t1 and t2 but keep t1*t2 unchanged, to test change of
   // LocalTransformSpace of c1.
   invalidator.SetTracksRasterInvalidations(true);
-  t1->Update(t0(), TransformPaintPropertyNode::State{
-                       TransformationMatrix().Translate(-10, -20)});
-  t2->Update(*t1, TransformPaintPropertyNode::State{
-                      TransformationMatrix().Translate(10, 20)});
+  t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(-10, -20)});
+  t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(10, 20)});
 
   invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
   const auto& invalidations = TrackedRasterInvalidations(invalidator);
@@ -452,10 +451,8 @@
 
   // Change both t1 and t2 but keep t1*t2 unchanged.
   invalidator.SetTracksRasterInvalidations(true);
-  t1->Update(t0(), TransformPaintPropertyNode::State{
-                       TransformationMatrix().Translate(-10, -20)});
-  t2->Update(*t1, TransformPaintPropertyNode::State{
-                      TransformationMatrix().Translate(10, 20)});
+  t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(-10, -20)});
+  t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(10, 20)});
 
   invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
   EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
@@ -466,10 +463,8 @@
   RasterInvalidator invalidator(kNoopRasterInvalidation);
 
   auto layer_transform = CreateTransform(t0(), TransformationMatrix().Scale(5));
-  auto transform0 = CreateTransform(*layer_transform,
-                                    TransformationMatrix().Translate(10, 20));
-  auto transform1 =
-      CreateTransform(*transform0, TransformationMatrix().Translate(-50, -60));
+  auto transform0 = Create2DTranslation(*layer_transform, 10, 20);
+  auto transform1 = Create2DTranslation(*transform0, -50, -60);
 
   PropertyTreeState layer_state(*layer_transform, c0(), e0());
   auto artifact = TestPaintArtifact()
@@ -496,11 +491,10 @@
   // the new node become the transform of the layer state should not cause
   // raster invalidation in the layer. This simulates a composited layer is
   // scrolled from its original location.
-  auto new_layer_transform = CreateTransform(
-      *layer_transform, TransformationMatrix().Translate(-100, -200));
+  auto new_layer_transform = Create2DTranslation(*layer_transform, -100, -200);
   layer_state = PropertyTreeState(*new_layer_transform, c0(), e0());
-  transform0->Update(*new_layer_transform,
-                     TransformPaintPropertyNode::State{transform0->Matrix()});
+  transform0->Update(*new_layer_transform, TransformPaintPropertyNode::State{
+                                               transform0->Translation2D()});
 
   invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
   EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
@@ -509,8 +503,8 @@
   // Removing transform nodes above the layer state should not cause raster
   // invalidation in the layer.
   layer_state = DefaultPropertyTreeState();
-  transform0->Update(layer_state.Transform(),
-                     TransformPaintPropertyNode::State{transform0->Matrix()});
+  transform0->Update(layer_state.Transform(), TransformPaintPropertyNode::State{
+                                                  transform0->Translation2D()});
 
   invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
   EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
@@ -519,14 +513,12 @@
   // Change transform0 and transform1, while keeping the combined transform0
   // and transform1 unchanged for chunk 2. We should invalidate only chunk 0
   // for changed paint property.
-  transform0->Update(
-      layer_state.Transform(),
-      TransformPaintPropertyNode::State{
-          TransformationMatrix(transform0->Matrix()).Translate(20, 30)});
-  transform1->Update(
-      *transform0,
-      TransformPaintPropertyNode::State{
-          TransformationMatrix(transform1->Matrix()).Translate(-20, -30)});
+  transform0->Update(layer_state.Transform(),
+                     TransformPaintPropertyNode::State{
+                         transform0->Translation2D() + FloatSize(20, 30)});
+  transform1->Update(*transform0,
+                     TransformPaintPropertyNode::State{
+                         transform1->Translation2D() + FloatSize(-20, -30)});
 
   invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
   const auto& invalidations = TrackedRasterInvalidations(invalidator);
@@ -547,8 +539,7 @@
   RasterInvalidator invalidator(kNoopRasterInvalidation);
 
   auto layer_transform = CreateTransform(t0(), TransformationMatrix().Scale(5));
-  auto chunk_transform = CreateTransform(
-      *layer_transform, TransformationMatrix().Translate(10, 20));
+  auto chunk_transform = Create2DTranslation(*layer_transform, 10, 20);
 
   PropertyTreeState layer_state(*layer_transform, c0(), e0());
   auto artifact = TestPaintArtifact()
@@ -561,12 +552,12 @@
 
   // Change chunk_transform by tiny difference, which should be ignored.
   invalidator.SetTracksRasterInvalidations(true);
-  chunk_transform->Update(layer_state.Transform(),
-                          TransformPaintPropertyNode::State{
-                              TransformationMatrix(chunk_transform->Matrix())
-                                  .Translate(0.0000001, -0.0000001)
-                                  .Scale(1.0000001)
-                                  .Rotate(0.0000001)});
+  chunk_transform->Update(
+      layer_state.Transform(),
+      TransformPaintPropertyNode::State{chunk_transform->SlowMatrix()
+                                            .Translate(0.0000001, -0.0000001)
+                                            .Scale(1.0000001)
+                                            .Rotate(0.0000001)});
 
   invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
   EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
@@ -576,12 +567,12 @@
   // accumulation is large enough.
   bool invalidated = false;
   for (int i = 0; i < 100 && !invalidated; i++) {
-    chunk_transform->Update(layer_state.Transform(),
-                            TransformPaintPropertyNode::State{
-                                TransformationMatrix(chunk_transform->Matrix())
-                                    .Translate(0.0000001, -0.0000001)
-                                    .Scale(1.0000001)
-                                    .Rotate(0.0000001)});
+    chunk_transform->Update(
+        layer_state.Transform(),
+        TransformPaintPropertyNode::State{chunk_transform->SlowMatrix()
+                                              .Translate(0.0000001, -0.0000001)
+                                              .Scale(1.0000001)
+                                              .Rotate(0.0000001)});
     invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
     invalidated = !TrackedRasterInvalidations(invalidator).IsEmpty();
     FinishCycle(*artifact);
@@ -649,10 +640,8 @@
   // Change both t1 and t2 but keep t1*t2 unchanged, to test change of
   // LocalTransformSpace of e1.
   invalidator.SetTracksRasterInvalidations(true);
-  t1->Update(t0(), TransformPaintPropertyNode::State{
-                       TransformationMatrix().Translate(-10, -20)});
-  t2->Update(*t1, TransformPaintPropertyNode::State{
-                      TransformationMatrix().Translate(10, 20)});
+  t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(-10, -20)});
+  t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(10, 20)});
 
   invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
   const auto& invalidations = TrackedRasterInvalidations(invalidator);
@@ -687,10 +676,8 @@
 
   // Change both t1 and t2 but keep t1*t2 unchanged.
   invalidator.SetTracksRasterInvalidations(true);
-  t1->Update(t0(), TransformPaintPropertyNode::State{
-                       TransformationMatrix().Translate(-10, -20)});
-  t2->Update(*t1, TransformPaintPropertyNode::State{
-                      TransformationMatrix().Translate(10, 20)});
+  t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(-10, -20)});
+  t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(10, 20)});
 
   invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
   EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc
index d59f866..d67713b 100644
--- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc
@@ -12,8 +12,7 @@
   DEFINE_STATIC_REF(
       TransformPaintPropertyNode, root,
       base::AdoptRef(new TransformPaintPropertyNode(
-          nullptr,
-          State{TransformationMatrix(), &ScrollPaintPropertyNode::Root()},
+          nullptr, State{FloatSize(), &ScrollPaintPropertyNode::Root()},
           true /* is_parent_alias */)));
   return *root;
 }
@@ -50,10 +49,13 @@
     json->SetString("parent", String::Format("%p", Parent()));
   if (NodeChanged())
     json->SetBoolean("changed", true);
-  if (!state_.matrix.IsIdentity())
-    json->SetString("matrix", state_.matrix.ToString());
-  if (!state_.matrix.IsIdentityOrTranslation())
-    json->SetString("origin", state_.origin.ToString());
+  if (IsIdentityOr2DTranslation()) {
+    if (!Translation2D().IsZero())
+      json->SetString("translation2d", Translation2D().ToString());
+  } else {
+    json->SetString("matrix", Matrix().ToString());
+    json->SetString("origin", Origin().ToString());
+  }
   if (!state_.flattens_inherited_transform)
     json->SetBoolean("flattensInheritedTransform", false);
   if (state_.backface_visibility != BackfaceVisibility::kInherited) {
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
index 9a48168..e5a651b4 100644
--- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -43,17 +43,70 @@
     kVisible,
   };
 
+  // Stores a transform and origin with an optimization for the identity and
+  // 2d translation cases that avoids allocating a full matrix and origin.
+  class TransformAndOrigin {
+   public:
+    TransformAndOrigin() {}
+    // These constructors are not explicit so that we can use FloatSize or
+    // TransformationMatrix directly in the initialization list of State.
+    TransformAndOrigin(const FloatSize& translation_2d)
+        : translation_2d_(translation_2d) {}
+    // This should be used for arbitrary matrix only. If the caller knows that
+    // the transform is identity or a 2d translation, the translation_2d version
+    // should be used instead.
+    TransformAndOrigin(const TransformationMatrix& matrix,
+                       const FloatPoint3D& origin = FloatPoint3D(),
+                       bool disable_optimization = false) {
+      if (!disable_optimization && matrix.IsIdentityOr2DTranslation())
+        translation_2d_ = matrix.To2DTranslation();
+      else
+        matrix_and_origin_.reset(new MatrixAndOrigin{matrix, origin});
+    }
+
+    bool IsIdentityOr2DTranslation() const { return !matrix_and_origin_; }
+    bool IsIdentity() const {
+      return !matrix_and_origin_ && translation_2d_.IsZero();
+    }
+    const FloatSize& Translation2D() const {
+      DCHECK(IsIdentityOr2DTranslation());
+      return translation_2d_;
+    }
+    const TransformationMatrix& Matrix() const {
+      DCHECK(matrix_and_origin_);
+      return matrix_and_origin_->matrix;
+    }
+    TransformationMatrix SlowMatrix() const {
+      return matrix_and_origin_
+                 ? matrix_and_origin_->matrix
+                 : TransformationMatrix().Translate(translation_2d_.Width(),
+                                                    translation_2d_.Height());
+    }
+    FloatPoint3D Origin() const {
+      return matrix_and_origin_ ? matrix_and_origin_->origin : FloatPoint3D();
+    }
+    bool TransformEquals(const TransformAndOrigin& other) const {
+      return translation_2d_ == other.translation_2d_ &&
+             ((!matrix_and_origin_ && !other.matrix_and_origin_) ||
+              (matrix_and_origin_ && other.matrix_and_origin_ &&
+               matrix_and_origin_->matrix == other.matrix_and_origin_->matrix));
+    }
+
+   private:
+    struct MatrixAndOrigin {
+      TransformationMatrix matrix;
+      FloatPoint3D origin;
+    };
+    FloatSize translation_2d_;
+    std::unique_ptr<MatrixAndOrigin> matrix_and_origin_;
+  };
+
   // To make it less verbose and more readable to construct and update a node,
   // a struct with default values is used to represent the state.
   struct State {
-    TransformationMatrix matrix;
+    TransformAndOrigin transform_and_origin;
     scoped_refptr<const ScrollPaintPropertyNode> scroll;
-    FloatPoint3D origin;
     bool flattens_inherited_transform = false;
-    // Caches value of matrix_.IsIdentityOr2DTranslation(). The caller can set
-    // this field to true if the matrix is known to be identity or 2d
-    // translation, or the field will be updated automatically.
-    bool is_identity_or_2d_translation = false;
     bool affected_by_outer_viewport_bounds_delta = false;
     // TODO(crbug.com/937929): Put this into CompositingReasons when we can
     // detect composited animation status changes in LayoutObject::SetStyle().
@@ -65,7 +118,8 @@
     std::unique_ptr<CompositorStickyConstraint> sticky_constraint;
 
     PaintPropertyChangeType CheckChange(const State& other) const {
-      if (origin != other.origin ||
+      if (transform_and_origin.Origin() !=
+              other.transform_and_origin.Origin() ||
           flattens_inherited_transform != other.flattens_inherited_transform ||
           affected_by_outer_viewport_bounds_delta !=
               other.affected_by_outer_viewport_bounds_delta ||
@@ -81,7 +135,7 @@
           !StickyConstraintEquals(other)) {
         return PaintPropertyChangeType::kChangedOnlyValues;
       }
-      if (matrix != other.matrix) {
+      if (!transform_and_origin.TransformEquals(other.transform_and_origin)) {
         return is_running_animation_on_compositor
                    ? PaintPropertyChangeType::
                          kChangedOnlyCompositedAnimationValues
@@ -122,7 +176,6 @@
       DCHECK(!IsParentAlias()) << "Changed the state of an alias node.";
       state_ = std::move(state);
       SetChanged();
-      CheckAndUpdateIsIdentityOr2DTranslation();
       Validate();
     }
     return std::max(parent_changed, state_changed);
@@ -134,8 +187,25 @@
   // from |this| and |relative_to_node| to the root.
   bool Changed(const TransformPaintPropertyNode& relative_to_node) const;
 
-  const TransformationMatrix& Matrix() const { return state_.matrix; }
-  const FloatPoint3D& Origin() const { return state_.origin; }
+  bool IsIdentityOr2DTranslation() const {
+    return state_.transform_and_origin.IsIdentityOr2DTranslation();
+  }
+  bool IsIdentity() const { return state_.transform_and_origin.IsIdentity(); }
+  // Only available when IsIdentityOr2DTranslation() is true.
+  const FloatSize& Translation2D() const {
+    return state_.transform_and_origin.Translation2D();
+  }
+  // Only available when IsIdentityOr2DTranslation() is false.
+  const TransformationMatrix& Matrix() const {
+    return state_.transform_and_origin.Matrix();
+  }
+  // The slow version always return meaningful TransformationMatrix regardless
+  // of IsIdentityOr2DTranslation(). Should be used only in contexts that are
+  // not performance sensitive.
+  TransformationMatrix SlowMatrix() const {
+    return state_.transform_and_origin.SlowMatrix();
+  }
+  FloatPoint3D Origin() const { return state_.transform_and_origin.Origin(); }
 
   // The associated scroll node, or nullptr otherwise.
   const ScrollPaintPropertyNode* ScrollNode() const {
@@ -165,12 +235,6 @@
     return state_.flattens_inherited_transform;
   }
 
-  bool IsIdentityOr2DTranslation() const {
-    DCHECK_EQ(state_.is_identity_or_2d_translation,
-              state_.matrix.IsIdentityOr2DTranslation());
-    return state_.is_identity_or_2d_translation;
-  }
-
   // Returns the local BackfaceVisibility value set on this node.
   // See |IsBackfaceHidden()| for computing whether this transform node is
   // hidden or not.
@@ -231,7 +295,6 @@
                              State&& state,
                              bool is_parent_alias)
       : PaintPropertyNode(parent, is_parent_alias), state_(std::move(state)) {
-    CheckAndUpdateIsIdentityOr2DTranslation();
     Validate();
   }
 
@@ -240,25 +303,15 @@
     return state_.direct_compositing_reasons;
   }
 
-  void CheckAndUpdateIsIdentityOr2DTranslation() {
-    if (IsParentAlias()) {
-      DCHECK(state_.matrix.IsIdentity());
-      state_.is_identity_or_2d_translation = true;
-    } else if (state_.is_identity_or_2d_translation) {
-      DCHECK(state_.matrix.IsIdentityOr2DTranslation());
-    } else {
-      state_.is_identity_or_2d_translation =
-          state_.matrix.IsIdentityOr2DTranslation();
-    }
-  }
-
   void Validate() const {
 #if DCHECK_IS_ON()
+    if (IsParentAlias())
+      DCHECK(IsIdentity());
     DCHECK(!IsRunningAnimationOnCompositor() || HasActiveTransformAnimation());
     if (state_.scroll) {
       // If there is an associated scroll node, this can only be a 2d
       // translation for scroll offset.
-      DCHECK(state_.is_identity_or_2d_translation);
+      DCHECK(IsIdentityOr2DTranslation());
       // The scroll compositor element id should be stored on the scroll node.
       DCHECK(!state_.compositor_element_id);
     }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 1be0a51..8dd1e95e2 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -316,10 +316,6 @@
       status: "stable",
     },
     {
-      name: "CSSInBodyDoesNotBlockPaint",
-      status: "stable",
-    },
-    {
       name: "CSSIndependentTransformProperties",
       status: "experimental",
     },
@@ -520,6 +516,7 @@
     },
     {
       name: "FeaturePolicyForSandbox",
+      status: "experimental",
     },
     {
       name: "FeaturePolicyJavaScriptInterface",
diff --git a/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc b/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc
index fbb4850..e30fb5e 100644
--- a/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 
+#include "base/auto_reset.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/thread_specific.h"
@@ -11,6 +12,12 @@
 namespace blink {
 namespace scheduler {
 
+namespace {
+// Minimum time interval between nested loop runs.
+constexpr WTF::TimeDelta kNestedLoopMinimumInterval =
+    WTF::TimeDelta::FromMilliseconds(15);
+}  // namespace
+
 // static
 CooperativeSchedulingManager* CooperativeSchedulingManager::Instance() {
   DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<CooperativeSchedulingManager>,
@@ -44,5 +51,25 @@
   DCHECK_GE(whitelisted_stack_scope_depth_, 0);
 }
 
+void CooperativeSchedulingManager::SafepointSlow() {
+  // Avoid nesting more than two levels.
+  if (running_nested_loop_)
+    return;
+
+  // TODO(keishi): Also bail if V8 EnteredContextCount is more than 1
+
+  RunNestedLoop();
+}
+
+void CooperativeSchedulingManager::RunNestedLoop() {
+  TRACE_EVENT0("renderer.scheduler",
+               "CooperativeSchedulingManager::RunNestedLoop");
+  base::AutoReset<bool>(&running_nested_loop_, true);
+  wait_until_ = WTF::CurrentTimeTicks() + kNestedLoopMinimumInterval;
+
+  // TODO(keishi): Ask scheduler to run high priority tasks from different
+  // EventLoops.
+}
+
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager_unittest.cc
index a4720007..43654f0 100644
--- a/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager_unittest.cc
@@ -4,7 +4,9 @@
 
 #include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
 
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h"
 
 namespace blink {
 namespace scheduler {
@@ -26,5 +28,42 @@
   EXPECT_FALSE(manager->InWhitelistedStackScope());
 }
 
+class MockCooperativeSchedulingManager : public CooperativeSchedulingManager {
+ public:
+  MockCooperativeSchedulingManager() : CooperativeSchedulingManager() {
+    ON_CALL(*this, RunNestedLoop())
+        .WillByDefault(testing::Invoke(
+            this, &MockCooperativeSchedulingManager::RealRunNestedLoop));
+  }
+  ~MockCooperativeSchedulingManager() override = default;
+  MOCK_METHOD0(RunNestedLoop, void());
+  void RealRunNestedLoop() { CooperativeSchedulingManager::RunNestedLoop(); }
+};
+
+TEST(CooperativeSchedulingManager, SafePoint) {
+  {
+    std::unique_ptr<MockCooperativeSchedulingManager> manager =
+        std::make_unique<MockCooperativeSchedulingManager>();
+    EXPECT_CALL(*manager, RunNestedLoop()).Times(0);
+    // Should not run nested loop because stack is not whitelisted
+    manager->Safepoint();
+  }
+  {
+    WTF::ScopedMockClock clock;
+    std::unique_ptr<MockCooperativeSchedulingManager> manager =
+        std::make_unique<MockCooperativeSchedulingManager>();
+    CooperativeSchedulingManager::WhitelistedStackScope scope(manager.get());
+    EXPECT_CALL(*manager, RunNestedLoop()).Times(2);
+    // Should run nested loop
+    manager->Safepoint();
+    clock.Advance(TimeDelta::FromMilliseconds(14));
+    // Should not run nested loop because called too soon
+    manager->Safepoint();
+    clock.Advance(TimeDelta::FromMilliseconds(2));
+    // Should run nested loop
+    manager->Safepoint();
+  }
+}
+
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h b/third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h
index d1b5e33..9c53d56 100644
--- a/third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h
+++ b/third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h
@@ -35,21 +35,43 @@
   static CooperativeSchedulingManager* Instance();
 
   CooperativeSchedulingManager();
+  virtual ~CooperativeSchedulingManager() = default;
 
   // Returns true if the C++ stack has been whitelisted for reentry.
   bool InWhitelistedStackScope() const {
     return whitelisted_stack_scope_depth_ > 0;
   }
 
+  // Calls to this should be inserted where nested loops can be run safely.
+  // Typically this is is where Blink has not modified any global state that the
+  // nested code could touch.
+  void Safepoint();
+
+ protected:
+  virtual void RunNestedLoop();
+
  private:
   void EnterWhitelistedStackScope();
   void LeaveWhitelistedStackScope();
+  void SafepointSlow();
 
   int whitelisted_stack_scope_depth_ = 0;
+  bool running_nested_loop_ = false;
+  WTF::TimeTicks wait_until_;
 
   DISALLOW_COPY_AND_ASSIGN(CooperativeSchedulingManager);
 };
 
+inline void CooperativeSchedulingManager::Safepoint() {
+  if (!InWhitelistedStackScope())
+    return;
+
+  if (WTF::CurrentTimeTicks() < wait_until_)
+    return;
+
+  SafepointSlow();
+}
+
 }  // namespace scheduler
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h b/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
index af5b5ae..9a9e268 100644
--- a/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
+++ b/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
@@ -141,8 +141,7 @@
     float x,
     float y) {
   return TransformPaintPropertyNode::Create(
-      parent, TransformPaintPropertyNode::State{
-                  TransformationMatrix().Translate(x, y)});
+      parent, TransformPaintPropertyNode::State{FloatSize(x, y)});
 }
 
 inline scoped_refptr<TransformPaintPropertyNode> CreateTransform(
@@ -150,9 +149,8 @@
     const TransformationMatrix& matrix,
     const FloatPoint3D& origin = FloatPoint3D(),
     CompositingReasons compositing_reasons = CompositingReason::kNone) {
-  TransformPaintPropertyNode::State state;
-  state.matrix = matrix;
-  state.origin = origin;
+  TransformPaintPropertyNode::State state{
+      TransformPaintPropertyNode::TransformAndOrigin(matrix, origin)};
   state.direct_compositing_reasons = compositing_reasons;
   return TransformPaintPropertyNode::Create(parent, std::move(state));
 }
@@ -163,8 +161,7 @@
     float offset_y,
     const ScrollPaintPropertyNode& scroll,
     CompositingReasons compositing_reasons = CompositingReason::kNone) {
-  TransformPaintPropertyNode::State state;
-  state.matrix.Translate(offset_x, offset_y);
+  TransformPaintPropertyNode::State state{FloatSize(offset_x, offset_y)};
   state.direct_compositing_reasons = compositing_reasons;
   state.scroll = &scroll;
   return TransformPaintPropertyNode::Create(parent, std::move(state));
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
index 4d37e2ba..025157f 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -482,7 +482,6 @@
 crbug.com/591099 http/tests/webfont/crbug-655076.html [ Pass ]
 crbug.com/591099 images/feature-policy-oversized-images-resize.html [ Pass ]
 crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-origin-url.js [ Crash Pass ]
-crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-pseudo-element.js [ Failure ]
 crbug.com/591099 jquery/offset.html [ Pass ]
 crbug.com/591099 media/autoplay/webaudio-audio-context-resume.html [ Failure Pass ]
 crbug.com/591099 media_capabilities/encodingInfo-avc1.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 66661859..07947a7 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1731,6 +1731,7 @@
 crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/ttwf-reftest-flex-wrap-reverse.html [ Failure ]
 crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/hittest-overlapping-margin.html [ Failure ]
 crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/hittest-overlapping-order.html [ Failure ]
+crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html [ Failure ]
 
 ### virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-lines/
 crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-lines/multi-line-wrap-reverse-column-reverse.html [ Failure ]
@@ -2907,7 +2908,7 @@
 crbug.com/939406 external/wpt/html/browsers/windows/embedded-opener-remove-frame.html [ Failure ]
 
 # Sheriff 2019-03-08
-crbug.com/940050 virtual/threaded/external/wpt/animation-worklet/playback-rate.https.html [ Failure ]
+crbug.com/940050 virtual/threaded/external/wpt/animation-worklet/playback-rate.https.html [ Failure Timeout ]
 
 # Untriaged failures after https://crrev.com/c/543695/.
 # These need to be updated but appear not to be related to that change.
@@ -3037,9 +3038,6 @@
 crbug.com/939181 virtual/not-site-per-process/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Failure Timeout ]
 
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 [ Mac10.12 ] virtual/threaded/external/wpt/animation-worklet/playback-rate.https.html [ Timeout ]
-crbug.com/626703 [ Mac10.13 ] virtual/threaded/external/wpt/animation-worklet/playback-rate.https.html [ Timeout ]
-crbug.com/626703 [ Retina ] virtual/threaded/external/wpt/animation-worklet/playback-rate.https.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-sizing/range-percent-intrinsic-size-2a.html [ Failure ]
 crbug.com/626703 external/wpt/infrastructure/reftest/reftest_fuzzy.html [ Failure ]
 crbug.com/626703 external/wpt/infrastructure/reftest/reftest_fuzzy_1.html [ Failure ]
@@ -4231,6 +4229,9 @@
 crbug.com/835717 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-interception.https.html [ Skip ]
 # This is crashing because of DCHECK.
 crbug.com/835717 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html [ Skip ]
+# These are timing out.
+crbug.com/835717 virtual/omt-worker-fetch/external/wpt/content-security-policy/inside-worker/dedicated-script.html [ Skip ]
+crbug.com/835717 virtual/omt-worker-fetch/external/wpt/content-security-policy/inside-worker/dedicated-inheritance.html [ Skip ]
 
 # This fails because AllowedByNoSniff::MimeTypeAsScript() blocks the nested worker's
 # worker script, because the script url has a .html file extension.
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index a3b160c..20f7696 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -456,47 +456,47 @@
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/fetch",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/http",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/referrer-policy",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/service-workers",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/xhr",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "http/tests/fetch",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "http/tests/navigation",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "http/tests/security",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "http/tests/xmlhttprequest",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "presentation",
@@ -591,6 +591,16 @@
   },
   {
     "prefix": "omt-worker-fetch",
+    "base": "external/wpt/content-security-policy/inside-worker",
+    "args": ["--enable-features=OffMainThreadDedicatedWorkerScriptFetch,PlzDedicatedWorker,OffMainThreadServiceWorkerScriptFetch,OffMainThreadSharedWorkerScriptFetch"]
+  },
+  {
+    "prefix": "omt-worker-fetch",
+    "base": "external/wpt/content-security-policy/worker-src",
+    "args": ["--enable-features=OffMainThreadDedicatedWorkerScriptFetch,PlzDedicatedWorker,OffMainThreadServiceWorkerScriptFetch,OffMainThreadSharedWorkerScriptFetch"]
+  },
+  {
+    "prefix": "omt-worker-fetch",
     "base": "external/wpt/mixed-content/classic-data-worker-fetch",
     "args": ["--enable-features=OffMainThreadDedicatedWorkerScriptFetch,OffMainThreadServiceWorkerScriptFetch,OffMainThreadSharedWorkerScriptFetch"]
   },
diff --git a/third_party/blink/web_tests/editing/editability/ignored-content.html b/third_party/blink/web_tests/editing/editability/ignored-content.html
index e119033..17613654 100644
--- a/third_party/blink/web_tests/editing/editability/ignored-content.html
+++ b/third_party/blink/web_tests/editing/editability/ignored-content.html
@@ -24,7 +24,7 @@
     test.childNodes[i].appendChild(textNode);
     // OBJECT fallback content rendering is asynchronous.
     if (window.internals)
-        internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+        internals.updateLayoutAndRunPostLayoutTasks();
     window.getSelection().setBaseAndExtent(textNode, 6, textNode, 11);
     document.execCommand('bold', false, null);
 }
diff --git a/third_party/blink/web_tests/editing/shadow/selection-after-remove-children.html b/third_party/blink/web_tests/editing/shadow/selection-after-remove-children.html
new file mode 100644
index 0000000..23ca21a
--- /dev/null
+++ b/third_party/blink/web_tests/editing/shadow/selection-after-remove-children.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<body>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../assert_selection.js"></script>
+<script>
+selection_test(
+  '<div id="host"><div></div>child text</div>',
+  selection => {
+    console.log(selection.document.documentElement.innerHTML);
+    const host = selection.document.querySelector('#host');
+    const shadowRoot = host.attachShadow({mode: 'closed'});
+    shadowRoot.innerHTML = '<span>shadow text</span>';
+    const shadowSelection = shadowRoot.getSelection();
+    const range = document.createRange();
+    range.selectNode(shadowRoot.firstChild);
+    shadowSelection.addRange(range);
+
+    host.textContent = '';
+  },
+  '<div id="host">^<span>shadow text</span>|</div>',
+  {dumpAs: 'flattree'},
+  'Removing light children of a hos element should not affect selection in ' +
+      'its shadow tree');
+
+selection_test(
+  '<textarea id="host">abc^def\nghi|</textarea>',
+  selection => {
+    console.log(selection.document.documentElement.innerHTML);
+    const host = selection.document.querySelector('#host');
+    // Make the TEXTAREA dirty to avoid textContent affects the value.
+    eventSender.keyDown('j');
+
+    host.textContent = '';
+  },
+  '<textarea id="host">abcj|</textarea>',
+  'Removing light children of a TEXTAREA element should not affect its ' +
+      'selection');
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index 5d07795..0d68317 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -175163,6 +175163,11 @@
      {}
     ]
    ],
+   "idle-detection/mock.js": [
+    [
+     {}
+    ]
+   ],
    "imagebitmap-renderingcontext/META.yml": [
     [
      {}
@@ -218517,6 +218522,12 @@
      {}
     ]
    ],
+   "css/css-flexbox/intrinsic-width-overflow-auto.tentative.html": [
+    [
+     "/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html",
+     {}
+    ]
+   ],
    "css/css-flexbox/order_value.html": [
     [
      "/css/css-flexbox/order_value.html",
@@ -231247,6 +231258,12 @@
      {}
     ]
    ],
+   "custom-elements/reactions/HTMLMeterElement.html": [
+    [
+     "/custom-elements/reactions/HTMLMeterElement.html",
+     {}
+    ]
+   ],
    "custom-elements/reactions/HTMLModElement.html": [
     [
      "/custom-elements/reactions/HTMLModElement.html",
@@ -231259,6 +231276,12 @@
      {}
     ]
    ],
+   "custom-elements/reactions/HTMLOptGroupElement.html": [
+    [
+     "/custom-elements/reactions/HTMLOptGroupElement.html",
+     {}
+    ]
+   ],
    "custom-elements/reactions/HTMLOptionElement.html": [
     [
      "/custom-elements/reactions/HTMLOptionElement.html",
@@ -231277,6 +231300,18 @@
      {}
     ]
    ],
+   "custom-elements/reactions/HTMLParamElement.html": [
+    [
+     "/custom-elements/reactions/HTMLParamElement.html",
+     {}
+    ]
+   ],
+   "custom-elements/reactions/HTMLProgressElement.html": [
+    [
+     "/custom-elements/reactions/HTMLProgressElement.html",
+     {}
+    ]
+   ],
    "custom-elements/reactions/HTMLQuoteElement.html": [
     [
      "/custom-elements/reactions/HTMLQuoteElement.html",
@@ -259139,6 +259174,12 @@
      {}
     ]
    ],
+   "idle-detection/interceptor.https.html": [
+    [
+     "/idle-detection/interceptor.https.html",
+     {}
+    ]
+   ],
    "imagebitmap-renderingcontext/bitmaprenderer-as-imagesource.html": [
     [
      "/imagebitmap-renderingcontext/bitmaprenderer-as-imagesource.html",
@@ -349710,6 +349751,10 @@
    "0220d79d901cca14324ea331d0ddfd9c086a08ee",
    "manual"
   ],
+  "css/css-flexbox/intrinsic-width-overflow-auto.tentative.html": [
+   "8310e66cc4a2ef680d15f5c3ea56feb6edf4252e",
+   "testharness"
+  ],
   "css/css-flexbox/item-with-table-with-infinite-max-intrinsic-width.html": [
    "f475db5bcffd1449be231da943cd1511b15e20b1",
    "reftest"
@@ -393659,7 +393704,7 @@
    "testharness"
   ],
   "css/cssom/css-style-declaration-modifications.html": [
-   "4db637d7de9edfa0b037fe434067a199784d36b8",
+   "a0e22754911cc93bc5c8641d71a1e0fc99b3fcee",
    "testharness"
   ],
   "css/cssom/css-style-reparse.html": [
@@ -395343,7 +395388,7 @@
    "support"
   ],
   "css/mediaqueries/test_media_queries.html": [
-   "42a8a1e83d6d70cfb3cbffa1ea18e20b5a22079b",
+   "d08d83c34fd8112e2ecfee0f89893353e84df714",
    "testharness"
   ],
   "css/mediaqueries/viewport-script-dynamic-ref.html": [
@@ -402726,6 +402771,10 @@
    "1010aa7367cdada919acf1e22857e4404a681212",
    "testharness"
   ],
+  "custom-elements/reactions/HTMLMeterElement.html": [
+   "a152eb0f5a00f778906751cea58a187756e685f3",
+   "testharness"
+  ],
   "custom-elements/reactions/HTMLModElement.html": [
    "850fe170a50d21c1a5cb5a042f05bd2fb062d3fd",
    "testharness"
@@ -402734,6 +402783,10 @@
    "4e53cdb0a510453960feccd2104109610f23e665",
    "testharness"
   ],
+  "custom-elements/reactions/HTMLOptGroupElement.html": [
+   "afa31bb465f33debae79cbc0cbef4de0db382680",
+   "testharness"
+  ],
   "custom-elements/reactions/HTMLOptionElement.html": [
    "418ef282b32fd5e7c29f21a0a9eb17b6c4796167",
    "testharness"
@@ -402746,6 +402799,14 @@
    "02e669bc7a75558686dd56b4ab8fc5918892de2e",
    "testharness"
   ],
+  "custom-elements/reactions/HTMLParamElement.html": [
+   "a3f24ddb54ed5026f093f916adb54c8508e1f6e8",
+   "testharness"
+  ],
+  "custom-elements/reactions/HTMLProgressElement.html": [
+   "1be45f8d395b9f4ab6911c04151bd3d1cb45f28a",
+   "testharness"
+  ],
   "custom-elements/reactions/HTMLQuoteElement.html": [
    "97ab10a170e66eba7e036321111e99dbba8bcff8",
    "testharness"
@@ -405511,7 +405572,7 @@
    "testharness"
   ],
   "element-timing/cross-origin-element.sub.html": [
-   "ed820d0e66558d1db01109a6c4227c960f15644b",
+   "a122819fc499bde272daf1f8ccf086d856e69a62",
    "testharness"
   ],
   "element-timing/cross-origin-iframe-element.sub.html": [
@@ -405531,7 +405592,7 @@
    "testharness"
   ],
   "element-timing/observe-child-element.html": [
-   "83cc2ef94b3fe929ffd87b6c4a49f7424e6be29b",
+   "9166a4b0e6d129c356d74da2b81a6e02c08105b6",
    "testharness"
   ],
   "element-timing/observe-elementtiming.html": [
@@ -431442,6 +431503,14 @@
    "4bda5c1a85b71e8fcb1c050710279bfec2919b68",
    "testharness"
   ],
+  "idle-detection/interceptor.https.html": [
+   "03595afccdcd224f918f6e8baaf21c2419c24062",
+   "testharness"
+  ],
+  "idle-detection/mock.js": [
+   "d88d1ad1c55afaee243e1e9146827b073c380613",
+   "support"
+  ],
   "imagebitmap-renderingcontext/META.yml": [
    "f6a06f4e7d7625855e271ec5422629ca5e734560",
    "support"
@@ -432659,7 +432728,7 @@
    "support"
   ],
   "interfaces/mediasession.idl": [
-   "0fc9ff05f9475cd7f48fde6c22765d431b51310c",
+   "6fd5725dbb2975e724594629f0c2882477455caa",
    "support"
   ],
   "interfaces/mediastream-recording.idl": [
@@ -432907,7 +432976,7 @@
    "support"
   ],
   "interfaces/webxr.idl": [
-   "e91a50c28ee7acbcc5e04ed9e7b929def64afee3",
+   "1bbe7efd2da4c5f17967257cb52d1c6139624ddf",
    "support"
   ],
   "interfaces/worklets.idl": [
@@ -456843,7 +456912,7 @@
    "support"
   ],
   "resources/chromium/webxr-test.js": [
-   "c6c21a6fed6c05a1981b9241d233a1b501fdf3ab",
+   "8816273705806dd8efb9c33a52a61689f802ecf2",
    "support"
   ],
   "resources/chromium/webxr-test.js.headers": [
@@ -480071,7 +480140,7 @@
    "support"
   ],
   "webxr/idlharness.https.window-expected.txt": [
-   "0b323e5bdfed735daa238fc63bd6ebfd755ac396",
+   "c491e806fb5c5c9aed9f7cad7e6cc65e080b8350",
    "support"
   ],
   "webxr/idlharness.https.window.js": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html
new file mode 100644
index 0000000..8310e66
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<link rel="author" title="Google" href="https://www.google.com/" />
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#intrinsic-sizes" />
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1865" />
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.flexbox')">
+<div class="flexbox" style="display: flex; width: min-content;" data-expected-width="0">
+  <div style="overflow: auto;">
+    <div style="width: 100px; height: 100px;"></div>
+  </div>
+</div>
+
+<div class="flexbox" style="display: flex; width: min-content;" data-expected-width="10">
+  <div style="overflow: auto; border: 5px solid;">
+    <div style="width: 100px; height: 100px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/css-style-declaration-modifications.html b/third_party/blink/web_tests/external/wpt/css/cssom/css-style-declaration-modifications.html
index 4db637d..a0e2275 100644
--- a/third_party/blink/web_tests/external/wpt/css/cssom/css-style-declaration-modifications.html
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/css-style-declaration-modifications.html
@@ -48,6 +48,7 @@
         declaration.setProperty("margin-left", "15px");
         declaration.setProperty("padding-left", "15px");
 
+
         assert_equals(declaration.length, 2);
         assert_equals(declaration.item(0), "margin-left");
         assert_equals(declaration.item(1), "padding-left");
@@ -57,7 +58,14 @@
         var computedStyle = window.getComputedStyle(document.getElementById("test"));
         assert_equals(computedStyle.getPropertyValue("margin-left"), "15px");
         assert_equals(computedStyle.getPropertyValue("padding-left"), "15px");
+
     }, "Calling CSSStyleDeclaration#setProperty");
+
+    test(function() {
+        declaration.setProperty("background-color", "red", "ImPoRtAnt");
+        assert_equals(declaration.getPropertyPriority("background-color"), "important");
+    }, "setProperty priority should be case-insensitive");
+
  </script>
  </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/test_media_queries.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/test_media_queries.html
index 42a8a1e..d08d83c34 100644
--- a/third_party/blink/web_tests/external/wpt/css/mediaqueries/test_media_queries.html
+++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/test_media_queries.html
@@ -539,6 +539,40 @@
     var overflow_inline_none = query_applies("(overflow-inline: none)");
     assert_not_equals(any_overflow_inline, overflow_inline_none, "overflow-inline should be equivalent to not (overflow-inline: none)");
 
+    // Parsing tests for interaction media features.
+    expression_should_be_parseable("hover")
+    expression_should_be_parseable("hover: hover")
+    expression_should_be_parseable("hover: none")
+    expression_should_be_parseable("any-hover")
+    expression_should_be_parseable("any-hover: hover")
+    expression_should_be_parseable("any-hover: none")
+
+    assert_equals(query_applies("(hover)"), query_applies("(hover: hover)"), "(hover) == (hover: hover)");
+    assert_not_equals(query_applies("(hover)"), query_applies("(hover: none)"), "(hover) == not (hover: none)");
+    assert_equals(query_applies("(any-hover)"), query_applies("(any-hover: hover)"), "(any-hover) == (any-hover: hover)");
+    assert_not_equals(query_applies("(any-hover)"), query_applies("(any-hover: none)"), "(any-hover) == not (any-hover: none)");
+
+    expression_should_be_parseable("pointer")
+    expression_should_be_parseable("pointer: coarse")
+    expression_should_be_parseable("pointer: fine")
+    expression_should_be_parseable("pointer: none")
+    expression_should_be_parseable("any-pointer")
+    expression_should_be_parseable("any-pointer: coarse")
+    expression_should_be_parseable("any-pointer: fine")
+    expression_should_be_parseable("any-pointer: none")
+    assert_equals(query_applies("(pointer)"),
+                  query_applies("(pointer: coarse)") || query_applies("(pointer: fine)"),
+                  "(pointer) == (pointer: coarse) or (pointer: fine)");
+    assert_not_equals(query_applies("(pointer)"),
+                      query_applies("(pointer: none)"),
+                      "(pointer) == not (pointer: none)");
+    assert_equals(query_applies("(any-pointer)"),
+                  query_applies("(any-pointer: coarse)") || query_applies("(any-pointer: fine)"),
+                  "(any-pointer) == (any-pointer: coarse) or (any-pointer: fine)");
+    assert_not_equals(query_applies("(any-pointer)"),
+                      query_applies("(any-pointer: none)"),
+                      "(any-pointer) == not (any-pointer: none)");
+
     done();
 }
 
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLMeterElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLMeterElement.html
new file mode 100644
index 0000000..a152eb0f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLMeterElement.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>Custom Elements: CEReactions on HTMLMeterElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="value, min, max, low, high, optimum of
+  HTMLMeterElement interface must have CEReactions">
+<meta name="help" content="https://html.spec.whatwg.org/#the-meter-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/custom-elements-helpers.js"></script>
+<script src="./resources/reactions.js"></script>
+
+<body>
+<script>
+
+function getParentElement() {
+  return document.body;
+}
+
+function setAttributes(instance) {
+  instance.setAttribute('value', '0.6');
+}
+
+testReflectAttribute(
+  'value', 'value', '0.3',
+  '0.4', 'value on HTMLMeterElement', 'meter',
+  HTMLMeterElement
+);
+testReflectAttributeWithDependentAttributes(
+  'min', 'min', '0.1',
+  '0.2', 'min on HTMLMeterElement', 'meter',
+  getParentElement, instance => setAttributes(instance), HTMLMeterElement
+);
+testReflectAttributeWithDependentAttributes(
+  'max', 'max', '2',
+  '3', 'max on HTMLMeterElement', 'meter',
+  getParentElement, instance => setAttributes(instance), HTMLMeterElement
+);
+testReflectAttributeWithDependentAttributes(
+  'low', 'low', '0.1',
+  '0.2', 'low on HTMLMeterElement', 'meter',
+  getParentElement, instance => setAttributes(instance), HTMLMeterElement
+);
+testReflectAttributeWithDependentAttributes(
+  'high', 'high', '2',
+  '3', 'high on HTMLMeterElement', 'meter',
+  getParentElement, instance => setAttributes(instance), HTMLMeterElement
+);
+testReflectAttributeWithDependentAttributes(
+  'optimum', 'optimum', '0.3',
+  '0.4', 'optimum on HTMLMeterElement', 'meter',
+  getParentElement, instance => setAttributes(instance), HTMLMeterElement
+);
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptGroupElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptGroupElement.html
new file mode 100644
index 0000000..afa31bb4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptGroupElement.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<title>Custom Elements: CEReactions on HTMLOptGroupElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="disabled, label of
+  HTMLOptGroupElement interface must have CEReactions">
+<meta name="help" content="https://html.spec.whatwg.org/#the-optgroup-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/custom-elements-helpers.js"></script>
+<script src="./resources/reactions.js"></script>
+
+<body>
+<script>
+
+function getParentElement() {
+  let element = document.createElement('select');
+  document.body.appendChild(element);
+  return element;
+}
+
+function setAttributes(instance) {
+  instance.setAttribute('label', 'group1');
+}
+
+testReflectBooleanAttributeWithDependentAttributes(
+  'disabled', 'disabled', 'disabled on HTMLOptGroupElement',
+  'optgroup', getParentElement, instance => setAttributes(instance),
+  HTMLOptGroupElement
+);
+
+testReflectAttributeWithParentNode(
+  'label', 'label', 'group1',
+  'group2', 'label on HTMLOptGroupElement', 'optgroup',
+  getParentElement, HTMLOptGroupElement
+);
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLParamElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLParamElement.html
new file mode 100644
index 0000000..a3f24dd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLParamElement.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>Custom Elements: CEReactions on HTMLParamElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="name, value of HTMLParamElement
+  interface must have CEReactions">
+<meta name="help" content="https://html.spec.whatwg.org/#the-param-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/custom-elements-helpers.js"></script>
+<script src="./resources/reactions.js"></script>
+
+<body>
+<script>
+
+function getParentElement() {
+  let element = document.createElement('object');
+  element['type'] = 'image/png';
+  element['data'] = '/images/blue.png';
+  document.body.appendChild(element);
+  return element;
+}
+
+function setAttributes(instance, attribute, value) {
+  instance.setAttribute(attribute, value);
+}
+
+testReflectAttributeWithDependentAttributes(
+  'name', 'name', 'image1',
+  'image2', 'name on HTMLParamElement', 'param',
+  getParentElement, instance => setAttributes(instance, 'value', 'blue'),
+  HTMLParamElement
+);
+testReflectAttributeWithDependentAttributes(
+  'value', 'value', 'blue1',
+  'blue2', 'value on HTMLParamElement', 'param',
+  getParentElement, instance => setAttributes(instance, 'name', 'image'),
+  HTMLParamElement
+);
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLProgressElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLProgressElement.html
new file mode 100644
index 0000000..1be45f8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLProgressElement.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>Custom Elements: CEReactions on HTMLProgressElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="value, max of HTMLProgressElement
+  interface must have CEReactions">
+<meta name="help" content="https://html.spec.whatwg.org/#the-progress-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/custom-elements-helpers.js"></script>
+<script src="./resources/reactions.js"></script>
+
+<script>
+
+testReflectAttribute(
+  'value', 'value', '0.15',
+  '0.2', 'value on HTMLProgressElement', 'progress',
+  HTMLProgressElement
+);
+testReflectAttribute(
+  'max', 'max', '2',
+  '4', 'max on HTMLProgressElement', 'progress',
+  HTMLProgressElement
+);
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/mediasession.idl b/third_party/blink/web_tests/external/wpt/interfaces/mediasession.idl
index 0fc9ff05..6fd5725 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/mediasession.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/mediasession.idl
@@ -22,6 +22,7 @@
   "previoustrack",
   "nexttrack",
   "skipad",
+  "stop",
 };
 
 callback MediaSessionActionHandler = void();
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
index e91a50c..1bbe7efd 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
@@ -133,7 +133,6 @@
 [SecureContext, Exposed=Window] interface XRView {
   readonly attribute XREye eye;
   readonly attribute Float32Array projectionMatrix;
-  readonly attribute Float32Array viewMatrix;
   readonly attribute XRRigidTransform transform;
 };
 
@@ -150,6 +149,8 @@
   readonly attribute DOMPointReadOnly position;
   readonly attribute DOMPointReadOnly orientation;
   readonly attribute Float32Array matrix;
+
+  XRRigidTransform inverse();
 };
 
 [SecureContext, Exposed=Window,
@@ -200,6 +201,7 @@
   boolean depth = true;
   boolean stencil = false;
   boolean alpha = true;
+  boolean ignoreDepthValues = false;
   double framebufferScaleFactor = 1.0;
 };
 
@@ -214,6 +216,7 @@
   readonly attribute boolean depth;
   readonly attribute boolean stencil;
   readonly attribute boolean alpha;
+  readonly attribute boolean ignoreDepthValues;
 
   readonly attribute WebGLFramebuffer framebuffer;
   readonly attribute unsigned long framebufferWidth;
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
index 0b323e5b..c491e80 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 215 tests; 198 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 216 tests; 197 PASS, 19 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS Partial interface Navigator: original interface defined
 PASS Partial dictionary WebGLContextAttributes: original dictionary defined
@@ -104,7 +104,6 @@
 PASS XRView interface: existence and properties of interface prototype object's @@unscopables property
 PASS XRView interface: attribute eye
 PASS XRView interface: attribute projectionMatrix
-PASS XRView interface: attribute viewMatrix
 PASS XRView interface: attribute transform
 PASS XRViewport interface: existence and properties of interface object
 PASS XRViewport interface object length
@@ -125,6 +124,7 @@
 PASS XRRigidTransform interface: attribute position
 PASS XRRigidTransform interface: attribute orientation
 PASS XRRigidTransform interface: attribute matrix
+FAIL XRRigidTransform interface: operation inverse() assert_own_property: interface prototype object missing non-static operation expected property "inverse" missing
 PASS XRRay interface: existence and properties of interface object
 PASS XRRay interface object length
 PASS XRRay interface object name
@@ -176,6 +176,7 @@
 PASS XRWebGLLayer interface: attribute depth
 PASS XRWebGLLayer interface: attribute stencil
 PASS XRWebGLLayer interface: attribute alpha
+FAIL XRWebGLLayer interface: attribute ignoreDepthValues assert_true: The prototype object must have a property "ignoreDepthValues" expected true got false
 PASS XRWebGLLayer interface: attribute framebuffer
 PASS XRWebGLLayer interface: attribute framebufferWidth
 PASS XRWebGLLayer interface: attribute framebufferHeight
diff --git a/third_party/blink/web_tests/fast/css/acid2.html b/third_party/blink/web_tests/fast/css/acid2.html
index d7531ae4..b330083 100644
--- a/third_party/blink/web_tests/fast/css/acid2.html
+++ b/third_party/blink/web_tests/fast/css/acid2.html
@@ -151,7 +151,7 @@
    if (window.testRunner)
      testRunner.dumpAsTextWithPixelResults();
    if (window.internals)
-     internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+     internals.updateLayoutAndRunPostLayoutTasks();
  </script>
  </body>
 </html>
diff --git a/third_party/blink/web_tests/fast/css/crash-layout-detached-document.html b/third_party/blink/web_tests/fast/css/crash-layout-detached-document.html
index f7eef38a..59e4be5b 100644
--- a/third_party/blink/web_tests/fast/css/crash-layout-detached-document.html
+++ b/third_party/blink/web_tests/fast/css/crash-layout-detached-document.html
@@ -12,8 +12,6 @@
     if (window.testRunner)
         testRunner.dumpAsText();
     var iframeDocument = iframe.contentDocument;
-    // Need to use link elements in this test to create placeholder styles so
-    // we'll go into the Force case inside updateLayoutIgnorePendingStylesheets.
     var link = document.createElement("link");
     link.href = "doesnotexist.css";
     link.rel = "stylesheet";
diff --git a/third_party/blink/web_tests/fast/css/mask-missing-image-crash.html b/third_party/blink/web_tests/fast/css/mask-missing-image-crash.html
index 00778d1..dd75f28d 100644
--- a/third_party/blink/web_tests/fast/css/mask-missing-image-crash.html
+++ b/third_party/blink/web_tests/fast/css/mask-missing-image-crash.html
@@ -6,4 +6,4 @@
 </script>
 <object style="-webkit-mask-image: url(url-not-found);">text
 <object style="-webkit-mask-box-image: url(url-not-found); ">text</object></object>
-<script>internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();</script>
+<script>internals.updateLayoutAndRunPostLayoutTasks();</script>
diff --git a/third_party/blink/web_tests/fast/dom/HTMLObjectElement/form/nested-form-element.html b/third_party/blink/web_tests/fast/dom/HTMLObjectElement/form/nested-form-element.html
index ef3326333..e3db63b 100644
--- a/third_party/blink/web_tests/fast/dom/HTMLObjectElement/form/nested-form-element.html
+++ b/third_party/blink/web_tests/fast/dom/HTMLObjectElement/form/nested-form-element.html
@@ -5,7 +5,7 @@
           testRunner.dumpAsText();
   </script>
 </head>
-<body onload="internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();">
+<body onload="internals.updateLayoutAndRunPostLayoutTasks();">
   <p>This test checks whether WebKit can parse a page that contains &lt;object&gt; elements which are in nested and defective &lt;form&gt; elements. WebKit should not crash when it renders this page.</p>
 
   <form><div></form><table><form><object></form><object>
diff --git a/third_party/blink/web_tests/fast/harness/internals-no-document-crash.html b/third_party/blink/web_tests/fast/harness/internals-no-document-crash.html
index 6655df9..19dc4906 100644
--- a/third_party/blink/web_tests/fast/harness/internals-no-document-crash.html
+++ b/third_party/blink/web_tests/fast/harness/internals-no-document-crash.html
@@ -6,7 +6,7 @@
         testRunner.dumpAsText();
     if (window.internals) {
         try {
-            internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(document.querySelector('iframe'));
+            internals.updateLayoutAndRunPostLayoutTasks(document.querySelector('iframe'));
         } catch (e) {}
     }
 </script>
diff --git a/third_party/blink/web_tests/http/tests/fouc/scroll-left-while-loading.html b/third_party/blink/web_tests/http/tests/fouc/scroll-left-while-loading.html
deleted file mode 100644
index 321396b9..0000000
--- a/third_party/blink/web_tests/http/tests/fouc/scroll-left-while-loading.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<script>
-if (window.testRunner) {
-    testRunner.dumpAsText();
-    testRunner.waitUntilDone();
-}
-setTimeout(function(){
-    document.scrollingElement.scrollLeft;
-    // Check that ignoreLayoutWithPendingStylesheets will return true if we did a
-    // forced repaint after the access to scrollLeft. We should not since the delayed
-    // stylesheet below is pending.
-    if (!window.internals || internals.ignoreLayoutWithPendingStylesheets(document))
-        document.write("FAIL");
-    else
-        document.write("PASS");
-    document.close();
-    if (window.testRunner)
-        testRunner.notifyDone();
-}, 0);
-</script>
-<link rel="stylesheet" href="/resources/slow-script.pl?delay=100">
diff --git a/third_party/blink/web_tests/http/tests/loading/nested_bad_objects.php b/third_party/blink/web_tests/http/tests/loading/nested_bad_objects.php
index 19bc0b59..0c323ac 100644
--- a/third_party/blink/web_tests/http/tests/loading/nested_bad_objects.php
+++ b/third_party/blink/web_tests/http/tests/loading/nested_bad_objects.php
@@ -9,7 +9,7 @@
     if (window.testRunner)
         testRunner.dumpAsText();
     window.onload = function() {
-        internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+        internals.updateLayoutAndRunPostLayoutTasks();
     };
     </script>
     <object type="image/jpeg" data="nested_bad_objects.php?object">
diff --git a/third_party/blink/web_tests/http/tests/misc/acid2.html b/third_party/blink/web_tests/http/tests/misc/acid2.html
index 57bcd336..c17d49c 100644
--- a/third_party/blink/web_tests/http/tests/misc/acid2.html
+++ b/third_party/blink/web_tests/http/tests/misc/acid2.html
@@ -152,7 +152,7 @@
     if (window.testRunner)
       testRunner.dumpAsTextWithPixelResults();
     if (window.internals)
-      internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+      internals.updateLayoutAndRunPostLayoutTasks();
   </script>
  </body>
 </html>
diff --git a/third_party/blink/web_tests/http/tests/security/contentSecurityPolicy/resources/multiple-iframe-plugin-test.js b/third_party/blink/web_tests/http/tests/security/contentSecurityPolicy/resources/multiple-iframe-plugin-test.js
index 8987a98..73299e4 100644
--- a/third_party/blink/web_tests/http/tests/security/contentSecurityPolicy/resources/multiple-iframe-plugin-test.js
+++ b/third_party/blink/web_tests/http/tests/security/contentSecurityPolicy/resources/multiple-iframe-plugin-test.js
@@ -40,7 +40,7 @@
 
     iframe.onload = function() {
         if (window.internals)
-            internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(iframe);
+            internals.updateLayoutAndRunPostLayoutTasks(iframe);
         testImpl(experimental);
     };
     document.body.appendChild(iframe);
diff --git a/third_party/blink/web_tests/http/tests/security/mixedContent/resources/frame-with-insecure-plugin.html b/third_party/blink/web_tests/http/tests/security/mixedContent/resources/frame-with-insecure-plugin.html
index ef4d4270..5943f20 100644
--- a/third_party/blink/web_tests/http/tests/security/mixedContent/resources/frame-with-insecure-plugin.html
+++ b/third_party/blink/web_tests/http/tests/security/mixedContent/resources/frame-with-insecure-plugin.html
@@ -2,7 +2,7 @@
 window.onload = function() {
   setTimeout(function() {
     if (window.internals)
-      internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(document);
+      internals.updateLayoutAndRunPostLayoutTasks(document);
     if (window.testRunner)
       testRunner.notifyDone();
   }, 0);
diff --git a/third_party/blink/web_tests/plugins/fullscreen-plugins-dont-reload.html b/third_party/blink/web_tests/plugins/fullscreen-plugins-dont-reload.html
index af7ebb7..9b9d897e 100644
--- a/third_party/blink/web_tests/plugins/fullscreen-plugins-dont-reload.html
+++ b/third_party/blink/web_tests/plugins/fullscreen-plugins-dont-reload.html
@@ -14,7 +14,7 @@
 
     var plugin = document.querySelector('embed');
     plugin.addEventListener('webkitfullscreenchange', function () {
-        internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+        internals.updateLayoutAndRunPostLayoutTasks();
         testRunner.notifyDone();
     })
     document.addEventListener('keydown', function () {
diff --git a/third_party/blink/web_tests/plugins/gesture-events-scrolled.html b/third_party/blink/web_tests/plugins/gesture-events-scrolled.html
index 0c003cc..2a43c7d 100644
--- a/third_party/blink/web_tests/plugins/gesture-events-scrolled.html
+++ b/third_party/blink/web_tests/plugins/gesture-events-scrolled.html
@@ -21,7 +21,7 @@
         document.write("This test does not work in manual mode.");
     } else {
         testRunner.dumpAsText();
-        internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+        internals.updateLayoutAndRunPostLayoutTasks();
 
         // Scroll so the plugin is 100px down the page
         window.scroll(0, 400);
diff --git a/third_party/blink/web_tests/plugins/plugin-initiate-popup-window.html b/third_party/blink/web_tests/plugins/plugin-initiate-popup-window.html
index d51ebec8..cfce3b6 100644
--- a/third_party/blink/web_tests/plugins/plugin-initiate-popup-window.html
+++ b/third_party/blink/web_tests/plugins/plugin-initiate-popup-window.html
@@ -63,7 +63,7 @@
 }
 </script>
 </head>
-<body onload="internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(); test();">
+<body onload="internals.updateLayoutAndRunPostLayoutTasks(); test();">
 <embed type="application/x-blink-deprecated-test-plugin" width=100 height=40 mousedownscript="popup_by_mousedown()" windowedplugin="false"></embed><br>
 <embed type="application/x-blink-deprecated-test-plugin" width=100 height=40 keydownscript="popup_by_keydown()" windowedplugin="false"></embed><br>
 Specify a script and a mouse/keyboard event to the plugin. The specified script will be evaluated in the browser when the specified event is received by the plugin. The test is for bug https://bugs.webkit.org/show_bug.cgi?id=41292.<br>
diff --git a/third_party/blink/web_tests/plugins/user-gesture.html b/third_party/blink/web_tests/plugins/user-gesture.html
index cabf5f1..9aa2310e 100644
--- a/third_party/blink/web_tests/plugins/user-gesture.html
+++ b/third_party/blink/web_tests/plugins/user-gesture.html
@@ -12,7 +12,7 @@
         document.write("This test does not work in manual mode.");
     } else {
         testRunner.dumpAsText();
-        internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+        internals.updateLayoutAndRunPostLayoutTasks();
 
         // Click on the plugin.
         eventSender.mouseMoveTo(20, 20);
diff --git a/third_party/blink/web_tests/resources/plugin.js b/third_party/blink/web_tests/resources/plugin.js
index d12c336..5326cb16 100644
--- a/third_party/blink/web_tests/resources/plugin.js
+++ b/third_party/blink/web_tests/resources/plugin.js
@@ -4,7 +4,7 @@
         testRunner.waitUntilDone();
     window.addEventListener('load', function() {
         if (window.internals)
-            internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(node);
+            internals.updateLayoutAndRunPostLayoutTasks(node);
         if (f)
             f();
         testRunner.notifyDone();
diff --git a/third_party/blink/web_tests/shadow-dom/focus-flat-tree.html b/third_party/blink/web_tests/shadow-dom/focus-flat-tree.html
deleted file mode 100644
index 41f8f70..0000000
--- a/third_party/blink/web_tests/shadow-dom/focus-flat-tree.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<script>
-function clickOn(el) {
-  return new Promise(function(resolve, reject) {
-    chrome.gpuBenchmarking.pointerActionSequence([{
-      source: 'mouse',
-      actions: [
-        { name: 'pointerDown',
-          x: el.offsetLeft + 5,
-          y: el.offsetTop + 5
-        },
-        { name: 'pointerUp' }
-      ]
-    }], resolve);
-  });
-}
-</script>
-<body>
-  <div id='normalDiv' tabindex='0'><span id='normalSpan'>OK</span></div>
-  <div id='container'><span id='slottedSpan'>OK</span></div>
-</body>
-<script>
-let sr = container.attachShadow({ mode: 'open' });
-sr.innerHTML = '<div id="shadowDiv" tabindex="0"><slot></slot></div>';
-
-promise_test(async () => {
-  await clickOn(normalSpan);
-  assert_equals(document.activeElement, normalDiv);
-  await clickOn(slottedSpan);
-  assert_equals(sr.activeElement, sr.getElementById('shadowDiv'));
-}, 'Clicking on non-focusable slot inside focusable button will make the flat-tree focusable ancestor get focused');
-</script>
diff --git a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/content-security-policy/inside-worker/shared-script-expected.txt b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/content-security-policy/inside-worker/shared-script-expected.txt
new file mode 100644
index 0000000..5967e9c
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/content-security-policy/inside-worker/shared-script-expected.txt
@@ -0,0 +1,12 @@
+This is a testharness.js-based test.
+PASS Cross-origin `importScripts()` not blocked in http:
+PASS `eval()` not blocked in http:
+PASS `setTimeout([string])` not blocked in http:
+PASS Cross-origin `importScripts()` blocked in http:?pipe=sub|header(Content-Security-Policy,script-src%20%27self%27
+FAIL `eval()` blocked in http:?pipe=sub|header(Content-Security-Policy,script-src%20%27self%27 assert_throws: `eval()` should throw 'EvalError'. function "_ => eval("1 + 1")" did not throw
+PASS `setTimeout([string])` blocked in http:?pipe=sub|header(Content-Security-Policy,script-src%20%27self%27
+PASS Cross-origin `importScripts()` blocked in http:?pipe=sub|header(Content-Security-Policy,default-src%20%27self%27
+FAIL `eval()` blocked in http:?pipe=sub|header(Content-Security-Policy,default-src%20%27self%27 assert_throws: `eval()` should throw 'EvalError'. function "_ => eval("1 + 1")" did not throw
+PASS `setTimeout([string])` blocked in http:?pipe=sub|header(Content-Security-Policy,default-src%20%27self%27
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
index 26ac7bd4..883503a 100644
--- a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
+++ b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
@@ -9,6 +9,7 @@
 document-write
 encrypted-media
 font-display-late-swap
+forms
 fullscreen
 geolocation
 gyroscope
@@ -19,13 +20,20 @@
 magnetometer
 microphone
 midi
+modals
+orientation-lock
 oversized-images
 payment
 picture-in-picture
+pointer-lock
+popups
+presentation
+scripts
 serial
 speaker
 sync-script
 sync-xhr
+top-navigation
 unoptimized-images
 unsized-media
 usb
diff --git a/third_party/libaom/options.gni b/third_party/libaom/options.gni
index 6d01c372..06717a33 100644
--- a/third_party/libaom/options.gni
+++ b/third_party/libaom/options.gni
@@ -2,6 +2,5 @@
 
 declare_args() {
   # Enable decoding AV1 video files.
-  enable_av1_decoder =
-      !is_android && !is_ios && (current_cpu == "x86" || current_cpu == "x64")
+  enable_av1_decoder = !is_android && !is_ios
 }
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 78478702..5efd410a 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -508,6 +508,7 @@
       'Mac V8 FYI Release (Intel)': 'gpu_tests_release_trybot',
       'V8 Android GN (dbg)': 'android_debug_bot',
       'V8 Linux GN': 'release_bot',
+      'V8 Blink Linux Layout NG': 'release_bot',
       'V8-Blink Linux 64': 'release_bot',
       'V8-Blink Linux 64 - future': 'release_bot',
       'V8-Blink Linux 64 (dbg)': 'release_bot_v8_debug',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index b66568f..fed76465 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -22178,6 +22178,7 @@
   <int value="2825" label="BuiltInModuleVirtualScroller"/>
   <int value="2826" label="AdClickNavigation"/>
   <int value="2827" label="RTCStatsRelativePacketArrivalDelay"/>
+  <int value="2828" label="FlexboxWithOverflowFlexItemIntrinsicSize"/>
 </enum>
 
 <enum name="FeaturePolicyFeature">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 40d25d3..a806ee7a 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -128183,6 +128183,10 @@
 
 <histogram name="Webapp.Engagement.EngagementType"
     enum="SiteEngagementServiceEngagementType" expires_after="2019-03-07">
+  <obsolete>
+    Removed 3/2019 because only counts PWAs. Superseded by the WebApp.Engagement
+    histogram with suffixes.
+  </obsolete>
   <owner>calamity@chromium.org</owner>
   <owner>mgiuca@chromium.org</owner>
   <summary>
@@ -128190,9 +128194,7 @@
     accumulation in site engagement within a PWA app window. Should be collected
     for a subset of SiteEngagementService.EngagementType, which is triggered for
     all browsing contexts. Recorded at the time of engagement accumulation
-    (e.g., when mouse is clicked). Deprecated because only counts PWAs.
-    Superseded by the WebApp.Engagement histogram with suffixes.
-    http://crbug.com/918089.
+    (e.g., when mouse is clicked).
   </summary>
 </histogram>
 
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index 41f2d03..726c2a1 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -246,6 +246,7 @@
     "java/src/org/chromium/ui/base/Clipboard.java",
     "java/src/org/chromium/ui/base/DeviceFormFactor.java",
     "java/src/org/chromium/ui/base/EventForwarder.java",
+    "java/src/org/chromium/ui/base/TouchlessEventHandler.java",
     "java/src/org/chromium/ui/base/IdleDetector.java",
     "java/src/org/chromium/ui/base/LocalizationUtils.java",
     "java/src/org/chromium/ui/base/PermissionCallback.java",
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc
index c4ea2d3d..43e4045a 100644
--- a/ui/android/delegated_frame_host_android.cc
+++ b/ui/android/delegated_frame_host_android.cc
@@ -196,7 +196,7 @@
     content_layer_->RemoveFromParent();
     content_layer_ = nullptr;
   }
-  if (!HasSavedFrame())
+  if (!HasSavedFrame() || frame_evictor_->visible())
     return;
   std::vector<viz::SurfaceId> surface_ids = {
       viz::SurfaceId(frame_sink_id_, local_surface_id_)};
diff --git a/ui/android/delegated_frame_host_android_unittest.cc b/ui/android/delegated_frame_host_android_unittest.cc
index 3ebfea41..41e707eb 100644
--- a/ui/android/delegated_frame_host_android_unittest.cc
+++ b/ui/android/delegated_frame_host_android_unittest.cc
@@ -368,16 +368,15 @@
 // Make sure frame evictor is notified of the newly embedded surface after
 // WasShown.
 TEST_F(DelegatedFrameHostAndroidVizTest, EmbedWhileHidden) {
-  {
-    EXPECT_CALL(client_, WasEvicted());
-    frame_host_->EvictDelegatedFrame();
-  }
+  // Ensure there is currently no frame.
+  frame_host_->WasHidden();
+  frame_host_->EvictDelegatedFrame();
   EXPECT_FALSE(frame_host_->HasSavedFrame());
+
   allocator_.GenerateId();
   viz::LocalSurfaceId id =
       allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
   gfx::Size size(100, 100);
-  frame_host_->WasHidden();
   frame_host_->EmbedSurface(id, size, cc::DeadlinePolicy::UseDefaultDeadline());
   EXPECT_FALSE(frame_host_->HasSavedFrame());
   frame_host_->WasShown(id, size);
diff --git a/ui/android/java/src/org/chromium/ui/base/TouchlessEventHandler.java b/ui/android/java/src/org/chromium/ui/base/TouchlessEventHandler.java
new file mode 100644
index 0000000..8c2d75f
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/base/TouchlessEventHandler.java
@@ -0,0 +1,35 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.ui.base;
+
+/**
+ * org.chromium.ui.base.TouchlessEventHandler
+ */
+public class TouchlessEventHandler {
+    private static final String EVENT_HANDLER_INTERNAL =
+            "org.chromium.ui.base.TouchlessEventHandlerInternal";
+    private static TouchlessEventHandler sInstance;
+
+    static {
+        try {
+            sInstance = (TouchlessEventHandler) Class.forName(EVENT_HANDLER_INTERNAL).newInstance();
+        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
+                | IllegalArgumentException e) {
+            sInstance = null;
+        }
+    }
+
+    public static boolean hasTouchlessEventHandler() {
+        return sInstance != null;
+    }
+
+    public static boolean onUnconsumedKeyboardEventAck(int nativeCode) {
+        return sInstance.onUnconsumedKeyboardEventAckInternal(nativeCode);
+    }
+
+    protected boolean onUnconsumedKeyboardEventAckInternal(int nativeCode) {
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
index 2d7151fb..5452738 100644
--- a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
+++ b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
@@ -434,4 +434,14 @@
         ViewGroup containerView = getContainerView();
         if (containerView != null) ViewUtils.requestFocus(containerView);
     }
+
+    @CalledByNative
+    private boolean hasTouchlessEventHandler() {
+        return TouchlessEventHandler.hasTouchlessEventHandler();
+    }
+
+    @CalledByNative
+    private boolean onUnconsumedKeyboardEventAck(int nativeCode) {
+        return TouchlessEventHandler.onUnconsumedKeyboardEventAck(nativeCode);
+    }
 }
diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc
index 023147c..1528f37 100644
--- a/ui/android/view_android.cc
+++ b/ui/android/view_android.cc
@@ -633,4 +633,20 @@
   bounds_.SetRect(x, y, width, height);
 }
 
+bool ViewAndroid::OnUnconsumedKeyboardEventAck(int native_code) {
+  ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
+  if (delegate.is_null())
+    return false;
+
+  JNIEnv* env = base::android::AttachCurrentThread();
+  static bool s_has_touchless_event_handler =
+      Java_ViewAndroidDelegate_hasTouchlessEventHandler(env, delegate);
+
+  if (!s_has_touchless_event_handler)
+    return false;
+
+  return Java_ViewAndroidDelegate_onUnconsumedKeyboardEventAck(env, delegate,
+                                                               native_code);
+}
+
 }  // namespace ui
diff --git a/ui/android/view_android.h b/ui/android/view_android.h
index d59fb3b..a7639980 100644
--- a/ui/android/view_android.h
+++ b/ui/android/view_android.h
@@ -185,6 +185,8 @@
     return OnTouchEvent(event);
   }
 
+  bool OnUnconsumedKeyboardEventAck(int native_code);
+
  protected:
   void RemoveAllChildren(bool attached_to_window);
 
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc
index b5ee3f3..85fa6c9 100644
--- a/ui/aura/mus/window_tree_client.cc
+++ b/ui/aura/mus/window_tree_client.cc
@@ -751,6 +751,10 @@
 
   DCHECK(!IsRoot(window));
 
+  window->GetWindow()->SetProperty(
+      aura::client::kClientWindowHasContent,
+      window->GetWindow()->layer()->type() != ui::LAYER_NOT_DRAWN);
+
   PropertyConverter* property_converter = delegate_->GetPropertyConverter();
   base::flat_map<std::string, std::vector<uint8_t>> transport_properties =
       property_converter->GetTransportProperties(window->GetWindow());
diff --git a/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js b/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js
index 40cffd8..ce5271c 100644
--- a/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js
+++ b/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js
@@ -60,6 +60,9 @@
   result.renderedTop = size.top;
   result.renderedLeft = size.left;
 
+  // Get the scroll position of the element.
+  result.scrollLeft = element.scrollLeft;
+
   return result;
 }
 
@@ -289,6 +292,31 @@
 };
 
 /**
+ * Sets the left scroll position of an element.
+ * Used to enable testing of horizontal scrolled areas.
+ * @param {Window} contentWindow Window to be tested.
+ * @param {string} query Query for the test element.
+ * @param {number} position scrollLeft position to set.
+ */
+test.util.sync.setScrollLeft = (contentWindow, query, position) => {
+  const scrollablElement = contentWindow.document.querySelector(query);
+  scrollablElement.scrollLeft = position;
+};
+
+/**
+ * Sets style properties for an element using the CSS OM.
+ * @param {Window} contentWindow Window to be tested.
+ * @param {string} query Query for the test element.
+ * @param {!Object<?, string>} properties CSS Property name/values to set.
+ */
+test.util.sync.setElementStyles = (contentWindow, query, properties) => {
+  const element = contentWindow.document.querySelector(query);
+  for (let [prop, value] of Object.entries(properties)) {
+    element.style[prop] = value;
+  }
+};
+
+/**
  * Sends an event to the element specified by |targetQuery| or active element.
  *
  * @param {Window} contentWindow Window to be tested.
diff --git a/ui/file_manager/file_manager/background/js/test_util.js b/ui/file_manager/file_manager/background/js/test_util.js
index 7389ae4..83ac94b 100644
--- a/ui/file_manager/file_manager/background/js/test_util.js
+++ b/ui/file_manager/file_manager/background/js/test_util.js
@@ -262,14 +262,14 @@
  * @return {boolean} True if Team Drive folder got selected, false otherwise.
  */
 test.util.sync.selectTeamDrive = (contentWindow, teamDriveName) => {
-  // Select + expand Team Drives gran root.
+  // Select + expand Shared drives grand root.
   const teamDrivesSelector = '#directory-tree .tree-item ' +
-      '[entry-label="Team Drives"]:not([hidden])';
+      '[entry-label="Shared drives"]:not([hidden])';
   if (!test.util.sync.fakeMouseClick(contentWindow, teamDrivesSelector)) {
     return false;
   }
 
-  // Expand the 'Team Drives' root.
+  // Expand the 'Shared drives' root.
   if (!test.util.sync.expandSelectedFolderInTree(contentWindow)) {
     return false;
   }
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js
index d692ec8..73ea9cd 100644
--- a/ui/file_manager/file_manager/common/js/util.js
+++ b/ui/file_manager/file_manager/common/js/util.js
@@ -1075,7 +1075,7 @@
     //   ^^^^^^^^^^^
     // By this reason, we return the label of the Team Drives grand root here.
     case VolumeManagerCommon.RootType.TEAM_DRIVES_GRAND_ROOT:
-      return str('DRIVE_TEAM_DRIVES_LABEL');
+      return str('DRIVE_SHARED_DRIVES_LABEL');
     case VolumeManagerCommon.RootType.COMPUTER:
     case VolumeManagerCommon.RootType.COMPUTERS_GRAND_ROOT:
       return str('DRIVE_COMPUTERS_LABEL');
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css
index 4fac7e0e..eb8fffd 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -100,6 +100,7 @@
   display: flex;
   flex: 1 1 auto;
   margin-top: 8px;
+  overflow-x: auto;
   position: relative;
 }
 
@@ -114,8 +115,8 @@
 div.splitter {
   cursor: col-resize;
   flex: none;
-  margin-left: -3px;
-  margin-right: -3px;
+  margin-inline-end: -3px;
+  margin-inline-start: -3px;
   position: relative;
   width: 6px;
   z-index: 500;  /* Must be below the contextmenu (600). */
@@ -125,7 +126,7 @@
   bottom: 0;
   flex: none;
   left: 0;
-  overflow-x: hidden;
+  min-width: min-content;
   overflow-y: auto;
   position: absolute;
   right: 0;
@@ -898,12 +899,12 @@
 .breadcrumbs .breadcrumb-path:first-child {
   /* margin-inline-start isn't proper
      because folder names should be ltr even in RTL languages. */
-  margin-left: 8px;
+  margin-inline-start: 8px;
 }
 
 html[dir='rtl'] .breadcrumbs .breadcrumb-path:first-child {
-  margin-left: 0;
-  margin-right: 8px;
+  margin-inline-end: 8px;
+  margin-inline-start: 0;
 }
 
 .breadcrumbs .breadcrumb-path:active {
@@ -978,7 +979,7 @@
       no-repeat;
   height: 16px;
   left: 50%;
-  margin-left: -8px;
+  margin-inline-start: -8px;
   margin-top: -8px;
   opacity: 0.5;
   position: absolute;
@@ -1369,7 +1370,7 @@
   background-position: 5px center;
   background-repeat: no-repeat;
   background-size: 16px 16px;
-  padding-left: 26px;
+  padding-inline-start: 26px;
 }
 
 #list-container list > li[selected],
@@ -1665,7 +1666,7 @@
 #share-sub-menu cr-menu-item,
 #tasks-menu cr-menu-item:not(.change-default) {
   background-position: left 10px center;
-  padding-left: 32px;
+  padding-inline-start: 32px;
 }
 
 #share-menu cr-menu-item[command='#share'] {
@@ -1789,7 +1790,7 @@
   color: #333;
   display: none;
   left: 0;
-  padding-left: 50px;
+  padding-inline-start: 50px;
   padding-top: 20px;
   position: absolute;
   right: 0;
@@ -2071,7 +2072,7 @@
 }
 
 #multi-profile-share-dialog .mail-label {
-  padding-right: 16px;
+  padding-inline-end: 16px;
 }
 
 #multi-profile-share-dialog .mail-label::after {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
index 90577c4a..0476b01 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -727,7 +727,7 @@
       item.setAttribute('drive-label', location.volumeInfo.driveLabel);
     }
   } else {
-    const rootType = location.rootType || null;
+    const rootType = location && location.rootType ? location.rootType : null;
     const iconOverride = FileType.getIconOverrides(dirEntry, rootType);
     // Add Downloads icon as volume so current test code passes with
     // MyFilesVolume flag enabled and disabled.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js
index 60848ed..ef4091e4 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree_unittest.js
@@ -218,7 +218,8 @@
       }).then(() => {
         // There exist 1 my drive entry and 3 fake entries under the drive item.
         assertEquals(str('DRIVE_MY_DRIVE_LABEL'), driveItem.items[0].label);
-        assertEquals(str('DRIVE_TEAM_DRIVES_LABEL'), driveItem.items[1].label);
+        assertEquals(
+            str('DRIVE_SHARED_DRIVES_LABEL'), driveItem.items[1].label);
         assertEquals(
             str('DRIVE_SHARED_WITH_ME_COLLECTION_LABEL'),
             driveItem.items[2].label);
@@ -261,7 +262,7 @@
       }).then(() => {
         let teamDrivesItemFound = false;
         for (let i = 0; i < driveItem.items.length; i++) {
-          if (driveItem.items[i].label == str('DRIVE_TEAM_DRIVES_LABEL')) {
+          if (driveItem.items[i].label == str('DRIVE_SHARED_DRIVES_LABEL')) {
             teamDrivesItemFound = true;
             break;
           }
@@ -419,7 +420,8 @@
       }).then(() => {
         // There exist 1 my drive entry and 3 fake entries under the drive item.
         assertEquals(str('DRIVE_MY_DRIVE_LABEL'), driveItem.items[0].label);
-        assertEquals(str('DRIVE_TEAM_DRIVES_LABEL'), driveItem.items[1].label);
+        assertEquals(
+            str('DRIVE_SHARED_DRIVES_LABEL'), driveItem.items[1].label);
         assertEquals(str('DRIVE_COMPUTERS_LABEL'), driveItem.items[2].label);
         assertEquals(
             str('DRIVE_SHARED_WITH_ME_COLLECTION_LABEL'),
@@ -612,7 +614,7 @@
             return waitUntil(() => {
               for (let i = 0; i < driveItem.items.length; i++) {
                 if (driveItem.items[i].label ==
-                    str('DRIVE_TEAM_DRIVES_LABEL')) {
+                    str('DRIVE_SHARED_DRIVES_LABEL')) {
                   return !driveItem.items[i].hidden;
                 }
               }
@@ -674,7 +676,7 @@
             return waitUntil(() => {
               for (let i = 0; i < driveItem.items.length; i++) {
                 if (driveItem.items[i].label ==
-                    str('DRIVE_TEAM_DRIVES_LABEL')) {
+                    str('DRIVE_SHARED_DRIVES_LABEL')) {
                   return false;
                 }
               }
diff --git a/ui/file_manager/integration_tests/file_manager/context_menu.js b/ui/file_manager/integration_tests/file_manager/context_menu.js
index d82f6ae..8129f8c 100644
--- a/ui/file_manager/integration_tests/file_manager/context_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/context_menu.js
@@ -15,7 +15,7 @@
  * creating entries with pre-set combinations of permissions and ensuring the
  * outcome is always as expected.
  *
- * TODO(sashab): Once Team Drives is enabled, add tests for team drive roots
+ * TODO(sashab): Once Shared drives is enabled, add tests for team drive roots
  * and entries as well.
  */
 
@@ -547,11 +547,11 @@
   chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
       'focus', appId, ['#file-list:not([hidden])']));
 
-  // Select 'Team Drives'.
+  // Select 'Shared drives'.
   chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
-      'selectFolderInTree', appId, ['Team Drives']));
+      'selectFolderInTree', appId, ['Shared drives']));
 
-  // Expand 'Team Drives'.
+  // Expand 'Shared drives'.
   chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
       'expandSelectedFolderInTree', appId, []));
 
diff --git a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
index 17e480c..dd144876 100644
--- a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
@@ -649,14 +649,25 @@
 };
 
 /**
- * Tests context menu for Crostini real root.
- * TODO(lucmult): Check menus for a crostini folder.
+ * Tests context menu for Crostini real root and a folder inside it.
  */
 testcase.dirContextMenuCrostini = async () => {
   const linuxMenus = [
     ['#new-folder', true],
   ];
+  const folderMenus = [
+    ['#cut', true],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#rename', true],
+    ['#delete', true],
+    ['#new-folder', true],
+  ];
   const linuxQuery = '#directory-tree [entry-label="Linux files"]';
+  const folderQuery = linuxQuery + ' [entry-label="photos"]';
+
+  // Add a crostini folder.
+  await addEntries(['crostini'], [ENTRIES.photos]);
 
   // Open Files app on local Downloads.
   const appId = await setupAndWaitUntilReady(
@@ -678,18 +689,37 @@
 
   // Check the context menu for Linux files.
   await checkContextMenu(appId, linuxQuery, linuxMenus, false /* rootMenu */);
+
+  // Expand Crostini to display its folders, it dismisses the context menu.
+  await expandTreeItem(appId, linuxQuery);
+
+  // Check the context menu for a folder in Linux files.
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
 };
 
 /**
- * Tests context menu for ARC++/Play files root.
- * TODO(lucmult): Check menus for a Play folder.
+ * Tests context menu for ARC++/Play files root and a folder inside it.
  */
 testcase.dirContextMenuPlayFiles = async () => {
   const playFilesMenus = [
     ['#share-with-linux', true],
     ['#new-folder', false],
   ];
+  const folderMenus = [
+    ['#cut', true],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#share-with-linux', true],
+    ['#rename', false],
+    ['#delete', true],
+    ['#new-folder', true],
+  ];
+
   const playFilesQuery = '#directory-tree [entry-label="Play files"]';
+  const folderQuery = playFilesQuery + ' [entry-label="Documents"]';
+
+  // Add an Android folder.
+  await addEntries(['android_files'], [ENTRIES.directoryDocuments]);
 
   // Open Files app on local Downloads.
   const appId = await setupAndWaitUntilReady(
@@ -698,11 +728,16 @@
   // Check the context menu for Play files.
   await checkContextMenu(
       appId, playFilesQuery, playFilesMenus, false /* rootMenu */);
+
+  // Expand Play files to display its folders, it dismisses the context menu.
+  await expandTreeItem(appId, playFilesQuery);
+
+  // Check the context menu for a folder in Play files.
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
 };
 
 /**
  * Tests context menu for USB root (single and multiple partitions).
- * TODO(lucmult): Check menus for a USB folder.
  */
 testcase.dirContextMenuUsbs = async () => {
   const singleUsbMenus = [
@@ -721,10 +756,21 @@
     ['#rename', false],
     ['#new-folder', true],
   ];
+  const folderMenus = [
+    ['#cut', true],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#share-with-linux', true],
+    ['#rename', true],
+    ['#delete', true],
+    ['#new-folder', true],
+  ];
 
   const singleUsbQuery = '#directory-tree [entry-label="fake-usb"]';
   const partitionsRootQuery = '#directory-tree [entry-label="Drive Label"]';
   const partition1Query = '#directory-tree [entry-label="partition-1"]';
+  const singleUsbFolderQuery = singleUsbQuery + ' [entry-label="A"]';
+  const partition1FolderQuery = partition1Query + ' [entry-label="Folder"]';
 
   // Mount removable volumes.
   await sendTestMessage({name: 'mountUsbWithPartitions'});
@@ -745,17 +791,114 @@
   // Check the context menu for multiple partitions USB (actual partition).
   await checkContextMenu(
       appId, partition1Query, partition1Menus, false /* rootMenu */);
+
+  // Check the context menu for a folder inside a singlue USB partition.
+  await expandTreeItem(appId, singleUsbQuery);
+  await checkContextMenu(
+      appId, singleUsbFolderQuery, folderMenus, false /* rootMenu */);
+
+  // Check the context menu for a folder inside a partition1.
+  await expandTreeItem(appId, partition1Query);
+  await checkContextMenu(
+      appId, partition1FolderQuery, folderMenus, false /* rootMenu */);
+
 };
 
 /**
- * Tests context menu for FSP root.
- * TODO(lucmult): Check menus for a FSP.
+ * Tests context menu for Mtp root and a folder inside it.
+ */
+testcase.dirContextMenuMtp = async () => {
+  const folderMenus = [
+    ['#cut', true],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#rename', true],
+    ['#delete', true],
+    ['#new-folder', true],
+  ];
+  const mtpQuery = '#directory-tree [entry-label="fake-mtp"]';
+  const folderQuery = mtpQuery + ' [entry-label="A"]';
+
+  // Mount fake MTP volume.
+  await sendTestMessage({name: 'mountFakeMtp'});
+
+  // Open Files app on local Downloads.
+  const appId =
+      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.beautiful], []);
+
+  // Right click on MTP root.
+  await remoteCall.waitForElement(appId, mtpQuery);
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'fakeMouseRightClick', appId, [mtpQuery]),
+      'fakeMouseRightClick failed');
+
+  // Check that both menus are still hidden, since there is not context menu for
+  // MTP root.
+  await remoteCall.waitForElement(appId, '#roots-context-menu[hidden]');
+  await remoteCall.waitForElement(
+      appId, '#directory-tree-context-menu[hidden]');
+
+  // Check the context menu for a folder inside a MTP.
+  await expandTreeItem(appId, mtpQuery);
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
+};
+
+/**
+ * Tests context menu for USB root with DCIM folder.
+ */
+testcase.dirContextMenuUsbDcim = async () => {
+  const usbMenus = [
+    ['#unmount', true],
+    ['#format', true],
+    ['#rename', false],
+    ['#share-with-linux', true],
+  ];
+  const dcimFolderMenus = [
+    ['#cut', true],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#share-with-linux', true],
+    ['#rename', true],
+    ['#delete', true],
+    ['#new-folder', true],
+  ];
+  const usbQuery = '#directory-tree [entry-label="fake-usb"]';
+  const dcimFolderQuery = usbQuery + ' [entry-label="DCIM"]';
+
+  // Mount removable volumes.
+  await sendTestMessage({name: 'mountFakeUsbDcim'});
+
+  // Open Files app on local Downloads.
+  const appId =
+      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.beautiful], []);
+
+  // Check the context menu for single partition USB.
+  await checkContextMenu(appId, usbQuery, usbMenus, true /* rootMenu */);
+
+  // Check the context menu for the DCIM folder inside USB.
+  await expandTreeItem(appId, usbQuery);
+  await checkContextMenu(
+      appId, dcimFolderQuery, dcimFolderMenus, false /* rootMenu */);
+};
+
+/**
+ * Tests context menu for FSP root and a folder inside it.
  */
 testcase.dirContextMenuFsp = async () => {
   const fspMenus = [
     ['#unmount', true],
   ];
+  const folderMenus = [
+    ['#cut', false],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#rename', false],
+    ['#delete', false],
+    ['#new-folder', false],
+  ];
   const fspQuery = '#directory-tree [entry-label="Test (1)"]';
+  const folderQuery = fspQuery + ' [entry-label="folder"]';
 
   // Install a FSP.
   const manifest = 'manifest_source_file.json';
@@ -767,6 +910,47 @@
 
   // Check the context menu for FSP.
   await checkContextMenu(appId, fspQuery, fspMenus, true /* rootMenu */);
+
+  // Check the context menu for a folder inside a FSP.
+  await expandTreeItem(appId, fspQuery);
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
+};
+
+/**
+ * Tests context menu for DocumentsProvider root and a folder inside it.
+ */
+testcase.dirContextMenuDocumentsProvider = async () => {
+  const folderMenus = [
+    ['#cut', false],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#rename', false],
+    ['#delete', false],
+    ['#new-folder', false],
+  ];
+  const documentsProviderQuery =
+      '#directory-tree [entry-label="DocumentsProvider"]';
+  const folderQuery = documentsProviderQuery + ' [entry-label="photos"]';
+
+  // Add a DocumentsProvider folder.
+  await addEntries(['documents_provider'], [ENTRIES.photos]);
+
+  // Open Files app on local Downloads.
+  const appId =
+      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.beautiful], []);
+
+  // Wait for DocumentsProvider to appear.
+  await remoteCall.waitForElement(appId, documentsProviderQuery);
+
+  // Check that both menus are still hidden, because DocumentsProvider root
+  // doesn't show any context menu.
+  await remoteCall.waitForElement(appId, '#roots-context-menu[hidden]');
+  await remoteCall.waitForElement(
+      appId, '#directory-tree-context-menu[hidden]');
+
+  // Check the context menu for a folder inside a DocumentsProvider.
+  await expandTreeItem(appId, documentsProviderQuery);
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
 };
 
 })();
diff --git a/ui/file_manager/integration_tests/file_manager/file_display.js b/ui/file_manager/integration_tests/file_manager/file_display.js
index ab7728c..7371e56 100644
--- a/ui/file_manager/integration_tests/file_manager/file_display.js
+++ b/ui/file_manager/integration_tests/file_manager/file_display.js
@@ -649,7 +649,10 @@
   if (removableDirectory === 'partition-1' ||
       removableDirectory === 'partition-2') {
     const partitionQuery = `#file-list [file-name="${removableDirectory}"]`;
-    const partitionFiles = [ENTRIES.hello.getExpectedRow()];
+    const partitionFiles = [
+      ENTRIES.hello.getExpectedRow(),
+      ['Folder', '--', 'Folder', Date()],
+    ];
     await remoteCall.callRemoteTestUtil(
         'fakeMouseDoubleClick', appId, [partitionQuery]);
     await remoteCall.waitUntilCurrentDirectoryIsChanged(
diff --git a/ui/file_manager/integration_tests/file_manager/metadata.js b/ui/file_manager/integration_tests/file_manager/metadata.js
index b4a7bb0f..91da5f36 100644
--- a/ui/file_manager/integration_tests/file_manager/metadata.js
+++ b/ui/file_manager/integration_tests/file_manager/metadata.js
@@ -277,21 +277,21 @@
 
   // Downloads just some entries. Load some in Downloads and Downloads to
   // check that Downloads entries don't issue metadata calls when navigating on
-  // Drive/Team Drives.
+  // Drive/Shared drives.
   const downloadsEntries = entries.slice(0, 7);
 
-  const teamDriveTreeItem = '#directory-tree [entry-label="Team Drives"]';
+  const sharedDrivesTreeItem = '#directory-tree [entry-label="Shared drives"]';
 
   // Open Files app on Drive.
   const appId = await setupAndWaitUntilReady(
       RootPath.DRIVE, downloadsEntries, entries.concat(driveEntries));
 
-  // Navigate to Team Drives root.
+  // Navigate to Shared drives root.
   await remoteCall.navigateWithDirectoryTree(
-      appId, '/team_drives', 'Team Drives', 'drive');
+      appId, '/team_drives', 'Shared drives', 'drive');
 
   // Expand Team Drives, because expanding might need metadata.
-  const expandIcon = teamDriveTreeItem + ' > .tree-row > .expand-icon';
+  const expandIcon = sharedDrivesTreeItem + ' > .tree-row > .expand-icon';
   await remoteCall.waitForElement(appId, expandIcon);
 
   // Click expand icon.
@@ -300,13 +300,13 @@
 
   // Wait for the subtree to expand and display its children.
   const expandedSubItems =
-      teamDriveTreeItem + ' > .tree-children[expanded] > .tree-item';
+      sharedDrivesTreeItem + ' > .tree-children[expanded] > .tree-item';
   await remoteCall.waitForElement(appId, expandedSubItems);
 
   // Get all Team Drives' children.
   const elements = await remoteCall.callRemoteTestUtil(
       'queryAllElements', appId,
-      [teamDriveTreeItem + ' > .tree-children[expanded] > .tree-item']);
+      [sharedDrivesTreeItem + ' > .tree-children[expanded] > .tree-item']);
 
   // Check that we have 50 team drives.
   chrome.test.assertEq(50, elements.length);
diff --git a/ui/file_manager/integration_tests/file_manager/navigation_list.js b/ui/file_manager/integration_tests/file_manager/navigation_list.js
new file mode 100644
index 0000000..5cfe271
--- /dev/null
+++ b/ui/file_manager/integration_tests/file_manager/navigation_list.js
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+(() => {
+  /**
+   * Tests that the directory tree area can be horizontally scrolled.
+   */
+  testcase.navigationScrollsWhenClipped = async () => {
+    // Open FilesApp with the Downloads folder visible.
+    const appId = await setupAndWaitUntilReady(
+        RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, []);
+    await expandRoot(appId, TREEITEM_DOWNLOADS);
+
+    // Get the navigationList width property and make sure it has non-zero size.
+    const navigationList = '.dialog-navigation-list-contents';
+    let list =
+        await remoteCall.waitForElementStyles(appId, navigationList, ['width']);
+    const originalWidth = Number(list.styles['width'].match(/[0-9]*/));
+    chrome.test.assertTrue(originalWidth > 0);
+
+    // Shrink the navigation list tree area to 100px.
+    await remoteCall.callRemoteTestUtil(
+        'setElementStyles', appId, [navigationList, {width: '50px'}]);
+
+    // Check the navigation list area is scrolled completely to the left side.
+    chrome.test.assertTrue(list.scrollLeft == 0);
+
+    // Attempt to scroll the navigation list area to the right.
+    await remoteCall.callRemoteTestUtil(
+        'setScrollLeft', appId, [navigationList, 100]);
+
+    // Get the current state of the NavigationWidth width and left scroll
+    // offset.
+    list =
+        await remoteCall.waitForElementStyles(appId, navigationList, ['width']);
+
+    // Check that the width has been reduced.
+    const newWidth = Number(list.styles['width'].match(/[0-9]*/));
+    chrome.test.assertTrue(newWidth < originalWidth);
+
+    // Check the navigation list area has scrolled.
+    chrome.test.assertTrue(list.scrollLeft > 0);
+  };
+})();
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index 20a9251..a179ab7 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -195,7 +195,10 @@
       'fakeMouseClick failed');
 
   // Check: the 'hello.txt' file should appear in the file list.
-  const files = [ENTRIES.hello.getExpectedRow()];
+  const files = [
+    ENTRIES.hello.getExpectedRow(),
+    ['Folder', '--', 'Folder', Date()],
+  ];
   await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
 
   // Open the file in Quick View.
diff --git a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
index cd3e29b..7c53bcd 100644
--- a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
+++ b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
@@ -21,7 +21,7 @@
   if (teamDrive !== undefined) {
     await remoteCall.navigateWithDirectoryTree(
         appId, teamDrive === '' ? '/team_drives' : `/team_drives/${teamDrive}`,
-        'Team Drives', 'drive');
+        'Shared drives', 'drive');
 
     // Wait for the file list to update.
     await remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length);
@@ -82,7 +82,7 @@
   if (teamDrive !== undefined) {
     await remoteCall.navigateWithDirectoryTree(
         appId, teamDrive === '' ? '/team_drives' : `/team_drives/${teamDrive}`,
-        'Team Drives', 'drive');
+        'Shared drives', 'drive');
 
     // Wait for the file list to update.
     await remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length);
@@ -199,7 +199,7 @@
 
   // Navigate to the team drive.
   await remoteCall.navigateWithDirectoryTree(
-      appId, `/team_drives/${teamDrive}`, 'Team Drives', 'drive');
+      appId, `/team_drives/${teamDrive}`, 'Shared drives', 'drive');
 
   // Wait for the file list to update.
   await remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length);
diff --git a/ui/file_manager/integration_tests/file_manager_test_manifest.json b/ui/file_manager/integration_tests/file_manager_test_manifest.json
index 6c03c46..577c3ab 100644
--- a/ui/file_manager/integration_tests/file_manager_test_manifest.json
+++ b/ui/file_manager/integration_tests/file_manager_test_manifest.json
@@ -33,6 +33,7 @@
       "file_manager/launcher_search.js",
       "file_manager/metadata.js",
       "file_manager/my_files.js",
+      "file_manager/navigation_list.js",
       "file_manager/open_audio_files.js",
       "file_manager/open_image_files.js",
       "file_manager/open_video_files.js",
diff --git a/ui/file_manager/integration_tests/testing_provider/background.js b/ui/file_manager/integration_tests/testing_provider/background.js
index 8033db2..15bc66a 100644
--- a/ui/file_manager/integration_tests/testing_provider/background.js
+++ b/ui/file_manager/integration_tests/testing_provider/background.js
@@ -26,10 +26,22 @@
       });
     });
 
-chrome.fileSystemProvider.onReadDirectoryRequested.addListener(
-    function(options, onSuccess, onError) {
-      onSuccess([], false /* hasMore */);
-    });
+chrome.fileSystemProvider.onReadDirectoryRequested.addListener(function(
+    options, onSuccess, onError) {
+  // For anything other than root, return no entries.
+  if (options.directoryPath !== '/') {
+    onSuccess([], false /* hasMore */);
+    return;
+  }
+  // For root we return 1 folder entry.
+  const entries = [
+    {
+      isDirectory: true,
+      name: 'folder',
+    },
+  ];
+  onSuccess(entries, false /* hasMore */);
+});
 
 chrome.fileSystemProvider.onMountRequested.addListener(mountFileSystem);
 
diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn
index b3babf7..b1862db 100644
--- a/ui/keyboard/BUILD.gn
+++ b/ui/keyboard/BUILD.gn
@@ -90,8 +90,8 @@
     "test/keyboard_test_util.h",
     "test/test_keyboard_layout_delegate.cc",
     "test/test_keyboard_layout_delegate.h",
-    "test/test_keyboard_ui.cc",
-    "test/test_keyboard_ui.h",
+    "test/test_keyboard_ui_factory.cc",
+    "test/test_keyboard_ui_factory.h",
   ]
   deps = [
     ":keyboard",
diff --git a/ui/keyboard/container_behavior.h b/ui/keyboard/container_behavior.h
index 41b2ffd..83ef906 100644
--- a/ui/keyboard/container_behavior.h
+++ b/ui/keyboard/container_behavior.h
@@ -80,10 +80,6 @@
   // overscroll is "enabled" depends on multiple external factors.
   virtual bool IsOverscrollAllowed() const = 0;
 
-  // Return whether the given coordinate is a drag handle.
-  virtual bool IsDragHandle(const gfx::Vector2d& offset,
-                            const gfx::Size& keyboard_size) const = 0;
-
   virtual void SavePosition(const gfx::Rect& keyboard_bounds_in_screen,
                             const gfx::Size& screen_size) = 0;
 
diff --git a/ui/keyboard/container_floating_behavior.cc b/ui/keyboard/container_floating_behavior.cc
index a3b5e5b0..3f43a11 100644
--- a/ui/keyboard/container_floating_behavior.cc
+++ b/ui/keyboard/container_floating_behavior.cc
@@ -177,16 +177,10 @@
   return valid_keyboard_bounds.origin();
 }
 
-bool ContainerFloatingBehavior::IsDragHandle(
-    const gfx::Vector2d& offset,
-    const gfx::Size& keyboard_size) const {
-  return draggable_area_.Contains(offset.x(), offset.y());
-}
-
 bool ContainerFloatingBehavior::HandlePointerEvent(
     const ui::LocatedEvent& event,
     const display::Display& current_display) {
-  auto kb_offset = gfx::Vector2d(event.x(), event.y());
+  const gfx::Vector2d kb_offset(event.x(), event.y());
 
   const gfx::Rect& keyboard_bounds_in_screen = delegate_->GetBoundsInScreen();
 
@@ -194,7 +188,7 @@
   if (keyboard_bounds_in_screen.height() <= 0)
     return false;
 
-  ui::PointerId pointer_id = -1;
+  ui::PointerId pointer_id = ui::MouseEvent::kMousePointerId;
   if (event.IsTouchEvent()) {
     const ui::TouchEvent* te = event.AsTouchEvent();
     pointer_id = te->pointer_details().id;
@@ -204,18 +198,15 @@
   switch (type) {
     case ui::ET_TOUCH_PRESSED:
     case ui::ET_MOUSE_PRESSED:
-      if (!IsDragHandle(kb_offset, keyboard_bounds_in_screen.size())) {
-        drag_descriptor_ = nullptr;
+      if (!draggable_area_.Contains(kb_offset.x(), kb_offset.y())) {
+        drag_descriptor_.reset();
       } else if (type == ui::ET_MOUSE_PRESSED &&
-                 !((const ui::MouseEvent*)&event)->IsOnlyLeftMouseButton()) {
+                 !((const ui::MouseEvent&)event).IsOnlyLeftMouseButton()) {
         // Mouse events are limited to just the left mouse button.
-        drag_descriptor_ = nullptr;
+        drag_descriptor_.reset();
       } else if (!drag_descriptor_) {
-        // If there is no active drag descriptor, start a new one.
-        bool drag_started_by_touch = (type == ui::ET_TOUCH_PRESSED);
-        drag_descriptor_.reset(
-            new DragDescriptor{keyboard_bounds_in_screen.origin(), kb_offset,
-                               drag_started_by_touch, pointer_id});
+        drag_descriptor_.reset(new DragDescriptor{
+            keyboard_bounds_in_screen.origin(), kb_offset, pointer_id});
       }
       break;
 
@@ -223,11 +214,6 @@
     case ui::ET_TOUCH_MOVED:
       if (!drag_descriptor_) {
         // do nothing
-      } else if (drag_descriptor_->is_touch_drag !=
-                 (type == ui::ET_TOUCH_MOVED)) {
-        // If the event isn't of the same type that started the drag, end the
-        // drag to prevent confusion.
-        drag_descriptor_ = nullptr;
       } else if (drag_descriptor_->pointer_id != pointer_id) {
         // do nothing.
       } else {
@@ -257,7 +243,7 @@
         } else {
           // Since the keyboard has jumped across screens, cancel the current
           // drag descriptor as though the user has lifted their finger.
-          drag_descriptor_ = nullptr;
+          drag_descriptor_.reset();
 
           gfx::Rect new_bounds_in_screen =
               new_bounds_in_local +
@@ -279,7 +265,7 @@
       break;
 
     default:
-      drag_descriptor_ = nullptr;
+      drag_descriptor_.reset();
       break;
   }
   return false;
diff --git a/ui/keyboard/container_floating_behavior.h b/ui/keyboard/container_floating_behavior.h
index 41a11d3..a6e7bcc 100644
--- a/ui/keyboard/container_floating_behavior.h
+++ b/ui/keyboard/container_floating_behavior.h
@@ -35,8 +35,6 @@
       const gfx::Rect& display_bounds,
       const gfx::Rect& requested_bounds_in_screen_coords) override;
   bool IsOverscrollAllowed() const override;
-  bool IsDragHandle(const gfx::Vector2d& offset,
-                    const gfx::Size& keyboard_size) const override;
   void SavePosition(const gfx::Rect& keyboard_bounds_in_screen,
                     const gfx::Size& screen_size) override;
   bool HandlePointerEvent(const ui::LocatedEvent& event,
diff --git a/ui/keyboard/container_floating_behavior_unittest.cc b/ui/keyboard/container_floating_behavior_unittest.cc
index cc13bd6..7ef63390 100644
--- a/ui/keyboard/container_floating_behavior_unittest.cc
+++ b/ui/keyboard/container_floating_behavior_unittest.cc
@@ -157,13 +157,4 @@
   ASSERT_EQ(center, result);
 }
 
-TEST(ContainerFloatingBehaviorTest, SetDraggableArea) {
-  ContainerFloatingBehavior floating_behavior(nullptr);
-  ASSERT_FALSE(
-      floating_behavior.IsDragHandle(gfx::Vector2d(2, 2), gfx::Size(600, 600)));
-  floating_behavior.SetDraggableArea(gfx::Rect(0, 0, 10, 10));
-  ASSERT_TRUE(
-      floating_behavior.IsDragHandle(gfx::Vector2d(2, 2), gfx::Size(600, 600)));
-}
-
 }  // namespace keyboard
diff --git a/ui/keyboard/container_full_width_behavior.cc b/ui/keyboard/container_full_width_behavior.cc
index 2e117a6..1154901 100644
--- a/ui/keyboard/container_full_width_behavior.cc
+++ b/ui/keyboard/container_full_width_behavior.cc
@@ -85,12 +85,6 @@
   // No-op. Nothing to save.
 }
 
-bool ContainerFullWidthBehavior::IsDragHandle(
-    const gfx::Vector2d& offset,
-    const gfx::Size& keyboard_size) const {
-  return false;
-}
-
 bool ContainerFullWidthBehavior::HandlePointerEvent(
     const ui::LocatedEvent& event,
     const display::Display& current_display) {
diff --git a/ui/keyboard/container_full_width_behavior.h b/ui/keyboard/container_full_width_behavior.h
index 8e82a50..33a5af5 100644
--- a/ui/keyboard/container_full_width_behavior.h
+++ b/ui/keyboard/container_full_width_behavior.h
@@ -31,8 +31,6 @@
       const gfx::Rect& display_bounds,
       const gfx::Rect& requested_bounds_in_screen_coords) override;
   bool IsOverscrollAllowed() const override;
-  bool IsDragHandle(const gfx::Vector2d& offset,
-                    const gfx::Size& keyboard_size) const override;
   void SavePosition(const gfx::Rect& keyboard_bounds,
                     const gfx::Size& screen_size) override;
   bool HandlePointerEvent(const ui::LocatedEvent& event,
diff --git a/ui/keyboard/drag_descriptor.h b/ui/keyboard/drag_descriptor.h
index 9da3586..9b10291 100644
--- a/ui/keyboard/drag_descriptor.h
+++ b/ui/keyboard/drag_descriptor.h
@@ -20,12 +20,8 @@
   gfx::Point original_keyboard_location;
   gfx::Vector2d original_click_offset;
 
-  // Distinguish whether the current drag is from a touch event or mouse event,
-  // so drag/move events can be filtered accordingly
-  bool is_touch_drag;
-
   // The pointer ID provided by the touch event to disambiguate multiple
-  // touch points. If this is a mouse event, then this value is -1.
+  // touch points. If this is a mouse event, then this value is kMousePointerId.
   ui::PointerId pointer_id;
 };
 
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc
index 3300a66b..d87ecb6 100644
--- a/ui/keyboard/keyboard_controller.cc
+++ b/ui/keyboard/keyboard_controller.cc
@@ -37,6 +37,7 @@
 #include "ui/keyboard/keyboard_controller_observer.h"
 #include "ui/keyboard/keyboard_layout_manager.h"
 #include "ui/keyboard/keyboard_ui.h"
+#include "ui/keyboard/keyboard_ui_factory.h"
 #include "ui/keyboard/keyboard_util.h"
 #include "ui/keyboard/notification_manager.h"
 #include "ui/keyboard/public/keyboard_switches.h"
@@ -163,7 +164,7 @@
   // ui::InputMethodKeyboardController
   bool DisplayVirtualKeyboard() override {
     // Calling |ShowKeyboardInternal| may move the keyboard to another display.
-    if (keyboard_controller_->IsKeyboardEnableRequested() &&
+    if (keyboard_controller_->IsEnabled() &&
         !keyboard_controller_->keyboard_locked()) {
       keyboard_controller_->ShowKeyboard(false /* locked */);
       return true;
@@ -249,16 +250,34 @@
   return g_keyboard_controller;
 }
 
-void KeyboardController::EnableKeyboard(std::unique_ptr<KeyboardUI> ui,
-                                        KeyboardLayoutDelegate* delegate) {
-  if (ui_)
-    DisableKeyboard();
+void KeyboardController::Initialize(
+    std::unique_ptr<KeyboardUIFactory> ui_factory,
+    KeyboardLayoutDelegate* layout_delegate) {
+  DCHECK(ui_factory);
+  DCHECK(layout_delegate);
 
-  ui_ = std::move(ui);
+  ui_factory_ = std::move(ui_factory);
+  layout_delegate_ = layout_delegate;
+
+  DCHECK(!IsKeyboardEnableRequested());
+}
+
+void KeyboardController::Shutdown() {
+  keyboard_enable_flags_.clear();
+  for (KeyboardControllerObserver& observer : observer_list_)
+    observer.OnKeyboardEnableFlagsChanged(keyboard_enable_flags_);
+
+  DCHECK(!IsKeyboardEnableRequested());
+  DisableKeyboard();
+}
+
+void KeyboardController::EnableKeyboard() {
+  if (ui_)
+    return;
+
+  ui_ = ui_factory_->CreateKeyboardUI();
   DCHECK(ui_);
 
-  DCHECK(delegate);
-  layout_delegate_ = delegate;
   show_on_keyboard_window_load_ = false;
   keyboard_locked_ = false;
   state_ = KeyboardControllerState::UNKNOWN;
@@ -414,6 +433,14 @@
   ui_->ReloadKeyboardIfNeeded();
 }
 
+void KeyboardController::RebuildKeyboardIfEnabled() {
+  if (!IsEnabled())
+    return;
+
+  DisableKeyboard();
+  EnableKeyboard();
+}
+
 void KeyboardController::AddObserver(KeyboardControllerObserver* observer) {
   observer_list_.AddObserver(observer);
 }
@@ -461,12 +488,25 @@
   }
   for (KeyboardControllerObserver& observer : observer_list_)
     observer.OnKeyboardEnableFlagsChanged(keyboard_enable_flags_);
+
+  if (IsKeyboardEnableRequested() && !IsEnabled())
+    EnableKeyboard();
+  else if (!IsKeyboardEnableRequested() && IsEnabled())
+    DisableKeyboard();
 }
 
 void KeyboardController::ClearEnableFlag(mojom::KeyboardEnableFlag flag) {
+  if (!IsEnableFlagSet(flag))
+    return;
+
   keyboard_enable_flags_.erase(flag);
   for (KeyboardControllerObserver& observer : observer_list_)
     observer.OnKeyboardEnableFlagsChanged(keyboard_enable_flags_);
+
+  if (IsKeyboardEnableRequested() && !IsEnabled())
+    EnableKeyboard();
+  else if (!IsKeyboardEnableRequested() && IsEnabled())
+    DisableKeyboard();
 }
 
 bool KeyboardController::IsEnableFlagSet(mojom::KeyboardEnableFlag flag) const {
@@ -502,7 +542,7 @@
 }
 
 bool KeyboardController::IsKeyboardOverscrollEnabled() const {
-  if (!IsKeyboardEnableRequested())
+  if (!IsEnabled())
     return false;
 
   // Users of the sticky accessibility on-screen keyboard are likely to be using
@@ -824,9 +864,9 @@
 }
 
 void KeyboardController::OnShowVirtualKeyboardIfEnabled() {
-  DVLOG(1) << "OnShowVirtualKeyboardIfEnabled: " << IsKeyboardEnableRequested();
+  DVLOG(1) << "OnShowVirtualKeyboardIfEnabled: " << IsEnabled();
   // Calling |ShowKeyboardInternal| may move the keyboard to another display.
-  if (IsKeyboardEnableRequested() && !keyboard_locked_)
+  if (IsEnabled() && !keyboard_locked_)
     ShowKeyboardInternal(layout_delegate_->GetContainerForDefaultDisplay());
 }
 
diff --git a/ui/keyboard/keyboard_controller.h b/ui/keyboard/keyboard_controller.h
index 0cffd19..541ec39c 100644
--- a/ui/keyboard/keyboard_controller.h
+++ b/ui/keyboard/keyboard_controller.h
@@ -45,6 +45,7 @@
 class CallbackAnimationObserver;
 class KeyboardControllerObserver;
 class KeyboardUI;
+class KeyboardUIFactory;
 
 // Represents the current state of the keyboard managed by the controller.
 // Don't change the numeric value of the members because they are used in UMA
@@ -76,6 +77,15 @@
   KeyboardController();
   ~KeyboardController() override;
 
+  // Initialize the virtual keyboard controller with two delegates:
+  // - ui_factory: Responsible for keyboard window loading.
+  // - layout_delegate: Responsible for moving keyboard window across displays.
+  void Initialize(std::unique_ptr<KeyboardUIFactory> ui_factory,
+                  KeyboardLayoutDelegate* layout_delegate);
+
+  // Resets all the flags and disables the virtual keyboard.
+  void Shutdown();
+
   // Retrieves the active keyboard controller. Guaranteed to not be null while
   // there is an ash::Shell.
   // TODO(stevenjb/shuchen/shend): Remove all access from src/chrome.
@@ -86,17 +96,6 @@
   // there is an ash::Shell).
   static bool HasInstance();
 
-  // Enables the virtual keyboard with a specified |ui| and |delegate|.
-  // Immediately starts pre-loading the keyboard window in the background.
-  // Disables and re-enables the keyboard if it is already enabled.
-  void EnableKeyboard(std::unique_ptr<KeyboardUI> ui,
-                      KeyboardLayoutDelegate* delegate);
-
-  // Disables the virtual keyboard. Resets the keyboard to its initial disabled
-  // state and destroys the keyboard window.
-  // Does nothing if the keyboard is already disabled.
-  void DisableKeyboard();
-
   // Returns the keyboard window, or null if the keyboard window has not been
   // created yet.
   aura::Window* GetKeyboardWindow() const;
@@ -116,6 +115,10 @@
   // loaded yet.
   void Reload();
 
+  // Rebuilds the keyboard by disabling and enabling it again.
+  // TODO(https://crbug.com/845780): Can this be replaced with |Reload|?
+  void RebuildKeyboardIfEnabled();
+
   // Management of the observer list.
   void AddObserver(KeyboardControllerObserver* observer);
   bool HasObserver(KeyboardControllerObserver* observer) const;
@@ -134,12 +137,6 @@
     return keyboard_enable_flags_;
   }
 
-  // Returns true if the keyboard should be enabled, i.e. the current result
-  // of Set/ClearEnableFlag should cause the keyboard to be enabled.
-  // TODO(stevenjb/shend): Consider removing this and have all calls to
-  // Set/ClearEnableFlag always enable or disable the keyboard directly.
-  bool IsKeyboardEnableRequested() const;
-
   // Returns true if keyboard overscroll is enabled.
   bool IsKeyboardOverscrollEnabled() const;
 
@@ -310,6 +307,20 @@
   void OnTextInputStateChanged(const ui::TextInputClient* client) override;
   void OnShowVirtualKeyboardIfEnabled() override;
 
+  // Enables the virtual keyboard.
+  // Immediately starts pre-loading the keyboard window in the background.
+  // Does nothing if the keyboard is already enabled.
+  void EnableKeyboard();
+
+  // Disables the virtual keyboard. Resets the keyboard to its initial disabled
+  // state and destroys the keyboard window.
+  // Does nothing if the keyboard is already disabled.
+  void DisableKeyboard();
+
+  // Returns true if the keyboard should be enabled, i.e. the current result
+  // of Set/ClearEnableFlag should cause the keyboard to be enabled.
+  bool IsKeyboardEnableRequested() const;
+
   // Attach the keyboard window as a child of the given parent window.
   // Can only be called when the keyboard is not activated. |parent| must not
   // have any children.
@@ -392,6 +403,7 @@
   // keyboard is loaded.
   void MarkKeyboardLoadFinished();
 
+  std::unique_ptr<KeyboardUIFactory> ui_factory_;
   std::unique_ptr<KeyboardUI> ui_;
   std::unique_ptr<ui::InputMethodKeyboardController>
       input_method_keyboard_controller_;
diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc
index a8aaaa0..0506a53 100644
--- a/ui/keyboard/keyboard_controller_unittest.cc
+++ b/ui/keyboard/keyboard_controller_unittest.cc
@@ -38,7 +38,7 @@
 #include "ui/keyboard/keyboard_util.h"
 #include "ui/keyboard/test/keyboard_test_util.h"
 #include "ui/keyboard/test/test_keyboard_layout_delegate.h"
-#include "ui/keyboard/test/test_keyboard_ui.h"
+#include "ui/keyboard/test/test_keyboard_ui_factory.h"
 #include "ui/wm/core/default_activation_client.h"
 
 #if defined(USE_OZONE)
@@ -158,17 +158,16 @@
     layout_delegate_.reset(new TestKeyboardLayoutDelegate(root_window()));
 
     // Force enable the virtual keyboard.
-    keyboard::SetTouchKeyboardEnabled(true);
-    controller_.EnableKeyboard(
-        std::make_unique<TestKeyboardUI>(host()->GetInputMethod()),
+    controller_.Initialize(
+        std::make_unique<TestKeyboardUIFactory>(host()->GetInputMethod()),
         layout_delegate_.get());
+    keyboard::SetTouchKeyboardEnabled(true);
     controller_.AddObserver(this);
   }
 
   void TearDown() override {
     keyboard::SetTouchKeyboardEnabled(false);
     controller_.RemoveObserver(this);
-    controller_.DisableKeyboard();
     focus_controller_.reset();
     aura::test::AuraTestBase::TearDown();
   }
@@ -496,7 +495,7 @@
   EXPECT_TRUE(keyboard_window->IsVisible());
   EXPECT_FALSE(IsKeyboardDisabled());
 
-  controller().DisableKeyboard();
+  keyboard::SetTouchKeyboardEnabled(false);
   EXPECT_TRUE(IsKeyboardDisabled());
 }
 
@@ -762,16 +761,14 @@
   EXPECT_TRUE(keyboard_window->IsVisible());
   EXPECT_FALSE(IsKeyboardDisabled());
 
-  controller().DisableKeyboard();
+  keyboard::SetTouchKeyboardEnabled(false);
   EXPECT_TRUE(IsKeyboardDisabled());
 
-  controller().EnableKeyboard(
-      std::make_unique<TestKeyboardUI>(host()->GetInputMethod()),
-      layout_delegate());
+  keyboard::SetTouchKeyboardEnabled(true);
   ClearKeyboardDisabled();
   EXPECT_FALSE(IsKeyboardDisabled());
 
-  controller().DisableKeyboard();
+  keyboard::SetTouchKeyboardEnabled(false);
   EXPECT_TRUE(IsKeyboardDisabled());
 }
 
diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc
index 4aba3ff..8b064ae 100644
--- a/ui/keyboard/keyboard_util.cc
+++ b/ui/keyboard/keyboard_util.cc
@@ -64,7 +64,7 @@
 }
 
 bool IsKeyboardEnabled() {
-  return KeyboardController::Get()->IsKeyboardEnableRequested();
+  return KeyboardController::Get()->IsEnabled();
 }
 
 }  // namespace keyboard
diff --git a/ui/keyboard/keyboard_util_unittest.cc b/ui/keyboard/keyboard_util_unittest.cc
index 333e0a3..df475234 100644
--- a/ui/keyboard/keyboard_util_unittest.cc
+++ b/ui/keyboard/keyboard_util_unittest.cc
@@ -13,7 +13,7 @@
 #include "ui/keyboard/keyboard_util.h"
 #include "ui/keyboard/test/keyboard_test_util.h"
 #include "ui/keyboard/test/test_keyboard_layout_delegate.h"
-#include "ui/keyboard/test/test_keyboard_ui.h"
+#include "ui/keyboard/test/test_keyboard_ui_factory.h"
 
 namespace keyboard {
 namespace {
@@ -56,9 +56,22 @@
 
   void SetUp() override {
     aura::test::AuraTestBase::SetUp();
+
+    layout_delegate_ =
+        std::make_unique<TestKeyboardLayoutDelegate>(root_window());
+    keyboard_controller_.Initialize(
+        std::make_unique<TestKeyboardUIFactory>(&input_method_),
+        layout_delegate_.get());
+
     ResetAllFlags();
   }
 
+  void TearDown() override {
+    ResetAllFlags();
+
+    aura::test::AuraTestBase::TearDown();
+  }
+
  protected:
   void SetEnableFlag(mojom::KeyboardEnableFlag flag) {
     keyboard_controller_.SetEnableFlag(flag);
@@ -70,6 +83,8 @@
 
   // Used indirectly by keyboard utils.
   KeyboardController keyboard_controller_;
+  ui::DummyInputMethod input_method_;
+  std::unique_ptr<TestKeyboardLayoutDelegate> layout_delegate_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(KeyboardUtilTest);
@@ -158,11 +173,6 @@
 TEST_F(KeyboardUtilTest, IsOverscrollEnabled) {
   ResetAllFlags();
 
-  ui::DummyInputMethod input_method;
-  TestKeyboardLayoutDelegate layout_delegate(root_window());
-  keyboard_controller_.EnableKeyboard(
-      std::make_unique<TestKeyboardUI>(&input_method), &layout_delegate);
-
   // Return false when keyboard is disabled.
   EXPECT_FALSE(keyboard_controller_.IsKeyboardOverscrollEnabled());
 
@@ -187,8 +197,6 @@
   keyboard_controller_.set_keyboard_locked(true);
   EXPECT_TRUE(keyboard_controller_.keyboard_locked());
   EXPECT_FALSE(keyboard_controller_.IsKeyboardOverscrollEnabled());
-
-  keyboard_controller_.DisableKeyboard();
 }
 
 }  // namespace keyboard
diff --git a/ui/keyboard/test/test_keyboard_ui.cc b/ui/keyboard/test/test_keyboard_ui.cc
deleted file mode 100644
index 98690159..0000000
--- a/ui/keyboard/test/test_keyboard_ui.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/keyboard/test/test_keyboard_ui.h"
-
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "ui/display/display.h"
-#include "ui/display/screen.h"
-#include "ui/keyboard/test/keyboard_test_util.h"
-
-namespace keyboard {
-
-TestKeyboardUI::TestKeyboardUI(ui::InputMethod* input_method)
-    : input_method_(input_method) {}
-
-TestKeyboardUI::~TestKeyboardUI() {
-  // Destroy the window before the delegate.
-  window_.reset();
-}
-
-aura::Window* TestKeyboardUI::LoadKeyboardWindow(LoadCallback callback) {
-  DCHECK(!window_);
-  window_ = std::make_unique<aura::Window>(&delegate_);
-  window_->Init(ui::LAYER_NOT_DRAWN);
-  window_->set_owned_by_parent(false);
-
-  // Set a default size for the keyboard.
-  display::Screen* screen = display::Screen::GetScreen();
-  window_->SetBounds(
-      KeyboardBoundsFromRootBounds(screen->GetPrimaryDisplay().bounds()));
-
-  // Simulate an asynchronous load.
-  base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                   std::move(callback));
-
-  return window_.get();
-}
-
-aura::Window* TestKeyboardUI::GetKeyboardWindow() const {
-  return window_.get();
-}
-
-ui::InputMethod* TestKeyboardUI::GetInputMethod() {
-  return input_method_;
-}
-
-}  // namespace keyboard
diff --git a/ui/keyboard/test/test_keyboard_ui.h b/ui/keyboard/test/test_keyboard_ui.h
deleted file mode 100644
index 86f7a23..0000000
--- a/ui/keyboard/test/test_keyboard_ui.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_KEYBOARD_TEST_TEST_KEYBOARD_UI_H_
-#define UI_KEYBOARD_TEST_TEST_KEYBOARD_UI_H_
-
-#include <memory>
-
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/keyboard/keyboard_ui.h"
-
-namespace aura {
-class Window;
-}
-
-namespace ui {
-class InputMethod;
-}
-
-namespace keyboard {
-
-class TestKeyboardUI : public KeyboardUI {
- public:
-  TestKeyboardUI(ui::InputMethod* input_method);
-  ~TestKeyboardUI() override;
-
-  // Overridden from KeyboardUI:
-  aura::Window* LoadKeyboardWindow(LoadCallback callback) override;
-  aura::Window* GetKeyboardWindow() const override;
-  ui::InputMethod* GetInputMethod() override;
-  void ReloadKeyboardIfNeeded() override {}
-
- private:
-  std::unique_ptr<aura::Window> window_;
-  aura::test::TestWindowDelegate delegate_;
-  ui::InputMethod* input_method_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestKeyboardUI);
-};
-
-}  // namespace keyboard
-
-#endif  // UI_KEYBOARD_TEST_TEST_KEYBOARD_UI_H_
diff --git a/ui/keyboard/test/test_keyboard_ui_factory.cc b/ui/keyboard/test/test_keyboard_ui_factory.cc
new file mode 100644
index 0000000..02175a2
--- /dev/null
+++ b/ui/keyboard/test/test_keyboard_ui_factory.cc
@@ -0,0 +1,63 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/keyboard/test/test_keyboard_ui_factory.h"
+
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
+#include "ui/keyboard/test/keyboard_test_util.h"
+
+#include <utility>
+
+namespace keyboard {
+
+TestKeyboardUIFactory::TestKeyboardUIFactory(ui::InputMethod* input_method)
+    : input_method_(input_method) {}
+
+TestKeyboardUIFactory::~TestKeyboardUIFactory() = default;
+
+std::unique_ptr<KeyboardUI> TestKeyboardUIFactory::CreateKeyboardUI() {
+  return std::make_unique<TestKeyboardUI>(input_method_);
+}
+
+// TestKeyboardUIFactory::TestKeyboardUI:
+
+TestKeyboardUIFactory::TestKeyboardUI::TestKeyboardUI(
+    ui::InputMethod* input_method)
+    : input_method_(input_method) {}
+
+TestKeyboardUIFactory::TestKeyboardUI::~TestKeyboardUI() {
+  // Destroy the window before the delegate.
+  window_.reset();
+}
+
+aura::Window* TestKeyboardUIFactory::TestKeyboardUI::LoadKeyboardWindow(
+    LoadCallback callback) {
+  DCHECK(!window_);
+  window_ = std::make_unique<aura::Window>(&delegate_);
+  window_->Init(ui::LAYER_NOT_DRAWN);
+  window_->set_owned_by_parent(false);
+
+  // Set a default size for the keyboard.
+  display::Screen* screen = display::Screen::GetScreen();
+  window_->SetBounds(
+      KeyboardBoundsFromRootBounds(screen->GetPrimaryDisplay().bounds()));
+
+  // Simulate an asynchronous load.
+  base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                   std::move(callback));
+
+  return window_.get();
+}
+
+aura::Window* TestKeyboardUIFactory::TestKeyboardUI::GetKeyboardWindow() const {
+  return window_.get();
+}
+
+ui::InputMethod* TestKeyboardUIFactory::TestKeyboardUI::GetInputMethod() {
+  return input_method_;
+}
+
+}  // namespace keyboard
diff --git a/ui/keyboard/test/test_keyboard_ui_factory.h b/ui/keyboard/test/test_keyboard_ui_factory.h
new file mode 100644
index 0000000..3605df24
--- /dev/null
+++ b/ui/keyboard/test/test_keyboard_ui_factory.h
@@ -0,0 +1,57 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_KEYBOARD_TEST_TEST_KEYBOARD_UI_FACTORY_H_
+#define UI_KEYBOARD_TEST_TEST_KEYBOARD_UI_FACTORY_H_
+
+#include <memory>
+
+#include "ui/aura/test/test_window_delegate.h"
+#include "ui/keyboard/keyboard_ui.h"
+#include "ui/keyboard/keyboard_ui_factory.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ui {
+class InputMethod;
+}
+
+namespace keyboard {
+
+class TestKeyboardUIFactory : public KeyboardUIFactory {
+ public:
+  class TestKeyboardUI : public KeyboardUI {
+   public:
+    explicit TestKeyboardUI(ui::InputMethod* input_method);
+    ~TestKeyboardUI() override;
+
+    // Overridden from KeyboardUI:
+    aura::Window* LoadKeyboardWindow(LoadCallback callback) override;
+    aura::Window* GetKeyboardWindow() const override;
+    ui::InputMethod* GetInputMethod() override;
+    void ReloadKeyboardIfNeeded() override {}
+
+   private:
+    std::unique_ptr<aura::Window> window_;
+    aura::test::TestWindowDelegate delegate_;
+    ui::InputMethod* input_method_;
+  };
+
+  explicit TestKeyboardUIFactory(ui::InputMethod* input_method);
+  ~TestKeyboardUIFactory() override;
+
+  // Overridden from KeyboardUIFactory:
+  std::unique_ptr<KeyboardUI> CreateKeyboardUI() override;
+
+ private:
+  ui::InputMethod* input_method_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestKeyboardUIFactory);
+};
+
+}  // namespace keyboard
+
+#endif  // UI_KEYBOARD_TEST_TEST_KEYBOARD_UI_FACTORY_H_
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
index 952e0c9..3ad856f 100644
--- a/ui/ozone/platform/wayland/BUILD.gn
+++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -223,6 +223,8 @@
 source_set("wayland_unittests") {
   testonly = true
 
+  assert(use_wayland_gbm)
+
   sources = [
     "wayland_buffer_manager_unittest.cc",
     "wayland_connection_unittest.cc",
@@ -254,6 +256,7 @@
     "//ui/events/ozone:events_ozone_layout",
     "//ui/ozone:platform",
     "//ui/ozone:test_support",
+    "//ui/ozone/common/linux:gbm",
   ]
 
   import("//ui/base/ui_features.gni")
@@ -261,10 +264,10 @@
     deps += [ "//ui/events/keycodes:xkb" ]
   }
 
-  defines = [ "WL_HIDE_DEPRECATED" ]
-  if (use_wayland_gbm) {
-    defines += [ "WAYLAND_GBM" ]
-  }
+  defines = [
+    "WL_HIDE_DEPRECATED",
+    "WAYLAND_GBM",
+  ]
 }
 
 fuzzer_test("wayland_buffer_fuzzer") {
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory.cc b/ui/ozone/platform/wayland/wayland_surface_factory.cc
index f3f49a2..65d8782 100644
--- a/ui/ozone/platform/wayland/wayland_surface_factory.cc
+++ b/ui/ozone/platform/wayland/wayland_surface_factory.cc
@@ -28,8 +28,9 @@
 
 class GLOzoneEGLWayland : public GLOzoneEGL {
  public:
-  explicit GLOzoneEGLWayland(WaylandConnectionProxy* connection)
-      : connection_(connection) {}
+  GLOzoneEGLWayland(WaylandConnectionProxy* connection,
+                    WaylandSurfaceFactory* factory)
+      : connection_(connection), factory_(factory) {}
   ~GLOzoneEGLWayland() override {}
 
   scoped_refptr<gl::GLSurface> CreateViewGLSurface(
@@ -46,7 +47,8 @@
   bool LoadGLES2Bindings(gl::GLImplementation impl) override;
 
  private:
-  WaylandConnectionProxy* connection_ = nullptr;
+  WaylandConnectionProxy* const connection_;
+  WaylandSurfaceFactory* const factory_;
 
   DISALLOW_COPY_AND_ASSIGN(GLOzoneEGLWayland);
 };
@@ -72,6 +74,8 @@
 
 scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateSurfacelessViewGLSurface(
     gfx::AcceleratedWidget window) {
+  DCHECK(factory_);
+
   // Only EGLGLES2 is supported with surfaceless view gl.
   if (gl::GetGLImplementation() != gl::kGLImplementationEGLGLES2)
     return nullptr;
@@ -80,10 +84,7 @@
   // If there is a gbm device available, use surfaceless gl surface.
   if (!connection_->gbm_device())
     return nullptr;
-  return gl::InitializeGLSurface(new GbmSurfacelessWayland(
-      static_cast<WaylandSurfaceFactory*>(
-          OzonePlatform::GetInstance()->GetSurfaceFactoryOzone()),
-      window));
+  return gl::InitializeGLSurface(new GbmSurfacelessWayland(factory_, window));
 #else
   return nullptr;
 #endif
@@ -115,7 +116,8 @@
 WaylandSurfaceFactory::WaylandSurfaceFactory(WaylandConnectionProxy* connection)
     : connection_(connection) {
   if (connection_)
-    egl_implementation_ = std::make_unique<GLOzoneEGLWayland>(connection_);
+    egl_implementation_ =
+        std::make_unique<GLOzoneEGLWayland>(connection_, this);
 }
 
 WaylandSurfaceFactory::~WaylandSurfaceFactory() {}
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc b/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc
index 3819f707..87861f46 100644
--- a/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc
+++ b/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc
@@ -7,6 +7,9 @@
 #include "base/run_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkSurface.h"
+#include "ui/ozone/common/linux/gbm_buffer.h"
+#include "ui/ozone/common/linux/gbm_device.h"
+#include "ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h"
 #include "ui/ozone/platform/wayland/test/mock_surface.h"
 #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h"
 #include "ui/ozone/platform/wayland/wayland_surface_factory.h"
@@ -21,9 +24,72 @@
 
 namespace ui {
 
+namespace {
+
+class FakeGbmBuffer : public GbmBuffer {
+ public:
+  FakeGbmBuffer() = default;
+  ~FakeGbmBuffer() override = default;
+
+  uint32_t GetFormat() const override { return 0; }
+  uint64_t GetFormatModifier() const override { return 0; }
+  uint32_t GetFlags() const override { return 0; }
+  gfx::Size GetSize() const override { return gfx::Size(); }
+  gfx::BufferFormat GetBufferFormat() const override {
+    return gfx::BufferFormat::BGRA_8888;
+  }
+  bool AreFdsValid() const override { return false; }
+  size_t GetNumPlanes() const override { return 0; }
+  int GetPlaneFd(size_t plane) const override { return -1; }
+  uint32_t GetPlaneHandle(size_t plane) const override { return 0; }
+  int GetPlaneStride(size_t plane) const override { return -1; }
+  int GetPlaneOffset(size_t plane) const override { return -1; }
+  size_t GetPlaneSize(size_t plane) const override { return 0; }
+  uint32_t GetHandle() const override { return 0; }
+  gfx::NativePixmapHandle ExportHandle() const override {
+    return gfx::NativePixmapHandle();
+  }
+  sk_sp<SkSurface> GetSurface() override { return nullptr; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeGbmBuffer);
+};
+
+class FakeGbmDevice : public GbmDevice {
+ public:
+  FakeGbmDevice() = default;
+  ~FakeGbmDevice() override = default;
+
+  std::unique_ptr<GbmBuffer> CreateBuffer(uint32_t format,
+                                          const gfx::Size& size,
+                                          uint32_t flags) override {
+    return nullptr;
+  }
+
+  std::unique_ptr<GbmBuffer> CreateBufferWithModifiers(
+      uint32_t format,
+      const gfx::Size& size,
+      uint32_t flags,
+      const std::vector<uint64_t>& modifiers) override {
+    return nullptr;
+  }
+  std::unique_ptr<GbmBuffer> CreateBufferFromFds(
+      uint32_t format,
+      const gfx::Size& size,
+      std::vector<base::ScopedFD> fds,
+      const std::vector<gfx::NativePixmapPlane>& planes) override {
+    return nullptr;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeGbmDevice);
+};
+
+}  // namespace
+
 class WaylandSurfaceFactoryTest : public WaylandTest {
  public:
-  WaylandSurfaceFactoryTest() : surface_factory(connection_proxy_.get()) {}
+  WaylandSurfaceFactoryTest() : surface_factory_(connection_proxy_.get()) {}
 
   ~WaylandSurfaceFactoryTest() override {}
 
@@ -33,30 +99,35 @@
     auto connection_ptr = connection_->BindInterface();
     connection_proxy_->SetWaylandConnection(std::move(connection_ptr));
 
-    canvas = surface_factory.CreateCanvasForWidget(widget_);
-    ASSERT_TRUE(canvas);
-
     // Wait until initialization and mojo calls go through.
     base::RunLoop().RunUntilIdle();
   }
 
   void TearDown() override {
-    canvas.reset();
-
-    // The mojo call to destroy shared buffer goes after canvas is destroyed.
+    // The mojo call to destroy shared buffer goes after surfaces are destroyed.
     // Wait until it's done.
     base::RunLoop().RunUntilIdle();
   }
 
  protected:
-  WaylandSurfaceFactory surface_factory;
-  std::unique_ptr<SurfaceOzoneCanvas> canvas;
+  std::unique_ptr<SurfaceOzoneCanvas> CreateCanvas(
+      gfx::AcceleratedWidget widget) {
+    auto canvas = surface_factory_.CreateCanvasForWidget(widget_);
+    base::RunLoop().RunUntilIdle();
+
+    return canvas;
+  }
+
+  WaylandSurfaceFactory surface_factory_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(WaylandSurfaceFactoryTest);
 };
 
 TEST_P(WaylandSurfaceFactoryTest, Canvas) {
+  auto canvas = CreateCanvas(widget_);
+  ASSERT_TRUE(canvas);
+
   canvas->ResizeCanvas(window_->GetBounds().size());
   canvas->GetSurface();
   canvas->PresentCanvas(gfx::Rect(5, 10, 20, 15));
@@ -83,6 +154,9 @@
 }
 
 TEST_P(WaylandSurfaceFactoryTest, CanvasResize) {
+  auto canvas = CreateCanvas(widget_);
+  ASSERT_TRUE(canvas);
+
   canvas->ResizeCanvas(window_->GetBounds().size());
   canvas->GetSurface();
   canvas->ResizeCanvas(gfx::Size(100, 50));
@@ -106,6 +180,31 @@
   EXPECT_EQ(wl_shm_buffer_get_height(buffer), 50);
 }
 
+TEST_P(WaylandSurfaceFactoryTest, CreateSurfaceCheckGbm) {
+  gl::SetGLImplementation(gl::kGLImplementationEGLGLES2);
+
+  // When gbm is not available, only canvas can be created with viz process
+  // used.
+  EXPECT_FALSE(connection_proxy_->gbm_device());
+
+  auto* gl_ozone = surface_factory_.GetGLOzone(gl::kGLImplementationEGLGLES2);
+  EXPECT_TRUE(gl_ozone);
+  auto gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_);
+  EXPECT_FALSE(gl_surface);
+
+  // Now, set gbm.
+  connection_proxy_->set_gbm_device(std::make_unique<FakeGbmDevice>());
+
+  gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_);
+  EXPECT_TRUE(gl_surface);
+
+  // Reset gbm now. WaylandConnectionProxy can reset it when zwp is not
+  // available. And factory must behave the same way as previously.
+  connection_proxy_->ResetGbmDevice();
+  gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_);
+  EXPECT_FALSE(gl_surface);
+}
+
 INSTANTIATE_TEST_SUITE_P(XdgVersionV5Test,
                          WaylandSurfaceFactoryTest,
                          ::testing::Values(kXdgShellV5));
diff --git a/ui/views/mus/desktop_window_tree_host_mus.cc b/ui/views/mus/desktop_window_tree_host_mus.cc
index 70a9ff8..3b0cda498 100644
--- a/ui/views/mus/desktop_window_tree_host_mus.cc
+++ b/ui/views/mus/desktop_window_tree_host_mus.cc
@@ -401,6 +401,10 @@
 
   // Sets the has-content info for the occlusion tracker that runs on the Window
   // Service side.
+  // TODO(edcourtney): Remove this once we plumb through the window's
+  // transparent value through mus. That, in combination with the layer type
+  // will let the occlusion tracker determine if the window should affect
+  // occlusion.
   content_window()->SetProperty(
       aura::client::kClientWindowHasContent,
       params.layer_type != ui::LAYER_NOT_DRAWN &&