diff --git a/DEPS b/DEPS
index 5aa4356..1f4dd70 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # 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': '789ec38b623c0fa9a57bc598b5447a8e859b4790',
+  'v8_revision': '74b683277b61ca81642c76386de81200860a12f1',
   # 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.
diff --git a/chrome/browser/ui/views/profiles/avatar_button.cc b/chrome/browser/ui/views/profiles/avatar_button.cc
index 8945445..20d0f3f 100644
--- a/chrome/browser/ui/views/profiles/avatar_button.cc
+++ b/chrome/browser/ui/views/profiles/avatar_button.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/views/profiles/profile_chooser_view.h"
 #include "chrome/grit/theme_resources.h"
+#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/theme_provider.h"
@@ -142,6 +143,26 @@
 constexpr gfx::Insets AvatarButtonThemedBorder::kBorderStrokeInsets;
 constexpr float AvatarButtonThemedBorder::kCornerRadius;
 
+class ShutdownNotifierFactory
+    : public BrowserContextKeyedServiceShutdownNotifierFactory {
+ public:
+  static ShutdownNotifierFactory* GetInstance() {
+    return base::Singleton<ShutdownNotifierFactory>::get();
+  }
+
+ private:
+  friend struct base::DefaultSingletonTraits<ShutdownNotifierFactory>;
+
+  ShutdownNotifierFactory()
+      : BrowserContextKeyedServiceShutdownNotifierFactory(
+            "AvatarButtonShutdownNotifierFactory") {
+    DependsOn(SigninManagerFactory::GetInstance());
+  }
+  ~ShutdownNotifierFactory() override {}
+
+  DISALLOW_COPY_AND_ASSIGN(ShutdownNotifierFactory);
+};
+
 }  // namespace
 
 AvatarButton::AvatarButton(views::ButtonListener* listener,
@@ -219,6 +240,10 @@
         CreateThemedBorder(kNormalImageSet, kHoverImageSet, kPressedImageSet));
   }
 
+  profile_shutdown_notifier_ =
+      ShutdownNotifierFactory::GetInstance()->Get(profile_)->Subscribe(
+          base::Bind(&AvatarButton::OnProfileShutdown, base::Unretained(this)));
+
   Update();
   SchedulePaint();
 }
@@ -339,7 +364,23 @@
   AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr);
 }
 
+void AvatarButton::OnProfileShutdown() {
+  // It looks like in some mysterious cases, the AvatarButton outlives the
+  // profile (see http://crbug.com/id=579690). The avatar button is owned by
+  // the browser frame (which is owned by the BrowserWindow), and there is an
+  // expectation for the UI to be destroyed before the profile is destroyed.
+  CHECK(false) << "Avatar button must not outlive the profile.";
+}
+
 void AvatarButton::Update() {
+  // It looks like in some mysterious cases, the AvatarButton outlives the
+  // profile manager (see http://crbug.com/id=579690). The avatar button is
+  // owned by the browser frame (which is owned by the BrowserWindow), and
+  // there is an expectation for the UI to be destroyed before the profile
+  // manager is destroyed.
+  CHECK(g_browser_process->profile_manager())
+      << "Avatar button must not outlive the profile manager";
+
   ProfileAttributesStorage& storage =
       g_browser_process->profile_manager()->GetProfileAttributesStorage();
 
diff --git a/chrome/browser/ui/views/profiles/avatar_button.h b/chrome/browser/ui/views/profiles/avatar_button.h
index fd1fbc4..f4d4357 100644
--- a/chrome/browser/ui/views/profiles/avatar_button.h
+++ b/chrome/browser/ui/views/profiles/avatar_button.h
@@ -11,6 +11,7 @@
 #include "chrome/browser/ui/avatar_button_error_controller.h"
 #include "chrome/browser/ui/avatar_button_error_controller_delegate.h"
 #include "chrome/browser/ui/views/profiles/avatar_button_style.h"
+#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/widget/widget_observer.h"
 
@@ -60,6 +61,9 @@
   // views::WidgetObserver
   void OnWidgetClosing(views::Widget* widget) override;
 
+  // Called when |profile_| is shutting down.
+  void OnProfileShutdown();
+
   // Called when the profile info cache or signin/sync error has changed, which
   // means we might have to update the icon/text of the button.
   void Update();
@@ -73,6 +77,12 @@
 
   AvatarButtonErrorController error_controller_;
   Profile* profile_;
+
+  // TODO(msarda): Remove |profile_shutdown_notifier_| when
+  // http://crbug.com/579690 is fixed (it was added to track down the crash in
+  // that bug).
+  std::unique_ptr<KeyedServiceShutdownNotifier::Subscription>
+      profile_shutdown_notifier_;
   ScopedObserver<ProfileAttributesStorage, AvatarButton> profile_observer_;
 
   // The icon displayed instead of the profile name in the local profile case.
diff --git a/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java b/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
index 2914ab83..53b91f6 100644
--- a/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
+++ b/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
@@ -66,8 +66,9 @@
         CrashDumpManager.tryToUploadMinidump(null);
     }
 
-    @SmallTest
-    @Feature({"Android-AppBase"})
+    // @SmallTest
+    // @Feature({"Android-AppBase"})
+    @DisabledTest // Flaky, crbug.com/726976.
     public void testUploadMinidump_FileDoesntExist() {
         registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
             @Override
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn
index 91c6ea4..f9703b0 100644
--- a/ios/chrome/browser/metrics/BUILD.gn
+++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -129,6 +129,7 @@
 }
 
 source_set("unit_tests_internal") {
+  configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
     "first_user_action_recorder_unittest.cc",
diff --git a/ios/chrome/browser/metrics/size_class_recorder_unittest.mm b/ios/chrome/browser/metrics/size_class_recorder_unittest.mm
index 238e13a6..2709ad2f 100644
--- a/ios/chrome/browser/metrics/size_class_recorder_unittest.mm
+++ b/ios/chrome/browser/metrics/size_class_recorder_unittest.mm
@@ -7,12 +7,15 @@
 
 #include <memory>
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/test/histogram_tester.h"
 #import "ios/chrome/browser/ui/ui_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using ios_internal::SizeClassForReporting;
 using ios_internal::SizeClassForReportingForUIUserInterfaceSizeClass;
 
@@ -30,7 +33,7 @@
     histogram_tester_.reset(new base::HistogramTester());
   }
 
-  base::scoped_nsobject<SizeClassRecorder> recorder_;
+  SizeClassRecorder* recorder_;
   std::unique_ptr<base::HistogramTester> histogram_tester_;
 };
 
@@ -39,9 +42,9 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified]);
-  recorder_.reset();
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
+  recorder_ = nil;
 
   histogram_tester_->ExpectTotalCount(kSizeClassUsedHistogramName, 0);
   histogram_tester_->ExpectTotalCount(kPageLoadSizeClassHistogramName, 0);
@@ -52,9 +55,9 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]);
-  recorder_.reset();
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
+  recorder_ = nil;
 
   histogram_tester_->ExpectTotalCount(kSizeClassUsedHistogramName, 0);
   histogram_tester_->ExpectTotalCount(kPageLoadSizeClassHistogramName, 0);
@@ -65,9 +68,9 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular]);
-  recorder_.reset();
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
+  recorder_ = nil;
 
   histogram_tester_->ExpectTotalCount(kSizeClassUsedHistogramName, 0);
   histogram_tester_->ExpectTotalCount(kPageLoadSizeClassHistogramName, 0);
@@ -78,8 +81,8 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]);
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
   [[NSNotificationCenter defaultCenter]
       postNotificationName:UIApplicationDidBecomeActiveNotification
                     object:nil];
@@ -95,8 +98,8 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]);
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
   [[NSNotificationCenter defaultCenter]
       postNotificationName:UIApplicationDidBecomeActiveNotification
                     object:nil];
@@ -114,8 +117,8 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified]);
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
   [recorder_ horizontalSizeClassDidChange:UIUserInterfaceSizeClassRegular];
 
   histogram_tester_->ExpectUniqueSample(kSizeClassUsedHistogramName,
@@ -128,8 +131,8 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified]);
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
   [[NSNotificationCenter defaultCenter]
       postNotificationName:UIApplicationDidEnterBackgroundNotification
                     object:nil];
@@ -145,8 +148,8 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified]);
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
   [[NSNotificationCenter defaultCenter]
       postNotificationName:UIApplicationDidEnterBackgroundNotification
                     object:nil];
@@ -165,8 +168,8 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified]);
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
   [recorder_
       pageLoadedWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
 
@@ -180,8 +183,8 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified]);
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
   [recorder_ pageLoadedWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
 
   histogram_tester_->ExpectTotalCount(kSizeClassUsedHistogramName, 0);
@@ -194,8 +197,8 @@
   if (!IsIPadIdiom())
     return;
 
-  recorder_.reset([[SizeClassRecorder alloc]
-      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified]);
+  recorder_ = [[SizeClassRecorder alloc]
+      initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
   [recorder_ pageLoadedWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
 
   histogram_tester_->ExpectTotalCount(kSizeClassUsedHistogramName, 0);
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_unittest.mm b/ios/chrome/browser/metrics/tab_usage_recorder_unittest.mm
index ccd9cd2..ca0817b 100644
--- a/ios/chrome/browser/metrics/tab_usage_recorder_unittest.mm
+++ b/ios/chrome/browser/metrics/tab_usage_recorder_unittest.mm
@@ -4,7 +4,6 @@
 
 #include <memory>
 
-#include "base/mac/scoped_nsobject.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram_samples.h"
 #include "base/stl_util.h"
@@ -20,6 +19,10 @@
 #include "testing/platform_test.h"
 #include "third_party/ocmock/ocmock_extensions.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 @interface TURTestTabMock : OCMockComplexTypeHelper {
   GURL _url;
 }
@@ -105,7 +108,7 @@
     [tab_mock setUrl:webUrl_];
     [[[web_controller_mock stub] andReturnBool:inMemory] isViewAlive];
     [[web_controller_mock stub] removeObserver:OCMOCK_ANY];
-    return [tab_mock autorelease];
+    return tab_mock;
   }
 
   GURL webUrl_;
@@ -312,8 +315,8 @@
   Tab* terminated_tab = MockTab(false);
 
   // Set up the delegate to return |kAliveTabsCountAtRenderTermination|.
-  base::scoped_nsobject<MockTabUsageRecorderDelegate> delegate(
-      [[MockTabUsageRecorderDelegate alloc] init]);
+  MockTabUsageRecorderDelegate* delegate =
+      [[MockTabUsageRecorderDelegate alloc] init];
   [delegate setLiveTabsCount:kAliveTabsCountAtRendererTermination];
   tab_usage_recorder_->SetDelegate(delegate);
 
diff --git a/ios/clean/chrome/browser/ui/tab/BUILD.gn b/ios/clean/chrome/browser/ui/tab/BUILD.gn
index 1a209c0..1b7c709 100644
--- a/ios/clean/chrome/browser/ui/tab/BUILD.gn
+++ b/ios/clean/chrome/browser/ui/tab/BUILD.gn
@@ -22,6 +22,7 @@
     "//ios/clean/chrome/browser/ui/tab_strip",
     "//ios/clean/chrome/browser/ui/toolbar",
     "//ios/clean/chrome/browser/ui/web_contents",
+    "//ios/shared/chrome/browser/ui/broadcaster",
     "//ios/shared/chrome/browser/ui/browser_list",
     "//ios/shared/chrome/browser/ui/commands",
     "//ios/shared/chrome/browser/ui/coordinators",
diff --git a/ios/clean/chrome/browser/ui/tab/tab_container_view_controller.h b/ios/clean/chrome/browser/ui/tab/tab_container_view_controller.h
index b2039ea..ba1426b 100644
--- a/ios/clean/chrome/browser/ui/tab/tab_container_view_controller.h
+++ b/ios/clean/chrome/browser/ui/tab/tab_container_view_controller.h
@@ -31,6 +31,9 @@
 // width of the tab.
 @property(nonatomic, strong) UIViewController* tabStripViewController;
 
+// YES if |tabStripViewController| is currently visible.
+@property(nonatomic, getter=isTabStripVisible) BOOL tabStripVisible;
+
 // View controller showing the find bar.  The location of this controller's view
 // is determined by size class and device type.  May be nil if the find bar is
 // currently closed.
diff --git a/ios/clean/chrome/browser/ui/tab/tab_container_view_controller.mm b/ios/clean/chrome/browser/ui/tab/tab_container_view_controller.mm
index 7c323fa..16a4e506 100644
--- a/ios/clean/chrome/browser/ui/tab/tab_container_view_controller.mm
+++ b/ios/clean/chrome/browser/ui/tab/tab_container_view_controller.mm
@@ -4,7 +4,6 @@
 
 #import "ios/clean/chrome/browser/ui/tab/tab_container_view_controller.h"
 
-#import "ios/clean/chrome/browser/ui/tab_strip/tab_strip_events.h"
 #import "ios/clean/chrome/browser/ui/ui_types.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -46,6 +45,7 @@
 @synthesize findBarViewController = _findBarViewController;
 @synthesize toolbarViewController = _toolbarViewController;
 @synthesize tabStripViewController = _tabStripViewController;
+@synthesize tabStripVisible = _tabStripVisible;
 @synthesize tabStripView = _tabStripView;
 @synthesize toolbarView = _toolbarView;
 @synthesize contentView = _contentView;
@@ -133,6 +133,15 @@
   _toolbarViewController = toolbarViewController;
 }
 
+- (void)setTabStripVisible:(BOOL)tabStripVisible {
+  if (tabStripVisible) {
+    self.tabStripHeightConstraint.constant = kTabStripHeight;
+  } else {
+    self.tabStripHeightConstraint.constant = 0.0f;
+  }
+  _tabStripVisible = tabStripVisible;
+}
+
 - (void)setTabStripViewController:(UIViewController*)tabStripViewController {
   if (self.tabStripViewController == tabStripViewController)
     return;
@@ -242,24 +251,14 @@
   return nil;
 }
 
-#pragma mark - Action handling
+#pragma mark - Tab Strip actions.
 
 - (void)showTabStrip:(id)sender {
-  self.tabStripHeightConstraint.constant = kTabStripHeight;
-  // HACK: Remove fake action.
-  [[UIApplication sharedApplication] sendAction:@selector(tabStripDidShow:)
-                                             to:nil
-                                           from:sender
-                                       forEvent:nil];
+  self.tabStripVisible = YES;
 }
 
 - (void)hideTabStrip:(id)sender {
-  self.tabStripHeightConstraint.constant = 0.0f;
-  // HACK: Remove fake action.
-  [[UIApplication sharedApplication] sendAction:@selector(tabStripDidHide:)
-                                             to:nil
-                                           from:sender
-                                       forEvent:nil];
+  self.tabStripVisible = NO;
 }
 
 #pragma mark - Abstract methods to be overriden by subclass
diff --git a/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm b/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm
index 1231d09..bf46bc8 100644
--- a/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm
+++ b/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm
@@ -17,6 +17,7 @@
 #import "ios/clean/chrome/browser/ui/tab_strip/tab_strip_coordinator.h"
 #import "ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.h"
 #import "ios/clean/chrome/browser/ui/web_contents/web_coordinator.h"
+#import "ios/shared/chrome/browser/ui/broadcaster/chrome_broadcaster.h"
 #import "ios/shared/chrome/browser/ui/browser_list/browser.h"
 #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h"
@@ -54,6 +55,11 @@
   _webStateObserver =
       base::MakeUnique<web::WebStateObserverBridge>(self.webState, self);
 
+  [self.browser->broadcaster()
+      broadcastValue:@"tabStripVisible"
+            ofObject:self.viewController
+            selector:@selector(broadcastTabStripVisible:)];
+
   CommandDispatcher* dispatcher = self.browser->dispatcher();
   // TabCommands
   [dispatcher startDispatchingToTarget:self forSelector:@selector(loadURL:)];
@@ -96,6 +102,8 @@
   for (BrowserCoordinator* child in self.children) {
     [self removeChildCoordinator:child];
   }
+  [self.browser->broadcaster()
+      stopBroadcastingForSelector:@selector(broadcastTabStripVisible:)];
   _webStateObserver.reset();
   [self.browser->dispatcher() stopDispatchingToTarget:self];
 }
diff --git a/ios/clean/chrome/browser/ui/tab_strip/tab_strip_events.h b/ios/clean/chrome/browser/ui/tab_strip/tab_strip_events.h
deleted file mode 100644
index 8c5c4f8..0000000
--- a/ios/clean/chrome/browser/ui/tab_strip/tab_strip_events.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2017 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 IOS_CLEAN_CHROME_BROWSER_UI_TAB_STRIP_TAB_STRIP_EVENTS_H_
-#define IOS_CLEAN_CHROME_BROWSER_UI_TAB_STRIP_TAB_STRIP_EVENTS_H_
-
-#import <Foundation/Foundation.h>
-
-// PLACEHOLDER: TabStrip related events, this might change or be renamed once we
-// figure out the command architecture.
-@protocol TabStripEvents
-@optional
-// Event triggered when the TabStrip has been hidden.
-- (void)tabStripDidHide:(id)sender;
-// Event triggered when the TabStrip has been shown.
-- (void)tabStripDidShow:(id)sender;
-@end
-
-#endif  // IOS_CLEAN_CHROME_BROWSER_UI_TAB_STRIP_TAB_STRIP_EVENTS_H_
diff --git a/ios/clean/chrome/browser/ui/toolbar/BUILD.gn b/ios/clean/chrome/browser/ui/toolbar/BUILD.gn
index 029838e..2648d06 100644
--- a/ios/clean/chrome/browser/ui/toolbar/BUILD.gn
+++ b/ios/clean/chrome/browser/ui/toolbar/BUILD.gn
@@ -18,6 +18,7 @@
     "//ios/clean/chrome/browser/ui/commands",
     "//ios/clean/chrome/browser/ui/omnibox",
     "//ios/clean/chrome/browser/ui/tools",
+    "//ios/shared/chrome/browser/ui/broadcaster",
     "//ios/shared/chrome/browser/ui/browser_list",
     "//ios/shared/chrome/browser/ui/commands",
     "//ios/shared/chrome/browser/ui/coordinators",
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_consumer.h b/ios/clean/chrome/browser/ui/toolbar/toolbar_consumer.h
index 2e9a44536..99e8e3d 100644
--- a/ios/clean/chrome/browser/ui/toolbar/toolbar_consumer.h
+++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_consumer.h
@@ -17,6 +17,8 @@
 - (void)setIsLoading:(BOOL)isLoading;
 // Updates the toolbar with the current progress of the loading WebState.
 - (void)setLoadingProgress:(double)progress;
+// Sets whether the toolbar should display for a visible tab strip or not.
+- (void)setTabStripVisible:(BOOL)visible;
 @end
 
 #endif  // IOS_CLEAN_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_CONSUMER_H_
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm
index b995e24..f2a5212 100644
--- a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm
+++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm
@@ -9,6 +9,7 @@
 #import "ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.h"
 #import "ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.h"
 #import "ios/clean/chrome/browser/ui/tools/tools_coordinator.h"
+#import "ios/shared/chrome/browser/ui/broadcaster/chrome_broadcaster.h"
 #import "ios/shared/chrome/browser/ui/browser_list/browser.h"
 #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h"
@@ -63,6 +64,9 @@
   self.viewController.dispatcher = static_cast<id>(self.browser->dispatcher());
   self.mediator.consumer = self.viewController;
 
+  [self.browser->broadcaster()
+      addObserver:self.mediator
+      forSelector:@selector(broadcastTabStripVisible:)];
   LocationBarCoordinator* locationBarCoordinator =
       [[LocationBarCoordinator alloc] init];
   self.locationBarCoordinator = locationBarCoordinator;
@@ -74,6 +78,9 @@
 
 - (void)stop {
   [super stop];
+  [self.browser->broadcaster()
+      removeObserver:self.mediator
+         forSelector:@selector(broadcastTabStripVisible:)];
   [self.browser->dispatcher() stopDispatchingToTarget:self];
 }
 
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.h b/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.h
index 2afe96d..e6059ed 100644
--- a/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.h
+++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.h
@@ -7,6 +7,8 @@
 
 #import <Foundation/Foundation.h>
 
+#import "ios/shared/chrome/browser/ui/broadcaster/chrome_broadcast_observer.h"
+
 @protocol ToolbarConsumer;
 
 namespace web {
@@ -15,7 +17,7 @@
 
 // A mediator object that provides the relevant properties of a web state
 // to a consumer.
-@interface ToolbarMediator : NSObject
+@interface ToolbarMediator : NSObject<ChromeBroadcastObserver>
 
 // The WebState whose properties this object mediates. This can change during
 // the lifetime of this object and may be null.
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.mm b/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.mm
index 540da63..e082076 100644
--- a/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.mm
+++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator.mm
@@ -52,6 +52,12 @@
   [self.consumer setLoadingProgress:progress];
 }
 
+#pragma mark - ChromeBroadcastObserver
+
+- (void)broadcastTabStripVisible:(BOOL)visible {
+  [self.consumer setTabStripVisible:visible];
+}
+
 #pragma mark - Setters
 
 - (void)setWebState:(web::WebState*)webState {
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm b/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
index 0a0c698..3adcfac4 100644
--- a/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
+++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
@@ -136,4 +136,15 @@
   [[consumer_ verify] setLoadingProgress:0.42];
 }
 
+// Test that the mediator's observation of -broadcastTabStripVisible: triggers
+// the correct consumer calls.
+TEST_F(ToolbarMediatorTest, TestTabStripVisible) {
+  mediator_.consumer = consumer_;
+
+  [mediator_ broadcastTabStripVisible:YES];
+  [[consumer_ verify] setTabStripVisible:YES];
+  [mediator_ broadcastTabStripVisible:NO];
+  [[consumer_ verify] setTabStripVisible:NO];
+}
+
 }  // namespace
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.mm b/ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.mm
index b8b60ca..39b3093 100644
--- a/ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.mm
+++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.mm
@@ -323,6 +323,12 @@
   [self.progressBar setProgress:progress animated:YES completion:nil];
 }
 
+- (void)setTabStripVisible:(BOOL)visible {
+  self.tabSwitchStripButton.hiddenInCurrentState = visible;
+  self.tabSwitchGridButton.hiddenInCurrentState = !visible;
+  [self updateAllButtonsVisibility];
+}
+
 #pragma mark - ZoomTransitionDelegate
 
 - (CGRect)rectForZoomWithKey:(NSObject*)key inView:(UIView*)view {
@@ -364,20 +370,6 @@
   [self.dispatcher showTabGrid];
 }
 
-#pragma mark - TabStripEvents
-
-- (void)tabStripDidShow:(id)sender {
-  self.tabSwitchStripButton.hiddenInCurrentState = YES;
-  self.tabSwitchGridButton.hiddenInCurrentState = NO;
-  [self updateAllButtonsVisibility];
-}
-
-- (void)tabStripDidHide:(id)sender {
-  self.tabSwitchStripButton.hiddenInCurrentState = NO;
-  self.tabSwitchGridButton.hiddenInCurrentState = YES;
-  [self updateAllButtonsVisibility];
-}
-
 #pragma mark - Helper Methods
 
 // Updates all Buttons visibility to match any recent WebState change.
diff --git a/ios/shared/chrome/browser/ui/browser_list/BUILD.gn b/ios/shared/chrome/browser/ui/browser_list/BUILD.gn
index 43231579..489be46 100644
--- a/ios/shared/chrome/browser/ui/browser_list/BUILD.gn
+++ b/ios/shared/chrome/browser/ui/browser_list/BUILD.gn
@@ -29,6 +29,7 @@
     "//ios/chrome/browser/sessions:serialisation",
     "//ios/chrome/browser/ssl",
     "//ios/chrome/browser/web_state_list",
+    "//ios/shared/chrome/browser/ui/broadcaster",
     "//ios/shared/chrome/browser/ui/commands",
     "//ios/web",
   ]
diff --git a/ios/shared/chrome/browser/ui/browser_list/browser.h b/ios/shared/chrome/browser/ui/browser_list/browser.h
index ed09a60..ef6cbb00 100644
--- a/ios/shared/chrome/browser/ui/browser_list/browser.h
+++ b/ios/shared/chrome/browser/ui/browser_list/browser.h
@@ -12,6 +12,7 @@
 class WebStateList;
 class WebStateListDelegate;
 
+@class ChromeBroadcaster;
 @class CommandDispatcher;
 
 namespace ios {
@@ -32,7 +33,10 @@
 
   ios::ChromeBrowserState* browser_state() const { return browser_state_; }
 
+  ChromeBroadcaster* broadcaster() { return broadcaster_; }
+
  private:
+  __strong ChromeBroadcaster* broadcaster_;
   __strong CommandDispatcher* dispatcher_;
   ios::ChromeBrowserState* browser_state_;
   std::unique_ptr<WebStateListDelegate> web_state_list_delegate_;
diff --git a/ios/shared/chrome/browser/ui/browser_list/browser.mm b/ios/shared/chrome/browser/ui/browser_list/browser.mm
index 28de14b4..b80b383 100644
--- a/ios/shared/chrome/browser/ui/browser_list/browser.mm
+++ b/ios/shared/chrome/browser/ui/browser_list/browser.mm
@@ -8,6 +8,7 @@
 #include "base/memory/ptr_util.h"
 
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
+#import "ios/shared/chrome/browser/ui/broadcaster/chrome_broadcaster.h"
 #import "ios/shared/chrome/browser/ui/browser_list/browser_web_state_list_delegate.h"
 #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h"
 
@@ -16,7 +17,8 @@
 #endif
 
 Browser::Browser(ios::ChromeBrowserState* browser_state)
-    : dispatcher_([[CommandDispatcher alloc] init]),
+    : broadcaster_([[ChromeBroadcaster alloc] init]),
+      dispatcher_([[CommandDispatcher alloc] init]),
       browser_state_(browser_state) {
   DCHECK(browser_state_);
   web_state_list_delegate_ =
diff --git a/ios/test/BUILD.gn b/ios/test/BUILD.gn
deleted file mode 100644
index f05c0ec..0000000
--- a/ios/test/BUILD.gn
+++ /dev/null
@@ -1,10 +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.
-
-# This empty target is there to help with upstreaming by removing a manual
-# step from the process (updating the //ios:all target). It will be changed
-# to a real target as part of upstreaming.
-group("all_tests") {
-  testonly = true
-}
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations
index f93ade5..073f458 100644
--- a/third_party/WebKit/LayoutTests/LeakExpectations
+++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -140,10 +140,6 @@
 crbug.com/674858 [ Linux ] virtual/threaded/printing/offscreencanvas-2d-printing.html [ Pass Crash ]
 crbug.com/674858 [ Linux ] virtual/threaded/printing/offscreencanvas-webgl-printing.html [ Pass Crash ]
 
-# Sheriff: Commit causing leak found but non-trivial to revert
-crbug.com/718114 [ Linux ] external/wpt/html/semantics/scripting-1/the-script-element/module/crossorigin.html [ Leak Failure ]
-crbug.com/724818 [ Linux ] external/wpt/html/semantics/scripting-1/the-script-element/module/import-subgraph-404.html [ Leak Failure ]
-
 # New tests revealed existing leak
 crbug.com/726218 [ Linux ] fast/dom/inert/inert-node-is-uneditable.html [ Leak ]
 crbug.com/726218 [ Linux ] fast/dom/inert/inert-inlines.html [ Leak ]
diff --git a/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLCanvasElement.html b/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLCanvasElement.html
index f5f692c..161df617 100644
--- a/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLCanvasElement.html
+++ b/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLCanvasElement.html
@@ -7,14 +7,13 @@
 <script src="resources/mock-textdetection.js"></script>
 <script>
 
-var createTestForCanvasElement = function(createDetector,
-                                          createCanvas,
-                                          mockReady,
-                                          detectionResultTest) {
-  async_test(function(t) {
-
-    var img = new Image();
-    img.onload = function() {
+function detectShapeForCanvas(createDetector,
+                              createCanvas,
+                              mockReady,
+                              detectionResultTest) {
+  return new Promise(function(resolve, reject) {
+      var img = new Image();
+      img.onload = function() {
 
       var canvas = createCanvas();
       canvas.getContext("2d").drawImage(img, 0, 0);
@@ -34,14 +33,29 @@
         })
         .then(detectionResult => {
           detectionResultTest(detectionResult, theMock);
-          t.done();
+          resolve("Success");
         })
         .catch(error => {
           assert_unreached("Error during detect(canvas): " + error);
         });
-    }
+      }
 
-    img.src = "../media/content/greenbox.png";
+      img.src = "../media/content/greenbox.png";
+  });
+}
+
+var createTestForCanvasElement = function(createDetector,
+                                          createCanvas,
+                                          mockReady,
+                                          detectionResultTest) {
+  promise_test(function() {
+    return detectShapeForCanvas(createDetector,
+                                createCanvas,
+                                mockReady,
+                                detectionResultTest)
+        .then(function(result) {
+            assert_equals(result, "Success", "Detect 'Success'");
+        });
   });
 };
 
diff --git a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js
index f7dd350..d117ee0 100644
--- a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js
+++ b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js
@@ -20,19 +20,19 @@
     }
 
     createFaceDetection(request, options) {
-      this.mock_service_ = new MockFaceDetection(request, options);
+      this.mockService_ = new MockFaceDetection(request, options);
     }
 
     getFrameData() {
-      return this.mock_service_.buffer_data_;
+      return this.mockService_.bufferData_;
     }
 
     getMaxDetectedFaces() {
-     return this.mock_service_.maxDetectedFaces_;
+     return this.mockService_.maxDetectedFaces_;
     }
 
     getFastMode () {
-      return this.mock_service_.fastMode_;
+      return this.mockService_.fastMode_;
     }
   }
 
@@ -46,7 +46,7 @@
 
     detect(frame_data, width, height) {
       let receivedStruct = mojo.mapBuffer(frame_data, 0, width*height*4, 0);
-      this.buffer_data_ = new Uint32Array(receivedStruct.buffer);
+      this.bufferData_ = new Uint32Array(receivedStruct.buffer);
       return Promise.resolve({
         results: [
           {
diff --git a/third_party/WebKit/Source/bindings/bindings.gni b/third_party/WebKit/Source/bindings/bindings.gni
index 3b1a6e8..f74196ac 100644
--- a/third_party/WebKit/Source/bindings/bindings.gni
+++ b/third_party/WebKit/Source/bindings/bindings.gni
@@ -152,7 +152,6 @@
                     "core/v8/V8PagePopupControllerBinding.cpp",
                     "core/v8/V8PagePopupControllerBinding.h",
                     "core/v8/V8PersistentValueVector.h",
-                    "core/v8/V8ResizeObserverCallbackCustom.cpp",
                     "core/v8/V8ScriptRunner.cpp",
                     "core/v8/V8ScriptRunner.h",
                     "core/v8/V8StringResource.h",
diff --git a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
index 329c32e2..b723540 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
+++ b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -271,6 +271,8 @@
   "$bindings_core_v8_output_dir/MojoWatchCallback.h",
   "$bindings_core_v8_output_dir/PerformanceObserverCallback.cpp",
   "$bindings_core_v8_output_dir/PerformanceObserverCallback.h",
+  "$bindings_core_v8_output_dir/ResizeObserverCallback.cpp",
+  "$bindings_core_v8_output_dir/ResizeObserverCallback.h",
 ]
 
 if (is_win) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ResizeObserverCallbackCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/V8ResizeObserverCallbackCustom.cpp
deleted file mode 100644
index ae63645..0000000
--- a/third_party/WebKit/Source/bindings/core/v8/V8ResizeObserverCallbackCustom.cpp
+++ /dev/null
@@ -1,53 +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 "bindings/core/v8/V8ResizeObserverCallback.h"
-
-#include "bindings/core/v8/ScriptController.h"
-#include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8ResizeObserver.h"
-#include "bindings/core/v8/V8ResizeObserverEntry.h"
-#include "core/dom/ExecutionContext.h"
-
-namespace blink {
-
-void V8ResizeObserverCallback::handleEvent(
-    const HeapVector<Member<ResizeObserverEntry>>& entries,
-    ResizeObserver* observer) {
-  v8::Isolate* isolate = script_state_->GetIsolate();
-  ExecutionContext* execution_context =
-      ExecutionContext::From(script_state_.Get());
-  if (!execution_context || execution_context->IsContextSuspended() ||
-      execution_context->IsContextDestroyed())
-    return;
-  if (!script_state_->ContextIsValid())
-    return;
-  ScriptState::Scope scope(script_state_.Get());
-
-  if (callback_.IsEmpty())
-    return;
-
-  v8::Local<v8::Value> observer_handle =
-      ToV8(observer, script_state_->GetContext()->Global(),
-           script_state_->GetIsolate());
-  if (!observer_handle->IsObject())
-    return;
-
-  v8::Local<v8::Object> this_object =
-      v8::Local<v8::Object>::Cast(observer_handle);
-  v8::Local<v8::Value> entries_handle =
-      ToV8(entries, script_state_->GetContext()->Global(),
-           script_state_->GetIsolate());
-  if (entries_handle.IsEmpty())
-    return;
-  v8::Local<v8::Value> argv[] = {entries_handle, observer_handle};
-
-  v8::TryCatch exception_catcher(script_state_->GetIsolate());
-  exception_catcher.SetVerbose(true);
-  V8ScriptRunner::CallFunction(
-      callback_.NewLocal(isolate), ExecutionContext::From(script_state_.Get()),
-      this_object, WTF_ARRAY_LENGTH(argv), argv, isolate);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/core_idl_files.gni b/third_party/WebKit/Source/core/core_idl_files.gni
index b72fa9f..9dad1a5 100644
--- a/third_party/WebKit/Source/core/core_idl_files.gni
+++ b/third_party/WebKit/Source/core/core_idl_files.gni
@@ -134,7 +134,6 @@
                                  "dom/ProcessingInstruction.idl",
                                  "dom/Range.idl",
                                  "dom/ResizeObserver.idl",
-                                 "dom/ResizeObserverCallback.idl",
                                  "dom/ResizeObserverEntry.idl",
                                  "dom/SharedArrayBuffer.idl",
                                  "dom/StaticRange.idl",
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index 91e2a87..37a14173 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -874,39 +874,6 @@
 }
 
 template <>
-inline CSSIdentifierValue::CSSIdentifierValue(Hyphens e)
-    : CSSValue(kIdentifierClass) {
-  switch (e) {
-    case Hyphens::kAuto:
-      value_id_ = CSSValueAuto;
-      break;
-    case Hyphens::kManual:
-      value_id_ = CSSValueManual;
-      break;
-    case Hyphens::kNone:
-      value_id_ = CSSValueNone;
-      break;
-  }
-}
-
-template <>
-inline Hyphens CSSIdentifierValue::ConvertTo() const {
-  switch (value_id_) {
-    case CSSValueAuto:
-      return Hyphens::kAuto;
-    case CSSValueManual:
-      return Hyphens::kManual;
-    case CSSValueNone:
-      return Hyphens::kNone;
-    default:
-      break;
-  }
-
-  NOTREACHED();
-  return Hyphens::kManual;
-}
-
-template <>
 inline CSSIdentifierValue::CSSIdentifierValue(LineBreak e)
     : CSSValue(kIdentifierClass) {
   switch (e) {
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index b70224a..c0d189ac 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -1272,10 +1272,10 @@
       name: "hyphens",
       inherited: true,
       runtime_flag: "CSSHyphens",
-      field_template: "storage_only",
+      field_template: "keyword",
       type_name: "Hyphens",
-      default_value: "Hyphens::kManual",
-      field_size: 2,
+      keywords: ["none", "manual", "auto"],
+      default_value: "manual",
       field_group: "rare-inherited",
     },
     {
@@ -2424,7 +2424,7 @@
       converter: "ConvertString<CSSValueAuto>",
       inherited: true,
       name_for_methods: "HyphenationString",
-      field_template: "storage_only",
+      field_template: "external",
       type_name: "AtomicString",
       include_paths: ["platform/wtf/text/AtomicString.h"],
       default_value: "AtomicString()",
diff --git a/third_party/WebKit/Source/core/dom/BUILD.gn b/third_party/WebKit/Source/core/dom/BUILD.gn
index 4a34c98..02d3b94f 100644
--- a/third_party/WebKit/Source/core/dom/BUILD.gn
+++ b/third_party/WebKit/Source/core/dom/BUILD.gn
@@ -271,7 +271,6 @@
     "ResizeObservation.h",
     "ResizeObserver.cpp",
     "ResizeObserver.h",
-    "ResizeObserverCallback.h",
     "ResizeObserverController.cpp",
     "ResizeObserverController.h",
     "ResizeObserverEntry.cpp",
diff --git a/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp b/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp
index 5d43e9b..0bbce98 100644
--- a/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp
+++ b/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp
@@ -31,7 +31,9 @@
       map_(this, ModuleMap::Create(this)),
       loader_registry_(ModuleScriptLoaderRegistry::Create()),
       tree_linker_registry_(ModuleTreeLinkerRegistry::Create()),
-      script_module_resolver_(ScriptModuleResolverImpl::Create(this)) {
+      script_module_resolver_(ScriptModuleResolverImpl::Create(
+          this,
+          ExecutionContext::From(script_state_.Get()))) {
   DCHECK(script_state_);
   DCHECK(task_runner_);
   DCHECK(fetcher_);
diff --git a/third_party/WebKit/Source/core/dom/ResizeObserver.cpp b/third_party/WebKit/Source/core/dom/ResizeObserver.cpp
index 61556cb..3a5c57b 100644
--- a/third_party/WebKit/Source/core/dom/ResizeObserver.cpp
+++ b/third_party/WebKit/Source/core/dom/ResizeObserver.cpp
@@ -4,9 +4,9 @@
 
 #include "core/dom/ResizeObserver.h"
 
+#include "bindings/core/v8/ResizeObserverCallback.h"
 #include "core/dom/Element.h"
 #include "core/dom/ResizeObservation.h"
-#include "core/dom/ResizeObserverCallback.h"
 #include "core/dom/ResizeObserverController.h"
 #include "core/dom/ResizeObserverEntry.h"
 #include "core/frame/LocalFrameView.h"
@@ -18,11 +18,26 @@
   return new ResizeObserver(callback, document);
 }
 
+ResizeObserver* ResizeObserver::Create(Document& document, Delegate* delegate) {
+  return new ResizeObserver(delegate, document);
+}
+
 ResizeObserver::ResizeObserver(ResizeObserverCallback* callback,
                                Document& document)
-    : callback_(callback),
+    : callback_(this, callback),
       skipped_observations_(false),
       element_size_changed_(false) {
+  DCHECK(callback_);
+  controller_ = &document.EnsureResizeObserverController();
+  controller_->AddObserver(*this);
+}
+
+ResizeObserver::ResizeObserver(Delegate* delegate, Document& document)
+    : callback_(this, nullptr),
+      delegate_(delegate),
+      skipped_observations_(false),
+      element_size_changed_(false) {
+  DCHECK(delegate_);
   controller_ = &document.EnsureResizeObserverController();
   controller_->AddObserver(*this);
 }
@@ -100,7 +115,11 @@
                                          LayoutRect(location, size));
     entries.push_back(entry);
   }
-  callback_->handleEvent(entries, this);
+  DCHECK(callback_ || delegate_);
+  if (callback_)
+    callback_->call(this, entries, this);
+  if (delegate_)
+    delegate_->OnResize(entries);
   ClearObservations();
 }
 
@@ -117,9 +136,14 @@
 
 DEFINE_TRACE(ResizeObserver) {
   visitor->Trace(callback_);
+  visitor->Trace(delegate_);
   visitor->Trace(observations_);
   visitor->Trace(active_observations_);
   visitor->Trace(controller_);
 }
 
+DEFINE_TRACE_WRAPPERS(ResizeObserver) {
+  visitor->TraceWrappers(callback_);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/ResizeObserver.h b/third_party/WebKit/Source/core/dom/ResizeObserver.h
index 2de6880..8aab9882 100644
--- a/third_party/WebKit/Source/core/dom/ResizeObserver.h
+++ b/third_party/WebKit/Source/core/dom/ResizeObserver.h
@@ -7,6 +7,7 @@
 
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
+#include "platform/bindings/TraceWrapperMember.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -15,6 +16,7 @@
 class Element;
 class ResizeObserverCallback;
 class ResizeObserverController;
+class ResizeObserverEntry;
 class ResizeObservation;
 
 // ResizeObserver represents ResizeObserver javascript api:
@@ -25,7 +27,17 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  // This delegate is an internal (non-web-exposed) version of ResizeCallback.
+  class Delegate : public GarbageCollectedFinalized<Delegate> {
+   public:
+    virtual ~Delegate() = default;
+    virtual void OnResize(
+        const HeapVector<Member<ResizeObserverEntry>>& entries) = 0;
+    DEFINE_INLINE_VIRTUAL_TRACE() {}
+  };
+
   static ResizeObserver* Create(Document&, ResizeObserverCallback*);
+  static ResizeObserver* Create(Document&, Delegate*);
 
   virtual ~ResizeObserver(){};
 
@@ -42,13 +54,18 @@
   void ElementSizeChanged();
   bool HasElementSizeChanged() { return element_size_changed_; }
   DECLARE_TRACE();
+  DECLARE_TRACE_WRAPPERS();
 
  private:
   ResizeObserver(ResizeObserverCallback*, Document&);
+  ResizeObserver(Delegate*, Document&);
 
   using ObservationList = HeapLinkedHashSet<WeakMember<ResizeObservation>>;
 
-  Member<ResizeObserverCallback> callback_;
+  // Either of |callback_| and |delegate_| should be non-null.
+  const TraceWrapperMember<ResizeObserverCallback> callback_;
+  const Member<Delegate> delegate_;
+
   // List of elements we are observing
   ObservationList observations_;
   // List of elements that have changes
diff --git a/third_party/WebKit/Source/core/dom/ResizeObserver.idl b/third_party/WebKit/Source/core/dom/ResizeObserver.idl
index 2239368..b8acec1 100644
--- a/third_party/WebKit/Source/core/dom/ResizeObserver.idl
+++ b/third_party/WebKit/Source/core/dom/ResizeObserver.idl
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://wicg.github.io/ResizeObserver/#resize-observer-callback
+
+callback ResizeObserverCallback = void (sequence<ResizeObserverEntry> entries, ResizeObserver observer);
+
 // https://wicg.github.io/ResizeObserver/#resize-observer-interface
 
 [
diff --git a/third_party/WebKit/Source/core/dom/ResizeObserverCallback.h b/third_party/WebKit/Source/core/dom/ResizeObserverCallback.h
deleted file mode 100644
index f10c4ff..0000000
--- a/third_party/WebKit/Source/core/dom/ResizeObserverCallback.h
+++ /dev/null
@@ -1,27 +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 ResizeObserverCallback_h
-#define ResizeObserverCallback_h
-
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-class ResizeObserver;
-class ResizeObserverEntry;
-
-class ResizeObserverCallback
-    : public GarbageCollectedFinalized<ResizeObserverCallback> {
- public:
-  virtual ~ResizeObserverCallback() {}
-  virtual void handleEvent(
-      const HeapVector<Member<ResizeObserverEntry>>& entries,
-      ResizeObserver*) = 0;
-  DEFINE_INLINE_VIRTUAL_TRACE() {}
-};
-
-}  // namespace blink
-
-#endif  // ResizeObserverCallback_h
diff --git a/third_party/WebKit/Source/core/dom/ResizeObserverCallback.idl b/third_party/WebKit/Source/core/dom/ResizeObserverCallback.idl
deleted file mode 100644
index 7d84657..0000000
--- a/third_party/WebKit/Source/core/dom/ResizeObserverCallback.idl
+++ /dev/null
@@ -1,9 +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.
-
-// https://wicg.github.io/ResizeObserver/#resize-observer-callback
-
-callback interface ResizeObserverCallback {
-    [Custom] void handleEvent(sequence<ResizeObserverEntry> entries, ResizeObserver observer);
-};
diff --git a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.cpp b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.cpp
index 71f082c..4366cf0 100644
--- a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.cpp
@@ -81,8 +81,15 @@
   return record;
 }
 
+void ScriptModuleResolverImpl::ContextDestroyed(ExecutionContext*) {
+  // crbug.com/725816 : What we should really do is to make the map key
+  // weak reference to v8::Module.
+  record_to_module_script_map_.clear();
+}
+
 DEFINE_TRACE(ScriptModuleResolverImpl) {
   ScriptModuleResolver::Trace(visitor);
+  ContextLifecycleObserver::Trace(visitor);
   visitor->Trace(record_to_module_script_map_);
   visitor->Trace(modulator_);
 }
diff --git a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.h b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.h
index 2b9429b..008929f 100644
--- a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.h
+++ b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.h
@@ -7,6 +7,7 @@
 
 #include "bindings/core/v8/ScriptModule.h"
 #include "core/CoreExport.h"
+#include "core/dom/ContextLifecycleObserver.h"
 #include "core/dom/ScriptModuleResolver.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/HashMap.h"
@@ -21,28 +22,40 @@
 // The ScriptModuleResolverImpl implements ScriptModuleResolver interface
 // and implements "HostResolveImportedModule" HTML spec algorithm to bridge
 // ModuleMap (via Modulator) and V8 bindings.
-class CORE_EXPORT ScriptModuleResolverImpl final : public ScriptModuleResolver {
+class CORE_EXPORT ScriptModuleResolverImpl final
+    : public ScriptModuleResolver,
+      public ContextLifecycleObserver {
  public:
-  static ScriptModuleResolverImpl* Create(Modulator* modulator) {
-    return new ScriptModuleResolverImpl(modulator);
+  static ScriptModuleResolverImpl* Create(Modulator* modulator,
+                                          ExecutionContext* execution_context) {
+    return new ScriptModuleResolverImpl(modulator, execution_context);
   }
 
   DECLARE_VIRTUAL_TRACE();
+  USING_GARBAGE_COLLECTED_MIXIN(ScriptModuleResolverImpl);
+
+ private:
+  explicit ScriptModuleResolverImpl(Modulator* modulator,
+                                    ExecutionContext* execution_context)
+      : ContextLifecycleObserver(execution_context), modulator_(modulator) {}
 
   // Implements ScriptModuleResolver:
 
-  void RegisterModuleScript(ModuleScript*) override;
+  void RegisterModuleScript(ModuleScript*) final;
   // Implements "Runtime Semantics: HostResolveImportedModule" per HTML spec.
   // https://html.spec.whatwg.org/#hostresolveimportedmodule(referencingmodule,-specifier)
   ScriptModule Resolve(const String& specifier,
                        const ScriptModule& referrer,
-                       ExceptionState&) override;
+                       ExceptionState&) final;
 
- private:
-  explicit ScriptModuleResolverImpl(Modulator* modulator)
-      : modulator_(modulator) {}
+  // Implements ContextLifecycleObserver:
+  void ContextDestroyed(ExecutionContext*) final;
 
   // Corresponds to the spec concept "referencingModule.[[HostDefined]]".
+  // crbug.com/725816 : ScriptModule contains strong ref to v8::Module thus we
+  // should not use ScriptModule as the map key. We currently rely on Detach()
+  // to clear the refs, but we should implement a key type which keeps a
+  // weak-ref to v8::Module.
   HeapHashMap<ScriptModule, Member<ModuleScript>> record_to_module_script_map_;
   Member<Modulator> modulator_;
 };
diff --git a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp
index b93bb84..e3fdc20 100644
--- a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp
@@ -129,9 +129,9 @@
 }
 
 TEST_F(ScriptModuleResolverImplTest, RegisterResolveSuccess) {
-  ScriptModuleResolverImpl* resolver =
-      ScriptModuleResolverImpl::Create(Modulator());
   V8TestingScope scope;
+  ScriptModuleResolver* resolver = ScriptModuleResolverImpl::Create(
+      Modulator(), scope.GetExecutionContext());
   Modulator()->SetScriptState(scope.GetScriptState());
 
   ModuleScript* referrer_module_script =
@@ -153,9 +153,9 @@
 }
 
 TEST_F(ScriptModuleResolverImplTest, ResolveInvalidModuleSpecifier) {
-  ScriptModuleResolverImpl* resolver =
-      ScriptModuleResolverImpl::Create(Modulator());
   V8TestingScope scope;
+  ScriptModuleResolver* resolver = ScriptModuleResolverImpl::Create(
+      Modulator(), scope.GetExecutionContext());
   Modulator()->SetScriptState(scope.GetScriptState());
 
   ModuleScript* referrer_module_script =
@@ -175,9 +175,9 @@
 }
 
 TEST_F(ScriptModuleResolverImplTest, ResolveLoadFailedModule) {
-  ScriptModuleResolverImpl* resolver =
-      ScriptModuleResolverImpl::Create(Modulator());
   V8TestingScope scope;
+  ScriptModuleResolver* resolver = ScriptModuleResolverImpl::Create(
+      Modulator(), scope.GetExecutionContext());
   Modulator()->SetScriptState(scope.GetScriptState());
 
   ModuleScript* referrer_module_script =
@@ -202,9 +202,9 @@
 }
 
 TEST_F(ScriptModuleResolverImplTest, ResolveInstantiationFailedModule) {
-  ScriptModuleResolverImpl* resolver =
-      ScriptModuleResolverImpl::Create(Modulator());
   V8TestingScope scope;
+  ScriptModuleResolver* resolver = ScriptModuleResolverImpl::Create(
+      Modulator(), scope.GetExecutionContext());
   Modulator()->SetScriptState(scope.GetScriptState());
 
   ModuleScript* referrer_module_script =
diff --git a/third_party/WebKit/Source/core/html/track/TextTrackContainer.cpp b/third_party/WebKit/Source/core/html/track/TextTrackContainer.cpp
index 5a867c6..3a96fa2 100644
--- a/third_party/WebKit/Source/core/html/track/TextTrackContainer.cpp
+++ b/third_party/WebKit/Source/core/html/track/TextTrackContainer.cpp
@@ -30,7 +30,6 @@
 #include "core/html/track/TextTrackContainer.h"
 
 #include "core/dom/ResizeObserver.h"
-#include "core/dom/ResizeObserverCallback.h"
 #include "core/dom/ResizeObserverEntry.h"
 #include "core/html/HTMLVideoElement.h"
 #include "core/html/track/CueTimeline.h"
@@ -41,13 +40,13 @@
 
 namespace {
 
-class VideoElementResizeCallback final : public ResizeObserverCallback {
+class VideoElementResizeDelegate final : public ResizeObserver::Delegate {
  public:
-  VideoElementResizeCallback(TextTrackContainer& container)
-      : ResizeObserverCallback(), text_track_container_(container) {}
+  VideoElementResizeDelegate(TextTrackContainer& container)
+      : ResizeObserver::Delegate(), text_track_container_(container) {}
 
-  void handleEvent(const HeapVector<Member<ResizeObserverEntry>>& entries,
-                   ResizeObserver*) override {
+  void OnResize(
+      const HeapVector<Member<ResizeObserverEntry>>& entries) override {
     DCHECK_EQ(entries.size(), 1u);
     DCHECK(isHTMLVideoElement(entries[0]->target()));
     text_track_container_->UpdateDefaultFontSize(
@@ -56,7 +55,7 @@
 
   DEFINE_INLINE_VIRTUAL_TRACE() {
     visitor->Trace(text_track_container_);
-    ResizeObserverCallback::Trace(visitor);
+    ResizeObserver::Delegate::Trace(visitor);
   }
 
  private:
@@ -90,7 +89,7 @@
 
 void TextTrackContainer::ObserveSizeChanges(Element& element) {
   video_size_observer_ = ResizeObserver::Create(
-      GetDocument(), new VideoElementResizeCallback(*this));
+      GetDocument(), new VideoElementResizeDelegate(*this));
   video_size_observer_->observe(&element);
 }
 
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index e890cf3..3d103410 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -1647,24 +1647,6 @@
   static Color InitialColor() { return Color::kBlack; }
   void SetColor(const Color&);
 
-  // hyphens
-  static Hyphens InitialHyphens() { return Hyphens::kManual; }
-  Hyphens GetHyphens() const {
-    return static_cast<Hyphens>(rare_inherited_data_->hyphens_);
-  }
-  void SetHyphens(Hyphens h) {
-    SET_VAR(rare_inherited_data_, hyphens_, static_cast<unsigned>(h));
-  }
-
-  // -webkit-hyphenate-character
-  static const AtomicString& InitialHyphenationString() { return g_null_atom; }
-  const AtomicString& HyphenationString() const {
-    return rare_inherited_data_->hyphenation_string_;
-  }
-  void SetHyphenationString(const AtomicString& h) {
-    SET_VAR(rare_inherited_data_, hyphenation_string_, h);
-  }
-
   // line-height
   static Length InitialLineHeight() { return Length(-100.0, kPercent); }
   Length LineHeight() const;
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index 344ae1a..67a66e0 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -275,8 +275,6 @@
 
 enum ELineClampType { kLineClampLineCount, kLineClampPercentage };
 
-enum class Hyphens { kNone, kManual, kAuto };
-
 enum class TextEmphasisFill { kFilled, kOpen };
 
 enum class TextEmphasisMark {
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorklet.cpp b/third_party/WebKit/Source/core/workers/MainThreadWorklet.cpp
index 43ac128..cdec9960 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorklet.cpp
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorklet.cpp
@@ -33,6 +33,13 @@
 
 MainThreadWorklet::MainThreadWorklet(LocalFrame* frame) : Worklet(frame) {}
 
+WorkletGlobalScopeProxy* MainThreadWorklet::FindAvailableGlobalScope() const {
+  DCHECK(IsMainThread());
+  // TODO(nhiroki): Support the case where there are multiple global scopes.
+  DCHECK_EQ(1u, GetNumberOfGlobalScopes());
+  return proxies_.begin()->get();
+}
+
 // Implementation of the second half of the "addModule(moduleURL, options)"
 // algorithm:
 // https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule
@@ -67,15 +74,14 @@
   //   10.2: "Add the WorkletGlobalScope to worklet's WorkletGlobalScopes."
   // "Depending on the type of worklet the user agent may create additional
   // WorkletGlobalScopes at this time."
-  // TODO(nhiroki): Create WorkletGlobalScopes at this point.
+  while (NeedsToCreateGlobalScope())
+    proxies_.insert(CreateGlobalScope());
+  DCHECK_EQ(1u, GetNumberOfGlobalScopes());
 
   // Step 11: "Let pendingTaskStruct be a new pending tasks struct with counter
   // initialized to the length of worklet's WorkletGlobalScopes."
-  // TODO(nhiroki): Introduce the concept of "worklet's WorkletGlobalScopes" and
-  // use the length of it here.
-  constexpr int number_of_global_scopes = 1;
   WorkletPendingTasks* pending_tasks =
-      new WorkletPendingTasks(number_of_global_scopes, resolver);
+      new WorkletPendingTasks(GetNumberOfGlobalScopes(), resolver);
 
   // Step 12: "For each workletGlobalScope in the worklet's
   // WorkletGlobalScopes, queue a task on the workletGlobalScope to fetch and
@@ -83,13 +89,16 @@
   // moduleResponsesMap, credentialOptions, outsideSettings, pendingTaskStruct,
   // and promise."
   // TODO(nhiroki): Queue a task instead of executing this here.
-  GetWorkletGlobalScopeProxy()->FetchAndInvokeScript(
-      module_url_record, credentials_mode, pending_tasks);
+  for (const auto& proxy : proxies_) {
+    proxy->FetchAndInvokeScript(module_url_record, credentials_mode,
+                                pending_tasks);
+  }
 }
 
 void MainThreadWorklet::ContextDestroyed(ExecutionContext* execution_context) {
   DCHECK(IsMainThread());
-  GetWorkletGlobalScopeProxy()->TerminateWorkletGlobalScope();
+  for (const auto& proxy : proxies_)
+    proxy->TerminateWorkletGlobalScope();
 }
 
 DEFINE_TRACE(MainThreadWorklet) {
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorklet.h b/third_party/WebKit/Source/core/workers/MainThreadWorklet.h
index 998ab29..72b1bc6 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorklet.h
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorklet.h
@@ -15,6 +15,7 @@
 
 class LocalFrame;
 class ScriptPromiseResolver;
+class WorkletGlobalScopeProxy;
 
 // A MainThreadWorklet is a worklet that runs only on the main thread.
 // TODO(nhiroki): This is a temporary class to support module loading for main
@@ -35,11 +36,30 @@
  protected:
   explicit MainThreadWorklet(LocalFrame*);
 
+  // Returns one of available global scopes.
+  WorkletGlobalScopeProxy* FindAvailableGlobalScope() const;
+
+  size_t GetNumberOfGlobalScopes() const { return proxies_.size(); }
+
  private:
   // Worklet.
   void FetchAndInvokeScript(const KURL& module_url_record,
                             const WorkletOptions&,
                             ScriptPromiseResolver*) override;
+
+  // Returns true if there are no global scopes or additional global scopes are
+  // necessary. CreateGlobalScope() will be called in that case. Each worklet
+  // can define how to pool global scopes here.
+  virtual bool NeedsToCreateGlobalScope() = 0;
+  virtual std::unique_ptr<WorkletGlobalScopeProxy> CreateGlobalScope() = 0;
+
+  // "A Worklet has a list of the worklet's WorkletGlobalScopes. Initially this
+  // list is empty; it is populated when the user agent chooses to create its
+  // WorkletGlobalScope."
+  // https://drafts.css-houdini.org/worklets/#worklet-section
+  // TODO(nhiroki): Make (Paint)WorkletGlobalScopeProxy GC-managed object to
+  // avoid that GC graphs are disjointed (https://crbug.com/719775).
+  HashSet<std::unique_ptr<WorkletGlobalScopeProxy>> proxies_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorklet.h b/third_party/WebKit/Source/core/workers/ThreadedWorklet.h
index 7a4fb4f..b41a955 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorklet.h
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorklet.h
@@ -15,6 +15,7 @@
 namespace blink {
 
 class LocalFrame;
+class WorkletGlobalScopeProxy;
 
 // A ThreadedWorklet is a worklet that runs off the main thread.
 // TODO(nhiroki): This is a temporary class to keep classic script loading for
@@ -36,6 +37,9 @@
   // ContextLifecycleObserver
   void ContextDestroyed(ExecutionContext*) final;
 
+  // Returns a proxy to WorkletGlobalScope on the context thread.
+  virtual WorkletGlobalScopeProxy* GetWorkletGlobalScopeProxy() const = 0;
+
   DECLARE_VIRTUAL_TRACE();
 
  protected:
diff --git a/third_party/WebKit/Source/core/workers/Worklet.h b/third_party/WebKit/Source/core/workers/Worklet.h
index 0ca938eb..7c2c2f2 100644
--- a/third_party/WebKit/Source/core/workers/Worklet.h
+++ b/third_party/WebKit/Source/core/workers/Worklet.h
@@ -16,7 +16,6 @@
 
 class LocalFrame;
 class ScriptPromiseResolver;
-class WorkletGlobalScopeProxy;
 
 // This is the base implementation of Worklet interface defined in the spec:
 // https://drafts.css-houdini.org/worklets/#worklet
@@ -38,9 +37,6 @@
                                   const String& module_url,
                                   const WorkletOptions&);
 
-  // Returns a proxy to WorkletGlobalScope on the context thread.
-  virtual WorkletGlobalScopeProxy* GetWorkletGlobalScopeProxy() const = 0;
-
   DECLARE_VIRTUAL_TRACE();
 
  protected:
diff --git a/third_party/WebKit/Source/modules/csspaint/BUILD.gn b/third_party/WebKit/Source/modules/csspaint/BUILD.gn
index 1ffa5c80..689cd693 100644
--- a/third_party/WebKit/Source/modules/csspaint/BUILD.gn
+++ b/third_party/WebKit/Source/modules/csspaint/BUILD.gn
@@ -19,6 +19,8 @@
     "PaintWorkletGlobalScope.h",
     "PaintWorkletGlobalScopeProxy.cpp",
     "PaintWorkletGlobalScopeProxy.h",
+    "PaintWorkletPendingGeneratorRegistry.cpp",
+    "PaintWorkletPendingGeneratorRegistry.h",
     "WindowPaintWorklet.cpp",
     "WindowPaintWorklet.h",
   ]
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorklet.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorklet.cpp
index 5631ede6..063effb 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorklet.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorklet.cpp
@@ -18,26 +18,43 @@
 
 PaintWorklet::PaintWorklet(LocalFrame* frame)
     : MainThreadWorklet(frame),
-      global_scope_proxy_(
-          WTF::MakeUnique<PaintWorkletGlobalScopeProxy>(frame)) {}
+      pending_generator_registry_(new PaintWorkletPendingGeneratorRegistry) {}
 
 PaintWorklet::~PaintWorklet() = default;
 
-WorkletGlobalScopeProxy* PaintWorklet::GetWorkletGlobalScopeProxy() const {
-  return global_scope_proxy_.get();
-}
-
 CSSPaintDefinition* PaintWorklet::FindDefinition(const String& name) {
-  return global_scope_proxy_->FindDefinition(name);
+  if (GetNumberOfGlobalScopes() == 0)
+    return nullptr;
+
+  PaintWorkletGlobalScopeProxy* proxy =
+      PaintWorkletGlobalScopeProxy::From(FindAvailableGlobalScope());
+  return proxy->FindDefinition(name);
 }
 
 void PaintWorklet::AddPendingGenerator(const String& name,
                                        CSSPaintImageGeneratorImpl* generator) {
-  return global_scope_proxy_->AddPendingGenerator(name, generator);
+  pending_generator_registry_->AddPendingGenerator(name, generator);
 }
 
 DEFINE_TRACE(PaintWorklet) {
+  visitor->Trace(pending_generator_registry_);
   MainThreadWorklet::Trace(visitor);
 }
 
+bool PaintWorklet::NeedsToCreateGlobalScope() {
+  // "The user agent must have, and select from at least two
+  // PaintWorkletGlobalScopes in the worklet's WorkletGlobalScopes list, unless
+  // the user agent is under memory constraints."
+  // https://drafts.css-houdini.org/css-paint-api-1/#drawing-an-image
+  // TODO(nhiroki): In the current impl, we create only one global scope. We
+  // should create at least two global scopes as the spec.
+  return !GetNumberOfGlobalScopes();
+}
+
+std::unique_ptr<WorkletGlobalScopeProxy> PaintWorklet::CreateGlobalScope() {
+  return WTF::MakeUnique<PaintWorkletGlobalScopeProxy>(
+      ToDocument(GetExecutionContext())->GetFrame(),
+      pending_generator_registry_);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorklet.h b/third_party/WebKit/Source/modules/csspaint/PaintWorklet.h
index 59c61e5..35848ae4 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorklet.h
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorklet.h
@@ -8,6 +8,7 @@
 #include "core/workers/MainThreadWorklet.h"
 #include "modules/ModulesExport.h"
 #include "modules/csspaint/PaintWorkletGlobalScopeProxy.h"
+#include "modules/csspaint/PaintWorkletPendingGeneratorRegistry.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -24,17 +25,25 @@
   static PaintWorklet* Create(LocalFrame*);
   ~PaintWorklet() override;
 
-  WorkletGlobalScopeProxy* GetWorkletGlobalScopeProxy() const final;
   CSSPaintDefinition* FindDefinition(const String& name);
   void AddPendingGenerator(const String& name, CSSPaintImageGeneratorImpl*);
 
   DECLARE_VIRTUAL_TRACE();
 
  private:
+  friend class PaintWorkletTest;
+
   explicit PaintWorklet(LocalFrame*);
 
-  // TODO(nhiroki): Make (Paint)WorkletGlobalScopeProxy GC-managed object.
-  std::unique_ptr<PaintWorkletGlobalScopeProxy> global_scope_proxy_;
+  // Implements MainThreadWorklet.
+  bool NeedsToCreateGlobalScope() final;
+  std::unique_ptr<WorkletGlobalScopeProxy> CreateGlobalScope() final;
+
+  Member<PaintWorkletPendingGeneratorRegistry> pending_generator_registry_;
+
+  // TODO(style-dev): Implement the "document paint definition" concept:
+  // https://drafts.css-houdini.org/css-paint-api/#document-paint-definition
+  // (https://crbug.com/578252)
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp
index 20c8688..253e2149 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp
@@ -23,10 +23,12 @@
     const KURL& url,
     const String& user_agent,
     PassRefPtr<SecurityOrigin> security_origin,
-    v8::Isolate* isolate) {
+    v8::Isolate* isolate,
+    PaintWorkletPendingGeneratorRegistry* pending_generator_registry) {
   PaintWorkletGlobalScope* paint_worklet_global_scope =
       new PaintWorkletGlobalScope(frame, url, user_agent,
-                                  std::move(security_origin), isolate);
+                                  std::move(security_origin), isolate,
+                                  pending_generator_registry);
   paint_worklet_global_scope->ScriptController()->InitializeContextIfNeeded();
   MainThreadDebugger::Instance()->ContextCreated(
       paint_worklet_global_scope->ScriptController()->GetScriptState(),
@@ -40,22 +42,26 @@
     const KURL& url,
     const String& user_agent,
     PassRefPtr<SecurityOrigin> security_origin,
-    v8::Isolate* isolate)
+    v8::Isolate* isolate,
+    PaintWorkletPendingGeneratorRegistry* pending_generator_registry)
     : MainThreadWorkletGlobalScope(frame,
                                    url,
                                    user_agent,
                                    std::move(security_origin),
-                                   isolate) {}
+                                   isolate),
+      pending_generator_registry_(pending_generator_registry) {}
 
 PaintWorkletGlobalScope::~PaintWorkletGlobalScope() {}
 
 void PaintWorkletGlobalScope::Dispose() {
   MainThreadDebugger::Instance()->ContextWillBeDestroyed(
       ScriptController()->GetScriptState());
+
   // Explicitly clear the paint defininitions to break a reference cycle
   // between them and this global scope.
   paint_definitions_.clear();
 
+  pending_generator_registry_ = nullptr;
   WorkletGlobalScope::Dispose();
 }
 
@@ -193,17 +199,7 @@
       native_invalidation_properties, custom_invalidation_properties,
       input_argument_types, has_alpha);
   paint_definitions_.Set(name, definition);
-
-  // Set the definition on any pending generators.
-  GeneratorHashSet* set = pending_generators_.at(name);
-  if (set) {
-    for (const auto& generator : *set) {
-      if (generator) {
-        generator->SetDefinition(definition);
-      }
-    }
-  }
-  pending_generators_.erase(name);
+  pending_generator_registry_->SetDefinition(name, definition);
 }
 
 CSSPaintDefinition* PaintWorkletGlobalScope::FindDefinition(
@@ -211,19 +207,9 @@
   return paint_definitions_.at(name);
 }
 
-void PaintWorkletGlobalScope::AddPendingGenerator(
-    const String& name,
-    CSSPaintImageGeneratorImpl* generator) {
-  Member<GeneratorHashSet>& set =
-      pending_generators_.insert(name, nullptr).stored_value->value;
-  if (!set)
-    set = new GeneratorHashSet;
-  set->insert(generator);
-}
-
 DEFINE_TRACE(PaintWorkletGlobalScope) {
   visitor->Trace(paint_definitions_);
-  visitor->Trace(pending_generators_);
+  visitor->Trace(pending_generator_registry_);
   MainThreadWorkletGlobalScope::Trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.h b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.h
index ce2b683..a2a514b 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.h
@@ -9,12 +9,12 @@
 #include "core/dom/ExecutionContext.h"
 #include "core/workers/MainThreadWorkletGlobalScope.h"
 #include "modules/ModulesExport.h"
+#include "modules/csspaint/PaintWorkletPendingGeneratorRegistry.h"
 #include "platform/graphics/ImageBuffer.h"
 
 namespace blink {
 
 class CSSPaintDefinition;
-class CSSPaintImageGeneratorImpl;
 class ExceptionState;
 
 class MODULES_EXPORT PaintWorkletGlobalScope final
@@ -27,7 +27,8 @@
                                          const KURL&,
                                          const String& user_agent,
                                          PassRefPtr<SecurityOrigin>,
-                                         v8::Isolate*);
+                                         v8::Isolate*,
+                                         PaintWorkletPendingGeneratorRegistry*);
   ~PaintWorkletGlobalScope() override;
   void Dispose() final;
 
@@ -37,7 +38,6 @@
                      ExceptionState&);
 
   CSSPaintDefinition* FindDefinition(const String& name);
-  void AddPendingGenerator(const String& name, CSSPaintImageGeneratorImpl*);
 
   DECLARE_VIRTUAL_TRACE();
 
@@ -46,17 +46,15 @@
                           const KURL&,
                           const String& user_agent,
                           PassRefPtr<SecurityOrigin>,
-                          v8::Isolate*);
+                          v8::Isolate*,
+                          PaintWorkletPendingGeneratorRegistry*);
 
+  // The implementation of the "paint definition" concept:
+  // https://drafts.css-houdini.org/css-paint-api/#paint-definition
   typedef HeapHashMap<String, Member<CSSPaintDefinition>> DefinitionMap;
   DefinitionMap paint_definitions_;
 
-  // The map of CSSPaintImageGeneratorImpl which are waiting for a
-  // CSSPaintDefinition to be registered. The global scope is expected to
-  // outlive the generators hence are held onto with a WeakMember.
-  typedef HeapHashSet<WeakMember<CSSPaintImageGeneratorImpl>> GeneratorHashSet;
-  typedef HeapHashMap<String, Member<GeneratorHashSet>> PendingGeneratorMap;
-  PendingGeneratorMap pending_generators_;
+  Member<PaintWorkletPendingGeneratorRegistry> pending_generator_registry_;
 };
 
 DEFINE_TYPE_CASTS(PaintWorkletGlobalScope,
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
index 6b6aab8d..39c89dd 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
@@ -18,12 +18,15 @@
   return static_cast<PaintWorkletGlobalScopeProxy*>(proxy);
 }
 
-PaintWorkletGlobalScopeProxy::PaintWorkletGlobalScopeProxy(LocalFrame* frame) {
+PaintWorkletGlobalScopeProxy::PaintWorkletGlobalScopeProxy(
+    LocalFrame* frame,
+    PaintWorkletPendingGeneratorRegistry* pending_generator_registry) {
   DCHECK(IsMainThread());
   Document* document = frame->GetDocument();
   global_scope_ = PaintWorkletGlobalScope::Create(
       frame, document->Url(), document->UserAgent(),
-      document->GetSecurityOrigin(), ToIsolate(document));
+      document->GetSecurityOrigin(), ToIsolate(document),
+      pending_generator_registry);
 }
 
 void PaintWorkletGlobalScopeProxy::FetchAndInvokeScript(
@@ -55,11 +58,4 @@
   return global_scope_->FindDefinition(name);
 }
 
-void PaintWorkletGlobalScopeProxy::AddPendingGenerator(
-    const String& name,
-    CSSPaintImageGeneratorImpl* generator) {
-  DCHECK(IsMainThread());
-  global_scope_->AddPendingGenerator(name, generator);
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
index df1a68dc..486c9369 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.h
@@ -21,7 +21,8 @@
  public:
   static PaintWorkletGlobalScopeProxy* From(WorkletGlobalScopeProxy*);
 
-  explicit PaintWorkletGlobalScopeProxy(LocalFrame*);
+  PaintWorkletGlobalScopeProxy(LocalFrame*,
+                               PaintWorkletPendingGeneratorRegistry*);
   virtual ~PaintWorkletGlobalScopeProxy() = default;
 
   // Implements WorkletGlobalScopeProxy.
@@ -32,7 +33,6 @@
   void TerminateWorkletGlobalScope() override;
 
   CSSPaintDefinition* FindDefinition(const String& name);
-  void AddPendingGenerator(const String& name, CSSPaintImageGeneratorImpl*);
 
   PaintWorkletGlobalScope* global_scope() const { return global_scope_.Get(); }
 
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletPendingGeneratorRegistry.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletPendingGeneratorRegistry.cpp
new file mode 100644
index 0000000..f8ae4b7
--- /dev/null
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletPendingGeneratorRegistry.cpp
@@ -0,0 +1,38 @@
+// Copyright 2017 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 "modules/csspaint/PaintWorkletPendingGeneratorRegistry.h"
+
+#include "modules/csspaint/CSSPaintDefinition.h"
+
+namespace blink {
+
+void PaintWorkletPendingGeneratorRegistry::SetDefinition(
+    const String& name,
+    CSSPaintDefinition* definition) {
+  GeneratorHashSet* set = pending_generators_.at(name);
+  if (set) {
+    for (const auto& generator : *set) {
+      if (generator)
+        generator->SetDefinition(definition);
+    }
+  }
+  pending_generators_.erase(name);
+}
+
+void PaintWorkletPendingGeneratorRegistry::AddPendingGenerator(
+    const String& name,
+    CSSPaintImageGeneratorImpl* generator) {
+  Member<GeneratorHashSet>& set =
+      pending_generators_.insert(name, nullptr).stored_value->value;
+  if (!set)
+    set = new GeneratorHashSet;
+  set->insert(generator);
+}
+
+DEFINE_TRACE(PaintWorkletPendingGeneratorRegistry) {
+  visitor->Trace(pending_generators_);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletPendingGeneratorRegistry.h b/third_party/WebKit/Source/modules/csspaint/PaintWorkletPendingGeneratorRegistry.h
new file mode 100644
index 0000000..9604fd1
--- /dev/null
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletPendingGeneratorRegistry.h
@@ -0,0 +1,42 @@
+// Copyright 2017 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 PaintWorkletPendingGeneratorRegistry_h
+#define PaintWorkletPendingGeneratorRegistry_h
+
+#include "modules/csspaint/CSSPaintImageGeneratorImpl.h"
+#include "platform/heap/Heap.h"
+#include "platform/heap/HeapAllocator.h"
+
+namespace blink {
+
+class CSSPaintDefinition;
+
+// Keeps pending CSSPaintImageGeneratorImpls until corresponding
+// CSSPaintDefinitions are registered. This is primarily owned by the
+// PaintWorklet instance.
+class PaintWorkletPendingGeneratorRegistry
+    : public GarbageCollected<PaintWorkletPendingGeneratorRegistry> {
+  WTF_MAKE_NONCOPYABLE(PaintWorkletPendingGeneratorRegistry);
+
+ public:
+  PaintWorkletPendingGeneratorRegistry() = default;
+
+  void SetDefinition(const String& name, CSSPaintDefinition*);
+  void AddPendingGenerator(const String& name, CSSPaintImageGeneratorImpl*);
+
+  DECLARE_TRACE();
+
+ private:
+  // The map of CSSPaintImageGeneratorImpl which are waiting for a
+  // CSSPaintDefinition to be registered. Owners of this registry is expected to
+  // outlive the generators hence are held onto with a WeakMember.
+  using GeneratorHashSet = HeapHashSet<WeakMember<CSSPaintImageGeneratorImpl>>;
+  using PendingGeneratorMap = HeapHashMap<String, Member<GeneratorHashSet>>;
+  PendingGeneratorMap pending_generators_;
+};
+
+}  // namespace blink
+
+#endif  // PaintWorkletPendingGeneratorRegistry_h
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
index 7a9be6568..7b973715 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
@@ -4,6 +4,7 @@
 
 #include "modules/csspaint/PaintWorklet.h"
 
+#include <memory>
 #include "bindings/core/v8/ScriptSourceCode.h"
 #include "bindings/core/v8/V8GCController.h"
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
@@ -11,9 +12,9 @@
 #include "core/testing/DummyPageHolder.h"
 #include "modules/csspaint/CSSPaintDefinition.h"
 #include "modules/csspaint/PaintWorkletGlobalScope.h"
+#include "modules/csspaint/PaintWorkletGlobalScopeProxy.h"
 #include "modules/csspaint/WindowPaintWorklet.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include <memory>
 
 namespace blink {
 
@@ -21,19 +22,30 @@
  public:
   PaintWorkletTest() : page_(DummyPageHolder::Create()) {}
 
+  void SetUp() override { proxy_ = GetPaintWorklet()->CreateGlobalScope(); }
+
   PaintWorklet* GetPaintWorklet() {
     return WindowPaintWorklet::From(*page_->GetFrame().DomWindow())
         .paintWorklet();
   }
 
- protected:
+  PaintWorkletGlobalScopeProxy* GetProxy() {
+    return PaintWorkletGlobalScopeProxy::From(proxy_.get());
+  }
+
+  void Terminate() {
+    page_.reset();
+    proxy_->TerminateWorkletGlobalScope();
+    proxy_.reset();
+  }
+
+ private:
   std::unique_ptr<DummyPageHolder> page_;
+  std::unique_ptr<WorkletGlobalScopeProxy> proxy_;
 };
 
 TEST_F(PaintWorkletTest, GarbageCollectionOfCSSPaintDefinition) {
-  PaintWorkletGlobalScopeProxy* proxy = PaintWorkletGlobalScopeProxy::From(
-      GetPaintWorklet()->GetWorkletGlobalScopeProxy());
-  PaintWorkletGlobalScope* global_scope = proxy->global_scope();
+  PaintWorkletGlobalScope* global_scope = GetProxy()->global_scope();
   global_scope->ScriptController()->Evaluate(
       ScriptSourceCode("registerPaint('foo', class { paint() { } });"));
 
@@ -60,7 +72,7 @@
   DCHECK(!handle.IsEmpty());
 
   // Delete the page & associated objects.
-  page_.reset();
+  Terminate();
 
   // Run a GC, the persistent should have been collected.
   ThreadState::Current()->CollectAllGarbage();
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
index 5a78bc51..f5a7ef2 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -34,7 +34,6 @@
 #include "core/dom/MutationObserverInit.h"
 #include "core/dom/MutationRecord.h"
 #include "core/dom/ResizeObserver.h"
-#include "core/dom/ResizeObserverCallback.h"
 #include "core/dom/ResizeObserverEntry.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/events/MouseEvent.h"
@@ -177,17 +176,17 @@
 // Count of number open batches for controls visibility.
 int MediaControlsImpl::BatchedControlUpdate::batch_depth_ = 0;
 
-class MediaControlsImpl::MediaControlsResizeObserverCallback final
-    : public ResizeObserverCallback {
+class MediaControlsImpl::MediaControlsResizeObserverDelegate final
+    : public ResizeObserver::Delegate {
  public:
-  explicit MediaControlsResizeObserverCallback(MediaControlsImpl* controls)
+  explicit MediaControlsResizeObserverDelegate(MediaControlsImpl* controls)
       : controls_(controls) {
     DCHECK(controls);
   }
-  ~MediaControlsResizeObserverCallback() override = default;
+  ~MediaControlsResizeObserverDelegate() override = default;
 
-  void handleEvent(const HeapVector<Member<ResizeObserverEntry>>& entries,
-                   ResizeObserver* observer) override {
+  void OnResize(
+      const HeapVector<Member<ResizeObserverEntry>>& entries) override {
     DCHECK_EQ(1u, entries.size());
     DCHECK_EQ(entries[0]->target(), controls_->MediaElement());
     controls_->NotifyElementSizeChanged(entries[0]->contentRect());
@@ -195,7 +194,7 @@
 
   DEFINE_INLINE_TRACE() {
     visitor->Trace(controls_);
-    ResizeObserverCallback::Trace(visitor);
+    ResizeObserver::Delegate::Trace(visitor);
   }
 
  private:
@@ -296,7 +295,7 @@
       is_paused_for_scrubbing_(false),
       resize_observer_(ResizeObserver::Create(
           media_element.GetDocument(),
-          new MediaControlsResizeObserverCallback(this))),
+          new MediaControlsResizeObserverDelegate(this))),
       element_size_changed_timer_(
           TaskRunnerHelper::Get(TaskType::kUnspecedTimer,
                                 &media_element.GetDocument()),
@@ -482,7 +481,7 @@
   if (!resize_observer_) {
     resize_observer_ =
         ResizeObserver::Create(MediaElement().GetDocument(),
-                               new MediaControlsResizeObserverCallback(this));
+                               new MediaControlsResizeObserverDelegate(this));
     HTMLMediaElement& html_media_element = MediaElement();
     resize_observer_->observe(&html_media_element);
   }
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
index 3fc98c3..02d6d9a 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
@@ -140,7 +140,7 @@
 
   // Need to be members of MediaControls for private member access.
   class BatchedControlUpdate;
-  class MediaControlsResizeObserverCallback;
+  class MediaControlsResizeObserverDelegate;
   class MediaElementMutationCallback;
 
   static MediaControlsImpl* Create(HTMLMediaElement&, ShadowRoot&);
diff --git a/third_party/WebKit/Source/web/tests/ResizeObserverTest.cpp b/third_party/WebKit/Source/web/tests/ResizeObserverTest.cpp
index faf79bb3f..bb2fac47 100644
--- a/third_party/WebKit/Source/web/tests/ResizeObserverTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ResizeObserverTest.cpp
@@ -8,7 +8,6 @@
 #include "bindings/core/v8/ScriptSourceCode.h"
 #include "bindings/core/v8/V8GCController.h"
 #include "core/dom/ResizeObservation.h"
-#include "core/dom/ResizeObserverCallback.h"
 #include "core/dom/ResizeObserverController.h"
 #include "core/exported/WebViewBase.h"
 #include "platform/testing/UnitTestHelpers.h"
@@ -23,19 +22,19 @@
 
 namespace {
 
-class TestResizeObserverCallback : public ResizeObserverCallback {
+class TestResizeObserverDelegate : public ResizeObserver::Delegate {
  public:
-  TestResizeObserverCallback(Document& document)
+  TestResizeObserverDelegate(Document& document)
       : document_(document), call_count_(0) {}
-  void handleEvent(const HeapVector<Member<ResizeObserverEntry>>& entries,
-                   ResizeObserver*) override {
+  void OnResize(
+      const HeapVector<Member<ResizeObserverEntry>>& entries) override {
     call_count_++;
   }
   ExecutionContext* GetExecutionContext() const { return document_; }
   int CallCount() const { return call_count_; }
 
   DEFINE_INLINE_TRACE() {
-    ResizeObserverCallback::Trace(visitor);
+    ResizeObserver::Delegate::Trace(visitor);
     visitor->Trace(document_);
   }
 
@@ -67,9 +66,9 @@
       "</svg>");
   main_resource.Finish();
 
-  ResizeObserverCallback* callback =
-      new TestResizeObserverCallback(GetDocument());
-  ResizeObserver* observer = ResizeObserver::Create(GetDocument(), callback);
+  ResizeObserver::Delegate* delegate =
+      new TestResizeObserverDelegate(GetDocument());
+  ResizeObserver* observer = ResizeObserver::Create(GetDocument(), delegate);
   Element* dom_target = GetDocument().getElementById("domTarget");
   Element* svg_target = GetDocument().getElementById("svgTarget");
   ResizeObservation* dom_observation =