diff --git a/BUILD.gn b/BUILD.gn
index 308243a..b5fbf42 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -240,6 +240,8 @@
       "//ios/chrome/app",
       "//ios/chrome/browser",
       "//ios/chrome/common",
+      "//ios/chrome/share_extension:packed_resources",
+      "//ios/chrome/today_extension:packed_resources",
       "//ios/net:ios_net_unittests",
       "//ios/public/provider/chrome/browser",
       "//ios/public/provider/web",
diff --git a/DEPS b/DEPS
index ecc51f4..17d5db7 100644
--- a/DEPS
+++ b/DEPS
@@ -43,7 +43,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': 'e891c24229b85a74a477314e8025af3ebbc30a14',
+  'v8_revision': '566565ee7faa3d1dbc8f3d9b7474004bbf6ecc23',
   # 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/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index 3908ff7..0b2bba82 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -418,7 +418,7 @@
   RootWindowController* controller =
       RootWindowController::ForTargetRootWindow();
   StatusAreaWidget* status_area_widget =
-      controller->shelf()->status_area_widget();
+      controller->shelf_widget()->status_area_widget();
   return status_area_widget &&
          status_area_widget->web_notification_tray()->visible();
 }
@@ -428,7 +428,7 @@
   RootWindowController* controller =
       RootWindowController::ForTargetRootWindow();
   StatusAreaWidget* status_area_widget =
-      controller->shelf()->status_area_widget();
+      controller->shelf_widget()->status_area_widget();
   if (status_area_widget) {
     WebNotificationTray* notification_tray =
         status_area_widget->web_notification_tray();
diff --git a/ash/mus/BUILD.gn b/ash/mus/BUILD.gn
index da25a6e..92459bf 100644
--- a/ash/mus/BUILD.gn
+++ b/ash/mus/BUILD.gn
@@ -42,7 +42,6 @@
     "//mash/shelf/public/interfaces",
     "//mash/wm/public/interfaces",
     "//mojo/common:common_base",
-    "//mojo/converters/geometry",
     "//mojo/converters/input_events",
     "//services/catalog/public/cpp",
     "//services/shell/public/cpp",
@@ -55,6 +54,7 @@
     "//ui/events/devices",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
     "//ui/keyboard:mojom",
     "//ui/message_center",
     "//ui/platform_window/stub",
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 11548a8c..aa29483 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -430,19 +430,20 @@
 }
 
 void RootWindowController::ShowShelf() {
-  if (!shelf_->shelf())
+  if (!shelf_widget_->shelf())
     return;
-  shelf_->shelf()->SetVisible(true);
-  shelf_->status_area_widget()->Show();
+  shelf_widget_->shelf()->SetVisible(true);
+  shelf_widget_->status_area_widget()->Show();
 }
 
 void RootWindowController::OnShelfCreated() {
   if (panel_layout_manager_)
-    panel_layout_manager_->SetShelf(shelf_->shelf()->wm_shelf());
+    panel_layout_manager_->SetShelf(shelf_widget_->shelf()->wm_shelf());
   if (docked_layout_manager_) {
-    docked_layout_manager_->SetShelf(shelf_->shelf()->wm_shelf());
-    if (shelf_->shelf_layout_manager())
-      docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
+    docked_layout_manager_->SetShelf(shelf_widget_->shelf()->wm_shelf());
+    if (shelf_widget_->shelf_layout_manager())
+      docked_layout_manager_->AddObserver(
+          shelf_widget_->shelf_layout_manager());
   }
 
   // Notify shell observers that the shelf has been created.
@@ -453,8 +454,8 @@
     user::LoginStatus status) {
   if (status != user::LOGGED_IN_NONE)
     mouse_event_target_.reset();
-  if (shelf_->status_area_widget())
-    shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
+  if (shelf_widget_->status_area_widget())
+    shelf_widget_->status_area_widget()->UpdateAfterLoginStatusChange(status);
 }
 
 void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
@@ -499,8 +500,10 @@
 
   // Remove observer as deactivating keyboard causes |docked_layout_manager_|
   // to fire notifications.
-  if (docked_layout_manager_ && shelf_ && shelf_->shelf_layout_manager())
-    docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
+  if (docked_layout_manager_ && shelf_widget_ &&
+      shelf_widget_->shelf_layout_manager())
+    docked_layout_manager_->RemoveObserver(
+        shelf_widget_->shelf_layout_manager());
 
   // Deactivate keyboard container before closing child windows and shutting
   // down associated layout managers.
@@ -519,8 +522,8 @@
   aura::Window* root_window = GetRootWindow();
   aura::client::SetDragDropClient(root_window, NULL);
 
-  if (shelf_)
-    shelf_->Shutdown();
+  if (shelf_widget_)
+    shelf_widget_->Shutdown();
 
   // Close background widget first as it depends on tooltip.
   wallpaper_controller_.reset();
@@ -560,7 +563,7 @@
     }
   }
 
-  shelf_.reset();
+  shelf_widget_.reset();
 }
 
 void RootWindowController::MoveWindowsTo(aura::Window* dst) {
@@ -572,21 +575,22 @@
 }
 
 ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
-  return shelf_->shelf_layout_manager();
+  return shelf_widget_->shelf_layout_manager();
 }
 
 SystemTray* RootWindowController::GetSystemTray() {
   // We assume in throughout the code that this will not return NULL. If code
   // triggers this for valid reasons, it should test status_area_widget first.
-  CHECK(shelf_->status_area_widget());
-  return shelf_->status_area_widget()->system_tray();
+  CHECK(shelf_widget_->status_area_widget());
+  return shelf_widget_->status_area_widget()->system_tray();
 }
 
 void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
                                            ui::MenuSourceType source_type) {
   ShellDelegate* delegate = Shell::GetInstance()->delegate();
   DCHECK(delegate);
-  menu_model_.reset(delegate->CreateContextMenu(shelf_->shelf(), nullptr));
+  menu_model_.reset(
+      delegate->CreateContextMenu(shelf_widget_->shelf(), nullptr));
   if (!menu_model_)
     return;
 
@@ -609,7 +613,7 @@
 }
 
 void RootWindowController::UpdateShelfVisibility() {
-  shelf_->shelf_layout_manager()->UpdateVisibilityState();
+  shelf_widget_->shelf_layout_manager()->UpdateVisibilityState();
 }
 
 aura::Window* RootWindowController::GetWindowForFullscreenMode() {
@@ -624,7 +628,7 @@
     return;
   }
   DCHECK(keyboard_controller);
-  keyboard_controller->AddObserver(shelf()->shelf_layout_manager());
+  keyboard_controller->AddObserver(shelf_widget()->shelf_layout_manager());
   keyboard_controller->AddObserver(panel_layout_manager_);
   keyboard_controller->AddObserver(docked_layout_manager_);
   keyboard_controller->AddObserver(workspace_controller_->layout_manager());
@@ -655,7 +659,7 @@
     // Virtual keyboard may be deactivated while still showing, notify all
     // observers that keyboard bounds changed to 0 before remove them.
     keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
-    keyboard_controller->RemoveObserver(shelf()->shelf_layout_manager());
+    keyboard_controller->RemoveObserver(shelf_widget()->shelf_layout_manager());
     keyboard_controller->RemoveObserver(panel_layout_manager_);
     keyboard_controller->RemoveObserver(docked_layout_manager_);
     keyboard_controller->RemoveObserver(
@@ -718,7 +722,7 @@
 
     // Create a shelf if a user is already logged in.
     if (shell->session_state_delegate()->NumberOfLoggedInUsers())
-      shelf()->CreateShelf();
+      shelf_widget()->CreateShelf();
 
     // Notify shell observers about new root window.
     shell->OnRootWindowAdded(root_window);
@@ -751,13 +755,14 @@
   always_on_top_controller_.reset(
       new AlwaysOnTopController(always_on_top_container));
 
-  DCHECK(!shelf_.get());
+  DCHECK(!shelf_widget_.get());
   aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
   // TODO(harrym): Remove when status area is view.
   aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer);
-  shelf_.reset(new ShelfWidget(
-      shelf_container, status_container, workspace_controller()));
-  workspace_layout_manager_delegate->set_shelf(shelf_->shelf_layout_manager());
+  shelf_widget_.reset(new ShelfWidget(shelf_container, status_container,
+                                      workspace_controller()));
+  workspace_layout_manager_delegate->set_shelf(
+      shelf_widget_->shelf_layout_manager());
 
   if (!Shell::GetInstance()->session_state_delegate()->
       IsActiveUserSessionStarted()) {
@@ -1047,7 +1052,7 @@
 }
 
 void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
-  shelf_->shelf_layout_manager()->UpdateVisibilityState();
+  shelf_widget_->shelf_layout_manager()->UpdateVisibilityState();
 }
 
 void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index 283468ec..760a033 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -118,9 +118,9 @@
     return always_on_top_controller_.get();
   }
 
-  // Access the shelf associated with this root window controller,
+  // Access the shelf widget associated with this root window controller,
   // NULL if no such shelf exists.
-  ShelfWidget* shelf() { return shelf_.get(); }
+  ShelfWidget* shelf_widget() { return shelf_widget_.get(); }
 
   // Get touch HUDs associated with this root window controller.
   TouchHudDebug* touch_hud_debug() const {
@@ -269,8 +269,8 @@
 
   std::unique_ptr<StackingController> stacking_controller_;
 
-  // The shelf for managing the shelf and the status widget.
-  std::unique_ptr<ShelfWidget> shelf_;
+  // The shelf widget for this root window.
+  std::unique_ptr<ShelfWidget> shelf_widget_;
 
   // An invisible/empty window used as a event target for
   // |MouseCursorEventFilter| before a user logs in.
diff --git a/ash/screen_util.cc b/ash/screen_util.cc
index b855dae..439588e2 100644
--- a/ash/screen_util.cc
+++ b/ash/screen_util.cc
@@ -32,7 +32,7 @@
 
 // static
 gfx::Rect ScreenUtil::GetMaximizedWindowBoundsInParent(aura::Window* window) {
-  if (GetRootWindowController(window->GetRootWindow())->shelf())
+  if (GetRootWindowController(window->GetRootWindow())->shelf_widget())
     return GetDisplayWorkAreaBoundsInParent(window);
   else
     return GetDisplayBoundsInParent(window);
diff --git a/ash/shelf/shelf.cc b/ash/shelf/shelf.cc
index 4124981..078606a8 100644
--- a/ash/shelf/shelf.cc
+++ b/ash/shelf/shelf.cc
@@ -67,7 +67,8 @@
 
 // static
 Shelf* Shelf::ForWindow(const aura::Window* window) {
-  ShelfWidget* shelf_widget = RootWindowController::ForWindow(window)->shelf();
+  ShelfWidget* shelf_widget =
+      RootWindowController::ForWindow(window)->shelf_widget();
   return shelf_widget ? shelf_widget->shelf() : nullptr;
 }
 
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index 46a36679..5dba0a9e 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -60,7 +60,7 @@
 }
 
 ShelfWidget* GetShelfWidget() {
-  return Shell::GetPrimaryRootWindowController()->shelf();
+  return Shell::GetPrimaryRootWindowController()->shelf_widget();
 }
 
 ShelfLayoutManager* GetShelfLayoutManager() {
@@ -2097,8 +2097,9 @@
 // the shelf.
 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) {
   ShelfLayoutManager* shelf = GetShelfLayoutManager();
-  StatusAreaWidget* status_area_widget =
-      Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
+  StatusAreaWidget* status_area_widget = Shell::GetPrimaryRootWindowController()
+                                             ->shelf_widget()
+                                             ->status_area_widget();
   SystemTray* tray = GetSystemTray();
 
   // Create a visible window so auto-hide behavior is enforced.
@@ -2210,8 +2211,9 @@
 TEST_F(ShelfLayoutManagerTest, MAYBE_StatusAreaHitBoxCoversEdge) {
   UpdateDisplay("400x400");
   ShelfLayoutManager* shelf = GetShelfLayoutManager();
-  StatusAreaWidget* status_area_widget =
-      Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
+  StatusAreaWidget* status_area_widget = Shell::GetPrimaryRootWindowController()
+                                             ->shelf_widget()
+                                             ->status_area_widget();
   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   generator.MoveMouseTo(399,399);
 
@@ -2291,8 +2293,9 @@
 
   UpdateDisplay("500x400, 500x400");
 
-  StatusAreaWidget* status_area_widget =
-      Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
+  StatusAreaWidget* status_area_widget = Shell::GetPrimaryRootWindowController()
+                                             ->shelf_widget()
+                                             ->status_area_widget();
   EXPECT_TRUE(status_area_widget->IsVisible());
   // Shelf should be in the first display's area.
   gfx::Rect status_area_bounds(status_area_widget->GetWindowBoundsInScreen());
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc
index 6e797ad..bf8d27d 100644
--- a/ash/shelf/shelf_view_unittest.cc
+++ b/ash/shelf/shelf_view_unittest.cc
@@ -223,7 +223,7 @@
 }
 
 TEST_F(ShelfViewIconObserverTest, BoundsChanged) {
-  ShelfWidget* widget = Shell::GetPrimaryRootWindowController()->shelf();
+  ShelfWidget* widget = Shell::GetPrimaryRootWindowController()->shelf_widget();
   gfx::Rect shelf_bounds = widget->GetWindowBoundsInScreen();
   shelf_bounds.set_width(shelf_bounds.width() / 2);
   ASSERT_GT(shelf_bounds.width(), 0);
diff --git a/ash/shelf/shelf_widget_unittest.cc b/ash/shelf/shelf_widget_unittest.cc
index df6860c..56799af 100644
--- a/ash/shelf/shelf_widget_unittest.cc
+++ b/ash/shelf/shelf_widget_unittest.cc
@@ -166,8 +166,8 @@
   for (Shell::RootWindowControllerList::const_iterator i = controllers.begin();
        i != controllers.end();
        ++i) {
-    if (!(*i)->shelf()->shelf()) {
-      shelf_widget = (*i)->shelf();
+    if (!(*i)->shelf_widget()->shelf()) {
+      shelf_widget = (*i)->shelf_widget();
       break;
     }
   }
diff --git a/ash/shell.cc b/ash/shell.cc
index 3cb781f6..245c9a7 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -446,7 +446,7 @@
   RootWindowControllerList controllers = GetAllRootWindowControllers();
   for (RootWindowControllerList::iterator iter = controllers.begin();
        iter != controllers.end(); ++iter)
-    (*iter)->shelf()->CreateShelf();
+    (*iter)->shelf_widget()->CreateShelf();
 }
 
 void Shell::OnShelfCreatedForRootWindow(aura::Window* root_window) {
@@ -490,8 +490,8 @@
   RootWindowControllerList controllers = GetAllRootWindowControllers();
   for (RootWindowControllerList::iterator iter = controllers.begin();
        iter != controllers.end(); ++iter) {
-    if ((*iter)->shelf())
-      (*iter)->shelf()->Shutdown();
+    if ((*iter)->shelf_widget())
+      (*iter)->shelf_widget()->Shutdown();
   }
 }
 
@@ -523,7 +523,7 @@
   RootWindowControllerList controllers = GetAllRootWindowControllers();
   for (RootWindowControllerList::iterator iter = controllers.begin();
        iter != controllers.end(); ++iter)
-    if ((*iter)->shelf())
+    if ((*iter)->shelf_widget())
       (*iter)->UpdateShelfVisibility();
 }
 
@@ -592,12 +592,14 @@
 }
 
 WebNotificationTray* Shell::GetWebNotificationTray() {
-  return GetPrimaryRootWindowController()->shelf()->
-      status_area_widget()->web_notification_tray();
+  return GetPrimaryRootWindowController()
+      ->shelf_widget()
+      ->status_area_widget()
+      ->web_notification_tray();
 }
 
 bool Shell::HasPrimaryStatusArea() {
-  ShelfWidget* shelf = GetPrimaryRootWindowController()->shelf();
+  ShelfWidget* shelf = GetPrimaryRootWindowController()->shelf_widget();
   return shelf && shelf->status_area_widget();
 }
 
diff --git a/ash/shell/window_type_launcher.cc b/ash/shell/window_type_launcher.cc
index ce5949c4..5f5b048 100644
--- a/ash/shell/window_type_launcher.cc
+++ b/ash/shell/window_type_launcher.cc
@@ -322,7 +322,7 @@
         message_center::RichNotificationData(), NULL /* delegate */));
 
     ash::Shell::GetPrimaryRootWindowController()
-        ->shelf()
+        ->shelf_widget()
         ->status_area_widget()
         ->web_notification_tray()
         ->message_center()
diff --git a/ash/system/tray/system_tray_unittest.cc b/ash/system/tray/system_tray_unittest.cc
index f77b4e2..27694a3 100644
--- a/ash/system/tray/system_tray_unittest.cc
+++ b/ash/system/tray/system_tray_unittest.cc
@@ -42,8 +42,10 @@
 namespace {
 
 SystemTray* GetSystemTray() {
-  return Shell::GetPrimaryRootWindowController()->shelf()->
-      status_area_widget()->system_tray();
+  return Shell::GetPrimaryRootWindowController()
+      ->shelf_widget()
+      ->status_area_widget()
+      ->system_tray();
 }
 
 // Trivial item implementation that tracks its views for testing.
@@ -180,8 +182,9 @@
 TEST_F(SystemTrayTest, SystemTrayColoringAfterAlignmentChange) {
   SystemTray* tray = GetSystemTray();
   ASSERT_TRUE(tray->GetWidget());
-  ShelfLayoutManager* manager =
-      Shell::GetPrimaryRootWindowController()->shelf()->shelf_layout_manager();
+  ShelfLayoutManager* manager = Shell::GetPrimaryRootWindowController()
+                                    ->shelf_widget()
+                                    ->shelf_layout_manager();
   manager->SetAlignment(wm::SHELF_ALIGNMENT_BOTTOM);
   // At the beginning the tray coloring is not active.
   ASSERT_FALSE(tray->draw_background_as_active());
@@ -350,10 +353,12 @@
 // Tests that the tray is laid out properly and is fully contained within
 // the shelf.
 TEST_F(SystemTrayTest, TrayBoundsInWidget) {
-  ShelfLayoutManager* manager =
-      Shell::GetPrimaryRootWindowController()->shelf()->shelf_layout_manager();
-  StatusAreaWidget* widget =
-      Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
+  ShelfLayoutManager* manager = Shell::GetPrimaryRootWindowController()
+                                    ->shelf_widget()
+                                    ->shelf_layout_manager();
+  StatusAreaWidget* widget = Shell::GetPrimaryRootWindowController()
+                                 ->shelf_widget()
+                                 ->status_area_widget();
   SystemTray* tray = widget->system_tray();
 
   // Test in bottom alignment.
diff --git a/ash/system/tray/tray_details_view_unittest.cc b/ash/system/tray/tray_details_view_unittest.cc
index 54332f8c..9b257f28 100644
--- a/ash/system/tray/tray_details_view_unittest.cc
+++ b/ash/system/tray/tray_details_view_unittest.cc
@@ -30,8 +30,10 @@
 namespace {
 
 SystemTray* GetSystemTray() {
-  return Shell::GetPrimaryRootWindowController()->shelf()->
-      status_area_widget()->system_tray();
+  return Shell::GetPrimaryRootWindowController()
+      ->shelf_widget()
+      ->status_area_widget()
+      ->system_tray();
 }
 
 class TestDetailsView : public TrayDetailsView,
diff --git a/ash/system/tray_update.cc b/ash/system/tray_update.cc
index 5b67baee..2caeeb1c 100644
--- a/ash/system/tray_update.cc
+++ b/ash/system/tray_update.cc
@@ -113,8 +113,9 @@
   }
 
   ~UpdateNagger() override {
-    StatusAreaWidget* status_area =
-        Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
+    StatusAreaWidget* status_area = Shell::GetPrimaryRootWindowController()
+                                        ->shelf_widget()
+                                        ->status_area_widget();
     if (status_area) {
       status_area->system_tray()->GetWidget()->GetNativeView()->layer()->
           GetAnimator()->RemoveObserver(this);
@@ -138,7 +139,7 @@
   void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
     // TODO(oshima): Find out if the updator will be shown on non
     // primary display.
-    if (Shell::GetPrimaryRootWindowController()->shelf()->IsVisible())
+    if (Shell::GetPrimaryRootWindowController()->shelf_widget()->IsVisible())
       timer_.Stop();
     else if (!timer_.IsRunning())
       RestartTimer();
@@ -195,7 +196,7 @@
 void TrayUpdate::OnUpdateRecommended(const UpdateInfo& info) {
   SetImageFromResourceId(DecideResource(info.severity, false));
   tray_view()->SetVisible(true);
-  if (!Shell::GetPrimaryRootWindowController()->shelf()->IsVisible() &&
+  if (!Shell::GetPrimaryRootWindowController()->shelf_widget()->IsVisible() &&
       !nagger_.get()) {
     // The shelf is not visible, and there is no nagger scheduled.
     nagger_.reset(new tray::UpdateNagger(this));
diff --git a/ash/test/status_area_widget_test_helper.cc b/ash/test/status_area_widget_test_helper.cc
index 8e7768f5..b0ae25f 100644
--- a/ash/test/status_area_widget_test_helper.cc
+++ b/ash/test/status_area_widget_test_helper.cc
@@ -17,8 +17,9 @@
 }
 
 StatusAreaWidget* StatusAreaWidgetTestHelper::GetStatusAreaWidget() {
-  return Shell::GetPrimaryRootWindowController()->shelf()->
-      status_area_widget();
+  return Shell::GetPrimaryRootWindowController()
+      ->shelf_widget()
+      ->status_area_widget();
 }
 
 StatusAreaWidget* StatusAreaWidgetTestHelper::GetSecondaryStatusAreaWidget() {
@@ -28,7 +29,7 @@
       Shell::GetAllRootWindowControllers();
   for (size_t i = 0; i < controllers.size(); ++i) {
     if (controllers[i] != primary_controller)
-      return controllers[i]->shelf()->status_area_widget();
+      return controllers[i]->shelf_widget()->status_area_widget();
   }
 
   return NULL;
diff --git a/ash/wm/aura/wm_root_window_controller_aura.cc b/ash/wm/aura/wm_root_window_controller_aura.cc
index 5297eeb..c66233c 100644
--- a/ash/wm/aura/wm_root_window_controller_aura.cc
+++ b/ash/wm/aura/wm_root_window_controller_aura.cc
@@ -63,7 +63,7 @@
 }
 
 bool WmRootWindowControllerAura::HasShelf() {
-  return root_window_controller_->shelf() != nullptr;
+  return root_window_controller_->shelf_widget() != nullptr;
 }
 
 WmGlobals* WmRootWindowControllerAura::GetGlobals() {
@@ -79,8 +79,8 @@
 }
 
 WmShelf* WmRootWindowControllerAura::GetShelf() {
-  return root_window_controller_->shelf()
-             ? root_window_controller_->shelf()->shelf()->wm_shelf()
+  return root_window_controller_->shelf_widget()
+             ? root_window_controller_->shelf_widget()->shelf()->wm_shelf()
              : nullptr;
 }
 
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager.cc b/ash/wm/maximize_mode/maximize_mode_window_manager.cc
index ccb1542..eede8b9 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager.cc
@@ -6,6 +6,7 @@
 
 #include "ash/ash_switches.h"
 #include "ash/root_window_controller.h"
+#include "ash/session/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/common/window_state.h"
@@ -164,6 +165,21 @@
 }
 
 void MaximizeModeWindowManager::OnTouchEvent(ui::TouchEvent* event) {
+  const SessionStateDelegate* delegate =
+      Shell::GetInstance()->session_state_delegate();
+
+  if (delegate->IsScreenLocked())
+    return;
+
+  switch (delegate->GetSessionState()) {
+    case SessionStateDelegate::SESSION_STATE_LOGIN_PRIMARY:
+      return;
+    case SessionStateDelegate::SESSION_STATE_ACTIVE:
+      break;
+    case SessionStateDelegate::SESSION_STATE_LOGIN_SECONDARY:
+      return;
+  }
+
   if (event->type() != ui::ET_TOUCH_PRESSED)
     return;
 
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc
index dbd6fdd..1671e55 100644
--- a/ash/wm/overview/window_selector_unittest.cc
+++ b/ash/wm/overview/window_selector_unittest.cc
@@ -860,7 +860,8 @@
   std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
   wm::WindowState* window_state = wm::GetWindowState(window1.get());
   window_state->Maximize();
-  ash::ShelfWidget* shelf = Shell::GetPrimaryRootWindowController()->shelf();
+  ash::ShelfWidget* shelf =
+      Shell::GetPrimaryRootWindowController()->shelf_widget();
   EXPECT_TRUE(shelf->GetDimsShelf());
   ToggleOverview();
   EXPECT_FALSE(shelf->GetDimsShelf());
diff --git a/ash/wm/panels/panel_window_resizer_unittest.cc b/ash/wm/panels/panel_window_resizer_unittest.cc
index 9efbe47..605628a 100644
--- a/ash/wm/panels/panel_window_resizer_unittest.cc
+++ b/ash/wm/panels/panel_window_resizer_unittest.cc
@@ -272,10 +272,12 @@
 
   // Hide the shelf. This minimizes all attached windows but should ignore
   // the dragged window.
-  ShelfLayoutManager* shelf = RootWindowController::ForWindow(window.get())->
-      shelf()->shelf_layout_manager();
-  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
-  shelf->UpdateVisibilityState();
+  ShelfLayoutManager* layout_manager =
+      RootWindowController::ForWindow(window.get())
+          ->shelf_widget()
+          ->shelf_layout_manager();
+  layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
+  layout_manager->UpdateVisibilityState();
   RunAllPendingInMessageLoop();
   EXPECT_FALSE(state->IsMinimized());
   EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
diff --git a/ash/wm/workspace_controller_unittest.cc b/ash/wm/workspace_controller_unittest.cc
index 79b138ae..aa81adb 100644
--- a/ash/wm/workspace_controller_unittest.cc
+++ b/ash/wm/workspace_controller_unittest.cc
@@ -146,7 +146,7 @@
   }
 
   ShelfWidget* shelf_widget() {
-    return Shell::GetPrimaryRootWindowController()->shelf();
+    return Shell::GetPrimaryRootWindowController()->shelf_widget();
   }
 
   ShelfLayoutManager* shelf_layout_manager() {
diff --git a/cc/animation/timing_function.cc b/cc/animation/timing_function.cc
index 494d8ef..e33943c 100644
--- a/cc/animation/timing_function.cc
+++ b/cc/animation/timing_function.cc
@@ -16,6 +16,23 @@
 
 TimingFunction::~TimingFunction() {}
 
+std::unique_ptr<TimingFunction> CubicBezierTimingFunction::CreatePreset(
+    EaseType ease_type) {
+  switch (ease_type) {
+    case EaseType::EASE:
+      return EaseTimingFunction::Create();
+    case EaseType::EASE_IN:
+      return EaseInTimingFunction::Create();
+    case EaseType::EASE_OUT:
+      return EaseOutTimingFunction::Create();
+    case EaseType::EASE_IN_OUT:
+      return EaseInOutTimingFunction::Create();
+    default:
+      NOTREACHED();
+      return nullptr;
+  }
+}
+
 std::unique_ptr<CubicBezierTimingFunction>
 CubicBezierTimingFunction::Create(double x1, double y1, double x2, double y2) {
   return base::WrapUnique(new CubicBezierTimingFunction(x1, y1, x2, y2));
diff --git a/cc/animation/timing_function.h b/cc/animation/timing_function.h
index 17b9014..d1807f6 100644
--- a/cc/animation/timing_function.h
+++ b/cc/animation/timing_function.h
@@ -33,6 +33,9 @@
 
 class CC_EXPORT CubicBezierTimingFunction : public TimingFunction {
  public:
+  enum class EaseType { EASE, EASE_IN, EASE_OUT, EASE_IN_OUT, CUSTOM };
+
+  static std::unique_ptr<TimingFunction> CreatePreset(EaseType ease_type);
   static std::unique_ptr<CubicBezierTimingFunction> Create(double x1,
                                                            double y1,
                                                            double x2,
diff --git a/chrome/VERSION b/chrome/VERSION
index 89efe4ca..f47ff3ec8 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=53
 MINOR=0
-BUILD=2749
+BUILD=2750
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/WebApkNotificationClient.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/WebApkNotificationClient.java
index 1814fed5..7172c5a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/WebApkNotificationClient.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/WebApkNotificationClient.java
@@ -6,7 +6,7 @@
 
 import android.os.RemoteException;
 
-import org.chromium.base.Callback;
+import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.webapk.lib.client.WebApkServiceConnectionManager;
 import org.chromium.webapk.lib.runtime_library.IWebApkApi;
@@ -19,11 +19,12 @@
     private static final String TAG = "cr_WebApk";
 
     // Callback which catches RemoteExceptions thrown due to IWebApkApi failure.
-    private abstract static class ApiUseCallback extends Callback<IWebApkApi> {
+    private abstract static class ApiUseCallback
+            implements WebApkServiceConnectionManager.ConnectionCallback {
         public abstract void useApi(IWebApkApi api) throws RemoteException;
 
         @Override
-        public void onResult(IWebApkApi api) {
+        public void onConnected(IWebApkApi api) {
             try {
                 useApi(api);
             } catch (RemoteException e) {
@@ -48,7 +49,8 @@
             }
         };
 
-        WebApkServiceConnectionManager.getInstance().connect(webApkPackage, connectionCallback);
+        WebApkServiceConnectionManager.getInstance().connect(
+                ContextUtils.getApplicationContext(), webApkPackage, connectionCallback);
     }
 
     /**
@@ -62,6 +64,7 @@
                 api.cancelNotification(platformTag, platformID);
             }
         };
-        WebApkServiceConnectionManager.getInstance().connect(webApkPackage, connectionCallback);
+        WebApkServiceConnectionManager.getInstance().connect(
+                ContextUtils.getApplicationContext(), webApkPackage, connectionCallback);
     }
 }
diff --git a/chrome/android/webapk/libs/client/BUILD.gn b/chrome/android/webapk/libs/client/BUILD.gn
index f19a3929..cdb2b8a 100644
--- a/chrome/android/webapk/libs/client/BUILD.gn
+++ b/chrome/android/webapk/libs/client/BUILD.gn
@@ -11,7 +11,6 @@
     "src/org/chromium/webapk/lib/client/WebApkValidator.java",
   ]
   deps = [
-    "//base:base_java",
     "//chrome/android/webapk/libs/common",
   ]
   srcjar_deps =
diff --git a/chrome/android/webapk/libs/client/DEPS b/chrome/android/webapk/libs/client/DEPS
index 2765109..a8953d02 100644
--- a/chrome/android/webapk/libs/client/DEPS
+++ b/chrome/android/webapk/libs/client/DEPS
@@ -1,4 +1,3 @@
 include_rules = [
-  "+base",
   "+chrome/android/webapk/libs/common",
 ]
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java
index 98b5ed7..7aa4489 100644
--- a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java
+++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java
@@ -9,8 +9,6 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 
-import org.chromium.base.Callback;
-import org.chromium.base.ContextUtils;
 import org.chromium.testing.local.CustomShadowAsyncTask;
 import org.chromium.testing.local.LocalRobolectricTestRunner;
 import org.chromium.webapk.lib.runtime_library.IWebApkApi;
@@ -35,18 +33,17 @@
     private ShadowApplication mShadowApplication;
     private WebApkServiceConnectionManager mConnectionManager;
 
-    private class TestCallback extends Callback<IWebApkApi> {
+    private class TestCallback implements WebApkServiceConnectionManager.ConnectionCallback {
         public boolean mGotResult = false;
 
         @Override
-        public void onResult(IWebApkApi api) {
+        public void onConnected(IWebApkApi api) {
             mGotResult = true;
         }
     }
 
     @Before
     public void setUp() {
-        ContextUtils.initApplicationContextForTests(Robolectric.application);
         mShadowApplication = Robolectric.shadowOf(Robolectric.application);
         mConnectionManager = new WebApkServiceConnectionManager();
     }
@@ -60,8 +57,8 @@
         TestCallback callback1 = new TestCallback();
         TestCallback callback2 = new TestCallback();
 
-        mConnectionManager.connect(WEB_APK_PACKAGE, callback1);
-        mConnectionManager.connect(WEB_APK_PACKAGE, callback2);
+        mConnectionManager.connect(Robolectric.application, WEB_APK_PACKAGE, callback1);
+        mConnectionManager.connect(Robolectric.application, WEB_APK_PACKAGE, callback2);
 
         // Only one connection should have been created.
         Assert.assertEquals(WEB_APK_PACKAGE, getNextStartedServicePackage());
@@ -109,12 +106,11 @@
         }
 
         AsyncBindContext asyncBindContext = new AsyncBindContext();
-        ContextUtils.initApplicationContextForTests(asyncBindContext);
 
         TestCallback callback1 = new TestCallback();
         TestCallback callback2 = new TestCallback();
-        mConnectionManager.connect(WEB_APK_PACKAGE, callback1);
-        mConnectionManager.connect(WEB_APK_PACKAGE, callback2);
+        mConnectionManager.connect(asyncBindContext, WEB_APK_PACKAGE, callback1);
+        mConnectionManager.connect(asyncBindContext, WEB_APK_PACKAGE, callback2);
 
         // The connection has not been established yet. Neither of the callbacks should have been
         // called.
@@ -132,12 +128,12 @@
      */
     @Test
     public void testDisconnectConnect() throws Exception {
-        mConnectionManager.connect(WEB_APK_PACKAGE, new TestCallback());
+        mConnectionManager.connect(Robolectric.application, WEB_APK_PACKAGE, new TestCallback());
         Assert.assertEquals(WEB_APK_PACKAGE, getNextStartedServicePackage());
         Assert.assertEquals(null, getNextStartedServicePackage());
 
-        mConnectionManager.disconnect(WEB_APK_PACKAGE);
-        mConnectionManager.connect(WEB_APK_PACKAGE, new TestCallback());
+        mConnectionManager.disconnect(Robolectric.application, WEB_APK_PACKAGE);
+        mConnectionManager.connect(Robolectric.application, WEB_APK_PACKAGE, new TestCallback());
         Assert.assertEquals(WEB_APK_PACKAGE, getNextStartedServicePackage());
         Assert.assertEquals(null, getNextStartedServicePackage());
     }
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
index c6b08f5..a2bcd65 100644
--- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
+++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
@@ -10,10 +10,8 @@
 import android.content.ServiceConnection;
 import android.os.AsyncTask;
 import android.os.IBinder;
+import android.util.Log;
 
-import org.chromium.base.Callback;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.Log;
 import org.chromium.webapk.lib.runtime_library.IWebApkApi;
 
 import java.util.ArrayList;
@@ -25,6 +23,17 @@
  */
 public class WebApkServiceConnectionManager {
     /**
+     * Interface for getting notified once Chrome is connected to the WebAPK service.
+     */
+    public interface ConnectionCallback {
+        /**
+         * Called once Chrome is connected to the WebAPK service.
+         * @param api The WebAPK service API.
+         */
+        public void onConnected(IWebApkApi api);
+    }
+
+    /**
      * Managed connection to WebAPK service.
      */
     private static class Connection implements ServiceConnection {
@@ -36,7 +45,7 @@
         /**
          * Callbacks to call once the connection is established.
          */
-        private ArrayList<Callback<IWebApkApi>> mCallbacks = new ArrayList<Callback<IWebApkApi>>();
+        private ArrayList<ConnectionCallback> mCallbacks = new ArrayList<ConnectionCallback>();
 
         /**
          * WebAPK IBinder interface.
@@ -51,7 +60,7 @@
             return mApi;
         }
 
-        public void addCallback(Callback<IWebApkApi> callback) {
+        public void addCallback(ConnectionCallback callback) {
             mCallbacks.add(callback);
         }
 
@@ -62,10 +71,10 @@
         public void onServiceConnected(ComponentName name, IBinder service) {
             mHasConnected = true;
             mApi = IWebApkApi.Stub.asInterface(service);
-            Log.d(TAG, "Got IWebApkApi: %s", mApi);
+            Log.d(TAG, String.format("Got IWebApkApi: %s", mApi));
 
-            for (Callback<IWebApkApi> callback : mCallbacks) {
-                callback.onResult(mApi);
+            for (ConnectionCallback callback : mCallbacks) {
+                callback.onConnected(mApi);
             }
             mCallbacks.clear();
         }
@@ -91,15 +100,17 @@
 
     /**
      * Connects Chrome application to WebAPK service. Can be called from any thread.
+     * @param appContext Application context.
      * @param webApkPackage WebAPK package to create connection for.
      * @param callback Callback to call after connection has been established. Called synchronously
      *   if the connection is already established.
      */
-    public void connect(final String webApkPackage, final Callback<IWebApkApi> callback) {
+    public void connect(final Context appContext, final String webApkPackage,
+            final ConnectionCallback callback) {
         Connection connection = mConnections.get(webApkPackage);
         if (connection != null) {
             if (connection.hasConnected()) {
-                callback.onResult(connection.getApi());
+                callback.onConnected(connection.getApi());
             } else {
                 connection.addCallback(callback);
             }
@@ -111,7 +122,6 @@
             protected Void doInBackground(Void... params) {
                 Connection newConnection = new Connection();
                 newConnection.addCallback(callback);
-                Context appContext = ContextUtils.getApplicationContext();
                 Intent intent = createConnectIntent(webApkPackage);
 
                 try {
@@ -130,9 +140,10 @@
 
     /**
      * Disconnects Chrome application from WebAPK service. Can be called from any thread.
+     * @param appContext Application context.
      * @param webApkPackage WebAPK package for the service to disconnect from.
      */
-    public void disconnect(String webApkPackage) {
+    public void disconnect(final Context appContext, String webApkPackage) {
         final Connection connection = mConnections.remove(webApkPackage);
         if (connection == null) {
             return;
@@ -141,7 +152,6 @@
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
-                Context appContext = ContextUtils.getApplicationContext();
                 appContext.unbindService(connection);
                 return null;
             }
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h
index 537e94b..3bc88e4 100644
--- a/chrome/app/chrome_command_ids.h
+++ b/chrome/app/chrome_command_ids.h
@@ -33,6 +33,10 @@
 #define IDC_RELOAD_BYPASSING_CACHE      33007
 #define IDC_LOAD_NEW_TAB_PAGE           33008
 #define IDC_RELOAD_CLEARING_CACHE       33009
+// Temporary commands to capture the old Back/Forward shortcuts and tell users
+// the new shortcut. May also trigger Back/Forward action if the
+// BackspaceGoesBack field trial is enabled.
+// TODO(mgiuca): Remove these in M54 (https://crbug.com/610039).
 #define IDC_BACKSPACE_BACK              33010
 #define IDC_BACKSPACE_FORWARD           33011
 
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index a81aaec22..15d033ab 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1302,6 +1302,12 @@
   <message name="IDS_FLAGS_FULLSCREEN_APP_LIST_DESCRIPTION" desc="Description for the flag to enable experimental fullscreen app list.">
     The app-list will appear as fullscreen mode when it's in touch view mode. This flag does nothing outside of the mode.
   </message>
+  <message name="IDS_FLAGS_STORAGE_MANAGER_NAME" desc="Description for the flag to enable experimental storage manager.">
+    Storage manager
+  </message>
+  <message name="IDS_FLAGS_STORAGE_MANAGER_DESCRIPTION" desc="Description for the flag to enable experimental storage manager.">
+    Enables storage manager to manage local storage.
+  </message>
   <message name="IDS_OFFERS_CONSENT_INFOBAR_LABEL_LEARN_MORE" desc="Text of the Learn More link in the echo dialog.">
     Learn More
   </message>
@@ -2065,6 +2071,9 @@
   <message name="IDS_OPTIONS_DEVICE_GROUP_KEYBOARD_SETTINGS_BUTTON_TITLE">
     Keyboard settings
   </message>
+  <message name="IDS_OPTIONS_DEVICE_GROUP_STORAGE_MANAGER_BUTTON_TITLE">
+    Storage
+  </message>
   <message name="IDS_OPTIONS_DEVICE_GROUP_POINTER_SECTION">
     Pointer speed:
   </message>
@@ -2533,12 +2542,15 @@
   <message name="IDS_OPTIONS_SETTINGS_ENABLE_DATA_ROAMING" desc="Appears in the Mobile Data drop-down menu in the Internet Connections section of the Settings tab.">
     Allow mobile data roaming
   </message>
-<message name="IDS_OPTIONS_SETTINGS_TOGGLE_DATA_ROAMING_RESTRICTION" desc="Tooltip for the 'enable data roaming' entry in the Mobile Data drop-down menu indicating why the command is disabled.">
+  <message name="IDS_OPTIONS_SETTINGS_TOGGLE_DATA_ROAMING_RESTRICTION" desc="Tooltip for the 'enable data roaming' entry in the Mobile Data drop-down menu indicating why the command is disabled.">
     This setting may only be modified by the owner.
   </message>
   <message name="IDS_OPTIONS_SETTINGS_DISABLE_DATA_ROAMING" desc="Appears in the Mobile Data drop-down menu in the Internet Connections section of the Settings tab.">
     Disable mobile data roaming
   </message>
+  <message name="IDS_OPTIONS_SETTINGS_STORAGE_MANAGER_TAB_TITLE" desc="Title for the storage manager tab.">
+    Storage
+  </message>
   <message name="IDS_OPTIONS_ACCOUNTS_ALLOW_BWSI_DESCRIPTION" desc="In the Accounts settings tab, the text on the checkbox to allow browse without signing in.">
     Enable Guest browsing
   </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index c3e19df..854d1cc 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -454,8 +454,8 @@
       </message>
 
       <!-- Material Design History Strings -->
-      <message name="IDS_MD_HISTORY_SEARCH" desc="Placeholder text/label for the search input in the history page">
-        Search
+      <message name="IDS_MD_HISTORY_SEARCH_PROMPT" desc="Placeholder text/label for the search input field in the history page">
+        Search history
       </message>
       <message name="IDS_MD_HISTORY_CLEAR_SEARCH" desc="Tooltip text for the button that clears the search term on the history page">
         Clear search
@@ -6594,11 +6594,17 @@
         <message name="IDS_FLAGS_APP_WINDOW_CYCLING_DESCRIPTION" desc="Description of flag to enable or disable custom Cmd+` App window cycling on Mac.">
           Changes the behavior of Cmd+` when a Chrome App becomes active. When enabled, Chrome Apps will not be cycled when Cmd+` is pressed from a browser window, and browser windows will not be cycled when a Chrome App is active.
         </message>
-        <message name="IDS_FLAGS_MAC_VIEWS_DIALOGS_NAME" desc="Name of the flag to enable toolkit-views browser dialogs on Mac.">
-          Toolkit-Views Browser Dialogs.
+        <message name="IDS_FLAGS_MAC_VIEWS_NATIVE_DIALOGS_NAME" desc="Name of the flag to enable toolkit-views for native-looking browser dialogs on Mac." translateable="false">
+          Toolkit-Views Native-style Browser Dialogs.
         </message>
-        <message name="IDS_FLAGS_MAC_VIEWS_DIALOGS_DESCRIPTION" desc="Description of the flag to enable toolkit-views browser dialogs on Mac.">
-          Causes Chrome on Mac to use a toolkit-views browser dialog when available, in place of the equivalent Cocoa dialog.
+        <message name="IDS_FLAGS_MAC_VIEWS_NATIVE_DIALOGS_DESCRIPTION" desc="Description of the flag to enable toolkit-views for native-looking browser dialogs on Mac." translateable="false">
+          Use toolkit-views dialogs in place of the native Cocoa dialogs that use unaltered OSX-style buttons.
+        </message>
+        <message name="IDS_FLAGS_MAC_VIEWS_WEBUI_DIALOGS_NAME" desc="Name of the flag to enable toolkit-views for WebUI-themed browser dialogs on Mac." translateable="false">
+          Toolkit-Views WebUI-style Browser Dialogs.
+        </message>
+        <message name="IDS_FLAGS_MAC_VIEWS_WEBUI_DIALOGS_DESCRIPTION" desc="Description of the flag to enable toolkit-views for WebUI-themed browser dialogs on Mac." translateable="false">
+          Use toolkit-views dialogs in place of the native Cocoa dialogs that use square, grey, webui-style buttons.
         </message>
       </if>
       <if expr="chromeos">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 180fcdc..b68ca3b 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -88,6 +88,10 @@
 #include "third_party/cros_system_api/switches/chrome_switches.h"
 #endif
 
+#if defined(OS_MACOSX)
+#include "chrome/browser/ui/browser_dialogs.h"
+#endif
+
 #if defined(ENABLE_APP_LIST)
 #include "ui/app_list/app_list_switches.h"
 #endif
@@ -1103,6 +1107,9 @@
     {"enable-fullscreen-app-list", IDS_FLAGS_FULLSCREEN_APP_LIST_NAME,
      IDS_FLAGS_FULLSCREEN_APP_LIST_DESCRIPTION, kOsCrOS,
      SINGLE_VALUE_TYPE(ash::switches::kAshEnableFullscreenAppList)},
+    {"enable-storage-manager", IDS_FLAGS_STORAGE_MANAGER_NAME,
+     IDS_FLAGS_STORAGE_MANAGER_DESCRIPTION, kOsCrOS,
+     SINGLE_VALUE_TYPE(chromeos::switches::kEnableStorageManager)},
 #endif
     {"enable-simple-cache-backend", IDS_FLAGS_SIMPLE_CACHE_BACKEND_NAME,
      IDS_FLAGS_SIMPLE_CACHE_BACKEND_DESCRIPTION,
@@ -1576,9 +1583,12 @@
      IDS_FLAGS_APP_WINDOW_CYCLING_DESCRIPTION, kOsMac,
      ENABLE_DISABLE_VALUE_TYPE(switches::kEnableAppWindowCycling,
                                switches::kDisableAppWindowCycling)},
-    {"mac-views-dialogs", IDS_FLAGS_MAC_VIEWS_DIALOGS_NAME,
-     IDS_FLAGS_MAC_VIEWS_DIALOGS_DESCRIPTION, kOsMac,
-     SINGLE_VALUE_TYPE(switches::kEnableMacViewsDialogs)},
+    {"mac-views-native-dialogs", IDS_FLAGS_MAC_VIEWS_NATIVE_DIALOGS_NAME,
+     IDS_FLAGS_MAC_VIEWS_NATIVE_DIALOGS_DESCRIPTION, kOsMac,
+     FEATURE_VALUE_TYPE(chrome::kMacViewsNativeDialogs)},
+    {"mac-views-webui-dialogs", IDS_FLAGS_MAC_VIEWS_WEBUI_DIALOGS_NAME,
+     IDS_FLAGS_MAC_VIEWS_WEBUI_DIALOGS_DESCRIPTION, kOsMac,
+     FEATURE_VALUE_TYPE(chrome::kMacViewsWebUIDialogs)},
 #endif
 #if defined(ENABLE_WEBVR)
     {"enable-webvr", IDS_FLAGS_WEBVR_NAME, IDS_FLAGS_WEBVR_DESCRIPTION, kOsAll,
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index e7fc3145..bf456ba 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -1653,16 +1653,11 @@
   ASSERT_TRUE(StartEmbeddedTestServer());
   // We don't care where the main browser is on this test.
   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
-  // Start the app for the pre-test.
-  LoadAndLaunchPlatformApp("web_view/storage_persistence",
-                           "WebViewTest.LAUNCHED");
-
-  // Send a message to run the PRE_StoragePersistence part of the test.
-  SendMessageToEmbedder("run-pre-test");
-
-  ExtensionTestMessageListener test_passed_listener("WebViewTest.PASSED",
-                                                    false);
-  EXPECT_TRUE(test_passed_listener.WaitUntilSatisfied());
+  // Since this test is PRE_ step, we need file access.
+  ASSERT_TRUE(RunPlatformAppTestWithFlags(
+      "platform_apps/web_view/storage_persistence", "PRE_StoragePersistence",
+      kFlagEnableFileAccess))
+      << message_;
 }
 
 // This is the post-reset portion of the StoragePersistence test.  See
@@ -1671,16 +1666,13 @@
   ASSERT_TRUE(StartEmbeddedTestServer());
   // We don't care where the main browser is on this test.
   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
-  // Start the app for the pre-test.
-  LoadAndLaunchPlatformApp("web_view/storage_persistence",
-                           "WebViewTest.LAUNCHED");
 
-  // Send a message to run the StoragePersistence part of the test.
-  SendMessageToEmbedder("run-test");
-
-  ExtensionTestMessageListener test_passed_listener("WebViewTest.PASSED",
-                                                    false);
-  EXPECT_TRUE(test_passed_listener.WaitUntilSatisfied());
+  // Since this test has PRE_ step, we need file access (possibly because we
+  // need to access previous profile).
+  ASSERT_TRUE(RunPlatformAppTestWithFlags(
+      "platform_apps/web_view/storage_persistence", "StoragePersistence",
+      kFlagEnableFileAccess))
+      << message_;
 }
 
 // This tests DOM storage isolation for packaged apps with webview tags. It
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
index cc28471c..c1bbc20e 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
@@ -193,3 +193,8 @@
   RunTest(base::FilePath(
       FILE_PATH_LITERAL("foreground/js/spinner_controller_unittest.html")));
 }
+
+IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileListModel) {
+  RunTest(base::FilePath(
+      FILE_PATH_LITERAL("foreground/js/file_list_model_unittest.html")));
+}
diff --git a/chrome/browser/chromeos/hats/hats_notification_controller.cc b/chrome/browser/chromeos/hats/hats_notification_controller.cc
index e852beb1..5cc39117 100644
--- a/chrome/browser/chromeos/hats/hats_notification_controller.cc
+++ b/chrome/browser/chromeos/hats/hats_notification_controller.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/network/network_state.h"
 #include "content/public/browser/browser_thread.h"
 #include "grit/ash_strings.h"
 #include "grit/theme_resources.h"
@@ -31,11 +32,14 @@
 
 HatsNotificationController::HatsNotificationController(Profile* profile)
     : profile_(profile) {
-  std::unique_ptr<Notification> notification(CreateNotification());
-  g_browser_process->notification_ui_manager()->Add(*notification, profile_);
+  // Add self as an observer to be notified when an internet connection is
+  // available.
+  network_portal_detector::GetInstance()->AddAndFireObserver(this);
 }
 
-HatsNotificationController::~HatsNotificationController() {}
+HatsNotificationController::~HatsNotificationController() {
+  network_portal_detector::GetInstance()->RemoveObserver(this);
+}
 
 // static
 // TODO(malaykeshav): Implement this stub.
@@ -55,6 +59,27 @@
 // message_center::NotificationDelegate override:
 void HatsNotificationController::Close(bool by_user) {}
 
+// NetworkPortalDetector::Observer override:
+void HatsNotificationController::OnPortalDetectionCompleted(
+    const NetworkState* network,
+    const NetworkPortalDetector::CaptivePortalState& state) {
+  VLOG(1) << "HatsController::OnPortalDetectionCompleted(): "
+          << "network=" << (network ? network->path() : "") << ", "
+          << "state.status=" << state.status << ", "
+          << "state.response_code=" << state.response_code;
+  // Return if device is not connected to the internet.
+  if (state.status != NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE)
+    return;
+  // Remove self as an observer to no longer receive network change updates.
+  network_portal_detector::GetInstance()->RemoveObserver(this);
+  ShowNotification();
+}
+
+void HatsNotificationController::ShowNotification() {
+  std::unique_ptr<Notification> notification(CreateNotification());
+  g_browser_process->notification_ui_manager()->Add(*notification, profile_);
+}
+
 Notification* HatsNotificationController::CreateNotification() {
   message_center::RichNotificationData optional;
   optional.buttons.push_back(message_center::ButtonInfo(
diff --git a/chrome/browser/chromeos/hats/hats_notification_controller.h b/chrome/browser/chromeos/hats/hats_notification_controller.h
index c6bd83b..bcd4599 100644
--- a/chrome/browser/chromeos/hats/hats_notification_controller.h
+++ b/chrome/browser/chromeos/hats/hats_notification_controller.h
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "chrome/browser/notifications/notification.h"
 #include "chrome/browser/notifications/notification_delegate.h"
+#include "chromeos/network/portal_detector/network_portal_detector.h"
 
 class Profile;
 class NetworkState;
@@ -16,7 +17,8 @@
 
 // Happiness tracking survey (HaTS) notification controller is responsible for
 // managing the HaTS notification that is displayed to the user.
-class HatsNotificationController : public NotificationDelegate {
+class HatsNotificationController : public NotificationDelegate,
+                                   public NetworkPortalDetector::Observer {
  public:
   static const char kDelegateId[];
   static const char kNotificationId[];
@@ -34,6 +36,12 @@
   void Close(bool by_user) override;
   std::string id() const override;
 
+  // NetworkPortalDetector::Observer override:
+  void OnPortalDetectionCompleted(
+      const NetworkState* network,
+      const NetworkPortalDetector::CaptivePortalState& state) override;
+
+  void ShowNotification();
   Notification* CreateNotification();
 
   Profile* profile_;
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
index d0e8d5f..0342cac3 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -1299,7 +1299,7 @@
   EXPECT_TRUE(all_settings_dictionary->empty());
 }
 
-TEST_F(HostContentSettingsMapTest, MigrateOldSettings) {
+TEST_F(HostContentSettingsMapTest, MigrateKeygenSettings) {
   TestingProfile profile;
   HostContentSettingsMap* host_content_settings_map =
       HostContentSettingsMapFactory::GetForProfile(&profile);
@@ -1326,7 +1326,7 @@
             host_content_settings_map->GetContentSetting(
                 host, host, CONTENT_SETTINGS_TYPE_KEYGEN, std::string()));
 
-  host_content_settings_map->MigrateOldSettings();
+  host_content_settings_map->MigrateKeygenSettings();
 
   ContentSettingsForOneType settings;
   host_content_settings_map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_KEYGEN,
diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc
index b10215d..0402aac 100644
--- a/chrome/browser/extensions/extension_apitest.cc
+++ b/chrome/browser/extensions/extension_apitest.cc
@@ -264,8 +264,7 @@
 
 bool ExtensionApiTest::RunPlatformAppTestWithArg(
     const std::string& extension_name, const char* custom_arg) {
-  return RunExtensionTestImpl(
-      extension_name, std::string(), custom_arg, kFlagLaunchPlatformApp);
+  return RunPlatformAppTestWithFlags(extension_name, custom_arg, kFlagNone);
 }
 
 bool ExtensionApiTest::RunPlatformAppTestWithFlags(
@@ -274,6 +273,15 @@
       extension_name, std::string(), NULL, flags | kFlagLaunchPlatformApp);
 }
 
+bool ExtensionApiTest::RunPlatformAppTestWithFlags(
+    const std::string& extension_name,
+    const char* custom_arg,
+    int flags) {
+  return RunExtensionTestImpl(extension_name, std::string(), custom_arg,
+                              flags | kFlagLaunchPlatformApp);
+}
+
+
 // Load |extension_name| extension and/or |page_url| and wait for
 // PASSED or FAILED notification.
 bool ExtensionApiTest::RunExtensionTestImpl(const std::string& extension_name,
diff --git a/chrome/browser/extensions/extension_apitest.h b/chrome/browser/extensions/extension_apitest.h
index 009ffdc..84788ce 100644
--- a/chrome/browser/extensions/extension_apitest.h
+++ b/chrome/browser/extensions/extension_apitest.h
@@ -134,11 +134,18 @@
   bool RunPlatformAppTestWithArg(
       const std::string& extension_name, const char* custom_arg);
 
+
   // Similar to RunPlatformAppTest, with custom |flags| (as defined in the Flags
   // enum). The kFlagLaunchPlatformApp flag is automatically added.
   bool RunPlatformAppTestWithFlags(const std::string& extension_name,
                                    int flags);
 
+  // Similar to RunPlatformAppTestWithFlags above, except it has an additional
+  // string argument |customArg| to the test config object.
+  bool RunPlatformAppTestWithFlags(const std::string& extension_name,
+                                   const char* custom_arg,
+                                   int flags);
+
   // Start the test server, and store details of its state.  Those details
   // will be available to javascript tests using chrome.test.getConfig().
   bool StartEmbeddedTestServer();
diff --git a/chrome/browser/resources/md_history/app.html b/chrome/browser/resources/md_history/app.html
index 80347a9..cae5526 100644
--- a/chrome/browser/resources/md_history/app.html
+++ b/chrome/browser/resources/md_history/app.html
@@ -64,8 +64,11 @@
               searched-term="[[queryState_.info.term]]">
           </history-grouped-list>
         </template>
-        <history-synced-device-manager id="history-synced-device-manager">
-        </history-synced-device-manager>
+        <template is="dom-if" if="[[syncedTabsSelected_(selectedPage_)]]">
+          <history-synced-device-manager id="history-synced-device-manager"
+              session-list="[[queryState_.sessionList]]">
+          </history-synced-device-manager>
+        </template>
       </iron-pages>
     </div>
   </template>
diff --git a/chrome/browser/resources/md_history/app.js b/chrome/browser/resources/md_history/app.js
index ae9118f..a16204324a 100644
--- a/chrome/browser/resources/md_history/app.js
+++ b/chrome/browser/resources/md_history/app.js
@@ -8,7 +8,8 @@
  *            results: ?Array<!HistoryEntry>,
  *            info: ?HistoryQuery,
  *            range: HistoryRange,
- *            groupedOffset: number}}
+ *            groupedOffset: number,
+ *            sessionList: ?Array<!ForeignSession>}}
  */
 var QueryState;
 
@@ -17,9 +18,7 @@
 
   properties: {
     // The id of the currently selected page.
-    selectedPage_: {
-      type: String,
-    },
+    selectedPage_: String,
 
     // Whether domain-grouped history is enabled.
     grouped_: Boolean,
@@ -45,6 +44,7 @@
           range: HistoryRange.ALL_TIME,
           // TODO(calamity): Make history toolbar buttons change the offset.
           groupedOffset: 0,
+          sessionList: null,
         };
       }
     },
@@ -201,12 +201,7 @@
     if (!isTabSyncEnabled)
       return;
 
-    // TODO(calamity): Add a 'no synced devices' message when sessions are
-    // empty.
-    var syncedDeviceElem = this.$['history-synced-device-manager'];
-    var syncedDeviceManager =
-        /** @type {HistorySyncedDeviceManagerElement} */(syncedDeviceElem);
-    syncedDeviceManager.setSyncedHistory(sessionList);
+    this.set('queryState_.sessionList', sessionList);
   },
 
   getSelectedPage: function(selectedPage, range) {
@@ -215,4 +210,8 @@
 
     return selectedPage;
   },
+
+  syncedTabsSelected_(selectedPage) {
+    return selectedPage == 'history-synced-device-manager';
+  }
 });
diff --git a/chrome/browser/resources/md_history/compiled_resources2.gyp b/chrome/browser/resources/md_history/compiled_resources2.gyp
index 7429be3..589cd18 100644
--- a/chrome/browser/resources/md_history/compiled_resources2.gyp
+++ b/chrome/browser/resources/md_history/compiled_resources2.gyp
@@ -53,7 +53,7 @@
     {
       'target_name': 'history_toolbar',
       'dependencies': [
-        '<(DEPTH)/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp:cr_search_field',
+        '<(DEPTH)/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp:cr_toolbar',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
       ],
diff --git a/chrome/browser/resources/md_history/history_toolbar.html b/chrome/browser/resources/md_history/history_toolbar.html
index 6eb2e583..c0478e41 100644
--- a/chrome/browser/resources/md_history/history_toolbar.html
+++ b/chrome/browser/resources/md_history/history_toolbar.html
@@ -1,13 +1,12 @@
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/hardware-icons.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/hardware-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-tabs/paper-tab.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-tabs/paper-tabs.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_search_field/cr_search_field.html">
+<link rel="import" href="chrome://resources/cr_elements/icons.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html">
 <link rel="import" href="chrome://history/shared_style.html">
 
 <dom-module id="history-toolbar">
@@ -19,10 +18,9 @@
         width: 100%;
       }
 
+      cr-toolbar,
       #overlay-buttons,
       #overlay-wrapper,
-      #main-content,
-      #button-container,
       #toolbar-container {
         @apply(--layout-center);
         @apply(--layout-horizontal);
@@ -33,49 +31,10 @@
         background: rgb(68, 136, 255);
       }
 
-      h1 {
-        @apply(--layout-flex);
-        -webkit-padding-start: 24px;
-        font-size: 123%;
-        font-weight: 400;
-      }
-
       #toolbar-container {
         height: 56px;
       }
 
-      #right-content {
-        flex: 1 0 0;
-      }
-
-      #left-content {
-        flex: 1 0 var(--side-bar-width);
-      }
-
-      #centered-content {
-        /** Padding-start gives space on one side, flex-basis gives space on the
-          other. */
-        -webkit-padding-start: var(--card-padding-side);
-        display: flex;
-        flex: 1 1 calc(var(--card-max-width) + var(--card-padding-side));
-      }
-
-      #right-content {
-        @apply(--layout-center);
-        @apply(--layout-horizontal);
-        justify-content: flex-end;
-      }
-
-      #search-input {
-        -webkit-padding-end: 20px;
-      }
-
-      #searching-spinner {
-        height: 20px;
-        width: 20px;
-        -webkit-padding-end: 10px;
-      }
-
       #overlay-buttons {
         margin: 0 auto;
         max-width: var(--card-max-width);
@@ -155,21 +114,10 @@
       }
     </style>
     <div id="toolbar-container">
-      <div id="main-content" hidden$="[[itemsSelected_]]">
-        <div id="left-content">
-          <h1 id="title">$i18n{title}</h1>
-        </div>
-        <div id="centered-content">
-          <div id="right-content">
-            <paper-spinner id="searching-spinner" active="[[searching]]">
-            </paper-spinner>
-            <cr-search-field id="search-input" label="$i18n{search}"
-                clear-label="$i18n{clearSearch}">
-            </cr-search-field>
-          </div>
-        </div>
-      </div>
-
+      <cr-toolbar id="main-toolbar" page-name="$i18n{title}"
+          clear-label="$i18n{clearSearch}" search-prompt="$i18n{searchPrompt}"
+          hidden$="[[itemsSelected_]]">
+      </cr-toolbar>
       <div id="overlay-wrapper" hidden$="[[!itemsSelected_]]">
         <div id="overlay-buttons">
           <paper-icon-button icon="cr:clear" id="cancel-icon-button"
diff --git a/chrome/browser/resources/md_history/history_toolbar.js b/chrome/browser/resources/md_history/history_toolbar.js
index 94c954e..6881058 100644
--- a/chrome/browser/resources/md_history/history_toolbar.js
+++ b/chrome/browser/resources/md_history/history_toolbar.js
@@ -89,7 +89,8 @@
       return;
 
     this.searchTerm = search;
-    var searchField = /** @type {SearchField} */(this.$['search-input']);
+    var searchField = /** @type {!CrToolbarElement} */(this.$['main-toolbar'])
+                          .getSearchField();
     searchField.showAndFocus().then(function(showing) {
       if (showing) searchField.setValue(search);
     });
@@ -105,7 +106,7 @@
 
   attached: function() {
     this.searchFieldDelegate_ = new ToolbarSearchFieldDelegate(this);
-    /** @type {SearchField} */(this.$['search-input'])
+    /** @type {!CrToolbarElement} */(this.$['main-toolbar']).getSearchField()
         .setDelegate(this.searchFieldDelegate_);
   },
 
diff --git a/chrome/browser/resources/md_history/synced_device_manager.html b/chrome/browser/resources/md_history/synced_device_manager.html
index 7f86a25..7165416 100644
--- a/chrome/browser/resources/md_history/synced_device_manager.html
+++ b/chrome/browser/resources/md_history/synced_device_manager.html
@@ -15,7 +15,7 @@
         padding-top: var(--first-card-padding-top);
       }
     </style>
-    <template is="dom-repeat" items="[[syncedDevices]]" as="syncedDevice">
+    <template is="dom-repeat" items="[[syncedDevices_]]" as="syncedDevice">
       <history-synced-device-card device="[[syncedDevice.device]]"
           last-update-time="[[syncedDevice.lastUpdateTime]]"
           tabs="[[syncedDevice.tabs]]">
diff --git a/chrome/browser/resources/md_history/synced_device_manager.js b/chrome/browser/resources/md_history/synced_device_manager.js
index aab4aefc..606f6646 100644
--- a/chrome/browser/resources/md_history/synced_device_manager.js
+++ b/chrome/browser/resources/md_history/synced_device_manager.js
@@ -16,10 +16,18 @@
 
   properties: {
     /**
+     * @type {?Array<!ForeignSession>}
+     */
+    sessionList: {
+      type: Array,
+      observer: 'setSyncedHistory',
+    },
+
+    /**
      * An array of synced devices with synced tab data.
      * @type {!Array<!ForeignDeviceInternal>}
      */
-    syncedDevices: {
+    syncedDevices_: {
       type: Array,
       value: function() { return []; }
     }
@@ -57,20 +65,23 @@
    * @param {!Array<!ForeignSession>} sessionList
    */
   setSyncedHistory: function(sessionList) {
+    if (!sessionList)
+      return;
+
     // First, update any existing devices that have changed.
-    var updateCount = Math.min(sessionList.length, this.syncedDevices.length);
+    var updateCount = Math.min(sessionList.length, this.syncedDevices_.length);
     for (var i = 0; i < updateCount; i++) {
-      var oldDevice = this.syncedDevices[i];
+      var oldDevice = this.syncedDevices_[i];
       if (oldDevice.tag != sessionList[i].tag ||
           oldDevice.timestamp != sessionList[i].timestamp) {
         this.splice(
-            'syncedDevices', i, 1, this.createInternalDevice_(sessionList[i]));
+            'syncedDevices_', i, 1, this.createInternalDevice_(sessionList[i]));
       }
     }
 
     // Then, append any new devices.
     for (var i = updateCount; i < sessionList.length; i++) {
-      this.push('syncedDevices', this.createInternalDevice_(sessionList[i]));
+      this.push('syncedDevices_', this.createInternalDevice_(sessionList[i]));
     }
   }
 });
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index 84b37586b..c8f7ef9 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -129,6 +129,9 @@
           <button id="display-options" i18n-content="displayOptions" disabled>
           </button>
         </span>
+        <button id="storage-manager-button"
+            i18n-content="storageManagerButtonTitle" hidden>
+        </button>
       </div>
       <div id="power-row" hidden>
         <a is="action-link" id="power-settings-link"
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js
index 2bc11d18..2a733d6 100644
--- a/chrome/browser/resources/options/browser_options.js
+++ b/chrome/browser/resources/options/browser_options.js
@@ -351,6 +351,12 @@
           chrome.send('coreOptionsUserMetricsAction',
                       ['Options_ShowTouchpadSettings']);
         };
+        if (loadTimeData.getBoolean('enableStorageManager')) {
+          $('storage-manager-button').hidden = false;
+          $('storage-manager-button').onclick = function(evt) {
+            PageManager.showPageByName('storage');
+          };
+        }
       }
 
       // Search section.
diff --git a/chrome/browser/resources/options/chromeos/storage_manager.css b/chrome/browser/resources/options/chromeos/storage_manager.css
new file mode 100644
index 0000000..e2d5c45
--- /dev/null
+++ b/chrome/browser/resources/options/chromeos/storage_manager.css
@@ -0,0 +1,7 @@
+/* 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. */
+
+#storageManagerPage {
+  min-width: 292px;
+}
diff --git a/chrome/browser/resources/options/chromeos/storage_manager.html b/chrome/browser/resources/options/chromeos/storage_manager.html
new file mode 100644
index 0000000..6ecbc69
--- /dev/null
+++ b/chrome/browser/resources/options/chromeos/storage_manager.html
@@ -0,0 +1,12 @@
+<div id="storageManagerPage" class="page" hidden>
+  <div class="close-button"></div>
+  <h1 i18n-content="storageManagerPage"></h1>
+
+  <div class="action-area">
+    <div class="button-strip">
+      <button id="storage-confirm" class="default-button"
+          i18n-content="done">
+      </button>
+    </div>
+  </div>
+</div>
diff --git a/chrome/browser/resources/options/chromeos/storage_manager.js b/chrome/browser/resources/options/chromeos/storage_manager.js
new file mode 100644
index 0000000..15d1b73
--- /dev/null
+++ b/chrome/browser/resources/options/chromeos/storage_manager.js
@@ -0,0 +1,33 @@
+// 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.
+
+cr.define('options', function() {
+  var Page = cr.ui.pageManager.Page;
+  var PageManager = cr.ui.pageManager.PageManager;
+
+  function StorageManager() {
+    Page.call(this, 'storage',
+              loadTimeData.getString('storageManagerPageTabTitle'),
+              'storageManagerPage');
+  }
+
+  cr.addSingletonGetter(StorageManager);
+
+  StorageManager.prototype = {
+    __proto__: Page.prototype,
+
+    /** @override */
+    initializePage: function() {
+      Page.prototype.initializePage.call(this);
+
+      $('storage-confirm').onclick = function() {
+        PageManager.closeOverlay();
+      };
+    }
+  };
+
+  return {
+    StorageManager: StorageManager
+  };
+});
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html
index 2b1b3f19..1b6e35e 100644
--- a/chrome/browser/resources/options/options.html
+++ b/chrome/browser/resources/options/options.html
@@ -61,6 +61,7 @@
 <link rel="stylesheet" href="chromeos/internet_detail.css">
 <link rel="stylesheet" href="chromeos/keyboard_overlay.css">
 <link rel="stylesheet" href="chromeos/pointer_overlay.css">
+<link rel="stylesheet" href="chromeos/storage_manager.css">
 <link rel="stylesheet" href="factory_reset_overlay.css">
 <link rel="stylesheet" href="../help/channel_change_page.css">
 </if>
@@ -139,6 +140,7 @@
   <include src="chromeos/keyboard_overlay.html">
   <include src="chromeos/pointer_overlay.html">
   <include src="chromeos/power_overlay.html">
+  <include src="chromeos/storage_manager.html">
   <include src="factory_reset_overlay.html">
 </if>
 <if expr="use_nss_certs">
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js
index bbfbf474..efbf7db5 100644
--- a/chrome/browser/resources/options/options.js
+++ b/chrome/browser/resources/options/options.js
@@ -223,6 +223,9 @@
     PageManager.registerOverlay(PowerOverlay.getInstance(),
                                 BrowserOptions.getInstance(),
                                 [$('power-settings-link')]);
+    PageManager.registerOverlay(StorageManager.getInstance(),
+                                BrowserOptions.getInstance(),
+                                [$('storage-manager-button')]);
     PageManager.registerOverlay(ThirdPartyImeConfirmOverlay.getInstance(),
                                 LanguageOptions.getInstance());
   }
diff --git a/chrome/browser/resources/options/options_bundle.js b/chrome/browser/resources/options/options_bundle.js
index e1b6e3b..a458baa 100644
--- a/chrome/browser/resources/options/options_bundle.js
+++ b/chrome/browser/resources/options/options_bundle.js
@@ -39,6 +39,7 @@
 <include src="chromeos/display_overscan.js">
 <include src="chromeos/keyboard_overlay.js">
 <include src="chromeos/pointer_overlay.js">
+<include src="chromeos/storage_manager.js">
 <include src="chromeos/third_party_ime_confirm_overlay.js">
 <include src="chromeos/power_overlay.js">
 var AccountsOptions = options.AccountsOptions;
@@ -52,6 +53,7 @@
 var KeyboardOverlay = options.KeyboardOverlay;
 var PointerOverlay = options.PointerOverlay;
 var PowerOverlay = options.PowerOverlay;
+var StorageManager = options.StorageManager;
 var UIAccountTweaks = uiAccountTweaks.UIAccountTweaks;
 </if>
 <if expr="use_nss_certs">
diff --git a/chrome/browser/resources/safe_browsing/BUILD.gn b/chrome/browser/resources/safe_browsing/BUILD.gn
index 6793358..6149d24 100644
--- a/chrome/browser/resources/safe_browsing/BUILD.gn
+++ b/chrome/browser/resources/safe_browsing/BUILD.gn
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(nparker): reduce the duplication between these two, somehow.
+
 # Generate the binary proto form of "file_types" from the ascii proto.
 action("make_file_types_protobuf") {
   script = "gen_file_type_proto.py"
@@ -10,7 +12,8 @@
   # chrome/browser/browser_resources.grd will look for it.
 
   input_filename = "download_file_types.asciipb"
-  output_filename = "$target_gen_dir/download_file_types.pb"
+  output_dir = target_gen_dir
+  output_basename = "download_file_types.pb"
   python_path_root = "$root_build_dir/pyproto"
   python_path_safe_browsing = "$python_path_root/chrome/common/safe_browsing"
 
@@ -32,18 +35,16 @@
   }
 
   inputs = [
-    script,
     input_filename,
   ]
 
-  # This script requires the generated python proto code
   deps = [
     "//chrome/common/safe_browsing:proto",
     "//third_party/protobuf:py_proto",
   ]
 
   outputs = [
-    output_filename,
+    "$output_dir/$output_basename",
   ]
 
   args = [
@@ -52,8 +53,51 @@
     target_arch,
     "-i",
     rebase_path(input_filename, root_build_dir),
+    "-d",
+    rebase_path(output_dir, root_build_dir),
     "-o",
-    rebase_path(output_filename, root_build_dir),
+    output_basename,
+    "-p",
+    rebase_path(python_path_root, root_build_dir),
+    "-p",
+    rebase_path(python_path_safe_browsing, root_build_dir),
+  ]
+}
+
+# Generate the binary proto for ALL platforms.  This is only run manually
+# when pushing the files to GCS for the component-updater to pick up.
+action("make_all_file_types_protobuf") {
+  script = "gen_file_type_proto.py"
+
+  input_filename = "download_file_types.asciipb"
+  output_dir = "$target_gen_dir/all"
+  output_basename = "download_file_types.pb"
+  python_path_root = "$root_build_dir/pyproto"
+  python_path_safe_browsing = "$python_path_root/chrome/common/safe_browsing"
+
+  inputs = [
+    input_filename,
+  ]
+
+  deps = [
+    "//chrome/common/safe_browsing:proto",
+    "//third_party/protobuf:py_proto",
+  ]
+
+  # A directory, since we can't derive the actual file names here.
+  outputs = [
+    output_dir,
+  ]
+
+  args = [
+    "-w",
+    "-a",
+    "-i",
+    rebase_path(input_filename, root_build_dir),
+    "-d",
+    rebase_path(output_dir, root_build_dir),
+    "-o",
+    output_basename,
     "-p",
     rebase_path(python_path_root, root_build_dir),
     "-p",
diff --git a/chrome/browser/resources/safe_browsing/README.md b/chrome/browser/resources/safe_browsing/README.md
index 503b016..61f2096 100644
--- a/chrome/browser/resources/safe_browsing/README.md
+++ b/chrome/browser/resources/safe_browsing/README.md
@@ -3,16 +3,26 @@
 This describes how to adjust file-type download behavior in
 Chrome including interactions with Safe Browsing. The metadata described
 here, and stored in `download_file_types.asciipb`, will be both baked into
-Chrome released and pushable to Chrome between releases. http://crbug.com/596555
+Chrome released and pushable to Chrome between releases (via
+`FileTypePolicies` class).  http://crbug.com/596555
 
 Rendered version of this file: https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/resources/safe_browsing/README.md
 
 
-## Procedure for adding a new type
-  * Edit `download_file_types.asciipb`, edit `download_stats.cc` (necessary
-    until it gets replaced), and update `histograms.xml`
-  * Get it reviewed, submit.
-  * Push via component update (PROCEDURE TBD)
+## Procedure for adding/modifying file type(s)
+  * **Edit** `download_file_types.asciipb` and update `histograms.xml`
+  * Get it reviewed, **submit.**
+  * **Push** it to all users via component update:
+    * Wait 1-3 day for this to run on Canary to verify it doesn't crash Chrome.
+    * In a synced checkout, generate protos for all platforms:
+        * % `ninja -C out-gn/Debug
+         chrome/browser/resources/safe_browsing:make_all_file_types_protobuf`
+    * That will instruct you to run another command to push the files to GCS.
+      You must a member of chrome-file-type-policies-pushers@google.com to have
+      access to the GCS bucket.
+    * The Component Updater system will notice those files and push them to
+      users withing ~6 hours. If not, contact `waffles@.`
+
 
 ## Guidelines for a DownloadFileType entry:
 See `download_file_types.proto` for all fields.
diff --git a/chrome/browser/resources/safe_browsing/gen_file_type_proto.py b/chrome/browser/resources/safe_browsing/gen_file_type_proto.py
index 1e55f9a1..63ed686 100755
--- a/chrome/browser/resources/safe_browsing/gen_file_type_proto.py
+++ b/chrome/browser/resources/safe_browsing/gen_file_type_proto.py
@@ -11,9 +11,11 @@
 """
 
 import optparse
+import os
 import re
 import subprocess
 import sys
+import traceback
 
 
 def ImportProtoModules(paths):
@@ -93,6 +95,7 @@
 
 def FilterPbForPlatform(full_pb, platform_type):
   """ Return a filtered protobuf for this platform_type """
+  assert type(platform_type) is int, "Bad platform_type type"
 
   new_pb = config_pb2.DownloadFileTypeConfig();
   new_pb.CopyFrom(full_pb)
@@ -127,25 +130,59 @@
   return new_pb
 
 
-def GeneratBinaryProtos(opts):
-  # Read the ASCII
-  ifile = open(opts.infile, 'r')
-  ascii_pb_str = ifile.read()
-  ifile.close()
-
-  # Parse it into a structure PB
-  pb = config_pb2.DownloadFileTypeConfig()
-  text_format.Merge(ascii_pb_str, pb)
-
-  ValidatePb(pb);
-  platform_type = PlatformTypes()[opts.type]
-  filtered_pb = FilterPbForPlatform(pb, platform_type);
+def FilterForPlatformAndWrite(full_pb, platform_type, outfile):
+  """ Filter and write out a file for this platform """
+  # Filter it
+  filtered_pb = FilterPbForPlatform(full_pb, platform_type);
 
   # Serialize it
   binary_pb_str = filtered_pb.SerializeToString()
 
   # Write it to disk
-  open(opts.outfile, 'wb').write(binary_pb_str)
+  open(outfile, 'wb').write(binary_pb_str)
+
+
+def MakeSubDirs(outfile):
+  """ Make the subdirectories needed to create file |outfile| """
+  dirname = os.path.dirname(outfile)
+  if not os.path.exists(dirname):
+    os.makedirs(dirname)
+
+
+def GenerateBinaryProtos(opts):
+  """ Read the ASCII proto and generate one or more binary protos. """
+  # Read the ASCII
+  ifile = open(opts.infile, 'r')
+  ascii_pb_str = ifile.read()
+  ifile.close()
+
+  # Parse it into a structured PB
+  full_pb = config_pb2.DownloadFileTypeConfig()
+  text_format.Merge(ascii_pb_str, full_pb)
+
+  ValidatePb(full_pb);
+
+  if opts.type is not None:
+    # Just one platform type
+    platform_enum = PlatformTypes()[opts.type]
+    outfile = os.path.join(opts.outdir, opts.outbasename)
+    FilterForPlatformAndWrite(full_pb, platform_enum, outfile)
+  else:
+    # Make a separate file for each platform
+    for platform_type, platform_enum in PlatformTypes().iteritems():
+      # e.g. .../all/77/chromeos/download_file_types.pb
+      outfile = os.path.join(opts.outdir,
+                             str(full_pb.version_id),
+                             platform_type,
+                             opts.outbasename)
+      MakeSubDirs(outfile)
+      FilterForPlatformAndWrite(full_pb, platform_enum, outfile)
+
+    print "\n\nTo push these files, run the following:"
+    print ("python " +
+           "chrome/browser/resources/safe_browsing/push_file_type_proto.py " +
+           "-d " + os.path.abspath(opts.outdir))
+    print "\n\n"
 
 
 def main():
@@ -155,44 +192,59 @@
                      help='Wrap this script in another python '
                      'execution to disable site-packages.  This is a '
                      'fix for http://crbug.com/605592')
+
+  parser.add_option('-a', '--all', action="store_true", default=False,
+                     help='Write a separate file for every platform. '
+                    'Outfile must have a %d for version and %s for platform.')
   parser.add_option('-t', '--type',
                     help='The platform type. One of android, chromeos, ' +
                     'linux, mac, win')
   parser.add_option('-i', '--infile',
                     help='The ASCII DownloadFileType-proto file to read.')
-  parser.add_option('-o', '--outfile',
-                    help='The binary file to write to.')
+  parser.add_option('-d', '--outdir',
+                    help='Directory underwhich binary file(s) will be written')
+  parser.add_option('-o', '--outbasename',
+                    help='Basename of the binary file to write to.')
   parser.add_option('-p', '--path', action="append",
                     help='Repeat this as needed.  Directory(s) containing ' +
                     'the download_file_types_pb2.py and ' +
                     'google.protobuf.text_format modules')
   (opts, args) = parser.parse_args()
-  if opts.infile is None or opts.outfile is None:
+  if opts.infile is None or opts.outdir is None or opts.outbasename is None:
     parser.print_help()
     return 1
 
   if opts.wrap:
     # Run this script again with different args to the interpreter.
     command = [sys.executable, '-S', '-s', sys.argv[0]]
-    command += ['-t', opts.type]
+    if opts.type is not None:
+      command += ['-t', opts.type]
+    if opts.all:
+      command += ['-a']
     command += ['-i', opts.infile]
-    command += ['-o', opts.outfile]
+    command += ['-d', opts.outdir]
+    command += ['-o', opts.outbasename]
     for path in opts.path:
       command += ['-p', path]
     sys.exit(subprocess.call(command))
 
   ImportProtoModules(opts.path)
 
-  if (opts.type not in PlatformTypes()):
+  if (not opts.all and opts.type not in PlatformTypes()):
     print "ERROR: Unknown platform type '%s'" % opts.type
     parser.print_help()
     return 1
 
+  if (bool(opts.all) == bool(opts.type)):
+    print "ERROR: Need exactly one of --type or --all"
+    parser.print_help()
+    return 1
+
   try:
-    GeneratBinaryProtos(opts)
+    GenerateBinaryProtos(opts)
   except Exception as e:
-    print "ERROR: Failed to render binary version of %s:\n  %s\n" % (
-        opts.infile, str(e))
+    print "ERROR: Failed to render binary version of %s:\n  %s\n%s" % (
+        opts.infile, str(e), traceback.format_exc())
     return 1
 
 
diff --git a/chrome/browser/resources/safe_browsing/push_file_type_proto.py b/chrome/browser/resources/safe_browsing/push_file_type_proto.py
new file mode 100755
index 0000000..0256ee8
--- /dev/null
+++ b/chrome/browser/resources/safe_browsing/push_file_type_proto.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+# 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.
+
+# Push the {vers}/{plaform}/download_file_types.pb files to GCS so
+# that the component update system will pick them up and push them
+# to users.  See README.md before running this.
+
+import optparse
+import os
+import subprocess
+import sys
+
+
+DEST_BUCKET = 'gs://chrome-component-file-type-policies'
+
+
+def main():
+  parser = optparse.OptionParser()
+  parser.add_option('-d', '--dir',
+                    help='The directory containing '
+                    '{vers}/{platform}/download_file_types.pb files.')
+
+  (opts, args) = parser.parse_args()
+  if opts.dir is None:
+    parser.print_help()
+    return 1
+
+  os.chdir(opts.dir)
+
+  # Sanity check that we're in the right place
+  assert opts.dir.endswith('/all'), '--dir should end with /all'
+  dirs = os.listdir('.')
+  assert (len(dirs) == 1 and dirs[0].isdigit()), (
+      'Should be exactly one version directory. Please delete the contents '
+      'of the target dir and regenerate the protos.')
+
+  # Push the files with their directories, in the form
+  #   {vers}/{platform}/download_file_types.pb
+  # Don't overwrite existing files, incase we forgot to increment the
+  # version.
+  vers_dir = dirs[0]
+  command = ['gsutil', 'cp', '-Rn', vers_dir, DEST_BUCKET]
+
+  print 'Going to run the following command'
+  print '   ', ' '.join(command)
+  print '\nIn directory'
+  print '   ', opts.dir
+  print '\nWhich should push the following files'
+  expected_files = [os.path.join(dp, f) for dp, dn, fn in
+                    os.walk(vers_dir) for f in fn]
+  for f in expected_files:
+    print '   ', f
+
+  shall = raw_input('\nAre you sure (y/N) ').lower() == 'y'
+  if not shall:
+    print 'aborting'
+    return 1
+  return subprocess.call(command)
+
+
+if __name__ == '__main__':
+  sys.exit(main())
+
diff --git a/chrome/browser/task_management/providers/arc/arc_process_task.cc b/chrome/browser/task_management/providers/arc/arc_process_task.cc
index c957d8d..f37c7f3 100644
--- a/chrome/browser/task_management/providers/arc/arc_process_task.cc
+++ b/chrome/browser/task_management/providers/arc/arc_process_task.cc
@@ -8,6 +8,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/common/process.mojom.h"
 #include "content/public/common/child_process_host.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -28,10 +29,12 @@
 ArcProcessTask::ArcProcessTask(
     base::ProcessId pid,
     base::ProcessId nspid,
-    const std::string& process_name)
+    const std::string& process_name,
+    arc::mojom::ProcessState process_state)
     : Task(MakeTitle(process_name), process_name, nullptr, pid),
       nspid_(nspid),
-      process_name_(process_name) {
+      process_name_(process_name),
+      process_state_(process_state) {
 }
 
 ArcProcessTask::~ArcProcessTask() {
@@ -46,6 +49,11 @@
   return content::ChildProcessHost::kInvalidUniqueID;
 }
 
+bool ArcProcessTask::IsKillable() {
+  // Do not kill persistent processes.
+  return process_state_ > arc::mojom::ProcessState::PERSISTENT_UI;
+}
+
 void ArcProcessTask::Kill() {
   arc::mojom::ProcessInstance* arc_process_instance =
       arc::ArcBridgeService::Get()->process_instance();
@@ -61,4 +69,8 @@
       nspid_, "Killed manually from Task Manager");
 }
 
+void ArcProcessTask::SetProcessState(arc::mojom::ProcessState process_state) {
+  process_state_ = process_state;
+}
+
 }  // namespace task_management
diff --git a/chrome/browser/task_management/providers/arc/arc_process_task.h b/chrome/browser/task_management/providers/arc/arc_process_task.h
index 3a873597..8acc525e 100644
--- a/chrome/browser/task_management/providers/arc/arc_process_task.h
+++ b/chrome/browser/task_management/providers/arc/arc_process_task.h
@@ -9,6 +9,7 @@
 
 #include "base/macros.h"
 #include "chrome/browser/task_management/providers/task.h"
+#include "components/arc/common/process.mojom.h"
 
 namespace task_management {
 
@@ -18,20 +19,25 @@
   ArcProcessTask(
       base::ProcessId pid,
       base::ProcessId nspid,
-      const std::string& process_name);
+      const std::string& process_name,
+      arc::mojom::ProcessState process_state);
   ~ArcProcessTask() override;
 
   // task_management::Task:
   Type GetType() const override;
   int GetChildProcessUniqueID() const override;
+  bool IsKillable() override;
   void Kill() override;
 
+  void SetProcessState(arc::mojom::ProcessState process_state);
+
   base::ProcessId nspid() const { return nspid_; }
   const std::string& process_name() const { return process_name_; }
 
  private:
   const base::ProcessId nspid_;
   const std::string process_name_;
+  arc::mojom::ProcessState process_state_;
 
   DISALLOW_COPY_AND_ASSIGN(ArcProcessTask);
 };
diff --git a/chrome/browser/task_management/providers/arc/arc_process_task_provider.cc b/chrome/browser/task_management/providers/arc/arc_process_task_provider.cc
index ca42ef36..dff7a7b 100644
--- a/chrome/browser/task_management/providers/arc/arc_process_task_provider.cc
+++ b/chrome/browser/task_management/providers/arc/arc_process_task_provider.cc
@@ -17,6 +17,7 @@
 #include "base/trace_event/trace_event.h"
 #include "chrome/browser/chromeos/arc/arc_process.h"
 #include "chrome/browser/chromeos/arc/arc_process_service.h"
+#include "components/arc/common/process.mojom.h"
 
 namespace task_management {
 
@@ -55,28 +56,34 @@
   // ArcProcessTaskProvider.
 
   set<ProcessId> nspid_to_remove;
-  for (const auto& it : nspid_to_task_)
-    nspid_to_remove.insert(it.first);
+  for (const auto& entry : nspid_to_task_)
+    nspid_to_remove.insert(entry.first);
 
-  for (const auto& it : processes) {
-    if (nspid_to_remove.erase(it.nspid) == 0) {
+  for (const auto& entry : processes) {
+    if (nspid_to_remove.erase(entry.nspid) == 0) {
       // New arc process.
-      std::unique_ptr<ArcProcessTask>& task = nspid_to_task_[it.nspid];
+      std::unique_ptr<ArcProcessTask>& task = nspid_to_task_[entry.nspid];
       // After calling NotifyObserverTaskAdded(), the raw pointer of |task| is
       // remebered somewhere else. One should not (implicitly) delete the
       // referenced object before calling NotifyObserverTaskRemoved() first
       // (crbug.com/587707).
       DCHECK(!task.get()) <<
           "Task with the same pid should not be added twice.";
-      task.reset(new ArcProcessTask(it.pid, it.nspid, it.process_name));
+      task.reset(new ArcProcessTask(
+          entry.pid, entry.nspid, entry.process_name, entry.process_state));
       NotifyObserverTaskAdded(task.get());
+    } else {
+      // Update process state of existing process.
+      std::unique_ptr<ArcProcessTask>& task = nspid_to_task_[entry.nspid];
+      DCHECK(task.get());
+      task->SetProcessState(entry.process_state);
     }
   }
 
-  for (const auto& it : nspid_to_remove) {
+  for (const auto& entry : nspid_to_remove) {
     // Stale arc process.
-    NotifyObserverTaskRemoved(nspid_to_task_[it].get());
-    nspid_to_task_.erase(it);
+    NotifyObserverTaskRemoved(nspid_to_task_[entry].get());
+    nspid_to_task_.erase(entry);
   }
   ScheduleNextRequest();
 }
diff --git a/chrome/browser/task_management/providers/browser_process_task.cc b/chrome/browser/task_management/providers/browser_process_task.cc
index 2e19345..3a9b5cf 100644
--- a/chrome/browser/task_management/providers/browser_process_task.cc
+++ b/chrome/browser/task_management/providers/browser_process_task.cc
@@ -55,6 +55,11 @@
 BrowserProcessTask::~BrowserProcessTask() {
 }
 
+bool BrowserProcessTask::IsKillable() {
+  // Never kill the browser process.
+  return false;
+}
+
 void BrowserProcessTask::Kill() {
   // Never kill the browser process.
 }
diff --git a/chrome/browser/task_management/providers/browser_process_task.h b/chrome/browser/task_management/providers/browser_process_task.h
index 45ccad6de..fe548dd9 100644
--- a/chrome/browser/task_management/providers/browser_process_task.h
+++ b/chrome/browser/task_management/providers/browser_process_task.h
@@ -19,6 +19,7 @@
   ~BrowserProcessTask() override;
 
   // task_management::Task:
+  bool IsKillable() override;
   void Kill() override;
   void Refresh(const base::TimeDelta& update_interval,
                int64_t refresh_flags) override;
diff --git a/chrome/browser/task_management/providers/task.cc b/chrome/browser/task_management/providers/task.cc
index c9ad00b2..f831ec85 100644
--- a/chrome/browser/task_management/providers/task.cc
+++ b/chrome/browser/task_management/providers/task.cc
@@ -58,6 +58,10 @@
 void Task::Activate() {
 }
 
+bool Task::IsKillable() {
+  return true;
+}
+
 void Task::Kill() {
   DCHECK_NE(process_id(), base::GetCurrentProcId());
   base::Process process = base::Process::Open(process_id());
diff --git a/chrome/browser/task_management/providers/task.h b/chrome/browser/task_management/providers/task.h
index 3899d20b..a73090d 100644
--- a/chrome/browser/task_management/providers/task.h
+++ b/chrome/browser/task_management/providers/task.h
@@ -61,6 +61,9 @@
   // (if possible).
   virtual void Activate();
 
+  // Returns if the task should be killable from the Task Manager UI.
+  virtual bool IsKillable();
+
   // Kills this task.
   virtual void Kill();
 
diff --git a/chrome/browser/task_management/sampling/task_manager_impl.cc b/chrome/browser/task_management/sampling/task_manager_impl.cc
index 957bf92..926b55d 100644
--- a/chrome/browser/task_management/sampling/task_manager_impl.cc
+++ b/chrome/browser/task_management/sampling/task_manager_impl.cc
@@ -75,6 +75,10 @@
   GetTaskByTaskId(task_id)->Activate();
 }
 
+bool TaskManagerImpl::IsTaskKillable(TaskId task_id) {
+  return GetTaskByTaskId(task_id)->IsKillable();
+}
+
 void TaskManagerImpl::KillTask(TaskId task_id) {
   GetTaskByTaskId(task_id)->Kill();
 }
diff --git a/chrome/browser/task_management/sampling/task_manager_impl.h b/chrome/browser/task_management/sampling/task_manager_impl.h
index 5dd5d2e..85213a6 100644
--- a/chrome/browser/task_management/sampling/task_manager_impl.h
+++ b/chrome/browser/task_management/sampling/task_manager_impl.h
@@ -36,6 +36,7 @@
 
   // task_management::TaskManagerInterface:
   void ActivateTask(TaskId task_id) override;
+  bool IsTaskKillable(TaskId task_id) override;
   void KillTask(TaskId task_id) override;
   double GetCpuUsage(TaskId task_id) const override;
   int64_t GetPhysicalMemoryUsage(TaskId task_id) const override;
diff --git a/chrome/browser/task_management/task_manager_interface.h b/chrome/browser/task_management/task_manager_interface.h
index 17f61196..cb94748 100644
--- a/chrome/browser/task_management/task_manager_interface.h
+++ b/chrome/browser/task_management/task_manager_interface.h
@@ -62,6 +62,9 @@
   // possible.
   virtual void ActivateTask(TaskId task_id) = 0;
 
+  // Returns if the task is killable.
+  virtual bool IsTaskKillable(TaskId task_id) = 0;
+
   // Kills the task with |task_id|.
   virtual void KillTask(TaskId task_id) = 0;
 
diff --git a/chrome/browser/task_management/test_task_manager.cc b/chrome/browser/task_management/test_task_manager.cc
index 7626d0d..79fd50e 100644
--- a/chrome/browser/task_management/test_task_manager.cc
+++ b/chrome/browser/task_management/test_task_manager.cc
@@ -19,6 +19,10 @@
 void TestTaskManager::ActivateTask(TaskId task_id) {
 }
 
+bool TestTaskManager::IsTaskKillable(TaskId task_id) {
+  return true;
+}
+
 void TestTaskManager::KillTask(TaskId task_id) {
 }
 
diff --git a/chrome/browser/task_management/test_task_manager.h b/chrome/browser/task_management/test_task_manager.h
index b4cc4b1..a38ff45 100644
--- a/chrome/browser/task_management/test_task_manager.h
+++ b/chrome/browser/task_management/test_task_manager.h
@@ -23,6 +23,7 @@
 
   // task_management::TaskManagerInterface:
   void ActivateTask(TaskId task_id) override;
+  bool IsTaskKillable(TaskId task_id) override;
   void KillTask(TaskId task_id) override;
   double GetCpuUsage(TaskId task_id) const override;
   int64_t GetPhysicalMemoryUsage(TaskId task_id) const override;
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
index 28950d5..7387419 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
@@ -1018,9 +1018,9 @@
             ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
                 window(0)->GetRootWindow()));
   EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
-  ash::ShelfWidget* shelf = ash::RootWindowController::ForWindow(
-      window(0))->shelf();
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  ash::ShelfWidget* shelf_widget =
+      ash::RootWindowController::ForWindow(window(0))->shelf_widget();
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
 
   // Start the animation and see that the old window is becoming invisible, the
   // new one is becoming visible, the background starts transitionining and the
@@ -1034,7 +1034,7 @@
   EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
             ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
                 window(0)->GetRootWindow()));
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
 
   // Staring the next step should show the shelf again, but there are many
   // subsystems missing (preferences system, ChromeLauncherController, ...)
@@ -1049,11 +1049,11 @@
   EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
             ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
                 window(0)->GetRootWindow()));
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
 
   // After the finalize the animation of the wallpaper should be finished.
   AdvanceUserTransitionAnimation();
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
   EXPECT_EQ(kBAccountIdString, GetWallpaperUserIdForTest());
 }
 
@@ -1310,22 +1310,22 @@
       chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
   EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
             ash::Shell::GetInstance()->GetShelfAutoHideBehavior(root_window));
-  ash::ShelfWidget* shelf = ash::RootWindowController::ForWindow(
-      root_window)->shelf();
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  ash::ShelfWidget* shelf_widget =
+      ash::RootWindowController::ForWindow(root_window)->shelf_widget();
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
 
   // First test that with no maximized window we show/hide the shelf.
   StartUserTransitionAnimation(account_id_B);
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
   EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
             ash::Shell::GetInstance()->GetShelfAutoHideBehavior(root_window));
 
   // Staring the next step should show the shelf again.
   AdvanceUserTransitionAnimation();
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
 
   AdvanceUserTransitionAnimation();
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
   ash::Shell::GetInstance()->SetShelfAutoHideBehavior(
       ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER, root_window);
 
@@ -1341,18 +1341,18 @@
   // Start the animation and see that the shelf gets hidden by the black bar,
   // and the AutoHide behavior remains as it was.
   StartUserTransitionAnimation(account_id_A);
-  EXPECT_TRUE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_TRUE(shelf_widget->IsShelfHiddenBehindBlackBar());
   EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
             ash::Shell::GetInstance()->GetShelfAutoHideBehavior(root_window));
 
   // Staring the next step should show the shelf again.
   AdvanceUserTransitionAnimation();
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
   EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
             ash::Shell::GetInstance()->GetShelfAutoHideBehavior(root_window));
 
   AdvanceUserTransitionAnimation();
-  EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar());
+  EXPECT_FALSE(shelf_widget->IsShelfHiddenBehindBlackBar());
   window(0)->RemoveObserver(&window_observer);
   window(1)->RemoveObserver(&window_observer);
   // No resize should have been done to the window.
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 87f1fe62..5d97b8f 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -321,14 +321,20 @@
   switch (id) {
     // Navigation commands
     case IDC_BACKSPACE_BACK:
-      if (!base::FeatureList::IsEnabled(kBackspaceGoesBackFeature))
+      if (!base::FeatureList::IsEnabled(kBackspaceGoesBackFeature)) {
+        browser_->window()->ShowNewBackShortcutBubble(false);
         break;
+      }
+      // FALL THROUGH
     case IDC_BACK:
       GoBack(browser_, disposition);
       break;
     case IDC_BACKSPACE_FORWARD:
-      if (!base::FeatureList::IsEnabled(kBackspaceGoesBackFeature))
+      if (!base::FeatureList::IsEnabled(kBackspaceGoesBackFeature)) {
+        browser_->window()->ShowNewBackShortcutBubble(true);
         break;
+      }
+      // FALL THROUGH
     case IDC_FORWARD:
       GoForward(browser_, disposition);
       break;
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h
index 968999d..864cfda 100644
--- a/chrome/browser/ui/browser_dialogs.h
+++ b/chrome/browser/ui/browser_dialogs.h
@@ -18,6 +18,10 @@
 class LoginHandler;
 class Profile;
 
+namespace base {
+struct Feature;
+}
+
 namespace bookmarks {
 class BookmarkBubbleObserver;
 }
@@ -48,6 +52,14 @@
 
 namespace chrome {
 
+#if defined(OS_MACOSX)
+// Makes ToolkitViewsDialogsEnabled() available to chrome://flags.
+extern const base::Feature kMacViewsNativeDialogs;
+
+// Makes ToolkitViewsWebUIDialogsEnabled() available to chrome://flags.
+extern const base::Feature kMacViewsWebUIDialogs;
+#endif  // OS_MACOSX
+
 // Shows or hides the Task Manager. |browser| can be NULL when called from Ash.
 // Returns a pointer to the underlying TableModel, which can be ignored, or used
 // for testing.
@@ -85,12 +97,11 @@
 #if defined(OS_MACOSX)
 
 // For Mac, returns true if Chrome should show an equivalent toolkit-views based
-// dialog using one of the functions below, rather than showing a Cocoa dialog.
+// dialog instead of a native-looking Cocoa dialog.
 bool ToolkitViewsDialogsEnabled();
 
 // For Mac, returns true if Chrome should show an equivalent toolkit-views based
-// dialog instead of a WebUI-styled Cocoa dialog. ToolkitViewsDialogsEnabled()
-// implies ToolkitViewsWebUIDialogsEnabled().
+// dialog instead of a WebUI-styled Cocoa dialog.
 bool ToolkitViewsWebUIDialogsEnabled();
 
 // Shows a Views website settings bubble at the given anchor point.
diff --git a/chrome/browser/ui/browser_dialogs_mac.cc b/chrome/browser/ui/browser_dialogs_mac.cc
index a85fbcb..2fd94ae 100644
--- a/chrome/browser/ui/browser_dialogs_mac.cc
+++ b/chrome/browser/ui/browser_dialogs_mac.cc
@@ -4,19 +4,20 @@
 
 #include "chrome/browser/ui/browser_dialogs.h"
 
-#include "base/command_line.h"
 #include "base/feature_list.h"
-#include "chrome/common/chrome_switches.h"
+
+namespace chrome {
+
+const base::Feature kMacViewsNativeDialogs {
+  "MacViewsNativeDialogs", base::FEATURE_DISABLED_BY_DEFAULT
+};
 
 const base::Feature kMacViewsWebUIDialogs {
   "MacViewsWebUIDialogs", base::FEATURE_DISABLED_BY_DEFAULT
 };
 
-namespace chrome {
-
 bool ToolkitViewsDialogsEnabled() {
-  return base::CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kEnableMacViewsDialogs);
+  return base::FeatureList::IsEnabled(kMacViewsNativeDialogs);
 }
 
 bool ToolkitViewsWebUIDialogsEnabled() {
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 43837dd10..34e5e509 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -146,6 +146,10 @@
   // Returns true if the fullscreen bubble is visible.
   virtual bool IsFullscreenBubbleVisible() const = 0;
 
+  // Shows a notice teaching the user the new shortcut for going Back or
+  // Forward.
+  virtual void ShowNewBackShortcutBubble(bool forward) = 0;
+
   // Returns the size of WebContents in the browser. This may be called before
   // the TabStripModel has an active tab.
   virtual gfx::Size GetContentsSize() const = 0;
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h
index f03c48b8..78f1657 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -82,6 +82,7 @@
   bool ShouldHideUIForFullscreen() const override;
   bool IsFullscreen() const override;
   bool IsFullscreenBubbleVisible() const override;
+  void ShowNewBackShortcutBubble(bool forward) override;
   LocationBar* GetLocationBar() const override;
   void SetFocusToLocationBar(bool select_all) override;
   void UpdateReloadStopState(bool is_loading, bool force) override;
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 779a79d2..4a007f8 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -433,6 +433,11 @@
   return false;  // Currently only called from toolkit-views website_settings.
 }
 
+void BrowserWindowCocoa::ShowNewBackShortcutBubble(bool forward) {
+  // TODO(mgiuca): Implement new back shortcut bubble Mac.
+  // https://crbug.com/610039.
+}
+
 LocationBar* BrowserWindowCocoa::GetLocationBar() const {
   return [controller_ locationBarBridge];
 }
diff --git a/chrome/browser/ui/task_manager/task_manager_table_model.cc b/chrome/browser/ui/task_manager/task_manager_table_model.cc
index 075e2e2..2cf8af1 100644
--- a/chrome/browser/ui/task_manager/task_manager_table_model.cc
+++ b/chrome/browser/ui/task_manager/task_manager_table_model.cc
@@ -715,9 +715,8 @@
     RemoveRefreshType(type);
 }
 
-bool TaskManagerTableModel::IsBrowserProcess(int row_index) const {
-  return observed_task_manager()->GetProcessId(tasks_[row_index]) ==
-      base::GetCurrentProcId();
+bool TaskManagerTableModel::IsTaskKillable(int row_index) const {
+  return observed_task_manager()->IsTaskKillable(tasks_[row_index]);
 }
 
 void TaskManagerTableModel::RetrieveSavedColumnsSettingsAndUpdateTable() {
diff --git a/chrome/browser/ui/task_manager/task_manager_table_model.h b/chrome/browser/ui/task_manager/task_manager_table_model.h
index 8ee8e9b2..e726e61 100644
--- a/chrome/browser/ui/task_manager/task_manager_table_model.h
+++ b/chrome/browser/ui/task_manager/task_manager_table_model.h
@@ -87,8 +87,8 @@
   // type will be enabled or disabled.
   void UpdateRefreshTypes(int column_id, bool visibility);
 
-  // Checks if the task at |row_index| is running on the browser process.
-  bool IsBrowserProcess(int row_index) const;
+  // Checks if the task at |row_index| is killable.
+  bool IsTaskKillable(int row_index) const;
 
   // Restores the saved columns settings from a previous session into
   // |columns_settings_| and updates the table view.
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 2eb4e51..c8f43ac 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -82,6 +82,7 @@
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
 #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
+#include "chrome/browser/ui/views/new_back_shortcut_bubble.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
 #include "chrome/browser/ui/views/profiles/profile_chooser_view.h"
 #include "chrome/browser/ui/views/profiles/profile_indicator_icon.h"
@@ -948,7 +949,13 @@
   if (bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE ||
       ShouldUseImmersiveFullscreenForUrl(url)) {
     exclusive_access_bubble_.reset();
-  } else if (exclusive_access_bubble_.get()) {
+    return;
+  }
+
+  // Hide the backspace shortcut bubble, to avoid overlapping.
+  new_back_shortcut_bubble_.reset();
+
+  if (exclusive_access_bubble_) {
     exclusive_access_bubble_->UpdateContent(url, bubble_type);
   } else {
     exclusive_access_bubble_.reset(
@@ -977,6 +984,16 @@
   return exclusive_access_bubble_ != nullptr;
 }
 
+void BrowserView::ShowNewBackShortcutBubble(bool forward) {
+  // Hide the exclusive access bubble, to avoid overlapping.
+  exclusive_access_bubble_.reset();
+
+  if (new_back_shortcut_bubble_)
+    new_back_shortcut_bubble_->UpdateContent(forward);
+  else
+    new_back_shortcut_bubble_.reset(new NewBackShortcutBubble(this, forward));
+}
+
 void BrowserView::RestoreFocus() {
   WebContents* selected_web_contents = GetActiveWebContents();
   if (selected_web_contents)
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index a2ac8bc..1973506 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -53,6 +53,7 @@
 class ExclusiveAccessBubbleViews;
 class InfoBarContainerView;
 class LocationBarView;
+class NewBackShortcutBubble;
 class StatusBubbleViews;
 class TabStrip;
 class ToolbarView;
@@ -286,6 +287,7 @@
   bool ShouldHideUIForFullscreen() const override;
   bool IsFullscreen() const override;
   bool IsFullscreenBubbleVisible() const override;
+  void ShowNewBackShortcutBubble(bool forward) override;
   LocationBar* GetLocationBar() const override;
   void SetFocusToLocationBar(bool select_all) override;
   void UpdateReloadStopState(bool is_loading, bool force) override;
@@ -665,6 +667,8 @@
 
   std::unique_ptr<ExclusiveAccessBubbleViews> exclusive_access_bubble_;
 
+  std::unique_ptr<NewBackShortcutBubble> new_back_shortcut_bubble_;
+
 #if defined(OS_WIN)
   // Helper class to listen for completion of first page load.
   std::unique_ptr<LoadCompleteListener> load_complete_listener_;
diff --git a/chrome/browser/ui/views/new_back_shortcut_bubble.cc b/chrome/browser/ui/views/new_back_shortcut_bubble.cc
new file mode 100644
index 0000000..c43d3f4
--- /dev/null
+++ b/chrome/browser/ui/views/new_back_shortcut_bubble.cc
@@ -0,0 +1,118 @@
+// 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 "chrome/browser/ui/views/new_back_shortcut_bubble.h"
+
+#include <utility>
+
+#include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/views/exclusive_access_bubble_views_context.h"
+#include "chrome/browser/ui/views/subtle_notification_view.h"
+#include "chrome/grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/animation/animation.h"
+#include "ui/gfx/animation/slide_animation.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/strings/grit/ui_strings.h"
+#include "ui/views/border.h"
+#include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
+
+namespace {
+
+const int kPopupTopPx = 45;
+const int kSlideInDurationMs = 350;
+const int kSlideOutDurationMs = 700;
+const int kShowDurationMs = 3800;
+
+}
+
+NewBackShortcutBubble::NewBackShortcutBubble(
+    ExclusiveAccessBubbleViewsContext* context,
+    bool forward)
+    : bubble_view_context_(context),
+      animation_(new gfx::SlideAnimation(this)),
+      view_(new SubtleNotificationView(nullptr)),
+      popup_(SubtleNotificationView::CreatePopupWidget(
+          bubble_view_context_->GetBubbleParentView(),
+          view_,
+          false)) {
+  UpdateContent(forward);
+}
+
+NewBackShortcutBubble::~NewBackShortcutBubble() {
+  // We might need to delete the widget asynchronously. See rationale in
+  // ~ExclusiveAccessBubbleViews.
+  popup_->Close();
+  base::MessageLoop::current()->DeleteSoon(FROM_HERE, popup_);
+}
+
+void NewBackShortcutBubble::UpdateContent(bool forward) {
+  // Note: The key names are parameters so that we can vary by operating system
+  // or change the direction of the arrow as necessary (see
+  // https://crbug.com/612685).
+
+#if defined(OS_MACOSX)
+  // U+2318 = PLACE OF INTEREST SIGN (Mac Command symbol).
+  base::string16 accelerator = base::WideToUTF16(L"\x2318");
+#else
+  base::string16 accelerator = l10n_util::GetStringUTF16(IDS_APP_ALT_KEY);
+#endif
+
+  int message_id = forward ? IDS_PRESS_ALT_RIGHT_TO_GO_FORWARD
+                           : IDS_PRESS_ALT_LEFT_TO_GO_BACK;
+  // U+2192 = RIGHTWARDS ARROW; U+2190 = LEFTWARDS ARROW.
+  base::string16 arrow_key = base::WideToUTF16(forward ? L"\x2192" : L"\x2190");
+  view_->UpdateContent(
+      l10n_util::GetStringFUTF16(message_id, accelerator, arrow_key),
+      base::string16());
+
+  view_->SetSize(GetPopupRect(true).size());
+  popup_->SetBounds(GetPopupRect(false));
+
+  // Show the bubble.
+  animation_->SetSlideDuration(kSlideInDurationMs);
+  animation_->Show();
+
+  // Wait a few seconds before hiding.
+  hide_timeout_.Start(FROM_HERE,
+                      base::TimeDelta::FromMilliseconds(kShowDurationMs), this,
+                      &NewBackShortcutBubble::OnTimerElapsed);
+}
+
+void NewBackShortcutBubble::AnimationProgressed(
+    const gfx::Animation* animation) {
+  int opacity = animation_->CurrentValueBetween(0, 255);
+  if (opacity == 0) {
+    popup_->Hide();
+  } else {
+    if (!popup_->IsVisible())
+      popup_->Show();
+
+    popup_->SetOpacity(opacity);
+  }
+}
+
+void NewBackShortcutBubble::AnimationEnded(const gfx::Animation* animation) {
+  AnimationProgressed(animation);
+}
+
+gfx::Rect NewBackShortcutBubble::GetPopupRect(
+    bool ignore_animation_state) const {
+  gfx::Size size = view_->GetPreferredSize();
+  gfx::Rect widget_bounds = bubble_view_context_->GetClientAreaBoundsInScreen();
+  int x = widget_bounds.x() + (widget_bounds.width() - size.width()) / 2;
+  // |desired_top| is the top of the bubble area including the shadow.
+  int desired_top = kPopupTopPx - view_->border()->GetInsets().top();
+  int y = widget_bounds.y() + desired_top;
+  return gfx::Rect(gfx::Point(x, y), size);
+}
+
+void NewBackShortcutBubble::OnTimerElapsed() {
+  // Hide the bubble.
+  animation_->SetSlideDuration(kSlideOutDurationMs);
+  animation_->Hide();
+}
diff --git a/chrome/browser/ui/views/new_back_shortcut_bubble.h b/chrome/browser/ui/views/new_back_shortcut_bubble.h
new file mode 100644
index 0000000..38b2e991
--- /dev/null
+++ b/chrome/browser/ui/views/new_back_shortcut_bubble.h
@@ -0,0 +1,66 @@
+// 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 CHROME_BROWSER_UI_VIEWS_NEW_BACK_SHORTCUT_BUBBLE_H_
+#define CHROME_BROWSER_UI_VIEWS_NEW_BACK_SHORTCUT_BUBBLE_H_
+
+#include <memory>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/timer/timer.h"
+#include "ui/gfx/animation/animation_delegate.h"
+
+class ExclusiveAccessBubbleViewsContext;
+class SubtleNotificationView;
+
+namespace gfx {
+class Animation;
+class Rect;
+class SlideAnimation;
+}
+
+namespace views {
+class View;
+class Widget;
+}
+
+// NewBackShortcutBubble shows a short-lived notification along the top of the
+// screen when the user presses the old Back/Forward shortcut, telling them how
+// to use the new shortcut. This will only be available for a few milestones to
+// let users adapt.
+// TODO(mgiuca): Remove this in M54 (https://crbug.com/610039).
+class NewBackShortcutBubble : public gfx::AnimationDelegate {
+ public:
+  NewBackShortcutBubble(ExclusiveAccessBubbleViewsContext* context,
+                        bool forward);
+  ~NewBackShortcutBubble() override;
+
+  void UpdateContent(bool forward);
+
+ private:
+  // gfx::AnimationDelegate:
+  void AnimationProgressed(const gfx::Animation* animation) override;
+  void AnimationEnded(const gfx::Animation* animation) override;
+
+  gfx::Rect GetPopupRect(bool ignore_animation_state) const;
+  void OnTimerElapsed();
+
+  ExclusiveAccessBubbleViewsContext* const bubble_view_context_;
+
+  // Animation controlling showing/hiding of the bubble.
+  std::unique_ptr<gfx::SlideAnimation> animation_;
+
+  // Timer before the bubble disappears.
+  base::OneShotTimer hide_timeout_;
+
+  // The contents of the popup.
+  SubtleNotificationView* const view_;
+
+  views::Widget* const popup_;
+
+  DISALLOW_COPY_AND_ASSIGN(NewBackShortcutBubble);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_NEW_BACK_SHORTCUT_BUBBLE_H_
diff --git a/chrome/browser/ui/views/new_task_manager_view.cc b/chrome/browser/ui/views/new_task_manager_view.cc
index ca7e9a890..01a5d3c7 100644
--- a/chrome/browser/ui/views/new_task_manager_view.cc
+++ b/chrome/browser/ui/views/new_task_manager_view.cc
@@ -206,7 +206,7 @@
   const ui::ListSelectionModel::SelectedIndices& selections(
       tab_table_->selection_model().selected_indices());
   for (const auto& selection : selections) {
-    if (table_model_->IsBrowserProcess(selection))
+    if (!table_model_->IsTaskKillable(selection))
       return false;
   }
 
diff --git a/chrome/browser/ui/views/subtle_notification_view.cc b/chrome/browser/ui/views/subtle_notification_view.cc
index 3957d701..8d42713 100644
--- a/chrome/browser/ui/views/subtle_notification_view.cc
+++ b/chrome/browser/ui/views/subtle_notification_view.cc
@@ -28,16 +28,22 @@
 // Partially-transparent background color.
 const SkColor kBackgroundColor = SkColorSetARGB(0xcc, 0x28, 0x2c, 0x32);
 
+// Spacing around the key name.
+const int kKeyNameMarginHorizPx = 7;
+const int kKeyNameBorderPx = 1;
+const int kKeyNameCornerRadius = 2;
+const int kKeyNamePaddingPx = 5;
+
 }  // namespace
 
 // Class containing the instruction text. Contains fancy styling on the keyboard
 // key (not just a simple label).
 class SubtleNotificationView::InstructionView : public views::View {
  public:
-  // Creates an InstructionView with specific text. |text| may contain a single
-  // segment delimited by a pair of pipes ('|'); this segment will be displayed
-  // as a keyboard key. e.g., "Press |Esc| to exit" will have "Esc" rendered as
-  // a key.
+  // Creates an InstructionView with specific text. |text| may contain one or
+  // more segments delimited by a pair of pipes ('|'); each of these segments
+  // will be displayed as a keyboard key. e.g., "Press |Alt|+|Q| to exit" will
+  // have "Alt" and "Q" rendered as keys.
   InstructionView(const base::string16& text,
                   const gfx::FontList& font_list,
                   SkColor foreground_color,
@@ -46,10 +52,16 @@
   void SetText(const base::string16& text);
 
  private:
-  views::Label* before_key_;
-  views::Label* key_name_label_;
-  views::View* key_name_;
-  views::Label* after_key_;
+  // Adds a label to the end of the notification text. If |format_as_key|,
+  // surrounds the label in a rounded-rect border to indicate that it is a
+  // keyboard key.
+  void AddTextSegment(const base::string16& text, bool format_as_key);
+
+  const gfx::FontList& font_list_;
+  SkColor foreground_color_;
+  SkColor background_color_;
+
+  base::string16 text_;
 
   DISALLOW_COPY_AND_ASSIGN(InstructionView);
 };
@@ -58,70 +70,69 @@
     const base::string16& text,
     const gfx::FontList& font_list,
     SkColor foreground_color,
-    SkColor background_color) {
-  // Spacing around the key name.
-  const int kKeyNameMarginHorizPx = 7;
-  const int kKeyNameBorderPx = 1;
-  const int kKeyNameCornerRadius = 2;
-  const int kKeyNamePaddingPx = 5;
-
+    SkColor background_color)
+    : font_list_(font_list),
+      foreground_color_(foreground_color),
+      background_color_(background_color) {
   // The |between_child_spacing| is the horizontal margin of the key name.
   views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kHorizontal,
                                                   0, 0, kKeyNameMarginHorizPx);
   SetLayoutManager(layout);
 
-  before_key_ = new views::Label(base::string16(), font_list);
-  before_key_->SetEnabledColor(foreground_color);
-  before_key_->SetBackgroundColor(background_color);
-  AddChildView(before_key_);
-
-  key_name_label_ = new views::Label(base::string16(), font_list);
-  key_name_label_->SetEnabledColor(foreground_color);
-  key_name_label_->SetBackgroundColor(background_color);
-
-  key_name_ = new views::View;
-  views::BoxLayout* key_name_layout = new views::BoxLayout(
-      views::BoxLayout::kHorizontal, kKeyNamePaddingPx, 0, 0);
-  key_name_layout->set_minimum_cross_axis_size(
-      key_name_label_->GetPreferredSize().height() + kKeyNamePaddingPx * 2);
-  key_name_->SetLayoutManager(key_name_layout);
-  key_name_->AddChildView(key_name_label_);
-  // The key name has a border around it.
-  std::unique_ptr<views::Border> border(views::Border::CreateRoundedRectBorder(
-      kKeyNameBorderPx, kKeyNameCornerRadius, foreground_color));
-  key_name_->SetBorder(std::move(border));
-  AddChildView(key_name_);
-
-  after_key_ = new views::Label(base::string16(), font_list);
-  after_key_->SetEnabledColor(foreground_color);
-  after_key_->SetBackgroundColor(background_color);
-  AddChildView(after_key_);
-
   SetText(text);
 }
 
 void SubtleNotificationView::InstructionView::SetText(
     const base::string16& text) {
+  // Avoid replacing the contents with the same text.
+  if (text == text_)
+    return;
+
+  RemoveAllChildViews(true);
+
   // Parse |text|, looking for pipe-delimited segment.
   std::vector<base::string16> segments =
       base::SplitString(text, base::ASCIIToUTF16("|"), base::TRIM_WHITESPACE,
                         base::SPLIT_WANT_ALL);
-  // Expect 1 or 3 pieces (either no pipe-delimited segments, or one).
-  DCHECK(segments.size() <= 1 || segments.size() == 3);
+  // SplitString() returns empty strings for zero-length segments, so given an
+  // even number of pipes, there should always be an odd number of segments.
+  // The exception is if |text| is entirely empty, in which case the returned
+  // list is also empty (rather than containing a single empty string).
+  DCHECK(segments.empty() || segments.size() % 2 == 1);
 
-  before_key_->SetText(segments.size() ? segments[0] : base::string16());
+  // Add text segment, alternating between non-key (no border) and key (border)
+  // formatting.
+  bool format_as_key = false;
+  for (const auto& segment : segments) {
+    AddTextSegment(segment, format_as_key);
+    format_as_key = !format_as_key;
+  }
 
-  if (segments.size() < 3) {
-    key_name_->SetVisible(false);
-    after_key_->SetVisible(false);
+  text_ = text;
+}
+
+void SubtleNotificationView::InstructionView::AddTextSegment(
+    const base::string16& text, bool format_as_key) {
+  views::Label* label = new views::Label(text, font_list_);
+  label->SetEnabledColor(foreground_color_);
+  label->SetBackgroundColor(background_color_);
+  if (!format_as_key) {
+    AddChildView(label);
     return;
   }
 
-  before_key_->SetText(segments[0]);
-  key_name_label_->SetText(segments[1]);
-  key_name_->SetVisible(true);
-  after_key_->SetVisible(true);
-  after_key_->SetText(segments[2]);
+  views::View* key = new views::View;
+  views::BoxLayout* key_name_layout = new views::BoxLayout(
+      views::BoxLayout::kHorizontal, kKeyNamePaddingPx, 0, 0);
+  key_name_layout->set_minimum_cross_axis_size(
+      label->GetPreferredSize().height() + kKeyNamePaddingPx * 2);
+  key->SetLayoutManager(key_name_layout);
+  key->AddChildView(label);
+  // The key name has a border around it.
+  std::unique_ptr<views::Border> border(views::Border::CreateRoundedRectBorder(
+      kKeyNameBorderPx, kKeyNameCornerRadius, foreground_color_));
+  key->SetBorder(std::move(border));
+  AddChildView(key);
 }
 
 SubtleNotificationView::SubtleNotificationView(
diff --git a/chrome/browser/ui/webui/md_history_ui.cc b/chrome/browser/ui/webui/md_history_ui.cc
index 71145e4..ee6fb2cc 100644
--- a/chrome/browser/ui/webui/md_history_ui.cc
+++ b/chrome/browser/ui/webui/md_history_ui.cc
@@ -59,7 +59,7 @@
   source->AddLocalizedString("rangeNext", IDS_HISTORY_RANGE_NEXT);
   source->AddLocalizedString("rangePrevious", IDS_HISTORY_RANGE_PREVIOUS);
   source->AddLocalizedString("removeFromHistory", IDS_HISTORY_REMOVE_PAGE);
-  source->AddLocalizedString("search", IDS_MD_HISTORY_SEARCH);
+  source->AddLocalizedString("searchPrompt", IDS_MD_HISTORY_SEARCH_PROMPT);
   source->AddLocalizedString("searchResult", IDS_HISTORY_SEARCH_RESULT);
   source->AddLocalizedString("searchResults", IDS_HISTORY_SEARCH_RESULTS);
   source->AddLocalizedString("title", IDS_HISTORY_TITLE);
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index 4c077679..d8cb840 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -491,6 +491,8 @@
       IDS_OPTIONS_RESOLVE_TIMEZONE_BY_GEOLOCATION_DESCRIPTION },
     { "sectionTitleDevice", IDS_OPTIONS_DEVICE_GROUP_NAME },
     { "sectionTitleInternet", IDS_OPTIONS_INTERNET_OPTIONS_GROUP_LABEL },
+    { "storageManagerButtonTitle",
+      IDS_OPTIONS_DEVICE_GROUP_STORAGE_MANAGER_BUTTON_TITLE },
     { "syncButtonTextStart", IDS_SYNC_SETUP_BUTTON_LABEL },
     { "thirdPartyImeConfirmDisable", IDS_CANCEL },
     { "thirdPartyImeConfirmEnable", IDS_OK },
@@ -731,6 +733,10 @@
   bool allow_bluetooth = true;
   cros_settings->GetBoolean(chromeos::kAllowBluetooth, &allow_bluetooth);
   values->SetBoolean("allowBluetooth", allow_bluetooth);
+
+  values->SetBoolean("enableStorageManager",
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          chromeos::switches::kEnableStorageManager));
 #endif
 }
 
diff --git a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc
new file mode 100644
index 0000000..aa25f873a
--- /dev/null
+++ b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc
@@ -0,0 +1,35 @@
+// 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 "chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h"
+
+#include "chrome/grit/generated_resources.h"
+
+namespace chromeos {
+namespace options {
+
+StorageManagerHandler::StorageManagerHandler() {
+}
+
+StorageManagerHandler::~StorageManagerHandler() {
+}
+
+void StorageManagerHandler::GetLocalizedValues(
+    base::DictionaryValue* localized_strings) {
+  DCHECK(localized_strings);
+
+  RegisterTitle(localized_strings, "storageManagerPage",
+                IDS_OPTIONS_SETTINGS_STORAGE_MANAGER_TAB_TITLE);
+}
+
+void StorageManagerHandler::InitializePage() {
+  DCHECK(web_ui());
+}
+
+void StorageManagerHandler::RegisterMessages() {
+  DCHECK(web_ui());
+}
+
+}  // namespace options
+}  // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h
new file mode 100644
index 0000000..bad3844
--- /dev/null
+++ b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h
@@ -0,0 +1,34 @@
+// 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 CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STORAGE_MANAGER_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STORAGE_MANAGER_HANDLER_H_
+
+#include "base/macros.h"
+#include "chrome/browser/ui/webui/options/options_ui.h"
+
+namespace chromeos {
+namespace options {
+
+// Storage manager overlay page UI handler.
+class StorageManagerHandler : public ::options::OptionsPageUIHandler {
+ public:
+  StorageManagerHandler();
+  ~StorageManagerHandler() override;
+
+  // OptionsPageUIHandler implementation.
+  void GetLocalizedValues(base::DictionaryValue* localized_strings) override;
+  void InitializePage() override;
+
+  // WebUIMessageHandler implementation.
+  void RegisterMessages() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StorageManagerHandler);
+};
+
+}  // namespace options
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STORAGE_MANAGER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc
index f3dadcf..15da587b 100644
--- a/chrome/browser/ui/webui/options/options_ui.cc
+++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -97,6 +97,7 @@
 #include "chrome/browser/ui/webui/options/chromeos/power_handler.h"
 #include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h"
 #include "chrome/browser/ui/webui/options/chromeos/stats_options_handler.h"
+#include "chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h"
 #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h"
 #endif
 
@@ -341,6 +342,8 @@
       new chromeos::options::ChangePictureOptionsHandler());
   AddOptionsPageUIHandler(localized_strings,
                           new chromeos::options::StatsOptionsHandler());
+  AddOptionsPageUIHandler(localized_strings,
+                          new chromeos::options::StorageManagerHandler());
 
   policy::ConsumerManagementService* consumer_management =
       g_browser_process->platform_part()->browser_policy_connector_chromeos()->
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 66287e29..aaa1f51 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -1932,6 +1932,8 @@
       'browser/ui/webui/options/chromeos/proxy_handler.h',
       'browser/ui/webui/options/chromeos/stats_options_handler.cc',
       'browser/ui/webui/options/chromeos/stats_options_handler.h',
+      'browser/ui/webui/options/chromeos/storage_manager_handler.cc',
+      'browser/ui/webui/options/chromeos/storage_manager_handler.h',
       'browser/ui/webui/options/chromeos/user_image_source.cc',
       'browser/ui/webui/options/chromeos/user_image_source.h',
       'browser/ui/webui/options/clear_browser_data_handler.cc',
@@ -2147,6 +2149,8 @@
       'browser/ui/views/login_handler_views.cc',
       'browser/ui/views/login_view.cc',
       'browser/ui/views/login_view.h',
+      'browser/ui/views/new_back_shortcut_bubble.cc',
+      'browser/ui/views/new_back_shortcut_bubble.h',
       'browser/ui/views/new_task_manager_view.cc',
       'browser/ui/views/new_task_manager_view.h',
       'browser/ui/views/subtle_notification_view.cc',
diff --git a/chrome/chrome_resources.gyp b/chrome/chrome_resources.gyp
index ff94d95..daf559b 100644
--- a/chrome/chrome_resources.gyp
+++ b/chrome/chrome_resources.gyp
@@ -313,7 +313,8 @@
           'variables' : {
             'script_file':'browser/resources/safe_browsing/gen_file_type_proto.py',
             'asciipb_file' : 'browser/resources/safe_browsing/download_file_types.asciipb',
-            'output_file' : '<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/safe_browsing/download_file_types.pb',
+            'output_dir' : '<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/safe_browsing',
+            'output_basename' : 'download_file_types.pb',
             'conditions': [
               ['OS=="android"', {
                 'platform': 'android'
@@ -336,14 +337,15 @@
             '<(asciipb_file)',
           ],
           'outputs': [
-            '<(output_file)',
+            '<(output_dir)/<(output_basename)',
           ],
           'action': [
             'python',
             '<(script_file)',
             '-w',
             '-i', '<(asciipb_file)',
-            '-o', '<(output_file)',
+            '-d', '<(output_dir)',
+            '-o', '<(output_basename)',
             '-t', '<(platform)',
             '-p', '<(PRODUCT_DIR)/pyproto',
             '-p', '<(PRODUCT_DIR)/pyproto/chrome/common/safe_browsing',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 5165238..e18442ad 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -1168,10 +1168,6 @@
 const char kEnableMacViewsNativeAppWindows[] =
     "enable-mac-views-native-app-windows";
 
-// Causes Chrome to use an equivalent toolkit-views version of a browser dialog
-// when available, rather than a Cocoa one.
-const char kEnableMacViewsDialogs[] = "enable-mac-views-dialogs";
-
 // Enables Translate experimental new UX which replaces the infobar.
 const char kEnableTranslateNewUX[] = "enable-translate-new-ux";
 
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 7810996..2c0ff4f 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -346,7 +346,6 @@
 extern const char kEnableFullscreenTabDetaching[];
 extern const char kEnableHostedAppsInWindows[];
 extern const char kEnableMacViewsNativeAppWindows[];
-extern const char kEnableMacViewsDialogs[];
 extern const char kEnableTranslateNewUX[];
 extern const char kMetricsClientID[];
 extern const char kRelauncherProcess[];
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc
index 29e4164..de299f63 100644
--- a/chrome/test/base/test_browser_window.cc
+++ b/chrome/test/base/test_browser_window.cc
@@ -119,6 +119,8 @@
   return false;
 }
 
+void TestBrowserWindow::ShowNewBackShortcutBubble(bool forward) {}
+
 LocationBar* TestBrowserWindow::GetLocationBar() const {
   return const_cast<TestLocationBar*>(&location_bar_);
 }
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index 2c75121..6ea4777 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -67,6 +67,7 @@
   bool ShouldHideUIForFullscreen() const override;
   bool IsFullscreen() const override;
   bool IsFullscreenBubbleVisible() const override;
+  void ShowNewBackShortcutBubble(bool forward) override;
   LocationBar* GetLocationBar() const override;
   void SetFocusToLocationBar(bool select_all) override {}
   void UpdateReloadStopState(bool is_loading, bool force) override {}
diff --git a/chrome/test/data/extensions/platform_apps/web_view/storage_persistence/tests.js b/chrome/test/data/extensions/platform_apps/web_view/storage_persistence/tests.js
index ba0a6c3c..7eec9c3 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/storage_persistence/tests.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/storage_persistence/tests.js
@@ -153,14 +153,6 @@
   return linkTestsAndReturnFirst(tests);
 }
 
-function onSuccess() {
-  chrome.test.sendMessage('WebViewTest.PASSED');
-}
-
-function onFailure() {
-  chrome.test.sendMessage('WebViewTest.FAILURE');
-}
-
 // Handles the |consolemessage| event for a webview.
 function onConsoleMessage(e) {
   console.log(this.id + ':' + e.message);
@@ -198,27 +190,10 @@
   var test = (testName === 'PRE_StoragePersistence') ?
       createPreStoragePersistenceTests(webviews, url) :
       createStoragePersistenceTests(webviews, url);
-  test.run(onSuccess, onFailure);
+  test.run(chrome.test.succeed, chrome.test.fail);
 }
 
-function run(testName) {
-  chrome.test.getConfig(function(config) {
-    runTest(config.testServer.port, testName);
-  });
-}
-
-window.onAppCommand = function(command) {
-  switch(command) {
-    case 'run-pre-test':
-      run('PRE_StoragePersistence');
-      break;
-    case 'run-test':
-      run('StoragePersistence');
-      break;
-    default:
-      onFailure();
-  }
-}
-
-// Send a message to C++ side to announce test launched.
-chrome.test.sendMessage('WebViewTest.LAUNCHED');
+chrome.test.getConfig(function(config) {
+  var testName = config.customArg;
+  runTest(config.testServer.port, testName);
+});
diff --git a/chrome/test/data/webui/md_history/history_synced_tabs_test.js b/chrome/test/data/webui/md_history/history_synced_tabs_test.js
index e6486a1d..898360c 100644
--- a/chrome/test/data/webui/md_history/history_synced_tabs_test.js
+++ b/chrome/test/data/webui/md_history/history_synced_tabs_test.js
@@ -30,12 +30,18 @@
     suite('synced-tabs', function() {
       var app;
       var element;
-      var sidebarElement;
 
-      suiteSetup(function() {
+      suiteSetup(function(done) {
         app = $('history-app');
-        element = app.$['history-synced-device-manager'];
-        sidebarElement = app.$['history-side-bar'];
+        // Not rendered until selected.
+        assertEquals(null, app.$$('#history-synced-device-manager'));
+
+        app.selectedPage_ = 'history-synced-device-manager';
+        flush(function() {
+          element = app.$$('#history-synced-device-manager');
+          assertTrue(!!element);
+          done();
+        });
       });
 
       test('single card, single window', function(done) {
diff --git a/chrome/test/data/webui/md_history/history_toolbar_test.js b/chrome/test/data/webui/md_history/history_toolbar_test.js
index e69ce86c..6e9cb93b 100644
--- a/chrome/test/data/webui/md_history/history_toolbar_test.js
+++ b/chrome/test/data/webui/md_history/history_toolbar_test.js
@@ -59,8 +59,9 @@
         registerMessageCallback('queryHistory', this, function (info) {
           assertEquals('example.com', info[0]);
           flush(function() {
-            assertEquals(toolbar.$$('#search-input').$$('#search-input').value,
-                'example.com');
+            assertEquals(
+                'example.com',
+                toolbar.$['main-toolbar'].getSearchField().getValue());
             done();
           });
         });
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index 1b53b2c..811776c 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -174,6 +174,9 @@
 const char kEnableScreenshotTestingWithMode[] =
     "enable-screenshot-testing-with-mode";
 
+// Enables experimental storage manager to manage local storage.
+const char kEnableStorageManager[] = "enable-storage-manager";
+
 // Enable Kiosk mode for ChromeOS. Note this switch refers to retail mode rather
 // than the kiosk app mode.
 const char kEnableKioskMode[] = "enable-kiosk-mode";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 94ba16f..5a12ebe 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -71,6 +71,7 @@
 CHROMEOS_EXPORT extern const char kEnablePhysicalKeyboardAutocorrect[];
 CHROMEOS_EXPORT extern const char kEnableRequestTabletSite[];
 CHROMEOS_EXPORT extern const char kEnableScreenshotTestingWithMode[];
+CHROMEOS_EXPORT extern const char kEnableStorageManager[];
 CHROMEOS_EXPORT extern const char kEnableTouchpadThreeFingerClick[];
 CHROMEOS_EXPORT extern const char kEnableVideoPlayerChromecastSupport[];
 CHROMEOS_EXPORT extern const char kEnterpriseDisableArc[];
diff --git a/components/bitmap_uploader/bitmap_uploader.cc b/components/bitmap_uploader/bitmap_uploader.cc
index 5c255db..5d4a836 100644
--- a/components/bitmap_uploader/bitmap_uploader.cc
+++ b/components/bitmap_uploader/bitmap_uploader.cc
@@ -12,10 +12,10 @@
 #include "components/mus/public/cpp/gles2_context.h"
 #include "components/mus/public/cpp/window.h"
 #include "components/mus/public/cpp/window_surface.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/surfaces/surfaces_type_converters.h"
 #include "mojo/converters/surfaces/surfaces_utils.h"
 #include "services/shell/public/cpp/connector.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace bitmap_uploader {
 namespace {
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc
index 67321bd1..65ed49d 100644
--- a/components/content_settings/core/browser/host_content_settings_map.cc
+++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -171,7 +171,7 @@
   default_provider->AddObserver(this);
   content_settings_providers_[DEFAULT_PROVIDER] = default_provider;
 
-  MigrateOldSettings();
+  MigrateKeygenSettings();
 
   RecordNumberOfExceptions();
 }
@@ -467,48 +467,33 @@
                                resource_identifier, setting);
 }
 
-void HostContentSettingsMap::MigrateOldSettings() {
-  const ContentSettingsType kMigrateContentSettingTypes[] = {
-      // Only content types of scoping type: REQUESTING_DOMAIN_ONLY_SCOPE,
-      // REQUESTING_ORIGIN_ONLY_SCOPE and TOP_LEVEL_DOMAIN_ONLY_SCOPE need to be
-      // migrated.
-      CONTENT_SETTINGS_TYPE_KEYGEN};
-  for (const ContentSettingsType& type : kMigrateContentSettingTypes) {
-    WebsiteSettingsInfo::ScopingType scoping_type =
-        content_settings::ContentSettingsRegistry::GetInstance()
-            ->Get(type)
-            ->website_settings_info()
-            ->scoping_type();
-    DCHECK_NE(
-        scoping_type,
-        WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE);
+void HostContentSettingsMap::MigrateKeygenSettings() {
+  ContentSettingsForOneType settings;
+  GetSettingsForOneType(CONTENT_SETTINGS_TYPE_KEYGEN, std::string(), &settings);
 
-    ContentSettingsForOneType settings;
-    GetSettingsForOneType(type, std::string(), &settings);
-    for (const ContentSettingPatternSource& setting_entry : settings) {
-      // Migrate user preference settings only.
-      if (setting_entry.source != "preference")
-        continue;
-      // Migrate old-format settings only.
-      if (setting_entry.secondary_pattern !=
-          ContentSettingsPattern::Wildcard()) {
-        GURL url(setting_entry.primary_pattern.ToString());
-        // Pull out the value of the old-format setting. Only do this if the
-        // patterns are as we expect them to be, otherwise the setting will just
-        // be removed for safety.
-        ContentSetting content_setting = CONTENT_SETTING_DEFAULT;
-        if (setting_entry.primary_pattern == setting_entry.secondary_pattern &&
-            url.is_valid()) {
-          content_setting = GetContentSetting(url, url, type, std::string());
-        }
-        // Remove the old pattern.
-        SetContentSettingCustomScope(setting_entry.primary_pattern,
-                          setting_entry.secondary_pattern, type, std::string(),
-                          CONTENT_SETTING_DEFAULT);
-        // Set the new pattern.
-        SetContentSettingDefaultScope(url, GURL(), type, std::string(),
-                                      content_setting);
+  for (const ContentSettingPatternSource& setting_entry : settings) {
+    // Migrate user preference settings only.
+    if (setting_entry.source != "preference")
+      continue;
+    // Migrate old-format settings only.
+    if (setting_entry.secondary_pattern != ContentSettingsPattern::Wildcard()) {
+      GURL url(setting_entry.primary_pattern.ToString());
+      // Pull out the value of the old-format setting. Only do this if the
+      // patterns are as we expect them to be, otherwise the setting will just
+      // be removed for safety.
+      ContentSetting content_setting = CONTENT_SETTING_DEFAULT;
+      if (setting_entry.primary_pattern == setting_entry.secondary_pattern &&
+          url.is_valid()) {
+        content_setting = GetContentSetting(
+            url, url, CONTENT_SETTINGS_TYPE_KEYGEN, std::string());
       }
+      // Remove the old pattern.
+      SetContentSettingCustomScope(
+          setting_entry.primary_pattern, setting_entry.secondary_pattern,
+          CONTENT_SETTINGS_TYPE_KEYGEN, std::string(), CONTENT_SETTING_DEFAULT);
+      // Set the new pattern.
+      SetContentSettingDefaultScope(url, GURL(), CONTENT_SETTINGS_TYPE_KEYGEN,
+                                    std::string(), content_setting);
     }
   }
 }
diff --git a/components/content_settings/core/browser/host_content_settings_map.h b/components/content_settings/core/browser/host_content_settings_map.h
index 3dad1621..4a3c946 100644
--- a/components/content_settings/core/browser/host_content_settings_map.h
+++ b/components/content_settings/core/browser/host_content_settings_map.h
@@ -283,7 +283,7 @@
 
  private:
   friend class base::RefCountedThreadSafe<HostContentSettingsMap>;
-  friend class HostContentSettingsMapTest_MigrateOldSettings_Test;
+  friend class HostContentSettingsMapTest_MigrateKeygenSettings_Test;
 
   friend class content_settings::TestUtils;
 
@@ -304,16 +304,15 @@
       ContentSettingsType content_type,
       ProviderType* provider_type) const;
 
-  // Migrate old settings for ContentSettingsTypes which only use a primary
-  // pattern. Settings which only used a primary pattern were inconsistent in
-  // what they did with the secondary pattern. Some stored a
-  // ContentSettingsPattern::Wildcard() whereas others stored the same pattern
-  // twice. This function migrates all such settings to use
-  // ContentSettingsPattern::Wildcard(). This allows us to make the scoping code
-  // consistent across different settings.
+  // Migrate Keygen settings which only use a primary pattern. Settings which
+  // only used a primary pattern were inconsistent in what they did with the
+  // secondary pattern. Some stored a ContentSettingsPattern::Wildcard() whereas
+  // others stored the same pattern twice. This function migrates all such
+  // settings to use ContentSettingsPattern::Wildcard(). This allows us to make
+  // the scoping code consistent across different settings.
   // TODO(lshang): Remove this when clients have migrated (~M53). We should
   // leave in some code to remove old-format settings for a long time.
-  void MigrateOldSettings();
+  void MigrateKeygenSettings();
 
   // Collect UMA data about the number of exceptions.
   void RecordNumberOfExceptions();
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index d45ee41f..c41a5e00 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -1963,7 +1963,7 @@
   }
 
   wl_resource* viewport_resource = wl_resource_create(
-      client, &wl_viewport_interface, wl_resource_get_version(resource), id);
+      client, &wp_viewport_interface, wl_resource_get_version(resource), id);
 
   SetImplementation(viewport_resource, &viewport_implementation,
                     base::WrapUnique(new Viewport(surface)));
diff --git a/components/mus/gles2/BUILD.gn b/components/mus/gles2/BUILD.gn
index c6096c4..c7d0165 100644
--- a/components/mus/gles2/BUILD.gn
+++ b/components/mus/gles2/BUILD.gn
@@ -45,14 +45,14 @@
     "//gpu/command_buffer/common:gles2_utils",
     "//gpu/command_buffer/service",
     "//gpu/config:config",
-    "//mojo/converters/geometry",
     "//mojo/public/cpp/bindings",
     "//mojo/public/cpp/system",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
     "//ui/gl",
     "//ui/gl/init",
-    "//ui/mojo/geometry:interfaces",
   ]
 
   if (use_ozone) {
diff --git a/components/mus/gles2/command_buffer_driver.cc b/components/mus/gles2/command_buffer_driver.cc
index a8d1782..ec8bf83 100644
--- a/components/mus/gles2/command_buffer_driver.cc
+++ b/components/mus/gles2/command_buffer_driver.cc
@@ -25,9 +25,9 @@
 #include "gpu/command_buffer/service/query_manager.h"
 #include "gpu/command_buffer/service/sync_point_manager.h"
 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "ui/gfx/buffer_format_util.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/vsync_provider.h"
 #include "ui/gl/gl_context.h"
diff --git a/components/mus/gles2/command_buffer_driver.h b/components/mus/gles2/command_buffer_driver.h
index 4e54ba1..265704b31 100644
--- a/components/mus/gles2/command_buffer_driver.h
+++ b/components/mus/gles2/command_buffer_driver.h
@@ -22,10 +22,10 @@
 #include "mojo/public/cpp/bindings/array.h"
 #include "mojo/public/cpp/system/buffer.h"
 #include "ui/gfx/buffer_types.h"
+#include "ui/gfx/geometry/mojo/geometry.mojom.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/swap_result.h"
-#include "ui/mojo/geometry/geometry.mojom.h"
 
 namespace gfx {
 class GLContext;
diff --git a/components/mus/gles2/gpu_impl.h b/components/mus/gles2/gpu_impl.h
index c46b2a96..73fb66e 100644
--- a/components/mus/gles2/gpu_impl.h
+++ b/components/mus/gles2/gpu_impl.h
@@ -13,7 +13,7 @@
 #include "components/mus/public/interfaces/gpu.mojom.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
-#include "ui/mojo/geometry/geometry.mojom.h"
+#include "ui/gfx/geometry/mojo/geometry.mojom.h"
 
 namespace mus {
 
diff --git a/components/mus/public/cpp/BUILD.gn b/components/mus/public/cpp/BUILD.gn
index f785a6f..497f235 100644
--- a/components/mus/public/cpp/BUILD.gn
+++ b/components/mus/public/cpp/BUILD.gn
@@ -57,7 +57,6 @@
     "//gpu/command_buffer/client:gles2_implementation",
     "//gpu/command_buffer/client:gles2_interface",
     "//gpu/command_buffer/common",
-    "//mojo/converters/geometry",
     "//mojo/converters/input_events",
     "//mojo/converters/surfaces",
     "//mojo/public/cpp/bindings:bindings",
@@ -66,7 +65,8 @@
     "//services/shell/public/interfaces",
     "//ui/events",
     "//ui/gfx/geometry",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 
   data_deps = [
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.cc b/components/mus/public/cpp/lib/window_tree_client_impl.cc
index 38485f3..181b414 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.cc
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.cc
@@ -22,11 +22,11 @@
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "components/mus/public/cpp/window_tree_connection_observer.h"
 #include "components/mus/public/cpp/window_tree_delegate.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/input_events/input_events_type_converters.h"
 #include "services/shell/public/cpp/connector.h"
 #include "ui/events/event.h"
 #include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace mus {
diff --git a/components/mus/public/cpp/tests/BUILD.gn b/components/mus/public/cpp/tests/BUILD.gn
index b5939b7..c33c823 100644
--- a/components/mus/public/cpp/tests/BUILD.gn
+++ b/components/mus/public/cpp/tests/BUILD.gn
@@ -21,8 +21,8 @@
   deps = [
     "//base",
     "//components/mus/public/cpp",
-    "//mojo/converters/geometry",
     "//testing/gtest",
+    "//ui/gfx/geometry/mojo",
   ]
 }
 
@@ -65,7 +65,6 @@
     "//components/mus/common:mus_common",
     "//components/mus/public/cpp",
     "//mojo/common:common_base",
-    "//mojo/converters/geometry",
     "//mojo/converters/input_events",
     "//mojo/edk/system",
     "//mojo/public/cpp/system",
@@ -74,7 +73,8 @@
     "//ui/events",
     "//ui/gfx:test_support",
     "//ui/gfx/geometry",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 
   if (use_x11) {
diff --git a/components/mus/public/cpp/tests/window_tree_client_impl_private.cc b/components/mus/public/cpp/tests/window_tree_client_impl_private.cc
index 28f6b0ff..69744fc 100644
--- a/components/mus/public/cpp/tests/window_tree_client_impl_private.cc
+++ b/components/mus/public/cpp/tests/window_tree_client_impl_private.cc
@@ -6,8 +6,8 @@
 
 #include "components/mus/public/cpp/lib/window_tree_client_impl.h"
 #include "components/mus/public/cpp/window.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/input_events/input_events_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mus {
 
diff --git a/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc b/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc
index fe375f0..4ac66c3 100644
--- a/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc
+++ b/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc
@@ -21,11 +21,11 @@
 #include "components/mus/public/cpp/window_tracker.h"
 #include "components/mus/public/cpp/window_tree_delegate.h"
 #include "mojo/common/common_type_converters.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/input_events/input_events_type_converters.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace mus {
diff --git a/components/mus/public/interfaces/BUILD.gn b/components/mus/public/interfaces/BUILD.gn
index 7b2b955..556ea86 100644
--- a/components/mus/public/interfaces/BUILD.gn
+++ b/components/mus/public/interfaces/BUILD.gn
@@ -39,7 +39,7 @@
 
   deps = [
     "//gpu/ipc/common:interfaces",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo:interfaces",
     "//ui/mojo/ime:interfaces",
   ]
 }
diff --git a/components/mus/public/interfaces/command_buffer.mojom b/components/mus/public/interfaces/command_buffer.mojom
index f8c3899..dcf1ca6 100644
--- a/components/mus/public/interfaces/command_buffer.mojom
+++ b/components/mus/public/interfaces/command_buffer.mojom
@@ -8,7 +8,7 @@
 import "gpu/ipc/common/command_buffer.mojom";
 import "gpu/ipc/common/mailbox.mojom";
 import "gpu/ipc/common/sync_token.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 struct CommandBufferInitializeResult {
   int32 command_buffer_namespace;
diff --git a/components/mus/public/interfaces/compositor_frame.mojom b/components/mus/public/interfaces/compositor_frame.mojom
index 014145b..0779b3a 100644
--- a/components/mus/public/interfaces/compositor_frame.mojom
+++ b/components/mus/public/interfaces/compositor_frame.mojom
@@ -5,7 +5,7 @@
 module mus.mojom;
 
 import "components/mus/public/interfaces/quads.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 import "gpu/ipc/common/mailbox_holder.mojom";
 import "gpu/ipc/common/sync_token.mojom";
 
diff --git a/components/mus/public/interfaces/event_matcher.mojom b/components/mus/public/interfaces/event_matcher.mojom
index d68e2fb..6cd88236 100644
--- a/components/mus/public/interfaces/event_matcher.mojom
+++ b/components/mus/public/interfaces/event_matcher.mojom
@@ -6,7 +6,7 @@
 
 import "components/mus/public/interfaces/input_event_constants.mojom";
 import "components/mus/public/interfaces/input_key_codes.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 struct KeyEventMatcher {
   KeyboardCode keyboard_code;
diff --git a/components/mus/public/interfaces/gpu_service.mojom b/components/mus/public/interfaces/gpu_service.mojom
index 89f7923..833ec725 100644
--- a/components/mus/public/interfaces/gpu_service.mojom
+++ b/components/mus/public/interfaces/gpu_service.mojom
@@ -8,7 +8,7 @@
 import "components/mus/public/interfaces/gpu.mojom";
 import "components/mus/public/interfaces/gpu_memory_buffer.mojom";
 import "gpu/ipc/common/sync_token.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 interface GpuService {
   // Tells the GPU service to create a new channel for communication with a
diff --git a/components/mus/public/interfaces/quads.mojom b/components/mus/public/interfaces/quads.mojom
index 38efdeb..39153b4 100644
--- a/components/mus/public/interfaces/quads.mojom
+++ b/components/mus/public/interfaces/quads.mojom
@@ -5,7 +5,7 @@
 module mus.mojom;
 
 import "components/mus/public/interfaces/surface_id.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 struct Color {
   uint32 rgba;
diff --git a/components/mus/public/interfaces/window_manager.mojom b/components/mus/public/interfaces/window_manager.mojom
index 807b9cf..b9b98279 100644
--- a/components/mus/public/interfaces/window_manager.mojom
+++ b/components/mus/public/interfaces/window_manager.mojom
@@ -8,7 +8,7 @@
 import "components/mus/public/interfaces/event_matcher.mojom";
 import "components/mus/public/interfaces/input_events.mojom";
 import "components/mus/public/interfaces/window_manager_constants.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 // WindowManager is used when a WindowTreeClient attempts to modify
 // a property of the embed root. When this happens WindowTree calls the
diff --git a/components/mus/public/interfaces/window_manager_constants.mojom b/components/mus/public/interfaces/window_manager_constants.mojom
index d0b29b6..a25f0d9 100644
--- a/components/mus/public/interfaces/window_manager_constants.mojom
+++ b/components/mus/public/interfaces/window_manager_constants.mojom
@@ -4,7 +4,7 @@
 
 module mus.mojom;
 
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 enum WindowManagerErrorCode {
   SUCCESS,
diff --git a/components/mus/public/interfaces/window_tree.mojom b/components/mus/public/interfaces/window_tree.mojom
index 045a9436..a836008 100644
--- a/components/mus/public/interfaces/window_tree.mojom
+++ b/components/mus/public/interfaces/window_tree.mojom
@@ -12,7 +12,7 @@
 import "components/mus/public/interfaces/surface_id.mojom";
 import "components/mus/public/interfaces/window_manager.mojom";
 import "components/mus/public/interfaces/window_manager_constants.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 import "ui/mojo/ime/text_input_state.mojom";
 
 struct ViewportMetrics {
diff --git a/components/mus/public/interfaces/window_tree_host.mojom b/components/mus/public/interfaces/window_tree_host.mojom
index cf33451..f542b8c 100644
--- a/components/mus/public/interfaces/window_tree_host.mojom
+++ b/components/mus/public/interfaces/window_tree_host.mojom
@@ -5,7 +5,7 @@
 module mus.mojom;
 
 import "components/mus/public/interfaces/window_tree.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 // WindowTreeHost encapsulates a unique underlying platform window, with a tree
 // of windows.
diff --git a/components/mus/surfaces/BUILD.gn b/components/mus/surfaces/BUILD.gn
index aa5e657c..65807e08 100644
--- a/components/mus/surfaces/BUILD.gn
+++ b/components/mus/surfaces/BUILD.gn
@@ -31,13 +31,13 @@
     "//gpu/command_buffer/client:gles2_cmd_helper",
     "//gpu/command_buffer/client:gles2_implementation",
     "//gpu/command_buffer/client:gles2_interface",
-    "//mojo/converters/geometry",
     "//mojo/converters/surfaces",
     "//services/shell/public/cpp",
     "//services/tracing/public/cpp",
     "//ui/gfx",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
     "//ui/gl",
-    "//ui/mojo/geometry:interfaces",
   ]
 
   if (use_ozone) {
diff --git a/components/mus/test_wm/BUILD.gn b/components/mus/test_wm/BUILD.gn
index 8b054f4..bdeb236b 100644
--- a/components/mus/test_wm/BUILD.gn
+++ b/components/mus/test_wm/BUILD.gn
@@ -14,8 +14,8 @@
     "//base",
     "//components/mus/public/cpp",
     "//components/mus/public/interfaces",
-    "//mojo/converters/geometry",
     "//services/shell/public/cpp",
+    "//ui/gfx/geometry/mojo",
     "//ui/mojo/display",
   ]
 
diff --git a/components/mus/test_wm/test_wm.cc b/components/mus/test_wm/test_wm.cc
index ef4748f..ec87329f 100644
--- a/components/mus/test_wm/test_wm.cc
+++ b/components/mus/test_wm/test_wm.cc
@@ -7,13 +7,13 @@
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "components/mus/public/cpp/window_tree_delegate.h"
 #include "components/mus/public/interfaces/window_manager_factory.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/public/c/system/main.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/shell/public/cpp/application_runner.h"
 #include "services/shell/public/cpp/connector.h"
 #include "services/shell/public/cpp/shell_client.h"
 #include "ui/display/display.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/mojo/display/display_type_converters.h"
 
 namespace mus {
diff --git a/components/mus/ws/BUILD.gn b/components/mus/ws/BUILD.gn
index 0ec4147..c9fce1c 100644
--- a/components/mus/ws/BUILD.gn
+++ b/components/mus/ws/BUILD.gn
@@ -99,7 +99,6 @@
     "//components/mus/public/interfaces",
     "//components/mus/surfaces",
     "//mojo/common:common_base",
-    "//mojo/converters/geometry",
     "//mojo/converters/ime",
     "//mojo/converters/input_events",
     "//mojo/converters/surfaces",
@@ -113,8 +112,9 @@
     "//ui/events/platform",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
     "//ui/gl",
-    "//ui/mojo/geometry:interfaces",
     "//ui/platform_window",
     "//ui/platform_window:platform_impls",
   ]
@@ -161,7 +161,7 @@
     "//components/mus/public/interfaces",
     "//mojo/common",
     "//mojo/public/cpp/bindings:bindings",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 }
 
@@ -211,7 +211,6 @@
     "//components/mus/public/cpp/tests:test_support",
     "//components/mus/public/interfaces",
     "//components/mus/surfaces",
-    "//mojo/converters/geometry",
     "//mojo/converters/input_events",
     "//mojo/converters/transform",
     "//mojo/public/cpp/bindings:bindings",
@@ -225,9 +224,10 @@
     "//ui/gfx",
     "//ui/gfx:test_support",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
+    "//ui/gfx/geometry/mojo:util",
     "//ui/gl",
-    "//ui/mojo/geometry:interfaces",
-    "//ui/mojo/geometry:util",
   ]
 
   if (use_x11) {
diff --git a/components/mus/ws/display.cc b/components/mus/ws/display.cc
index 8a745a6..9f68877 100644
--- a/components/mus/ws/display.cc
+++ b/components/mus/ws/display.cc
@@ -22,9 +22,9 @@
 #include "components/mus/ws/window_tree.h"
 #include "components/mus/ws/window_tree_binding.h"
 #include "mojo/common/common_type_converters.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "services/shell/public/interfaces/connector.mojom.h"
 #include "ui/base/cursor/cursor.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mus {
 namespace ws {
diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc
index 4a092a6..9e4e974 100644
--- a/components/mus/ws/event_dispatcher.cc
+++ b/components/mus/ws/event_dispatcher.cc
@@ -14,9 +14,9 @@
 #include "components/mus/ws/server_window_delegate.h"
 #include "components/mus/ws/window_coordinate_conversions.h"
 #include "components/mus/ws/window_finder.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/input_events/input_events_type_converters.h"
 #include "ui/events/event_utils.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/point_conversions.h"
 
diff --git a/components/mus/ws/event_matcher.cc b/components/mus/ws/event_matcher.cc
index bb0659b..aff01374 100644
--- a/components/mus/ws/event_matcher.cc
+++ b/components/mus/ws/event_matcher.cc
@@ -4,8 +4,8 @@
 
 #include "components/mus/ws/event_matcher.h"
 
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/input_events/input_events_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mus {
 namespace ws {
diff --git a/components/mus/ws/platform_display.cc b/components/mus/ws/platform_display.cc
index 10e6e7b..0616365a 100644
--- a/components/mus/ws/platform_display.cc
+++ b/components/mus/ws/platform_display.cc
@@ -22,7 +22,6 @@
 #include "components/mus/ws/server_window_surface.h"
 #include "components/mus/ws/server_window_surface_manager.h"
 #include "components/mus/ws/window_coordinate_conversions.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/input_events/input_events_type_converters.h"
 #include "mojo/converters/input_events/mojo_extended_key_event_data.h"
 #include "mojo/converters/surfaces/surfaces_type_converters.h"
@@ -35,6 +34,7 @@
 #include "ui/display/display.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/platform_window/platform_ime_controller.h"
 #include "ui/platform_window/platform_window.h"
 
diff --git a/components/mus/ws/server_window.cc b/components/mus/ws/server_window.cc
index 04a47906..8c40f71 100644
--- a/components/mus/ws/server_window.cc
+++ b/components/mus/ws/server_window.cc
@@ -13,7 +13,7 @@
 #include "components/mus/ws/server_window_delegate.h"
 #include "components/mus/ws/server_window_observer.h"
 #include "components/mus/ws/server_window_surface_manager.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mus {
 
diff --git a/components/mus/ws/server_window_surface.cc b/components/mus/ws/server_window_surface.cc
index 7403512..58ff6e4 100644
--- a/components/mus/ws/server_window_surface.cc
+++ b/components/mus/ws/server_window_surface.cc
@@ -11,8 +11,8 @@
 #include "components/mus/ws/server_window.h"
 #include "components/mus/ws/server_window_delegate.h"
 #include "components/mus/ws/server_window_surface_manager.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/surfaces/surfaces_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mus {
 namespace ws {
diff --git a/components/mus/ws/test_change_tracker.h b/components/mus/ws/test_change_tracker.h
index b606800..15bb6383 100644
--- a/components/mus/ws/test_change_tracker.h
+++ b/components/mus/ws/test_change_tracker.h
@@ -14,7 +14,7 @@
 #include "components/mus/common/types.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "mojo/public/cpp/bindings/array.h"
-#include "ui/mojo/geometry/geometry.mojom.h"
+#include "ui/gfx/geometry/mojo/geometry.mojom.h"
 
 namespace mus {
 
diff --git a/components/mus/ws/test_utils.cc b/components/mus/ws/test_utils.cc
index 495a46e..32692b8 100644
--- a/components/mus/ws/test_utils.cc
+++ b/components/mus/ws/test_utils.cc
@@ -11,9 +11,9 @@
 #include "components/mus/ws/server_window_surface_manager_test_api.h"
 #include "components/mus/ws/window_manager_access_policy.h"
 #include "components/mus/ws/window_manager_factory_service.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "services/shell/public/interfaces/connector.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mus {
 namespace ws {
diff --git a/components/mus/ws/window_manager_client_unittest.cc b/components/mus/ws/window_manager_client_unittest.cc
index 9cc9afe..edafe678 100644
--- a/components/mus/ws/window_manager_client_unittest.cc
+++ b/components/mus/ws/window_manager_client_unittest.cc
@@ -17,9 +17,9 @@
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "components/mus/public/cpp/window_tree_connection_observer.h"
 #include "components/mus/public/cpp/window_tree_delegate.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_util.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/mojo/geometry/geometry_util.h"
 
 namespace mus {
 namespace ws {
diff --git a/components/mus/ws/window_server.cc b/components/mus/ws/window_server.cc
index de480968..674dbf2 100644
--- a/components/mus/ws/window_server.cc
+++ b/components/mus/ws/window_server.cc
@@ -22,10 +22,10 @@
 #include "components/mus/ws/window_server_delegate.h"
 #include "components/mus/ws/window_tree.h"
 #include "components/mus/ws/window_tree_binding.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/input_events/input_events_type_converters.h"
 #include "mojo/converters/surfaces/surfaces_type_converters.h"
 #include "services/shell/public/cpp/connection.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/geometry/size_conversions.h"
 
 namespace mus {
diff --git a/components/mus/ws/window_tree.cc b/components/mus/ws/window_tree.cc
index d213e77..4909ab3 100644
--- a/components/mus/ws/window_tree.cc
+++ b/components/mus/ws/window_tree.cc
@@ -25,10 +25,10 @@
 #include "components/mus/ws/window_manager_state.h"
 #include "components/mus/ws/window_server.h"
 #include "components/mus/ws/window_tree_binding.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/ime/ime_type_converters.h"
 #include "mojo/converters/input_events/input_events_type_converters.h"
 #include "mojo/converters/surfaces/surfaces_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/platform_window/text_input_state.h"
 
 using mojo::Array;
diff --git a/components/mus/ws/window_tree_client_unittest.cc b/components/mus/ws/window_tree_client_unittest.cc
index e5353f8..1676b81 100644
--- a/components/mus/ws/window_tree_client_unittest.cc
+++ b/components/mus/ws/window_tree_client_unittest.cc
@@ -15,9 +15,9 @@
 #include "components/mus/public/interfaces/window_tree_host.mojom.h"
 #include "components/mus/ws/ids.h"
 #include "components/mus/ws/test_change_tracker.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
 #include "services/shell/public/cpp/shell_test.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 using mojo::Array;
 using mojo::Callback;
diff --git a/components/mus/ws/window_tree_unittest.cc b/components/mus/ws/window_tree_unittest.cc
index ab51cb4..c2ce517 100644
--- a/components/mus/ws/window_tree_unittest.cc
+++ b/components/mus/ws/window_tree_unittest.cc
@@ -31,11 +31,11 @@
 #include "components/mus/ws/window_server.h"
 #include "components/mus/ws/window_server_delegate.h"
 #include "components/mus/ws/window_tree_binding.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "services/shell/public/interfaces/connector.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace mus {
diff --git a/components/test_runner/test_common.cc b/components/test_runner/test_common.cc
index c387440..4d295815 100644
--- a/components/test_runner/test_common.cc
+++ b/components/test_runner/test_common.cc
@@ -34,10 +34,6 @@
   }
   ~MockBlinkPlatform() override {}
 
-  void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*,
-                                  const char* name) override {}
-  void unregisterMemoryDumpProvider(blink::WebMemoryDumpProvider*) override {}
-
  private:
   DISALLOW_COPY_AND_ASSIGN(MockBlinkPlatform);
 };
diff --git a/components/test_runner/test_runner.cc b/components/test_runner/test_runner.cc
index 99d728b..0c0b5d1 100644
--- a/components/test_runner/test_runner.cc
+++ b/components/test_runner/test_runner.cc
@@ -1551,6 +1551,7 @@
       spellcheck_(new SpellCheckClient(this)),
       chooser_count_(0),
       previously_focused_view_(nullptr),
+      did_request_after_reset_(false),
       weak_factory_(this) {}
 
 TestRunner::~TestRunner() {}
@@ -1575,6 +1576,7 @@
 }
 
 void TestRunner::Reset() {
+  did_request_after_reset_ = false;
   top_loading_frame_ = nullptr;
   layout_test_runtime_flags_.Reset();
   mock_screen_orientation_client_->ResetData();
diff --git a/components/test_runner/test_runner.h b/components/test_runner/test_runner.h
index 77c3136..fc9c732 100644
--- a/components/test_runner/test_runner.h
+++ b/components/test_runner/test_runner.h
@@ -132,6 +132,8 @@
   bool shouldDumpSpellCheckCallbacks() const;
   bool shouldWaitUntilExternalURLLoad() const;
   const std::set<std::string>* httpHeadersToClear() const;
+  bool did_request_after_reset() const { return did_request_after_reset_; }
+  void set_did_request_after_reset() { did_request_after_reset_ = true; }
 
   // To be called when |frame| starts loading - TestRunner will check if
   // there is currently no top-loading-frame being tracked and if so, then it
@@ -637,6 +639,9 @@
 
   std::set<blink::WebWidget*> widgets_with_scheduled_animations_;
 
+  // True if we requested any resource after Reset().
+  bool did_request_after_reset_;
+
   base::WeakPtrFactory<TestRunner> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(TestRunner);
diff --git a/components/test_runner/web_frame_test_client.cc b/components/test_runner/web_frame_test_client.cc
index 54fe96c..03c5c9e 100644
--- a/components/test_runner/web_frame_test_client.cc
+++ b/components/test_runner/web_frame_test_client.cc
@@ -598,6 +598,10 @@
     }
   }
 
+  if (!test_runner_->did_request_after_reset()) {
+    test_runner_->set_did_request_after_reset();
+    return;
+  }
   // Set the new substituted URL.
   request.setURL(
       delegate_->RewriteLayoutTestsURL(request.url().string().utf8()));
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 3730469..a810ce5 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -68,7 +68,6 @@
     "//media/midi",
     "//mojo/common",
     "//mojo/common:url_type_converters",
-    "//mojo/converters/geometry",
     "//mojo/public/cpp/bindings",
     "//mojo/public/js",
     "//net",
@@ -107,6 +106,7 @@
     "//ui/events/blink",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
     "//ui/gl",
     "//ui/native_theme",
     "//ui/resources",
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index e324279..cfdbce1 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -13,7 +13,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
-#include "base/sys_info.h"
 #include "base/trace_event/trace_event.h"
 #include "base/version.h"
 #include "build/build_config.h"
@@ -72,6 +71,9 @@
   kWinVista,
   kWin7,
   kWin8,
+  kWin8_1,
+  kWin10,
+  kWin10_TH2,
   kNumWinSubVersions
 };
 
@@ -79,21 +81,28 @@
   static WinSubVersion sub_version = kNumWinSubVersions;
   if (sub_version == kNumWinSubVersions) {
     sub_version = kWinOthers;
-    std::string version_str = base::SysInfo::OperatingSystemVersion();
-    size_t pos = version_str.find_first_not_of("0123456789.");
-    if (pos != std::string::npos)
-      version_str = version_str.substr(0, pos);
-    Version os_version(version_str);
-    if (os_version.IsValid() && os_version.components().size() >= 2) {
-      const std::vector<uint32_t>& version_numbers = os_version.components();
-      if (version_numbers[0] == 5)
-        sub_version = kWinXP;
-      else if (version_numbers[0] == 6 && version_numbers[1] == 0)
-        sub_version = kWinVista;
-      else if (version_numbers[0] == 6 && version_numbers[1] == 1)
+    switch (base::win::GetVersion()) {
+      case base::win::VERSION_PRE_XP:
+      case base::win::VERSION_XP:
+      case base::win::VERSION_SERVER_2003:
+      case base::win::VERSION_VISTA:
+      case base::win::VERSION_WIN_LAST:
+        break;
+      case base::win::VERSION_WIN7:
         sub_version = kWin7;
-      else if (version_numbers[0] == 6 && version_numbers[1] == 2)
+        break;
+      case base::win::VERSION_WIN8:
         sub_version = kWin8;
+        break;
+      case base::win::VERSION_WIN8_1:
+        sub_version = kWin8_1;
+        break;
+      case base::win::VERSION_WIN10:
+        sub_version = kWin10;
+        break;
+      case base::win::VERSION_WIN10_TH2:
+        sub_version = kWin10_TH2;
+        break;
     }
   }
   int entry_index = static_cast<int>(sub_version) * kGpuFeatureNumStatus;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index dd59a10..321514a 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -115,7 +115,6 @@
 #include "content/public/common/url_utils.h"
 #include "content/public/common/web_preferences.h"
 #include "mojo/common/url_type_converters.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "net/base/url_util.h"
 #include "net/http/http_cache.h"
 #include "net/http/http_transaction_factory.h"
@@ -126,6 +125,7 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/accessibility/ax_tree_combiner.h"
 #include "ui/base/layout.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gl/gl_switches.h"
 
 #if defined(OS_ANDROID)
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index f620d3c..31ae6faa 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -58,7 +58,6 @@
 #include "net/base/net_errors.h"
 #include "third_party/WebKit/public/platform/WebData.h"
 #include "third_party/WebKit/public/platform/WebFloatPoint.h"
-#include "third_party/WebKit/public/platform/WebMemoryDumpProvider.h"
 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 602c400..9953d2e 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -239,7 +239,7 @@
     "//services/shell/public/interfaces",
     "//skia/public/interfaces",
     "//third_party/WebKit/public:mojo_bindings",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo:interfaces",
     "//url/mojo:url_mojom_origin",
   ]
 }
diff --git a/content/common/image_downloader/image_downloader.mojom b/content/common/image_downloader/image_downloader.mojom
index b6ea34ed..1dfa0d2d 100644
--- a/content/common/image_downloader/image_downloader.mojom
+++ b/content/common/image_downloader/image_downloader.mojom
@@ -5,7 +5,7 @@
 module content.mojom;
 
 import "skia/public/interfaces/bitmap.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 interface ImageDownloader {
   // Fetch and decode an image from a given URL.
diff --git a/content/content.gyp b/content/content.gyp
index 5ddc717..225213e0 100644
--- a/content/content.gyp
+++ b/content/content.gyp
@@ -484,12 +484,12 @@
             '../mojo/mojo_public.gyp:mojo_bindings_java',
             '../net/net.gyp:net',
             '../skia/skia.gyp:skia_mojo',
-            '../ui/android/ui_android.gyp:ui_java',
-            '../ui/touch_selection/ui_touch_selection.gyp:selection_event_type_java',
-            '../ui/touch_selection/ui_touch_selection.gyp:touch_handle_orientation_java',
             '../third_party/android_tools/android_tools.gyp:android_support_v13_javalib',
             '../third_party/WebKit/public/blink_headers.gyp:blink_headers_java',
-            '../ui/mojo/geometry/mojo_bindings.gyp:mojo_geometry_bindings',
+            '../ui/android/ui_android.gyp:ui_java',
+            '../ui/gfx/gfx.gyp:mojo_geometry_bindings',
+            '../ui/touch_selection/ui_touch_selection.gyp:selection_event_type_java',
+            '../ui/touch_selection/ui_touch_selection.gyp:touch_handle_orientation_java',
             'common_aidl',
             'console_message_level_java',
             'content_common',
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 71d766a..edd46d1 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -25,7 +25,6 @@
     '../gpu/gpu.gyp:gpu',
     '../gpu/gpu.gyp:gpu_ipc_client',
     '../gpu/gpu.gyp:gpu_ipc_common',
-    '../mojo/mojo_base.gyp:mojo_geometry_lib',
     '../mojo/mojo_base.gyp:mojo_url_type_converters',
     '../mojo/mojo_public.gyp:mojo_cpp_bindings',
     '../mojo/mojo_public.gyp:mojo_js_bindings',
@@ -67,6 +66,7 @@
     '../ui/gfx/gfx.gyp:gfx',
     '../ui/gfx/gfx.gyp:gfx_geometry',
     '../ui/gfx/gfx.gyp:gfx_range',
+    '../ui/gfx/gfx.gyp:mojo_geometry_lib',
     '../ui/resources/ui_resources.gyp:ui_resources',
     '../ui/snapshot/snapshot.gyp:snapshot',
     '../ui/surface/surface.gyp:surface',
diff --git a/content/content_common_mojo_bindings.gyp b/content/content_common_mojo_bindings.gyp
index 807c78b..6ee89513 100644
--- a/content/content_common_mojo_bindings.gyp
+++ b/content/content_common_mojo_bindings.gyp
@@ -30,7 +30,7 @@
         '../services/shell/shell_public.gyp:shell_public',
         '../skia/skia.gyp:skia_mojo',
         '../third_party/WebKit/public/blink.gyp:mojo_bindings',
-        '../ui/mojo/geometry/mojo_bindings.gyp:mojo_geometry_bindings',
+        '../ui/gfx/gfx.gyp:mojo_geometry_bindings',
       ],
       'includes': [ '../mojo/mojom_bindings_generator_explicit.gypi' ],
     },
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 7abf917..16449e0 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -23,7 +23,6 @@
     '../media/gpu/ipc/media_ipc.gyp:media_gpu_ipc_common',
     '../media/media.gyp:media',
     '../media/media.gyp:media_gpu',
-    '../mojo/mojo_base.gyp:mojo_geometry_lib',
     '../mojo/mojo_base.gyp:mojo_url_type_converters',
     '../mojo/mojo_edk.gyp:mojo_js_lib',
     '../net/net.gyp:net',
@@ -45,6 +44,7 @@
     '../ui/gfx/gfx.gyp:gfx',
     '../ui/gfx/gfx.gyp:gfx_geometry',
     '../ui/gfx/gfx.gyp:gfx_range',
+    '../ui/gfx/gfx.gyp:mojo_geometry_lib',
     '../ui/native_theme/native_theme.gyp:native_theme',
     '../ui/surface/surface.gyp:surface',
     '../url/ipc/url_ipc.gyp:url_ipc',
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 13138ab1..329cac7 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -63,7 +63,6 @@
     "//media/gpu/ipc/common",
     "//media/midi",
     "//mojo/common",
-    "//mojo/converters/geometry",
     "//mojo/edk/js",
     "//mojo/public/cpp/bindings",
     "//mojo/public/js",
@@ -89,6 +88,7 @@
     "//ui/events:dom_keycode_converter",
     "//ui/events:events_base",
     "//ui/events/blink",
+    "//ui/gfx/geometry/mojo",
     "//ui/gl",
     "//ui/native_theme",
     "//ui/surface",
diff --git a/content/renderer/image_downloader/image_downloader_impl.cc b/content/renderer/image_downloader/image_downloader_impl.cc
index 0fd476c..774b234 100644
--- a/content/renderer/image_downloader/image_downloader_impl.cc
+++ b/content/renderer/image_downloader/image_downloader_impl.cc
@@ -14,7 +14,6 @@
 #include "content/public/renderer/render_thread.h"
 #include "content/renderer/fetchers/multi_resolution_image_resource_fetcher.h"
 #include "mojo/common/url_type_converters.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "net/base/data_url.h"
 #include "skia/ext/image_operations.h"
 #include "skia/public/type_converters.h"
@@ -23,6 +22,7 @@
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "ui/gfx/favicon_size.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/skbitmap_operations.h"
 #include "url/url_constants.h"
diff --git a/content/renderer/mus/BUILD.gn b/content/renderer/mus/BUILD.gn
index c2d3f93..dcf56ae 100644
--- a/content/renderer/mus/BUILD.gn
+++ b/content/renderer/mus/BUILD.gn
@@ -26,12 +26,12 @@
     "//content/public/common:common_sources",
     "//mojo/common",
     "//mojo/converters/blink",
-    "//mojo/converters/geometry",
     "//mojo/converters/input_events",
     "//mojo/converters/surfaces",
     "//services/shell/public/cpp",
     "//third_party/WebKit/public:blink",
     "//ui/events:events",
     "//ui/events:events_base",
+    "//ui/gfx/geometry/mojo",
   ]
 }
diff --git a/content/renderer/mus/render_widget_mus_connection.cc b/content/renderer/mus/render_widget_mus_connection.cc
index d1821e8b..da41c331 100644
--- a/content/renderer/mus/render_widget_mus_connection.cc
+++ b/content/renderer/mus/render_widget_mus_connection.cc
@@ -18,9 +18,9 @@
 #include "content/renderer/mus/compositor_mus_connection.h"
 #include "content/renderer/render_thread_impl.h"
 #include "content/renderer/render_view_impl.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/surfaces/surfaces_utils.h"
 #include "services/shell/public/cpp/connector.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace content {
 
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc
index 9673cf4..f5aae4f 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.cc
+++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -213,6 +213,8 @@
   const int kFileSchemeLen = arraysize(kFileScheme) - 1;
   if (utf8_url.compare(0, kFileSchemeLen, kFileScheme, kFileSchemeLen) != 0)
     return WebURL();
+  if (utf8_url.find("/LayoutTests/") != std::string::npos)
+    return WebURL();
 #if defined(OS_WIN)
   // +3 for a drive letter, :, and /.
   const int kFileSchemeAndDriveLen = kFileSchemeLen + 3;
diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc
index 2af671c..8298d84 100644
--- a/extensions/common/manifest_constants.cc
+++ b/extensions/common/manifest_constants.cc
@@ -49,6 +49,7 @@
 const char kFileBrowserHandlers[] = "file_browser_handlers";
 const char kFileHandlers[] = "file_handlers";
 const char kFileHandlerExtensions[] = "extensions";
+const char kFileHandlerIncludeDirectories[] = "include_directories";
 const char kFileHandlerTypes[] = "types";
 const char kFileHandlerVerb[] = "verb";
 const char kGlobal[] = "global";
diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h
index d86d1dc..4009db5 100644
--- a/extensions/common/manifest_constants.h
+++ b/extensions/common/manifest_constants.h
@@ -51,6 +51,7 @@
 extern const char kFileAccessList[];
 extern const char kFileHandlers[];
 extern const char kFileHandlerExtensions[];
+extern const char kFileHandlerIncludeDirectories[];
 extern const char kFileHandlerTypes[];
 extern const char kFileHandlerVerb[];
 extern const char kFileFilters[];
diff --git a/extensions/common/manifest_handlers/file_handler_info.cc b/extensions/common/manifest_handlers/file_handler_info.cc
index 5cc615e..8ee9960 100644
--- a/extensions/common/manifest_handlers/file_handler_info.cc
+++ b/extensions/common/manifest_handlers/file_handler_info.cc
@@ -93,8 +93,8 @@
   }
 
   handler.include_directories = false;
-  if (handler_info.HasKey("include_directories") &&
-      !handler_info.GetBoolean("include_directories",
+  if (handler_info.HasKey(keys::kFileHandlerIncludeDirectories) &&
+      !handler_info.GetBoolean(keys::kFileHandlerIncludeDirectories,
                                &handler.include_directories)) {
     *error = ErrorUtils::FormatErrorMessageUTF16(
         errors::kInvalidFileHandlerIncludeDirectories, handler_id);
@@ -152,6 +152,7 @@
        it.Advance()) {
     if (it.key() != keys::kFileHandlerExtensions &&
         it.key() != keys::kFileHandlerTypes &&
+        it.key() != keys::kFileHandlerIncludeDirectories &&
         it.key() != keys::kFileHandlerVerb) {
       install_warnings->push_back(
           InstallWarning(base::StringPrintf(kNotRecognized, it.key().c_str()),
diff --git a/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc b/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
index 6031849e..3d650e8c 100644
--- a/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
+++ b/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
@@ -30,6 +30,8 @@
                errors::kInvalidFileHandlerExtensionElement),
       Testcase("file_handlers_invalid_too_many.json",
                errors::kInvalidFileHandlersTooManyTypesAndExtensions),
+      Testcase("file_handlers_invalid_include_directories.json",
+               errors::kInvalidFileHandlerIncludeDirectories),
       Testcase("file_handlers_invalid_verb.json",
                errors::kInvalidFileHandlerVerb),
   };
@@ -44,9 +46,16 @@
   const FileHandlersInfo* handlers =
       FileHandlers::GetFileHandlers(extension.get());
   ASSERT_TRUE(handlers != NULL);
-  ASSERT_EQ(2U, handlers->size());
+  ASSERT_EQ(3U, handlers->size());
 
   FileHandlerInfo handler = handlers->at(0);
+  EXPECT_EQ("directories", handler.id);
+  EXPECT_EQ(0U, handler.types.size());
+  EXPECT_EQ(1U, handler.extensions.size());
+  EXPECT_EQ(1U, handler.extensions.count("*/*"));
+  EXPECT_EQ(true, handler.include_directories);
+
+  handler = handlers->at(1);
   EXPECT_EQ("image", handler.id);
   EXPECT_EQ(1U, handler.types.size());
   EXPECT_EQ(1U, handler.types.count("image/*"));
@@ -55,7 +64,7 @@
   EXPECT_EQ(1U, handler.extensions.count(".gif"));
   EXPECT_EQ("add_to", handler.verb);
 
-  handler = handlers->at(1);
+  handler = handlers->at(2);
   EXPECT_EQ("text", handler.id);
   EXPECT_EQ(1U, handler.types.size());
   EXPECT_EQ(1U, handler.types.count("text/*"));
diff --git a/extensions/test/data/manifest_tests/file_handlers_invalid_include_directories.json b/extensions/test/data/manifest_tests/file_handlers_invalid_include_directories.json
new file mode 100644
index 0000000..765230834
--- /dev/null
+++ b/extensions/test/data/manifest_tests/file_handlers_invalid_include_directories.json
@@ -0,0 +1,21 @@
+{
+  "name": "test",
+  "description": "App with file_handlers manifest.",
+  "version": "1",
+  "app": {
+    "background": {
+      "scripts": ["background.js"]
+    }
+  },
+  "file_handlers": {
+    "text": {
+      "types": [
+        "text/*"
+      ]
+    },
+    "directories": {
+      "extensions": ["*"],
+      "include_directories": "invalid_value"
+    }
+  }
+}
diff --git a/extensions/test/data/manifest_tests/file_handlers_valid.json b/extensions/test/data/manifest_tests/file_handlers_valid.json
index db90140..0e6335c3 100644
--- a/extensions/test/data/manifest_tests/file_handlers_valid.json
+++ b/extensions/test/data/manifest_tests/file_handlers_valid.json
@@ -22,6 +22,10 @@
         ".gif"
       ],
       "verb": "add_to"
+    },
+    "directories": {
+      "extensions": ["*/*"],
+      "include_directories": true
     }
   }
 }
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 1efa699..b093ac2 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -2935,7 +2935,6 @@
     'resource_type': 'TransformFeedback',
     'resource_types': 'TransformFeedbacks',
     'unsafe': True,
-    'unit_test': False,
   },
   'GetActiveAttrib': {
     'type': 'Custom',
@@ -4610,6 +4609,34 @@
     return 'cached_' + item['name']
   return item['name']
 
+def GuardState(state, operation):
+  if 'manual' in state:
+    assert state['manual']
+    return ""
+
+  result = []
+  result_end = []
+  if 'es3' in state:
+    assert state['es3']
+    result.append("  if (feature_info_->IsES3Capable()) {\n");
+    result_end.append("  }\n")
+  if 'extension_flag' in state:
+    result.append("  if (feature_info_->feature_flags().%s) {\n  " %
+                     (state['extension_flag']))
+    result_end.append("  }\n")
+  if 'gl_version_flag' in state:
+    name = state['gl_version_flag']
+    inverted = ''
+    if name[0] == '!':
+      inverted = '!'
+      name = name[1:]
+    result.append("  if (%sfeature_info_->gl_version_info().%s) {\n" %
+                      (inverted, name))
+    result_end.append("  }\n")
+
+  result.append(operation)
+  return ''.join(result + result_end)
+
 def ToGLExtensionString(extension_flag):
   """Returns GL-type extension string of a extension flag."""
   if extension_flag == "oes_compressed_etc1_rgb8_texture":
@@ -5583,8 +5610,9 @@
                  (state['name'], args[1].name))
       f.write("        state_.%s = %s;\n" % (state['name'], args[1].name))
       if not func.GetInfo("no_gl"):
-        f.write("        %s(%s);\n" %
-                   (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
+        operation = "        %s(%s);\n" % \
+                    (func.GetGLFunctionName(), func.MakeOriginalArgString(""))
+        f.write(GuardState(state, operation))
       f.write("      }\n")
       f.write("      break;\n")
     f.write("    default:\n")
@@ -6065,17 +6093,15 @@
 
   def WriteHandlerImplementation (self, func, f):
     """Overrriden from TypeHandler."""
-    f.write("  if (!%sHelper(n, %s)) {\n"
-               "    return error::kInvalidArguments;\n"
-               "  }\n" %
-               (func.name, func.GetLastOriginalArg().name))
+    raise NotImplementedError("GENn functions are immediate")
 
   def WriteImmediateHandlerImplementation(self, func, f):
     """Overrriden from TypeHandler."""
-    f.write("  if (!%sHelper(n, %s)) {\n"
+    param_name = func.GetLastOriginalArg().name
+    f.write("  if (!CheckUniqueIds(n, %s) || !%sHelper(n, %s)) {\n"
             "    return error::kInvalidArguments;\n"
             "  }\n" %
-            (func.original_name, func.GetLastOriginalArg().name))
+            (param_name, func.original_name, param_name))
 
   def WriteGLES2Implementation(self, func, f):
     """Overrriden from TypeHandler."""
@@ -6152,35 +6178,7 @@
 
   def WriteServiceUnitTest(self, func, f, *extras):
     """Overrriden from TypeHandler."""
-    valid_test = """
-TEST_P(%(test_name)s, %(name)sValidArgs) {
-  EXPECT_CALL(*gl_, %(gl_func_name)s(1, _))
-      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
-  GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
-  SpecializedSetup<cmds::%(name)s, 0>(true);
-  cmds::%(name)s cmd;
-  cmd.Init(%(args)s);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_TRUE(Get%(resource_name)s(kNewClientId, &service_id) != NULL);
-}
-"""
-    self.WriteValidUnitTest(func, f, valid_test, {
-        'resource_name': func.GetInfo('resource_type'),
-      }, *extras)
-    invalid_test = """
-TEST_P(%(test_name)s, %(name)sInvalidArgs) {
-  EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
-  GetSharedMemoryAs<GLuint*>()[0] = client_%(resource_name)s_id_;
-  SpecializedSetup<cmds::%(name)s, 0>(false);
-  cmds::%(name)s cmd;
-  cmd.Init(%(args)s);
-  EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
-}
-"""
-    self.WriteValidUnitTest(func, f, invalid_test, {
-          'resource_name': func.GetInfo('resource_type').lower(),
-        }, *extras)
+    raise NotImplementedError("GENn functions are immediate")
 
   def WriteImmediateServiceUnitTest(self, func, f, *extras):
     """Overrriden from TypeHandler."""
@@ -6205,6 +6203,26 @@
     self.WriteValidUnitTest(func, f, valid_test, {
         'resource_name': func.GetInfo('resource_type'),
       }, *extras)
+    duplicate_id_test = """
+TEST_P(%(test_name)s, %(name)sDuplicateIds) {
+  EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
+  cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
+  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+  SpecializedSetup<cmds::%(name)s, 1>(true);"""
+    if func.IsUnsafe():
+      duplicate_id_test += """
+  decoder_->set_unsafe_es3_apis_enabled(true);"""
+    duplicate_id_test += """
+  cmd->Init(3, temp);
+  EXPECT_EQ(error::kInvalidArguments,
+            ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_TRUE(Get%(resource_name)s(kNewClientId) == NULL);
+  EXPECT_TRUE(Get%(resource_name)s(kNewClientId + 1) == NULL);
+}
+    """
+    self.WriteValidUnitTest(func, f, duplicate_id_test, {
+        'resource_name': func.GetInfo('resource_type'),
+      }, *extras)
     invalid_test = """
 TEST_P(%(test_name)s, %(name)sInvalidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
@@ -10377,45 +10395,28 @@
             for item in state['states']:
               item_name = CachedStateName(item)
 
-              if 'manual' in item:
-                assert item['manual']
-                continue
-              if 'es3' in item:
-                assert item['es3']
-                f.write("  if (feature_info_->IsES3Capable()) {\n");
-              if 'extension_flag' in item:
-                f.write("  if (feature_info_->feature_flags().%s) {\n  " %
-                           item['extension_flag'])
+              operation = []
               if test_prev:
                 if isinstance(item['default'], list):
-                  f.write("  if (memcmp(prev_state->%s, %s, "
-                             "sizeof(%s) * %d)) {\n" %
-                             (item_name, item_name, item['type'],
-                              len(item['default'])))
+                  operation.append("  if (memcmp(prev_state->%s, %s, "
+                                      "sizeof(%s) * %d)) {\n" %
+                                      (item_name, item_name, item['type'],
+                                      len(item['default'])))
                 else:
-                  f.write("  if (prev_state->%s != %s) {\n  " %
-                             (item_name, item_name))
-              if 'gl_version_flag' in item:
-                item_name = item['gl_version_flag']
-                inverted = ''
-                if item_name[0] == '!':
-                  inverted = '!'
-                  item_name = item_name[1:]
-                f.write("  if (%sfeature_info_->gl_version_info().%s) {\n" %
-                           (inverted, item_name))
-              f.write("  gl%s(%s, %s);\n" %
-                         (state['func'],
-                          (item['enum_set']
-                             if 'enum_set' in item else item['enum']),
-                          item['name']))
-              if 'gl_version_flag' in item or 'es3' in item:
-                f.write("  }\n")
+                  operation.append("  if (prev_state->%s != %s) {\n  " %
+                                      (item_name, item_name))
+
+              operation.append("  gl%s(%s, %s);\n" %
+                             (state['func'],
+                             (item['enum_set']
+                                 if 'enum_set' in item else item['enum']),
+                             item['name']))
+
               if test_prev:
-                if 'extension_flag' in item:
-                  f.write("  ")
-                f.write("  }")
-              if 'extension_flag' in item:
-                f.write("  }")
+                operation.append("  }")
+
+              guarded_operation = GuardState(item, ''.join(operation))
+              f.write(guarded_operation)
           else:
             if 'extension_flag' in state:
               f.write("  if (feature_info_->feature_flags().%s)\n  " %
@@ -10619,6 +10620,7 @@
 }
 
 void GLES2DecoderTestBase::SetupInitStateExpectations(bool es3_capable) {
+  const auto& feature_info_ = group_->feature_info();
 """)
       # We need to sort the keys so the expectations match
       for state_name in sorted(_STATES.keys()):
@@ -10639,32 +10641,23 @@
             f.write("      .RetiresOnSaturation();\n")
         elif state['type'] == 'NamedParameter':
           for item in state['states']:
-            if 'manual' in item:
-              assert item['manual']
-              continue
-            if 'extension_flag' in item:
-              f.write("  if (group_->feature_info()->feature_flags().%s) {\n" %
-                         item['extension_flag'])
-              f.write("  ")
-            if 'es3' in item:
-              assert item['es3']
-              f.write("  if (es3_capable) {\n")
-              f.write("  ")
             expect_value = item['default']
             if isinstance(expect_value, list):
               # TODO: Currently we do not check array values.
               expect_value = "_"
 
-            f.write(
-                "  EXPECT_CALL(*gl_, %s(%s, %s))\n" %
-                (state['func'],
-                 (item['enum_set']
-                             if 'enum_set' in item else item['enum']),
-                 expect_value))
-            f.write("      .Times(1)\n")
-            f.write("      .RetiresOnSaturation();\n")
-            if 'extension_flag' in item or 'es3' in item:
-              f.write("  }\n")
+            operation = []
+            operation.append(
+                             "  EXPECT_CALL(*gl_, %s(%s, %s))\n" %
+                             (state['func'],
+                              (item['enum_set']
+                                  if 'enum_set' in item else item['enum']),
+                              expect_value))
+            operation.append("      .Times(1)\n")
+            operation.append("      .RetiresOnSaturation();\n")
+
+            guarded_operation = GuardState(item, ''.join(operation))
+            f.write(guarded_operation)
         else:
           if 'extension_flag' in state:
             f.write("  if (group_->feature_info()->feature_flags().%s) {\n" %
diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h
index c7d7eb1d..9ce5953 100644
--- a/gpu/command_buffer/service/context_state_impl_autogen.h
+++ b/gpu/command_buffer/service/context_state_impl_autogen.h
@@ -288,8 +288,8 @@
       glDepthRange(z_near, z_far);
     if ((front_face != prev_state->front_face))
       glFrontFace(front_face);
-    if (prev_state->hint_generate_mipmap != hint_generate_mipmap) {
-      if (!feature_info_->gl_version_info().is_desktop_core_profile) {
+    if (!feature_info_->gl_version_info().is_desktop_core_profile) {
+      if (prev_state->hint_generate_mipmap != hint_generate_mipmap) {
         glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
       }
     }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 81a6c97c..c4b461e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -193,6 +193,13 @@
   return object ? object->service_id() : 0;
 }
 
+bool CheckUniqueIds(GLsizei n, const GLuint* client_ids) {
+  if (n <= 0)
+    return true;
+  std::unordered_set<uint32_t> unique_ids(client_ids, client_ids + n);
+  return unique_ids.size() == static_cast<size_t>(n);
+}
+
 struct Vec4f {
   explicit Vec4f(const Vec4& data) {
     data.GetValues(v);
@@ -2048,9 +2055,12 @@
   GLsizei offscreen_target_samples_;
   GLboolean offscreen_target_buffer_preserved_;
 
-  // The copy that is saved when SwapBuffers is called.
-  std::unique_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
+  // The saved copy of the backbuffer after a call to SwapBuffers.
   std::unique_ptr<BackTexture> offscreen_saved_color_texture_;
+
+  // For simplicity, |offscreen_saved_color_texture_| is always bound to
+  // |offscreen_saved_frame_buffer_|.
+  std::unique_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
   scoped_refptr<TextureRef>
       offscreen_saved_color_texture_info_;
 
@@ -4222,7 +4232,7 @@
   state_.indexed_uniform_buffer_bindings = nullptr;
 
   if (offscreen_saved_color_texture_info_.get()) {
-    DCHECK(offscreen_target_color_texture_);
+    DCHECK(offscreen_saved_color_texture_);
     DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
               offscreen_saved_color_texture_->id());
     offscreen_saved_color_texture_->Invalidate();
@@ -4404,7 +4414,9 @@
   mailbox_manager()->ProduceTexture(
       mailbox, offscreen_saved_color_texture_info_->texture());
 
-  // Save the BackTexture and TextureRef.
+  // Save the BackTexture and TextureRef. There's no need to update
+  // |offscreen_saved_frame_buffer_| since CreateBackTexture() will take care of
+  // that.
   SavedBackTexture save;
   save.back_texture.swap(offscreen_saved_color_texture_);
   save.texture_ref = offscreen_saved_color_texture_info_;
@@ -4445,6 +4457,8 @@
       continue;
     offscreen_saved_color_texture_ = std::move(it->back_texture);
     offscreen_saved_color_texture_info_ = it->texture_ref;
+    offscreen_saved_frame_buffer_->AttachRenderTexture(
+        offscreen_saved_color_texture_.get());
     saved_back_textures_.erase(it);
     return;
   }
@@ -13238,6 +13252,8 @@
         offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
         offscreen_target_frame_buffer_->AttachRenderTexture(
             offscreen_target_color_texture_.get());
+        offscreen_saved_frame_buffer_->AttachRenderTexture(
+            offscreen_saved_color_texture_.get());
       }
 
       // Ensure the side effects of the copy are visible to the parent
@@ -13716,7 +13732,7 @@
 bool GLES2DecoderImpl::GenQueriesEXTHelper(
     GLsizei n, const GLuint* client_ids) {
   for (GLsizei ii = 0; ii < n; ++ii) {
-    if (query_manager_->GetQuery(client_ids[ii])) {
+    if (query_manager_->IsValidQuery(client_ids[ii])) {
       return false;
     }
   }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 75efd244..52b7fd69 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -1257,7 +1257,7 @@
   if (buffers == NULL) {
     return error::kOutOfBounds;
   }
-  if (!GenBuffersHelper(n, buffers)) {
+  if (!CheckUniqueIds(n, buffers) || !GenBuffersHelper(n, buffers)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
@@ -1294,7 +1294,8 @@
   if (framebuffers == NULL) {
     return error::kOutOfBounds;
   }
-  if (!GenFramebuffersHelper(n, framebuffers)) {
+  if (!CheckUniqueIds(n, framebuffers) ||
+      !GenFramebuffersHelper(n, framebuffers)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
@@ -1316,7 +1317,8 @@
   if (renderbuffers == NULL) {
     return error::kOutOfBounds;
   }
-  if (!GenRenderbuffersHelper(n, renderbuffers)) {
+  if (!CheckUniqueIds(n, renderbuffers) ||
+      !GenRenderbuffersHelper(n, renderbuffers)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
@@ -1340,7 +1342,7 @@
   if (samplers == NULL) {
     return error::kOutOfBounds;
   }
-  if (!GenSamplersHelper(n, samplers)) {
+  if (!CheckUniqueIds(n, samplers) || !GenSamplersHelper(n, samplers)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
@@ -1362,7 +1364,7 @@
   if (textures == NULL) {
     return error::kOutOfBounds;
   }
-  if (!GenTexturesHelper(n, textures)) {
+  if (!CheckUniqueIds(n, textures) || !GenTexturesHelper(n, textures)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
@@ -1386,7 +1388,7 @@
   if (ids == NULL) {
     return error::kOutOfBounds;
   }
-  if (!GenTransformFeedbacksHelper(n, ids)) {
+  if (!CheckUniqueIds(n, ids) || !GenTransformFeedbacksHelper(n, ids)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
@@ -2166,13 +2168,17 @@
     case GL_GENERATE_MIPMAP_HINT:
       if (state_.hint_generate_mipmap != mode) {
         state_.hint_generate_mipmap = mode;
-        glHint(target, mode);
+        if (!feature_info_->gl_version_info().is_desktop_core_profile) {
+          glHint(target, mode);
+        }
       }
       break;
     case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
       if (state_.hint_fragment_shader_derivative != mode) {
         state_.hint_fragment_shader_derivative = mode;
-        glHint(target, mode);
+        if (feature_info_->feature_flags().oes_standard_derivatives) {
+          glHint(target, mode);
+        }
       }
       break;
     default:
@@ -4451,7 +4457,7 @@
   if (queries == NULL) {
     return error::kOutOfBounds;
   }
-  if (!GenQueriesEXTHelper(n, queries)) {
+  if (!CheckUniqueIds(n, queries) || !GenQueriesEXTHelper(n, queries)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
@@ -4573,7 +4579,7 @@
   if (arrays == NULL) {
     return error::kOutOfBounds;
   }
-  if (!GenVertexArraysOESHelper(n, arrays)) {
+  if (!CheckUniqueIds(n, arrays) || !GenVertexArraysOESHelper(n, arrays)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index eb50373..23652c1a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -475,6 +475,39 @@
   // Test something fails if off.
 }
 
+TEST_P(GLES2DecoderTest, GenQueriesEXTImmediateValidArgs) {
+  cmds::GenQueriesEXTImmediate* cmd =
+      GetImmediateAs<cmds::GenQueriesEXTImmediate>();
+  GLuint temp = kNewClientId;
+  cmd->Init(1, &temp);
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  QueryManager* query_manager = decoder_->GetQueryManager();
+  ASSERT_TRUE(query_manager != NULL);
+  EXPECT_TRUE(query_manager->IsValidQuery(kNewClientId));
+}
+
+TEST_P(GLES2DecoderTest, GenQueriesEXTImmediateDuplicateIds) {
+  cmds::GenQueriesEXTImmediate* cmd =
+      GetImmediateAs<cmds::GenQueriesEXTImmediate>();
+  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+  cmd->Init(3, temp);
+  EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  QueryManager* query_manager = decoder_->GetQueryManager();
+  ASSERT_TRUE(query_manager != NULL);
+  EXPECT_FALSE(query_manager->IsValidQuery(kNewClientId));
+  EXPECT_FALSE(query_manager->IsValidQuery(kNewClientId + 1));
+}
+
+TEST_P(GLES2DecoderTest, GenQueriesEXTImmediateInvalidArgs) {
+  cmds::GenQueriesEXTImmediate* cmd =
+      GetImmediateAs<cmds::GenQueriesEXTImmediate>();
+  cmd->Init(1, &client_query_id_);
+  EXPECT_EQ(error::kInvalidArguments,
+            ExecuteImmediateCmd(*cmd, sizeof(&client_query_id_)));
+}
+
+
 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
   InitState init;
   init.extensions = "GL_EXT_occlusion_query_boolean";
@@ -1540,30 +1573,6 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_P(GLES3DecoderTest, GenDeleteTransformFeedbacksImmediateValidArgs) {
-  EXPECT_CALL(*gl_, GenTransformFeedbacks(1, _))
-      .WillOnce(SetArgPointee<1>(kNewServiceId));
-  cmds::GenTransformFeedbacksImmediate* gen_cmd =
-      GetImmediateAs<cmds::GenTransformFeedbacksImmediate>();
-  GLuint temp = kNewClientId;
-  SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(true);
-  gen_cmd->Init(1, &temp);
-  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*gen_cmd, sizeof(temp)));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_TRUE(GetTransformFeedback(kNewClientId) != nullptr);
-
-  EXPECT_CALL(*gl_,
-              DeleteTransformFeedbacks(1, Pointee(kNewServiceId)))
-      .Times(1);
-  cmds::DeleteTransformFeedbacksImmediate& delete_cmd =
-      *GetImmediateAs<cmds::DeleteTransformFeedbacksImmediate>();
-  SpecializedSetup<cmds::DeleteTransformFeedbacksImmediate, 0>(true);
-  delete_cmd.Init(1, &temp);
-  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(delete_cmd, sizeof(&temp)));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_TRUE(GetTransformFeedback(kNewClientId) == nullptr);
-}
-
 TEST_P(GLES3DecoderTest, DeleteTransformFeedbacksImmediateInvalidArgs) {
   cmds::DeleteTransformFeedbacksImmediate& cmd =
       *GetImmediateAs<cmds::DeleteTransformFeedbacksImmediate>();
@@ -1574,16 +1583,6 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_P(GLES3DecoderTest, GenTransformFeedbacksImmediateInvalidArgs) {
-  EXPECT_CALL(*gl_, GenTransformFeedbacks(_, _)).Times(0);
-  cmds::GenTransformFeedbacksImmediate* cmd =
-      GetImmediateAs<cmds::GenTransformFeedbacksImmediate>();
-  SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(false);
-  cmd->Init(1, &client_transformfeedback_id_);
-  EXPECT_EQ(error::kInvalidArguments,
-            ExecuteImmediateCmd(*cmd, sizeof(&client_transformfeedback_id_)));
-}
-
 TEST_P(GLES3DecoderTest, GetIntegeri_vValidArgs) {
   EXPECT_CALL(*gl_, GetIntegeri_v(_, _, _)).Times(0);
   typedef cmds::GetIntegeri_v::Result Result;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h
index 0c5de16..9868745 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h
@@ -35,6 +35,7 @@
 }
 
 void GLES2DecoderTestBase::SetupInitStateExpectations(bool es3_capable) {
+  const auto& feature_info_ = group_->feature_info();
   EXPECT_CALL(*gl_, BlendColor(0.0f, 0.0f, 0.0f, 0.0f))
       .Times(1)
       .RetiresOnSaturation();
@@ -64,22 +65,24 @@
   EXPECT_CALL(*gl_, DepthMask(true)).Times(1).RetiresOnSaturation();
   EXPECT_CALL(*gl_, DepthRange(0.0f, 1.0f)).Times(1).RetiresOnSaturation();
   EXPECT_CALL(*gl_, FrontFace(GL_CCW)).Times(1).RetiresOnSaturation();
-  EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE))
-      .Times(1)
-      .RetiresOnSaturation();
-  if (group_->feature_info()->feature_flags().oes_standard_derivatives) {
+  if (!feature_info_->gl_version_info().is_desktop_core_profile) {
+    EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE))
+        .Times(1)
+        .RetiresOnSaturation();
+  }
+  if (feature_info_->feature_flags().oes_standard_derivatives) {
     EXPECT_CALL(*gl_,
                 Hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, GL_DONT_CARE))
         .Times(1)
         .RetiresOnSaturation();
   }
   EXPECT_CALL(*gl_, LineWidth(1.0f)).Times(1).RetiresOnSaturation();
-  if (group_->feature_info()->feature_flags().chromium_path_rendering) {
+  if (feature_info_->feature_flags().chromium_path_rendering) {
     EXPECT_CALL(*gl_, MatrixLoadfEXT(GL_PATH_MODELVIEW_CHROMIUM, _))
         .Times(1)
         .RetiresOnSaturation();
   }
-  if (group_->feature_info()->feature_flags().chromium_path_rendering) {
+  if (feature_info_->feature_flags().chromium_path_rendering) {
     EXPECT_CALL(*gl_, MatrixLoadfEXT(GL_PATH_PROJECTION_CHROMIUM, _))
         .Times(1)
         .RetiresOnSaturation();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
index aa9201d..8c4f094 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
@@ -176,6 +176,18 @@
   }
 }
 
+template <>
+void GLES2DecoderTestBase::
+    SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(bool valid) {
+  if (valid) {
+    // Transform feedbacks are per-context, not per-group, so they get cleaned
+    // up at the end of the test.
+    EXPECT_CALL(*gl_, DeleteTransformFeedbacks(_, _))
+        .Times(1)
+        .RetiresOnSaturation();
+  }
+}
+
 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h"
 
 }  // namespace gles2
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
index a9bfe425..152a0278 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -704,6 +704,17 @@
   EXPECT_TRUE(GetBuffer(kNewClientId) != NULL);
 }
 
+TEST_P(GLES2DecoderTest1, GenBuffersImmediateDuplicateIds) {
+  EXPECT_CALL(*gl_, GenBuffersARB(_, _)).Times(0);
+  cmds::GenBuffersImmediate* cmd = GetImmediateAs<cmds::GenBuffersImmediate>();
+  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+  SpecializedSetup<cmds::GenBuffersImmediate, 1>(true);
+  cmd->Init(3, temp);
+  EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_TRUE(GetBuffer(kNewClientId) == NULL);
+  EXPECT_TRUE(GetBuffer(kNewClientId + 1) == NULL);
+}
+
 TEST_P(GLES2DecoderTest1, GenBuffersImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenBuffersARB(_, _)).Times(0);
   cmds::GenBuffersImmediate* cmd = GetImmediateAs<cmds::GenBuffersImmediate>();
@@ -753,6 +764,18 @@
   EXPECT_TRUE(GetFramebuffer(kNewClientId) != NULL);
 }
 
+TEST_P(GLES2DecoderTest1, GenFramebuffersImmediateDuplicateIds) {
+  EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)).Times(0);
+  cmds::GenFramebuffersImmediate* cmd =
+      GetImmediateAs<cmds::GenFramebuffersImmediate>();
+  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+  SpecializedSetup<cmds::GenFramebuffersImmediate, 1>(true);
+  cmd->Init(3, temp);
+  EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_TRUE(GetFramebuffer(kNewClientId) == NULL);
+  EXPECT_TRUE(GetFramebuffer(kNewClientId + 1) == NULL);
+}
+
 TEST_P(GLES2DecoderTest1, GenFramebuffersImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)).Times(0);
   cmds::GenFramebuffersImmediate* cmd =
@@ -776,6 +799,18 @@
   EXPECT_TRUE(GetRenderbuffer(kNewClientId) != NULL);
 }
 
+TEST_P(GLES2DecoderTest1, GenRenderbuffersImmediateDuplicateIds) {
+  EXPECT_CALL(*gl_, GenRenderbuffersEXT(_, _)).Times(0);
+  cmds::GenRenderbuffersImmediate* cmd =
+      GetImmediateAs<cmds::GenRenderbuffersImmediate>();
+  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+  SpecializedSetup<cmds::GenRenderbuffersImmediate, 1>(true);
+  cmd->Init(3, temp);
+  EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_TRUE(GetRenderbuffer(kNewClientId) == NULL);
+  EXPECT_TRUE(GetRenderbuffer(kNewClientId + 1) == NULL);
+}
+
 TEST_P(GLES2DecoderTest1, GenRenderbuffersImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenRenderbuffersEXT(_, _)).Times(0);
   cmds::GenRenderbuffersImmediate* cmd =
@@ -800,6 +835,19 @@
   EXPECT_TRUE(GetSampler(kNewClientId) != NULL);
 }
 
+TEST_P(GLES2DecoderTest1, GenSamplersImmediateDuplicateIds) {
+  EXPECT_CALL(*gl_, GenSamplers(_, _)).Times(0);
+  cmds::GenSamplersImmediate* cmd =
+      GetImmediateAs<cmds::GenSamplersImmediate>();
+  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+  SpecializedSetup<cmds::GenSamplersImmediate, 1>(true);
+  decoder_->set_unsafe_es3_apis_enabled(true);
+  cmd->Init(3, temp);
+  EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_TRUE(GetSampler(kNewClientId) == NULL);
+  EXPECT_TRUE(GetSampler(kNewClientId + 1) == NULL);
+}
+
 TEST_P(GLES2DecoderTest1, GenSamplersImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenSamplers(_, _)).Times(0);
   cmds::GenSamplersImmediate* cmd =
@@ -825,6 +873,18 @@
   EXPECT_TRUE(GetTexture(kNewClientId) != NULL);
 }
 
+TEST_P(GLES2DecoderTest1, GenTexturesImmediateDuplicateIds) {
+  EXPECT_CALL(*gl_, GenTextures(_, _)).Times(0);
+  cmds::GenTexturesImmediate* cmd =
+      GetImmediateAs<cmds::GenTexturesImmediate>();
+  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+  SpecializedSetup<cmds::GenTexturesImmediate, 1>(true);
+  cmd->Init(3, temp);
+  EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_TRUE(GetTexture(kNewClientId) == NULL);
+  EXPECT_TRUE(GetTexture(kNewClientId + 1) == NULL);
+}
+
 TEST_P(GLES2DecoderTest1, GenTexturesImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenTextures(_, _)).Times(0);
   cmds::GenTexturesImmediate* cmd =
@@ -835,6 +895,45 @@
             ExecuteImmediateCmd(*cmd, sizeof(&client_texture_id_)));
 }
 
+TEST_P(GLES2DecoderTest1, GenTransformFeedbacksImmediateValidArgs) {
+  EXPECT_CALL(*gl_, GenTransformFeedbacks(1, _))
+      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
+  cmds::GenTransformFeedbacksImmediate* cmd =
+      GetImmediateAs<cmds::GenTransformFeedbacksImmediate>();
+  GLuint temp = kNewClientId;
+  SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(true);
+  decoder_->set_unsafe_es3_apis_enabled(true);
+  cmd->Init(1, &temp);
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_TRUE(GetTransformFeedback(kNewClientId) != NULL);
+}
+
+TEST_P(GLES2DecoderTest1, GenTransformFeedbacksImmediateDuplicateIds) {
+  EXPECT_CALL(*gl_, GenTransformFeedbacks(_, _)).Times(0);
+  cmds::GenTransformFeedbacksImmediate* cmd =
+      GetImmediateAs<cmds::GenTransformFeedbacksImmediate>();
+  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+  SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 1>(true);
+  decoder_->set_unsafe_es3_apis_enabled(true);
+  cmd->Init(3, temp);
+  EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+  EXPECT_TRUE(GetTransformFeedback(kNewClientId) == NULL);
+  EXPECT_TRUE(GetTransformFeedback(kNewClientId + 1) == NULL);
+}
+
+TEST_P(GLES2DecoderTest1, GenTransformFeedbacksImmediateInvalidArgs) {
+  EXPECT_CALL(*gl_, GenTransformFeedbacks(_, _)).Times(0);
+  cmds::GenTransformFeedbacksImmediate* cmd =
+      GetImmediateAs<cmds::GenTransformFeedbacksImmediate>();
+  SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(false);
+  cmd->Init(1, &client_transformfeedback_id_);
+  decoder_->set_unsafe_es3_apis_enabled(true);
+  EXPECT_EQ(error::kInvalidArguments,
+            ExecuteImmediateCmd(*cmd, sizeof(&client_transformfeedback_id_)));
+  decoder_->set_unsafe_es3_apis_enabled(false);
+}
+
 TEST_P(GLES2DecoderTest1, GetBooleanvValidArgs) {
   EXPECT_CALL(*gl_, GetError()).WillRepeatedly(Return(GL_NO_ERROR));
   SpecializedSetup<cmds::GetBooleanv, 0>(true);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc
index 92738c1..40b455a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc
@@ -268,6 +268,17 @@
     AddExpectationsForDeleteVertexArraysOES();
   }
 
+  void GenVertexArraysOESImmediateDuplicateIds() {
+    cmds::GenVertexArraysOESImmediate* cmd =
+        GetImmediateAs<cmds::GenVertexArraysOESImmediate>();
+    GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
+    cmd->Init(3, temp);
+    EXPECT_EQ(error::kInvalidArguments,
+              ExecuteImmediateCmd(*cmd, sizeof(temp)));
+    EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) == NULL);
+    EXPECT_TRUE(GetVertexArrayInfo(kNewClientId + 1) == NULL);
+  }
+
   void GenVertexArraysOESImmediateInvalidArgs() {
     EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
     GenVertexArraysOESImmediate* cmd =
@@ -381,6 +392,15 @@
 }
 
 TEST_P(GLES2DecoderVertexArraysOESTest,
+       GenVertexArraysOESImmediateDuplicateIds) {
+  GenVertexArraysOESImmediateDuplicateIds();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       GenVertexArraysOESImmediateDuplicateIds) {
+  GenVertexArraysOESImmediateDuplicateIds();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest,
        GenVertexArraysOESImmediateInvalidArgs) {
   GenVertexArraysOESImmediateInvalidArgs();
 }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 1401d2d..8e063c7 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -344,15 +344,34 @@
   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER, 0))
       .Times(1)
       .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(normalized_init.has_alpha ? 8 : 0))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(normalized_init.has_depth ? 24 : 0))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(normalized_init.has_stencil ? 8 : 0))
-      .RetiresOnSaturation();
+
+  if (group_->feature_info()->gl_version_info().is_desktop_core_profile) {
+    EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(
+                          GL_FRAMEBUFFER, GL_BACK_LEFT,
+                          GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, _))
+        .WillOnce(SetArgumentPointee<3>(normalized_init.has_alpha ? 8 : 0))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(
+                          GL_FRAMEBUFFER, GL_DEPTH,
+                          GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, _))
+        .WillOnce(SetArgumentPointee<3>(normalized_init.has_depth ? 24 : 0))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(
+                          GL_FRAMEBUFFER, GL_STENCIL,
+                          GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, _))
+        .WillOnce(SetArgumentPointee<3>(normalized_init.has_stencil ? 8 : 0))
+        .RetiresOnSaturation();
+  } else {
+    EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
+        .WillOnce(SetArgumentPointee<1>(normalized_init.has_alpha ? 8 : 0))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+        .WillOnce(SetArgumentPointee<1>(normalized_init.has_depth ? 24 : 0))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+        .WillOnce(SetArgumentPointee<1>(normalized_init.has_stencil ? 8 : 0))
+        .RetiresOnSaturation();
+  }
 
   if (!group_->feature_info()->gl_version_info().BehavesLikeGLES()) {
     EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE))
@@ -362,6 +381,12 @@
     EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE))
         .Times(1)
         .RetiresOnSaturation();
+  } else if (group_->feature_info()
+                 ->gl_version_info()
+                 .is_desktop_core_profile) {
+    EXPECT_CALL(*gl_, Enable(GL_PROGRAM_POINT_SIZE))
+        .Times(1)
+        .RetiresOnSaturation();
   }
 
   if (group_->feature_info()->gl_version_info().IsAtLeastGL(3, 2)) {
@@ -475,6 +500,7 @@
       .WillOnce(SetArgumentPointee<1>(kServiceElementBufferId))
       .RetiresOnSaturation();
   GenHelper<cmds::GenBuffersImmediate>(client_element_buffer_id_);
+  GenHelper<cmds::GenQueriesEXTImmediate>(client_query_id_);
 
   DoCreateProgram(client_program_id_, kServiceProgramId);
   DoCreateShader(GL_VERTEX_SHADER, client_shader_id_, kServiceShaderId);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc
index 35a8197..10e31d1 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc
@@ -450,6 +450,38 @@
   DoBindBuffer(GL_PIXEL_UNPACK_BUFFER, client_buffer_id_, kServiceBufferId);
 }
 
+TEST_P(GLES2DecoderManualInitTest, MipmapHintOnCoreProfile) {
+  // On a core profile, glHint(GL_GENERATE_MIPMAP_HINT) should be a noop
+  InitState init;
+  init.gl_version = "3.2";
+  InitDecoder(init);
+
+  cmds::Hint cmd;
+  cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
+
+  EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_NICEST)).Times(0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, MipmapHintOnCompatibilityProfile) {
+  // On a compatibility profile, glHint(GL_GENERATE_MIPMAP_HINT) should be go
+  // through
+  InitState init;
+  init.gl_version = "3.2";
+  init.extensions += " GL_ARB_compatibility";
+  InitDecoder(init);
+
+  cmds::Hint cmd;
+  cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
+
+  EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_NICEST))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
 // TODO(vmiura): Tests for VAO restore.
 
 // TODO(vmiura): Tests for ContextState::RestoreAttribute().
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc
index 7f265328..3ad2093 100644
--- a/gpu/command_buffer/service/test_helper.cc
+++ b/gpu/command_buffer/service/test_helper.cc
@@ -343,7 +343,7 @@
       .RetiresOnSaturation();
   if (strstr(extensions, "GL_EXT_framebuffer_multisample") ||
       strstr(extensions, "GL_EXT_multisampled_render_to_texture") ||
-      gl_info.is_es3) {
+      gl_info.is_es3 || gl_info.is_desktop_core_profile) {
     EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _))
         .WillOnce(SetArgumentPointee<1>(kMaxSamples))
         .RetiresOnSaturation();
@@ -353,6 +353,18 @@
         .RetiresOnSaturation();
   }
 
+  if (strstr(extensions, "GL_EXT_draw_buffers") ||
+      strstr(extensions, "GL_ARB_draw_buffers") ||
+      (gl_info.is_es3 && strstr(extensions, "GL_NV_draw_buffers")) ||
+      gl_info.is_desktop_core_profile) {
+    EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, _))
+        .WillOnce(SetArgumentPointee<1>(8))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, _))
+        .WillOnce(SetArgumentPointee<1>(8))
+        .RetiresOnSaturation();
+  }
+
   if (gl_info.IsAtLeastGL(3, 3) ||
       (gl_info.IsAtLeastGL(3, 2) &&
        strstr(extensions, "GL_ARB_blend_func_extended")) ||
@@ -396,7 +408,8 @@
         .WillOnce(SetArgumentPointee<1>(kMaxArrayTextureLayers))
         .RetiresOnSaturation();
   }
-  if (strstr(extensions, "GL_ARB_texture_rectangle")) {
+  if (strstr(extensions, "GL_ARB_texture_rectangle") ||
+      gl_info.is_desktop_core_profile) {
     EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, _))
         .WillOnce(SetArgumentPointee<1>(kMaxRectangleTextureSize))
         .RetiresOnSaturation();
@@ -408,7 +421,7 @@
       .WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits))
       .RetiresOnSaturation();
 
-  if (gl_info.is_es) {
+  if (gl_info.is_es || gl_info.is_desktop_core_profile) {
     EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, _))
         .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors))
         .RetiresOnSaturation();
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 64b8ce4..cc3a818 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -185,7 +185,8 @@
       lose_context_when_out_of_memory(false),
       context_lost_allowed(false),
       context_type(gles2::CONTEXT_TYPE_OPENGLES2),
-      force_shader_name_hashing(false) {}
+      force_shader_name_hashing(false),
+      multisampled(false) {}
 
 GLManager::GLManager()
     : sync_point_manager_(nullptr),
@@ -286,6 +287,8 @@
   attribs.depth_size = 16;
   attribs.stencil_size = 8;
   attribs.context_type = options.context_type;
+  attribs.samples = options.multisampled ? 4 : 0;
+  attribs.sample_buffers = options.multisampled ? 1 : 0;
 
   if (!context_group) {
     GpuDriverBugWorkarounds gpu_driver_bug_workaround(&command_line);
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h
index a14cffe..c24c6881 100644
--- a/gpu/command_buffer/tests/gl_manager.h
+++ b/gpu/command_buffer/tests/gl_manager.h
@@ -75,6 +75,8 @@
     gles2::ContextType context_type;
     // Force shader name hashing for all context types.
     bool force_shader_name_hashing;
+    // Whether the buffer is multisampled.
+    bool multisampled;
   };
   GLManager();
   ~GLManager() override;
diff --git a/gpu/command_buffer/tests/gl_texture_mailbox_unittest.cc b/gpu/command_buffer/tests/gl_texture_mailbox_unittest.cc
index b34b0bf..47cb162 100644
--- a/gpu/command_buffer/tests/gl_texture_mailbox_unittest.cc
+++ b/gpu/command_buffer/tests/gl_texture_mailbox_unittest.cc
@@ -56,7 +56,7 @@
 
 class GLTextureMailboxTest : public testing::Test {
  protected:
-  void SetUp() override {
+  void SetUpContexts() {
     gl1_.Initialize(GLManager::Options());
     GLManager::Options options;
     options.share_mailbox_manager = &gl1_;
@@ -96,6 +96,7 @@
 };
 
 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTexture) {
+  SetUpContexts();
   gl1_.MakeCurrent();
 
   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
@@ -140,6 +141,7 @@
 }
 
 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTextureRGB) {
+  SetUpContexts();
   gl1_.MakeCurrent();
 
   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
@@ -184,6 +186,7 @@
 }
 
 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTextureDirect) {
+  SetUpContexts();
   gl1_.MakeCurrent();
 
   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
@@ -225,6 +228,7 @@
 }
 
 TEST_F(GLTextureMailboxTest, ConsumeTextureValidatesKey) {
+  SetUpContexts();
   GLuint tex;
   glGenTextures(1, &tex);
 
@@ -253,6 +257,7 @@
 }
 
 TEST_F(GLTextureMailboxTest, SharedTextures) {
+  SetUpContexts();
   gl1_.MakeCurrent();
   GLuint tex1;
   glGenTextures(1, &tex1);
@@ -351,6 +356,7 @@
 }
 
 TEST_F(GLTextureMailboxTest, TakeFrontBuffer) {
+  SetUpContexts();
   gl1_.MakeCurrent();
   Mailbox mailbox;
   glGenMailboxCHROMIUM(mailbox.name);
@@ -412,6 +418,7 @@
 // The client, represented by |gl2_|, will request 5 frontbuffers, and then
 // start returning them.
 TEST_F(GLTextureMailboxTest, FrontBufferCache) {
+  SetUpContexts();
   gl1_.MakeCurrent();
 
   std::vector<Mailbox> mailboxes;
@@ -451,6 +458,7 @@
 // Then the size of the buffer will be changed. All cached frontbuffers should
 // be discarded.
 TEST_F(GLTextureMailboxTest, FrontBufferChangeSize) {
+  SetUpContexts();
   gl1_.MakeCurrent();
 
   std::vector<Mailbox> mailboxes;
@@ -471,7 +479,59 @@
   EXPECT_EQ(0u, gl1_.decoder()->GetSavedBackTextureCountForTest());
 }
 
+// The client, represented by |gl2_|, will request and return 5 frontbuffers.
+// Then |gl1_| will start drawing with a different color. The returned
+// frontbuffers should pick up the new color.
+TEST_F(GLTextureMailboxTest, FrontBufferChangeColor) {
+  GLManager::Options options1;
+  options1.multisampled = true;
+  gl1_.Initialize(options1);
+
+  GLManager::Options options2;
+  options2.share_mailbox_manager = &gl1_;
+  gl2_.Initialize(options2);
+
+  gl1_.MakeCurrent();
+  std::vector<Mailbox> mailboxes;
+  for (int i = 0; i < 5; ++i) {
+    Mailbox mailbox = TakeAndConsumeMailbox();
+    mailboxes.push_back(mailbox);
+  }
+
+  for (int i = 0; i < 5; ++i) {
+    gl1_.decoder()->ReturnFrontBuffer(mailboxes[i], false);
+  }
+  mailboxes.clear();
+
+  for (int i = 0; i < 5; ++i) {
+    glClearColor(1, 0, 0, 1);
+    glClear(GL_COLOR_BUFFER_BIT);
+    ::gles2::GetGLContext()->SwapBuffers();
+
+    Mailbox mailbox;
+    glGenMailboxCHROMIUM(mailbox.name);
+    gl1_.decoder()->TakeFrontBuffer(mailbox);
+
+    // Normally, consumers of TakeFrontBuffer() must supply their own
+    // synchronization mechanism. For this test, just use a glFinish().
+    glFinish();
+
+    gl2_.MakeCurrent();
+    GLuint tex;
+    glGenTextures(1, &tex);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+
+    EXPECT_EQ(0xFF0000FFu, ReadTexel(tex, 0, 0));
+
+    glDeleteTextures(1, &tex);
+    glFlush();
+    gl1_.MakeCurrent();
+  }
+}
+
 TEST_F(GLTextureMailboxTest, ProduceTextureDirectInvalidTarget) {
+  SetUpContexts();
   gl1_.MakeCurrent();
 
   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
@@ -498,6 +558,7 @@
 // http://crbug.com/281565
 #if !defined(OS_ANDROID)
 TEST_F(GLTextureMailboxTest, TakeFrontBufferMultipleContexts) {
+  SetUpContexts();
   gl1_.MakeCurrent();
   Mailbox mailbox[2];
   glGenMailboxCHROMIUM(mailbox[0].name);
diff --git a/ios/chrome/extension_repack.gni b/ios/chrome/extension_repack.gni
new file mode 100644
index 0000000..aa71bcd
--- /dev/null
+++ b/ios/chrome/extension_repack.gni
@@ -0,0 +1,103 @@
+# 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.
+
+import("//tools/grit/repack.gni")
+
+# Pack all resources for an application extension for a given locale.
+#
+# Arguments:
+#
+#   extension [required]
+#       name of the application extension.
+#
+#   input_locale [required]
+#       name of the locale to pack.
+#
+#   output_locale [required]
+#       name of the locale (may be different from input_locale as iOS
+#       and Chrome does not use the same convention for naming locales
+#       with country variants).
+#
+#   visibility [optional]
+#       usual meaning.
+#
+template("_extension_repack_one_locale") {
+  assert(defined(invoker.extension), "Need extension for $target_name")
+  assert(defined(invoker.input_locale), "Need input_locale for $target_name")
+  assert(defined(invoker.output_locale), "Need output_locale for $target_name")
+
+  repack_and_bundle(target_name) {
+    forward_variables_from(invoker, [ "visibility" ])
+
+    deps = [
+      "//ios/chrome/${invoker.extension}/strings",
+    ]
+
+    sources = [
+      "$root_gen_dir/ios/${invoker.extension}/" +
+          "ios_${invoker.extension}_strings_${invoker.input_locale}.pak",
+    ]
+
+    output = "$target_gen_dir/${invoker.output_locale}.lproj/locale.pak"
+    bundle_output = "{{bundle_resources_dir}}/" +
+                    "${invoker.output_locale}.lproj/locale.pak"
+  }
+}
+
+# Pack all resoruces for an application extension for all locales.
+#
+# Arguments:
+#
+#   extension [required]
+#       name of the application extension.
+#
+#   input_locales [required]
+#       list of all locales to pack.
+#
+#   output_locales [required]
+#       list of all locales in application bundle (may differ from input
+#       locales as iOS and Chrome does not use the same convention for
+#       naming locales with country variants).
+#
+#       Must be the same length as input_locales.
+#
+#   visibility [optional]
+#       usual meaning.
+#
+template("extension_repack_all_locales") {
+  assert(defined(invoker.extension), "Need extension for $target_name")
+  assert(defined(invoker.input_locales), "Need input_locales for $target_name")
+  assert(defined(invoker.output_locales),
+         "Need output_locales for $target_name")
+
+  _target_name = target_name
+
+  # TODO(614747): GN parser does not grok invoker.output_locales[foo]. Use a
+  # local variables to workaround this issue until the issue is fixed.
+  _current_locale = 0
+  _output_locales = invoker.output_locales
+
+  # Collect all locale targets to avoid looping twice over the locales.
+  _locale_targets = []
+
+  foreach(_input_locale, invoker.input_locales) {
+    _output_locale = _output_locales[_current_locale]
+
+    _locale_target = _target_name + "_$_input_locale"
+    _extension_repack_one_locale(_locale_target) {
+      visibility = [ ":$_target_name" ]
+      input_locale = _input_locale
+      output_locale = _output_locale
+      extension = invoker.extension
+    }
+
+    _locale_targets += [ ":$_locale_target" ]
+    _current_locale = _current_locale + 1
+  }
+
+  group(_target_name) {
+    forward_variables_from(invoker, [ "visibility" ])
+    public_deps = _locale_targets
+  }
+}
diff --git a/ios/chrome/ios_share_extension_resources.gyp b/ios/chrome/ios_share_extension_resources.gyp
index 9fc705c..afe3b70 100644
--- a/ios/chrome/ios_share_extension_resources.gyp
+++ b/ios/chrome/ios_share_extension_resources.gyp
@@ -10,6 +10,7 @@
   },
   'targets': [
     {
+      # GN version: //ios/chrome/share_extensions:resources
       'target_name': 'ios_share_extension_resources',
       'type': 'none',
       'dependencies': [
@@ -17,6 +18,7 @@
       ],
     },
     {
+      # GN version: //ios/chrome/share_extensions/strings
       'target_name': 'ios_share_extension_strings_gen',
       'type': 'none',
       'hard_dependency': 1,
@@ -43,6 +45,7 @@
       }
     },
     {
+      # GN version: //ios/chrome/share_extensions:packed_resources
       'target_name': 'ios_share_extension_packed_resources',
       'type': 'none',
       'dependencies': [
diff --git a/ios/chrome/ios_today_extension_resources.gyp b/ios/chrome/ios_today_extension_resources.gyp
index 519fb48..90ac125 100644
--- a/ios/chrome/ios_today_extension_resources.gyp
+++ b/ios/chrome/ios_today_extension_resources.gyp
@@ -10,6 +10,7 @@
   },
   'targets': [
     {
+      # GN version: //ios/chrome/today_extension:resources
       'target_name': 'ios_today_extension_resources',
       'type': 'none',
       'dependencies': [
@@ -17,6 +18,7 @@
       ],
     },
     {
+      # GN version: //ios/chrome/today_extension/strings
       'target_name': 'ios_today_extension_strings_gen',
       'type': 'none',
       'hard_dependency': 1,
@@ -43,6 +45,7 @@
       }
     },
     {
+      # GN version: //ios/chrome/today_extension:packed_resources
       'target_name': 'ios_today_extension_packed_resources',
       'type': 'none',
       'dependencies': [
diff --git a/ios/chrome/share_extension/BUILD.gn b/ios/chrome/share_extension/BUILD.gn
new file mode 100644
index 0000000..1488271
--- /dev/null
+++ b/ios/chrome/share_extension/BUILD.gn
@@ -0,0 +1,18 @@
+# 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.
+
+import("//build/config/locales.gni")
+import("//ios/chrome/extension_repack.gni")
+
+group("resources") {
+  deps = [
+    "//ios/chrome/share_extension/strings",
+  ]
+}
+
+extension_repack_all_locales("packed_resources") {
+  extension = "share_extension"
+  input_locales = ios_packed_locales
+  output_locales = ios_packed_locales_as_mac_outputs
+}
diff --git a/ios/chrome/share_extension/strings/BUILD.gn b/ios/chrome/share_extension/strings/BUILD.gn
new file mode 100644
index 0000000..6c66a022
--- /dev/null
+++ b/ios/chrome/share_extension/strings/BUILD.gn
@@ -0,0 +1,18 @@
+# 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.
+
+import("//build/config/locales.gni")
+import("//tools/grit/grit_rule.gni")
+
+grit("strings") {
+  source = "ios_share_extension_strings.grd"
+  output_dir = "$root_gen_dir/ios/share_extension"
+  use_qualified_include = true
+  outputs = [
+    "grit/ios_share_extension_strings.h",
+  ]
+  foreach(locale, locales_with_fake_bidi) {
+    outputs += [ "ios_share_extension_strings_$locale.pak" ]
+  }
+}
diff --git a/ios/chrome/today_extension/BUILD.gn b/ios/chrome/today_extension/BUILD.gn
new file mode 100644
index 0000000..ffa17a9
--- /dev/null
+++ b/ios/chrome/today_extension/BUILD.gn
@@ -0,0 +1,18 @@
+# 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.
+
+import("//build/config/locales.gni")
+import("//ios/chrome/extension_repack.gni")
+
+group("resources") {
+  deps = [
+    "//ios/chrome/today_extension/strings",
+  ]
+}
+
+extension_repack_all_locales("packed_resources") {
+  extension = "today_extension"
+  input_locales = ios_packed_locales
+  output_locales = ios_packed_locales_as_mac_outputs
+}
diff --git a/ios/chrome/today_extension/strings/BUILD.gn b/ios/chrome/today_extension/strings/BUILD.gn
new file mode 100644
index 0000000..99fa954
--- /dev/null
+++ b/ios/chrome/today_extension/strings/BUILD.gn
@@ -0,0 +1,18 @@
+# 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.
+
+import("//build/config/locales.gni")
+import("//tools/grit/grit_rule.gni")
+
+grit("strings") {
+  source = "ios_today_extension_strings.grd"
+  output_dir = "$root_gen_dir/ios/today_extension"
+  use_qualified_include = true
+  outputs = [
+    "grit/ios_today_extension_strings.h",
+  ]
+  foreach(locale, locales_with_fake_bidi) {
+    outputs += [ "ios_today_extension_strings_$locale.pak" ]
+  }
+}
diff --git a/mash/browser/BUILD.gn b/mash/browser/BUILD.gn
index 844d7d4..d1b77e9 100644
--- a/mash/browser/BUILD.gn
+++ b/mash/browser/BUILD.gn
@@ -19,13 +19,13 @@
     "//base",
     "//components/mus/public/cpp",
     "//mash/public/interfaces",
-    "//mojo/converters/geometry",
     "//mojo/public/cpp/bindings",
     "//services/catalog/public/interfaces",
     "//services/navigation/public/interfaces",
     "//services/shell/public/cpp",
     "//services/shell/public/interfaces",
     "//services/tracing/public/cpp",
+    "//ui/gfx/geometry/mojo",
     "//ui/native_theme",
     "//ui/views",
     "//ui/views/mus:for_mojo_application",
diff --git a/mash/browser/browser.cc b/mash/browser/browser.cc
index 01c4ad33..431569d 100644
--- a/mash/browser/browser.cc
+++ b/mash/browser/browser.cc
@@ -14,7 +14,6 @@
 #include "components/mus/public/cpp/window.h"
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "mash/public/interfaces/launchable.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/public/c/system/main.h"
 #include "services/navigation/public/interfaces/view.mojom.h"
 #include "services/shell/public/cpp/application_runner.h"
@@ -23,6 +22,7 @@
 #include "services/tracing/public/cpp/tracing_impl.h"
 #include "ui/aura/mus/mus_util.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/paint_throbber.h"
 #include "ui/gfx/text_constants.h"
 #include "ui/native_theme/native_theme.h"
diff --git a/mash/example/views_examples/BUILD.gn b/mash/example/views_examples/BUILD.gn
index 0c7a5dfd..df571e9c 100644
--- a/mash/example/views_examples/BUILD.gn
+++ b/mash/example/views_examples/BUILD.gn
@@ -21,7 +21,6 @@
     "//base",
     "//components/mus/public/interfaces",
     "//mash/public/interfaces",
-    "//mojo/converters/geometry",
     "//mojo/public/cpp/bindings",
     "//services/shell/public/cpp",
     "//services/shell/public/cpp:sources",
@@ -29,6 +28,7 @@
     "//skia",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
     "//ui/views",
     "//ui/views/examples:views_examples_lib",
     "//ui/views/mus:for_mojo_application",
diff --git a/mash/example/window_type_launcher/BUILD.gn b/mash/example/window_type_launcher/BUILD.gn
index 5d94e8eb..ceb66cd 100644
--- a/mash/example/window_type_launcher/BUILD.gn
+++ b/mash/example/window_type_launcher/BUILD.gn
@@ -30,7 +30,6 @@
     "//mash/public/interfaces",
     "//mash/session/public/interfaces",
     "//mojo/common:common_base",
-    "//mojo/converters/geometry",
     "//mojo/edk/system",
     "//mojo/public/cpp/bindings",
     "//services/shell/public/cpp",
@@ -41,6 +40,7 @@
     "//ui/aura",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
     "//ui/views",
     "//ui/views/mus:for_shared_library",
   ]
diff --git a/mash/example/window_type_launcher/window_type_launcher.cc b/mash/example/window_type_launcher/window_type_launcher.cc
index 351c5cf..1a25f87 100644
--- a/mash/example/window_type_launcher/window_type_launcher.cc
+++ b/mash/example/window_type_launcher/window_type_launcher.cc
@@ -13,13 +13,13 @@
 #include "base/threading/platform_thread.h"
 #include "components/mus/public/cpp/property_type_converters.h"
 #include "mash/session/public/interfaces/session.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "services/shell/public/cpp/connection.h"
 #include "services/shell/public/cpp/connector.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/views/context_menu_controller.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/button/label_button.h"
diff --git a/mash/webtest/BUILD.gn b/mash/webtest/BUILD.gn
index d36a438..eac7ab6 100644
--- a/mash/webtest/BUILD.gn
+++ b/mash/webtest/BUILD.gn
@@ -19,12 +19,12 @@
     "//base",
     "//components/mus/public/cpp",
     "//mash/public/interfaces",
-    "//mojo/converters/geometry",
     "//mojo/public/cpp/bindings",
     "//services/navigation/public/interfaces",
     "//services/shell/public/cpp",
     "//services/shell/public/interfaces",
     "//services/tracing/public/cpp",
+    "//ui/gfx/geometry/mojo",
     "//ui/native_theme",
     "//ui/views",
     "//ui/views/mus:for_mojo_application",
diff --git a/mash/webtest/webtest.cc b/mash/webtest/webtest.cc
index 843a1bc..849963d3 100644
--- a/mash/webtest/webtest.cc
+++ b/mash/webtest/webtest.cc
@@ -14,7 +14,6 @@
 #include "components/mus/public/cpp/window.h"
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "mash/public/interfaces/launchable.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/public/c/system/main.h"
 #include "services/navigation/public/interfaces/view.mojom.h"
 #include "services/shell/public/cpp/application_runner.h"
@@ -23,6 +22,7 @@
 #include "services/tracing/public/cpp/tracing_impl.h"
 #include "ui/aura/mus/mus_util.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/paint_throbber.h"
 #include "ui/native_theme/native_theme.h"
 #include "ui/views/background.h"
diff --git a/mash/wm/BUILD.gn b/mash/wm/BUILD.gn
index 81a5b8c4..abd1412 100644
--- a/mash/wm/BUILD.gn
+++ b/mash/wm/BUILD.gn
@@ -90,7 +90,6 @@
     "//mash/wm/public/interfaces",
     "//mash/wm/resources",
     "//mojo/common:common_base",
-    "//mojo/converters/geometry",
     "//mojo/converters/input_events",
     "//services/shell/public/cpp",
     "//services/tracing/public/cpp",
@@ -99,6 +98,7 @@
     "//ui/events",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
     "//ui/mojo/display",
     "//ui/resources",
     "//ui/strings",
@@ -184,7 +184,6 @@
     "//components/mus/public/cpp/tests:unittest_support",
     "//components/mus/public/interfaces",
     "//mash/wm/public/interfaces",
-    "//mojo/converters/geometry",
     "//mojo/converters/input_events",
     "//mojo/edk/system",
     "//mojo/public/cpp/system",
@@ -196,8 +195,9 @@
     "//ui/events",
     "//ui/gfx:test_support",
     "//ui/gfx/geometry",
-    "//ui/mojo/geometry:interfaces",
-    "//ui/mojo/geometry:util",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
+    "//ui/gfx/geometry/mojo:util",
     "//ui/views/mus",
   ]
 
diff --git a/mash/wm/non_client_frame_controller.cc b/mash/wm/non_client_frame_controller.cc
index d2f7da3..a4c6998 100644
--- a/mash/wm/non_client_frame_controller.cc
+++ b/mash/wm/non_client_frame_controller.cc
@@ -24,11 +24,11 @@
 #include "mash/wm/frame/non_client_frame_view_mash.h"
 #include "mash/wm/property_util.h"
 #include "mash/wm/shadow.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "ui/aura/layout_manager.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/compositor/layer.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/geometry/vector2d.h"
 #include "ui/views/mus/native_widget_mus.h"
 #include "ui/views/widget/widget.h"
diff --git a/mash/wm/root_window_controller.cc b/mash/wm/root_window_controller.cc
index 6fdca0eb..9c2b70c 100644
--- a/mash/wm/root_window_controller.cc
+++ b/mash/wm/root_window_controller.cc
@@ -40,9 +40,9 @@
 #include "mash/wm/status_layout_manager.h"
 #include "mash/wm/window_manager.h"
 #include "mash/wm/window_manager_application.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/public/cpp/bindings/type_converter.h"
 #include "services/shell/public/cpp/connector.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/mojo/display/display_type_converters.h"
 
 namespace mash {
diff --git a/mash/wm/window_manager.cc b/mash/wm/window_manager.cc
index 7c394aa..5c5be91c 100644
--- a/mash/wm/window_manager.cc
+++ b/mash/wm/window_manager.cc
@@ -22,7 +22,7 @@
 #include "mash/wm/property_util.h"
 #include "mash/wm/public/interfaces/container.mojom.h"
 #include "mash/wm/root_window_controller.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mash {
 namespace wm {
diff --git a/media/base/android/media_codec_player.cc b/media/base/android/media_codec_player.cc
index 72ae559..2891663 100644
--- a/media/base/android/media_codec_player.cc
+++ b/media/base/android/media_codec_player.cc
@@ -679,14 +679,8 @@
       }
       break;
 
-    case kStatePaused:
-    case kStateWaitingForSeek:
-    case kStateError:
-      break;  // ignore
-
     default:
-      NOTREACHED() << __FUNCTION__ << ": wrong state " << AsString(state_);
-      break;
+      break;  // ignore
   }
 }
 
diff --git a/media/blink/run_all_unittests.cc b/media/blink/run_all_unittests.cc
index 38ca6aa6..1694d74d 100644
--- a/media/blink/run_all_unittests.cc
+++ b/media/blink/run_all_unittests.cc
@@ -71,9 +71,6 @@
   ~TestBlinkPlatformSupport() override;
 
   blink::WebThread* currentThread() override { return &m_currentThread; }
-  void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*,
-                                  const char* name) override {}
-  void unregisterMemoryDumpProvider(blink::WebMemoryDumpProvider*) override {}
 
  private:
   CurrentThreadMock m_currentThread;
diff --git a/media/mojo/common/BUILD.gn b/media/mojo/common/BUILD.gn
index b3805fd..04144cd 100644
--- a/media/mojo/common/BUILD.gn
+++ b/media/mojo/common/BUILD.gn
@@ -20,9 +20,9 @@
     "//media",
     "//media/mojo/interfaces",
     "//mojo/common",
-    "//mojo/converters/geometry",
     "//mojo/public/c/system:for_component",
     "//ui/gfx/geometry",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 }
diff --git a/media/mojo/common/media_type_converters.cc b/media/mojo/common/media_type_converters.cc
index 01f4c5c..76e11e68 100644
--- a/media/mojo/common/media_type_converters.cc
+++ b/media/mojo/common/media_type_converters.cc
@@ -25,8 +25,8 @@
 #include "media/base/video_frame.h"
 #include "media/mojo/common/mojo_shared_buffer_video_frame.h"
 #include "media/mojo/interfaces/demuxer_stream.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/public/cpp/system/buffer.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mojo {
 
diff --git a/media/mojo/interfaces/BUILD.gn b/media/mojo/interfaces/BUILD.gn
index 1b154cbc8..9947c0b 100644
--- a/media/mojo/interfaces/BUILD.gn
+++ b/media/mojo/interfaces/BUILD.gn
@@ -28,6 +28,6 @@
   }
 
   deps = [
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 }
diff --git a/media/mojo/interfaces/media_types.mojom b/media/mojo/interfaces/media_types.mojom
index d40288c0..b06b73bc 100644
--- a/media/mojo/interfaces/media_types.mojom
+++ b/media/mojo/interfaces/media_types.mojom
@@ -4,7 +4,7 @@
 
 module media.mojom;
 
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 // See media/base/buffering_state.h for descriptions.
 // Kept in sync with media::BufferingState via static_asserts.
diff --git a/media/mojo/interfaces/renderer.mojom b/media/mojo/interfaces/renderer.mojom
index e3135c8c..1318bad 100644
--- a/media/mojo/interfaces/renderer.mojom
+++ b/media/mojo/interfaces/renderer.mojom
@@ -6,7 +6,7 @@
 
 import "media/mojo/interfaces/demuxer_stream.mojom";
 import "media/mojo/interfaces/media_types.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 interface Renderer {
   // Initializes the Renderer with one or both of an audio and video stream,
diff --git a/media/mojo/services/mojo_renderer_impl.cc b/media/mojo/services/mojo_renderer_impl.cc
index 6f028c87..63d7abda2 100644
--- a/media/mojo/services/mojo_renderer_impl.cc
+++ b/media/mojo/services/mojo_renderer_impl.cc
@@ -15,7 +15,7 @@
 #include "media/base/video_renderer_sink.h"
 #include "media/mojo/services/mojo_demuxer_stream_impl.h"
 #include "media/renderers/video_overlay_factory.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace media {
 
diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc
index 3d207e8..f0eaf98 100644
--- a/media/mojo/services/mojo_renderer_service.cc
+++ b/media/mojo/services/mojo_renderer_service.cc
@@ -11,7 +11,7 @@
 #include "media/base/renderer.h"
 #include "media/mojo/services/demuxer_stream_provider_shim.h"
 #include "media/mojo/services/mojo_cdm_service_context.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace media {
 
diff --git a/mojo/converters/input_events/BUILD.gn b/mojo/converters/input_events/BUILD.gn
index b724bbe9..2a0a329 100644
--- a/mojo/converters/input_events/BUILD.gn
+++ b/mojo/converters/input_events/BUILD.gn
@@ -16,11 +16,11 @@
   deps = [
     "//base",
     "//components/mus/public/interfaces",
-    "//mojo/converters/geometry",
     "//mojo/public/c/system:for_component",
     "//ui/events",
     "//ui/events:dom_keycode_converter",
     "//ui/gfx/geometry",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 }
diff --git a/mojo/converters/input_events/DEPS b/mojo/converters/input_events/DEPS
index 95ec829..d725a02 100644
--- a/mojo/converters/input_events/DEPS
+++ b/mojo/converters/input_events/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+components/mus/public/interfaces",
   "+ui/events",
+  "+ui/gfx/geometry/mojo",
 ]
diff --git a/mojo/converters/input_events/input_events_type_converters.cc b/mojo/converters/input_events/input_events_type_converters.cc
index 3bf8a27..ce9fec1 100644
--- a/mojo/converters/input_events/input_events_type_converters.cc
+++ b/mojo/converters/input_events/input_events_type_converters.cc
@@ -14,11 +14,11 @@
 #endif
 
 #include "components/mus/public/interfaces/input_events.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/input_events/mojo_extended_key_event_data.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
 #include "ui/events/keycodes/keyboard_codes.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mojo {
 namespace {
diff --git a/mojo/converters/surfaces/BUILD.gn b/mojo/converters/surfaces/BUILD.gn
index 6609e8e..7fd5c1b 100644
--- a/mojo/converters/surfaces/BUILD.gn
+++ b/mojo/converters/surfaces/BUILD.gn
@@ -18,9 +18,9 @@
   defines = [ "MOJO_SURFACES_IMPLEMENTATION" ]
 
   public_deps = [
-    "//mojo/converters/geometry",
     "//mojo/converters/transform",
     "//ui/gfx",
+    "//ui/gfx/geometry/mojo",
   ]
 
   deps = [
diff --git a/mojo/converters/surfaces/surfaces_type_converters.cc b/mojo/converters/surfaces/surfaces_type_converters.cc
index 57742a2..cf36039 100644
--- a/mojo/converters/surfaces/surfaces_type_converters.cc
+++ b/mojo/converters/surfaces/surfaces_type_converters.cc
@@ -24,9 +24,9 @@
 #include "cc/quads/tile_draw_quad.h"
 #include "cc/quads/yuv_video_draw_quad.h"
 #include "cc/surfaces/surface_id_allocator.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/surfaces/custom_surface_converter.h"
 #include "mojo/converters/transform/transform_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 using mus::mojom::Color;
 using mus::mojom::ColorPtr;
diff --git a/mojo/converters/surfaces/surfaces_utils.cc b/mojo/converters/surfaces/surfaces_utils.cc
index 239263f..ddbe4f5 100644
--- a/mojo/converters/surfaces/surfaces_utils.cc
+++ b/mojo/converters/surfaces/surfaces_utils.cc
@@ -4,8 +4,8 @@
 
 #include "mojo/converters/surfaces/surfaces_utils.h"
 
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/transform/transform_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/transform.h"
diff --git a/mojo/converters/surfaces/tests/BUILD.gn b/mojo/converters/surfaces/tests/BUILD.gn
index 4cb915d..6e5551e 100644
--- a/mojo/converters/surfaces/tests/BUILD.gn
+++ b/mojo/converters/surfaces/tests/BUILD.gn
@@ -13,7 +13,6 @@
     "//cc/surfaces",
     "//components/mus/public/interfaces",
     "//gpu",
-    "//mojo/converters/geometry",
     "//mojo/converters/surfaces",
     "//mojo/converters/transform",
     "//mojo/edk/test:run_all_unittests",
@@ -22,7 +21,8 @@
     "//ui/gfx",
     "//ui/gfx:test_support",
     "//ui/gfx/geometry",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 
   sources = [
diff --git a/mojo/converters/surfaces/tests/surface_unittest.cc b/mojo/converters/surfaces/tests/surface_unittest.cc
index f8fae2d..9a154292 100644
--- a/mojo/converters/surfaces/tests/surface_unittest.cc
+++ b/mojo/converters/surfaces/tests/surface_unittest.cc
@@ -16,12 +16,12 @@
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
 #include "gpu/command_buffer/common/sync_token.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/surfaces/surfaces_type_converters.h"
 #include "mojo/converters/transform/transform_type_converters.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkXfermode.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 using mus::mojom::Color;
 using mus::mojom::ColorPtr;
diff --git a/mojo/converters/transform/BUILD.gn b/mojo/converters/transform/BUILD.gn
index 34da111f..5ff908b 100644
--- a/mojo/converters/transform/BUILD.gn
+++ b/mojo/converters/transform/BUILD.gn
@@ -11,7 +11,7 @@
   deps = [
     "//mojo/public/c/system:for_component",
     "//skia",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 
   defines = [ "MOJO_TRANSFORM_IMPLEMENTATION" ]
diff --git a/mojo/converters/transform/DEPS b/mojo/converters/transform/DEPS
index ed693dd..1474f70 100644
--- a/mojo/converters/transform/DEPS
+++ b/mojo/converters/transform/DEPS
@@ -1,4 +1,4 @@
 include_rules = [
   "+ui/gfx/transform.h",
-  "+ui/mojo/geometry",
+  "+ui/gfx/geometry/mojo",
 ]
diff --git a/mojo/converters/transform/transform_type_converters.h b/mojo/converters/transform/transform_type_converters.h
index 372c473..d2af06d 100644
--- a/mojo/converters/transform/transform_type_converters.h
+++ b/mojo/converters/transform/transform_type_converters.h
@@ -6,8 +6,8 @@
 #define MOJO_CONVERTERS_TRANSFORM_TRANSFORM_TYPE_CONVERTERS_H_
 
 #include "mojo/converters/transform/mojo_transform_export.h"
+#include "ui/gfx/geometry/mojo/geometry.mojom.h"
 #include "ui/gfx/transform.h"
-#include "ui/mojo/geometry/geometry.mojom.h"
 
 namespace mojo {
 
diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc
index 822165a9..6e93e9c7 100644
--- a/mojo/edk/system/node_controller.cc
+++ b/mojo/edk/system/node_controller.cc
@@ -190,14 +190,6 @@
   base::AutoLock lock(reserved_ports_lock_);
   auto result = reserved_ports_.insert(std::make_pair(token, port));
   DCHECK(result.second);
-
-  // Safeguard against unpredictable and exceptional cases where a reservation
-  // holder may disappear without ever claiming their reservation.
-  io_task_runner_->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&NodeController::CancelReservation,
-                 base::Unretained(this), token),
-      base::TimeDelta::FromMinutes(1));
 }
 
 void NodeController::MergePortIntoParent(const std::string& token,
@@ -547,19 +539,6 @@
     delete this;
 }
 
-void NodeController::CancelReservation(const std::string& token) {
-  ports::PortRef reserved_port;
-  {
-    base::AutoLock lock(reserved_ports_lock_);
-    auto iter = reserved_ports_.find(token);
-    if (iter == reserved_ports_.end())  // Already claimed!
-      return;
-    reserved_port = iter->second;
-    reserved_ports_.erase(iter);
-  }
-  node_->ClosePort(reserved_port);
-}
-
 void NodeController::GenerateRandomPortName(ports::PortName* port_name) {
   GenerateRandomName(port_name);
 }
diff --git a/mojo/edk/system/node_controller.h b/mojo/edk/system/node_controller.h
index e2207ca..815690c 100644
--- a/mojo/edk/system/node_controller.h
+++ b/mojo/edk/system/node_controller.h
@@ -137,7 +137,6 @@
                        ports::ScopedMessage message);
   void AcceptIncomingMessages();
   void DropAllPeers();
-  void CancelReservation(const std::string& token);
 
   // ports::NodeDelegate:
   void GenerateRandomPortName(ports::PortName* port_name) override;
diff --git a/mojo/mojo_base.gyp b/mojo/mojo_base.gyp
index b61cbc8..28a4dfb2 100644
--- a/mojo/mojo_base.gyp
+++ b/mojo/mojo_base.gyp
@@ -94,24 +94,6 @@
       ],
     },
     {
-      # GN version: //mojo/converters/geometry
-      'target_name': 'mojo_geometry_lib',
-      'type': '<(component)',
-      'defines': [
-        'MOJO_GEOMETRY_IMPLEMENTATION',
-      ],
-      'dependencies': [
-        '../ui/mojo/geometry/mojo_bindings.gyp:mojo_geometry_bindings',
-        '../ui/gfx/gfx.gyp:gfx_geometry',
-        '<(mojo_system_for_component)',
-      ],
-      'sources': [
-        'converters/geometry/geometry_type_converters.cc',
-        'converters/geometry/geometry_type_converters.h',
-        'converters/geometry/mojo_geometry_export.h',
-      ],
-    },
-    {
       # GN version: //mojo/common:test_common_custom_types
       'target_name': 'mojo_test_common_custom_types',
       'type': 'static_library',
diff --git a/services/navigation/BUILD.gn b/services/navigation/BUILD.gn
index 0a70e16..f73b3b35 100644
--- a/services/navigation/BUILD.gn
+++ b/services/navigation/BUILD.gn
@@ -62,10 +62,10 @@
     "//base",
     "//components/mus/public/cpp",
     "//content/public/browser",
-    "//mojo/converters/geometry",
     "//services/navigation/public/interfaces",
     "//services/shell/public/cpp",
     "//skia",
+    "//ui/gfx/geometry/mojo",
     "//ui/views",
     "//ui/views/controls/webview",
     "//ui/views/mus",
diff --git a/services/navigation/public/interfaces/BUILD.gn b/services/navigation/public/interfaces/BUILD.gn
index ec88b94b..50797892 100644
--- a/services/navigation/public/interfaces/BUILD.gn
+++ b/services/navigation/public/interfaces/BUILD.gn
@@ -11,7 +11,7 @@
 
   deps = [
     "//components/mus/public/interfaces",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo:interfaces",
     "//url/mojo:url_mojom_gurl",
   ]
 }
diff --git a/services/navigation/public/interfaces/view.mojom b/services/navigation/public/interfaces/view.mojom
index 0ceead80..e2fb3fa8 100644
--- a/services/navigation/public/interfaces/view.mojom
+++ b/services/navigation/public/interfaces/view.mojom
@@ -5,7 +5,7 @@
 module navigation.mojom;
 
 import "components/mus/public/interfaces/window_tree.mojom";
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 import "url/mojo/url.mojom";
 
 interface ViewFactory {
diff --git a/services/navigation/view_impl.cc b/services/navigation/view_impl.cc
index 227b358..23c9bd5 100644
--- a/services/navigation/view_impl.cc
+++ b/services/navigation/view_impl.cc
@@ -8,7 +8,7 @@
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/web_contents.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/mus/native_widget_mus.h"
 #include "ui/views/widget/widget.h"
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index 094093d..50c13f3a 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -174,6 +174,9 @@
 [ Mac ] imported/wpt/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html [ WontFix ]
 [ Mac ] imported/wpt/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html [ WontFix ]
 
+# SVG files in the directory are not tests.
+imported/wpt/images/ [ WontFix ]
+
 # We could fix this test for us and upstream it if the test shell user agent
 # would let us differentiate test_shell and WebKit DumpTreeNode.
 crbug.com/7482 [ Win Mac ] http/tests/misc/timer-vs-loading.html [ WontFix ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 1095455..8994ede0 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -681,6 +681,9 @@
 crbug.com/492664 imported/csswg-test/css-writing-modes-3/text-combine-upright-value-all-002.html [ Failure ]
 crbug.com/492664 imported/csswg-test/css-writing-modes-3/text-combine-upright-value-all-003.html [ Failure ]
 
+crbug.com/614917 printing/list-item-with-empty-first-line.html [ Failure ]
+crbug.com/614917 virtual/threaded/printing/list-item-with-empty-first-line.html [ Failure ]
+
 # These CSS Writing Modes Level 3 tests pass but causes 1px diff on images, notified to the submitter.
 crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/block-flow-direction-htb-001.xht [ Failure ]
 crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/block-flow-direction-vrl-002.xht [ Failure ]
@@ -1296,13 +1299,13 @@
 
 crbug.com/605525 [ Win ] http/tests/xmlhttprequest/redirect-cross-origin-post.html [ Failure Pass ]
 
-crbug.com/603703 [ Linux Mac ] imported/wpt/web-animations/animation-timeline/document-timeline.html [ Failure Pass ]
+crbug.com/603703 [ Linux Mac ] imported/wpt/web-animations/interfaces/AnimationTimeline/document-timeline.html [ Failure Pass ]
 
-crbug.com/600248 imported/wpt/web-animations/animation-effect-timing/endDelay.html [ Failure ]
-crbug.com/600248 imported/wpt/web-animations/animation/constructor.html [ Failure Timeout ]
-crbug.com/600248 imported/wpt/web-animations/animation/finished.html [ Pass Failure ]
-crbug.com/600248 imported/wpt/web-animations/animation/oncancel.html [ Pass Failure ]
-crbug.com/600248 imported/wpt/web-animations/animation/onfinish.html [ Pass Failure ]
+crbug.com/600248 imported/wpt/web-animations/interfaces/AnimationEffectTiming/endDelay.html [ Failure ]
+crbug.com/600248 imported/wpt/web-animations/interfaces/Animation/constructor.html [ Failure Timeout ]
+crbug.com/600248 imported/wpt/web-animations/interfaces/Animation/finished.html [ Pass Failure ]
+crbug.com/600248 imported/wpt/web-animations/interfaces/Animation/oncancel.html [ Pass Failure ]
+crbug.com/600248 imported/wpt/web-animations/interfaces/Animation/onfinish.html [ Pass Failure ]
 
 crbug.com/611658 [ Win7 ] fast/forms/text/text-font-height-mismatch.html [ Failure ]
 crbug.com/611658 [ Win7 ] fast/text/emphasis-combined-text.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index afe4f5f3..6394766e 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -171,7 +171,7 @@
 imported/csswg-test/vendor-imports/mozilla/mozilla-central-reftests/transforms [ Skip ]
 imported/csswg-test/vendor-imports/mozilla/mozilla-central-reftests/ui3 [ Skip ]
 imported/csswg-test/vendor-imports/mozilla/mozilla-central-reftests/values3 [ Skip ]
-## Owners: leviw@chromium.org, kojii@chromium.org
+## Owners: kojii@chromium.org
 # imported/csswg-test/vendor-imports/mozilla/mozilla-central-reftests/variables [ Pass ]
 imported/csswg-test/vendor-imports/mozilla/mozilla-central-reftests/variables/reftest.list [ Skip ]
 imported/csswg-test/vendor-imports/mozilla/mozilla-central-reftests/will-change [ Skip ]
@@ -197,7 +197,8 @@
 imported/wpt/animation-timing [ Skip ]
 imported/wpt/app-uri [ Skip ]
 imported/wpt/battery-status [ Skip ]
-imported/wpt/common [ Skip ]
+## Owners: none; No tests in the directory.
+# imported/wpt/common [ Pass ]
 imported/wpt/compat [ Skip ]
 imported/wpt/config.default.json [ Skip ]
 imported/wpt/conformance-checkers [ Skip ]
@@ -234,7 +235,8 @@
 imported/wpt/html-longdesc [ Skip ]
 imported/wpt/html-media-capture [ Skip ]
 imported/wpt/http [ Skip ]
-imported/wpt/images [ Skip ]
+## Owners: none; No tests in the directory.
+# imported/wpt/images [ Pass ]
 imported/wpt/infrastructure [ Skip ]
 imported/wpt/innerText [ Skip ]
 imported/wpt/js [ Skip ]
@@ -271,6 +273,7 @@
 imported/wpt/resources/webidl2/README.md [ Skip ]
 imported/wpt/resources/webidl2/test [ Skip ]
 imported/wpt/screen-orientation [ Skip ]
+imported/wpt/secure-contexts [ Skip ]
 imported/wpt/selection [ Skip ]
 imported/wpt/selectors [ Skip ]
 imported/wpt/selectors-api [ Skip ]
@@ -297,6 +300,7 @@
 ## Owners: suzyh@chromium.org
 # imported/wpt/web-animations [ Pass ]
 imported/wpt/webaudio [ Skip ]
+imported/wpt/webauthn [ Skip ]
 imported/wpt/webdriver [ Skip ]
 imported/wpt/webgl [ Skip ]
 imported/wpt/webmessaging [ Skip ]
@@ -310,10 +314,12 @@
 
 # Skip OWNERS files in web-platform-tests. crbug.com/584660
 imported/wpt/user-timing/OWNERS [ Skip ]
+imported/wpt/common/OWNERS [ Skip ]
 imported/wpt/custom-elements/OWNERS [ Skip ]
 imported/wpt/gamepad/OWNERS [ Skip ]
 imported/wpt/FileAPI/OWNERS [ Skip ]
 imported/wpt/html/OWNERS [ Skip ]
+imported/wpt/images/OWNERS [ Skip ]
 imported/wpt/webrtc/OWNERS [ Skip ]
 imported/wpt/html-imports/OWNERS [ Skip ]
 imported/wpt/IndexedDB/OWNERS [ Skip ]
@@ -324,6 +330,7 @@
 imported/wpt/pointerevents/OWNERS [ Skip ]
 imported/wpt/webstorage/OWNERS [ Skip ]
 imported/wpt/mediacapture-streams/OWNERS [ Skip ]
+imported/wpt/media/OWNERS [ Skip ]
 imported/wpt/touch-events/OWNERS [ Skip ]
 imported/wpt/uievents/OWNERS [ Skip ]
 imported/wpt/web-animations/OWNERS [ Skip ]
@@ -543,6 +550,8 @@
 imported/wpt/html/dom/dynamic-markup-insertion/opening-the-input-stream/document.open-03.html [ Skip ]
 imported/wpt/html/editing/focus/document-level-focus-apis/document-level-apis.html [ Skip ]
 imported/wpt/html/semantics/document-metadata/the-base-element/base_multiple.html [ Skip ]
+imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html [ Skip ]
+imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping.html [ Skip ]
 imported/wpt/html/semantics/embedded-content/the-object-element/object-handler.html [ Skip ]
 imported/wpt/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr.html [ Skip ]
 imported/wpt/html/semantics/forms/the-button-element/button-activate.html [ Skip ]
@@ -580,12 +589,14 @@
 imported/wpt/html/browsers/the-window-object/security-window/window-security.sub.html [ Skip ]
 
 # crbug.com/493465: Requires the pipe feature of wptserve
+imported/wpt/dom/events/EventListener-incumbent-global.sub.html [ Skip ]
+imported/wpt/html/browsers/history/the-location-interface/allow_prototype_cycle_through_location.sub.html [ Skip ]
 imported/wpt/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html [ Skip ]
 imported/wpt/html/infrastructure/urls/dynamic-changes-to-base-urls/dynamic-urls.sub.xhtml [ Skip ]
 imported/wpt/html/infrastructure/urls/resolving-urls [ Skip ]
 imported/wpt/html/infrastructure/urls/terminology-0/multiple-base.sub.html [ Skip ]
-imported/wpt/html/semantics/embedded-content/media-elements/track/track-element/cors [ Skip ]
 imported/wpt/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html [ Skip ]
+imported/wpt/html/semantics/embedded-content/media-elements/track/track-element/cors [ Skip ]
 
 # https://github.com/w3c/web-platform-tests/issues/1862:
 # The test doesn't handle ':' after a drive letter in file: URL on Windows.
@@ -779,3 +790,11 @@
 
 # crbug.com/574461: update-w3c-deps imports .py file with x-bit cleared
 imported/wpt/dom/nodes/Document-createElement-namespace-tests/generate.py [ Skip ]
+
+# Untriaged: Test results contain local file paths
+imported/wpt/html/semantics/document-metadata/the-base-element/base_about_blank.html [ Skip ]
+imported/wpt/html/semantics/document-metadata/the-base-element/base_srcdoc.html [ Skip ]
+
+# Untriaged: Tests don't complete.
+imported/wpt/html/semantics/document-metadata/the-style-element/style-error-01.html [ Skip ]
+imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/custom-elements/spec/selectors/pseudo-class-defined.html b/third_party/WebKit/LayoutTests/custom-elements/spec/selectors/pseudo-class-defined.html
new file mode 100644
index 0000000..a248f12
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/custom-elements/spec/selectors/pseudo-class-defined.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<iframe id="iframe"></iframe>
+<script>
+const testList = [
+  { tagName: 'div', defined: true },
+  { tagName: 'a-a', defined: false },
+  { tagName: 'font-face', defined: true },
+];
+
+// Setup iframe to test the parser.
+const neither = 'rgb(255, 0, 0)';
+const defined = 'rgb(255, 165, 0)';
+const not_defined = 'rgb(0, 0, 255)';
+iframe.srcdoc = `<style>
+  * { color:${neither}; }
+  :defined { color:${defined}; }
+  :not(:defined) { color:${not_defined}; }
+</style>`
+  + testList.map(d => `<${d.tagName}></${d.tagName}>`).join('');
+setup({ explicit_done: true });
+iframe.onload = () => {
+  const doc = iframe.contentDocument;
+  const doc_without_browsing_context = doc.implementation.createHTMLDocument();
+  for (const data of testList) {
+    // Test elements inserted by parser.
+    test_defined(data.defined, doc.getElementsByTagName(data.tagName)[0], `<${data.tagName}>`);
+
+    // Test DOM createElement() methods.
+    test_defined_for_createElement(data.defined, doc, data.tagName);
+
+    // Documents without browsing context should be "uncustomized"; i.e., "defined".
+    test_defined_for_createElement(true, doc_without_browsing_context, data.tagName, 'Without browsing context: ');
+  }
+
+  done();
+};
+
+function test_defined_for_createElement(defined, doc, tagName, description = '') {
+  // Test document.createElement().
+  let element = doc.createElement(tagName);
+  doc.body.appendChild(element);
+  test_defined(defined, element, `${description}createElement("${tagName}")`);
+
+  // Test document.createElementNS().
+  element = doc.createElementNS('http://www.w3.org/1999/xhtml', tagName);
+  doc.body.appendChild(element);
+  test_defined(defined, element, `${description}createElementNS("http://www.w3.org/1999/xhtml", "${tagName}")`);
+
+  // If the element namespace is not HTML, it should be "uncustomized"; i.e., "defined".
+  element = doc.createElementNS('http://www.w3.org/2000/svg', tagName);
+  doc.body.appendChild(element);
+  test_defined(true, element, `${description}createElementNS("http://www.w3.org/2000/svg", "${tagName}")`);
+}
+
+function test_defined(expected, element, description) {
+  test(() => {
+    assert_equals(element.matches(':defined'), expected, 'matches(":defined")');
+    assert_equals(element.matches(':not(:defined)'), !expected, 'matches(":not(:defined")');
+    const view = element.ownerDocument.defaultView;
+    if (!view)
+      return;
+    const style = view.getComputedStyle(element);
+    assert_equals(style.color, expected ? defined : not_defined, 'getComputedStyle');
+  }, `${description} should ${expected ? 'be' : 'not be'} :defined`);
+}
+</script>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/addRange-failures-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/addRange-failures-expected.txt
index bebff5d..8e11321 100644
--- a/third_party/WebKit/LayoutTests/editing/selection/addRange-failures-expected.txt
+++ b/third_party/WebKit/LayoutTests/editing/selection/addRange-failures-expected.txt
@@ -1,6 +1,5 @@
 CONSOLE ERROR: line 21: Discontiguous selection is not supported.
 CONSOLE ERROR: line 29: The given range isn't in document.
-CONSOLE ERROR: line 38: The given range does not belong to the current selection's document.
 CONSOLE ERROR: line 51: The given range and the current selection belong to two different document fragments.
 Test error handling of Selection.addRange().
 
diff --git a/third_party/WebKit/LayoutTests/editing/selection/transformed-selection-rects.html b/third_party/WebKit/LayoutTests/editing/selection/transformed-selection-rects.html
index b879b57..b7df488f 100644
--- a/third_party/WebKit/LayoutTests/editing/selection/transformed-selection-rects.html
+++ b/third_party/WebKit/LayoutTests/editing/selection/transformed-selection-rects.html
@@ -14,17 +14,17 @@
       font-weight: bold;
     }
   </style>
-<script src="../editing.js" language="JavaScript" type="text/JavaScript" ></script>
 <script>
 if (window.internals)
     internals.settings.setEditingBehavior('mac');
 function editingTest() {
     if (window.testRunner)
         window.testRunner.dumpSelectionRect();
-        
+
+    var selection = window.getSelection();
     var testNode = document.getElementById('test');
-    setSelectionCommand(testNode, 0, testNode, 0);
-    extendSelectionForwardByWordCommand();
+    selection.collapse(testNode, 0);
+    selection.modify('extend', 'forward', 'word');
 }
 </script>
 </head>
@@ -35,7 +35,7 @@
     <p>Lorem ipsum <span id="test">dolor sit amet, consectetur adipisicing</span> elit.</p>
   </div>
 
-<script>runEditingTest()</script>
+<script>editingTest()</script>
 </body>
 
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-with-zero-content-size-should-not-crash.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-with-zero-content-size-should-not-crash.html
index 84d9c11..53fffcb 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-with-zero-content-size-should-not-crash.html
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-with-zero-content-size-should-not-crash.html
@@ -8,7 +8,37 @@
     overflow-y: scroll;
     overflow-x: scroll;
 }
+.widthSmallerThanScroll {
+    width : 5px;
+}
+.widthSmallerThanBorderPlusScroll {
+    width : 15px;
+    border: 5px;
+}
+.widthSmallerThanBorderPlusPaddingPlusScroll {
+    width : 15px;
+    border: 5px;
+    padding: 10px;
+}
+.heightSmallerThanScroll {
+    height : 5px;
+}
+.heightSmallerThanBorderPlusScroll {
+    height : 15px;
+    border: 5px;
+}
+.heightSmallerThanBorderPlusPaddingPlusScroll {
+    height : 15px;
+    border: 5px;
+    padding: 10px;
+}
 </style>
 <script src="../../resources/js-test.js"></script>
 <p>The test has passed if it does not CRASH in Debug builds.</p>
 <div class="grid"></div>
+<div class="grid widthSmallerThanScroll"></div>
+<div class="grid widthSmallerThanBorderPlusScroll"></div>
+<div class="grid widthSmallerThanBorderPlusPaddingPlusScroll"></div>
+<div class="grid heightSmallerThanScroll"></div>
+<div class="grid heightSmallerThanBorderPlusScroll"></div>
+<div class="grid heightSmallerThanBorderPlusPaddingPlusScroll"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/form/test1-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/form/test1-expected.txt
deleted file mode 100644
index e374b37b..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/form/test1-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This test attempts to access an HTMLLabelElement's form property. The first test accesses the form property of an label which is inside of a form. The second test accesses the form property of an label which is not inside of a form
-
-Passed
-
-Passed
-
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/form/test1.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/form/test1.html
deleted file mode 100644
index 4af78c7..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/form/test1.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<html>
-    <head>
-        <script language="javascript">
-        function print(message)
-        {
-            var paragraph = document.createElement("p");
-            paragraph.appendChild(document.createTextNode(message));
-            document.getElementById("console").appendChild(paragraph);
-        }
-        function test() 
-        {
-            if(window.testRunner)
-                testRunner.dumpAsText();
-
-            labelInsideForm = document.getElementById("labelInsideForm");
-            labelNotInsideForm = document.getElementById("labelNotInsideForm");
-        
-            form = document.getElementById("form");
-            
-            if(labelInsideForm.form == form)
-                print("Passed");
-            else
-                print("Failed");
-            
-            if(labelNotInsideForm.form == null)
-                print("Passed");
-            else
-                print("Failed");
-        }
-        </script>
-    </head>
-
-    <body onload="test();">
-        <p>This test attempts to access an HTMLLabelElement's form property. The first test accesses the form property of an label which is inside of a form.  The second test accesses the form property of an label which is not inside of a form</p>
-        
-        <div id="console"></div>  
-              
-        <form id="form">
-            <label id="labelInsideForm">
-            </label>
-        </form>
-        
-        <label id="labelNotInsideForm">
-        </label>
-    </body>   
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/label-formAssociatedElement-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/label-formAssociatedElement-expected.txt
deleted file mode 100644
index ed8b4d64..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/label-formAssociatedElement-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-As per spec labels must support form association by parser.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS document.getElementById("lab").form.id is "form"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/label-formAssociatedElement.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/label-formAssociatedElement.html
deleted file mode 100644
index e6ac53e0..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLLabelElement/label-formAssociatedElement.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE HTML>
-<script src='../../../resources/js-test.js'></script>
-<script>
-description('As per spec labels must support form association by parser.');
-</script>
-
-<table>
-    <form id='form'>
-        <tr>
-            <td> <label id='lab'>
-        </tr>
-    </form>
-</table>
-
-<script>
-shouldBeEqualToString('document.getElementById("lab").form.id', 'form');
-</script>
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Range/range-selection-across-documents-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Range/range-selection-across-documents-crash-expected.txt
index 843908c1..c6f20fc 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Range/range-selection-across-documents-crash-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Range/range-selection-across-documents-crash-expected.txt
@@ -1,2 +1 @@
-CONSOLE ERROR: line 18: The given range does not belong to the current selection's document.
 Test passes if it does not crash. 
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-associated-element-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/form-associated-element-expected.txt
index d235937..5034469 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-associated-element-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-associated-element-expected.txt
@@ -6,9 +6,9 @@
 
 PASS elements.length > 0 is true
 Testing LABEL
-PASS formOwner is "defined"
+PASS formOwner is "not defined"
 Testing INPUT
-PASS formOwner is "defined"
+PASS formOwner is "not defined"
 Testing BUTTON
 PASS formOwner is "defined"
 Testing FIELDSET
@@ -20,9 +20,9 @@
 Testing KEYGEN
 PASS formOwner is "defined"
 Testing LABEL
-PASS formOwner is "defined"
+PASS formOwner is "not defined"
 Testing INPUT
-PASS formOwner is "defined"
+PASS formOwner is "not defined"
 Testing OBJECT
 PASS formOwner is "defined"
 Testing SELECT
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-associated-element.html b/third_party/WebKit/LayoutTests/fast/forms/form-associated-element.html
index a30eeb4..649e0c21 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-associated-element.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-associated-element.html
@@ -18,14 +18,14 @@
 <body>
 <div style="display: none;">
 <form id=topForm>
-<label form=topForm onerror="" onclick="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"><input type="button"/></label>
+<label form=topForm onerror="" onclick="hasFormOwner(false, typeof canary !== 'undefined' && canary, event);"><input type="button"/></label>
 <!-- Form-associated elements per http://whatwg.org/specs/web-apps/current-work/#form-associated-element -->
 <button onerror="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"></button>
 <fieldset onerror="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"></fieldset>
 <input type=radio onerror="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"/>
 <input type=number onerror="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"/>
 <keygen keytype=rsa onerror="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"></keygen>
-<label onerror="" onclick="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"><input type="button"/></label>
+<label onerror="" onclick="hasFormOwner(false, typeof canary !== 'undefined' && canary, event);"><input type="button"/></label>
 <object onerror="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"></object>
 <select onerror="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"></select>
 <textarea onerror="hasFormOwner(true, typeof canary !== 'undefined' && canary, event);"></textarea>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-attribute-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/form-attribute-expected.txt
index 2b671a0..7d7175e 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-attribute-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-attribute-expected.txt
@@ -9,7 +9,7 @@
 PASS document.getElementsByTagName("fieldset")[0].form is owner
 PASS document.getElementsByTagName("input")[0].form is owner
 PASS document.getElementsByTagName("keygen")[0].form is owner
-PASS document.getElementsByTagName("label")[0].form is owner
+PASS document.getElementsByTagName("label")[0].form is null
 PASS document.getElementsByTagName("object")[0].form is owner
 PASS document.getElementsByTagName("output")[0].form is owner
 PASS document.getElementsByTagName("select")[0].form is owner
@@ -23,24 +23,22 @@
 PASS inputElement1.form is owner
 PASS inputElement2.form is owner
 PASS inputElement3.form is owner
-PASS labelElement1.form is owner
-PASS labelElement2.form is owner
-PASS labelElement3.form is owner
+PASS labelElement1.form is null
+PASS labelElement2.form is null
+PASS labelElement3.form is null
 
 - Ensures that the form attribute points the form owner even if the form element is nested another form element.
 NOTE: It seems that nesting form elements is not allowed so we ensure each form-associated elements associate with the outmost form element.
 PASS inputElement1.form is owner
 PASS inputElement2.form is owner
 PASS inputElement3.form is owner
-PASS labelElement1.form is owner
-PASS labelElement2.form is owner
-PASS labelElement3.form is owner
+PASS labelElement1.form is null
+PASS labelElement2.form is null
+PASS labelElement3.form is null
 
 - Ensures whether the form owner is set correctly when the value of form attribute of a form-associated element changed.
 PASS inputElement.form is form1
 PASS inputElement.form is form2
-PASS labelElement.form is form1
-PASS labelElement.form is form2
 PASS objectElement.form is form1
 PASS objectElement.form is form2
 
@@ -48,9 +46,6 @@
 PASS inputElement.form is null
 PASS inputElement.form is owner
 PASS inputElement.form is null
-PASS labelElement.form is null
-PASS labelElement.form is owner
-PASS labelElement.form is null
 PASS objectElement.form is null
 PASS objectElement.form is owner
 PASS objectElement.form is null
@@ -59,11 +54,8 @@
 PASS owner.name is "firstOwner"
 PASS owner.name is "secondOwner"
 PASS inputElement.form is owner
-PASS labelElement.form is owner
 PASS inputElement.form is null
-PASS labelElement.form is null
 PASS inputElement.form is owner
-PASS labelElement.form is owner
 
 - Check if a form and a control are disassociated when they are removed from the document together.
 PASS owner.elements.length is 1
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-attribute-nonexistence-form-id-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/form-attribute-nonexistence-form-id-expected.txt
index 64bfd35c..0ee553a 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-attribute-nonexistence-form-id-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-attribute-nonexistence-form-id-expected.txt
@@ -6,8 +6,8 @@
 label1 label2
 PASS inputShouldHaveForm.form is form
 PASS inputShouldNotHaveForm.form is null
-PASS labelShouldHaveForm.form is form
-PASS labelShouldNotHaveForm.form is null
+PASS labelWithoutForm.form is null
+PASS labelWithInvalidForm.form is null
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-attribute-nonexistence-form-id.html b/third_party/WebKit/LayoutTests/fast/forms/form-attribute-nonexistence-form-id.html
index 8d35891..eabae5e 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-attribute-nonexistence-form-id.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-attribute-nonexistence-form-id.html
@@ -18,12 +18,12 @@
 var form = document.getElementById('form');
 var inputShouldHaveForm = document.getElementById('input1');
 var inputShouldNotHaveForm = document.getElementById('input2');
-var labelShouldHaveForm = document.getElementById('label1');
-var labelShouldNotHaveForm = document.getElementById('label2');
+var labelWithoutForm = document.getElementById('label1');
+var labelWithInvalidForm = document.getElementById('label2');
 shouldBe('inputShouldHaveForm.form', 'form');
 shouldBeNull('inputShouldNotHaveForm.form');
-shouldBe('labelShouldHaveForm.form', 'form');
-shouldBeNull('labelShouldNotHaveForm.form');
+shouldBeNull('labelWithoutForm.form');
+shouldBeNull('labelWithInvalidForm.form');
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-attribute.html b/third_party/WebKit/LayoutTests/fast/forms/form-attribute.html
index cfe8bc1..d9fb65a 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-attribute.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-attribute.html
@@ -18,7 +18,7 @@
     '<fieldset name=victim form=owner />' +
     '<input name=victim form=owner />' +
     '<keygen name=victim form=owner />' +
-    '<label name=victim form=owner />' +
+    '<label name=victim form=owner></label>' +
     '<object name=victim form=owner></object>' +
     '<output name=victim form=owner />' +
     '<select name=victim form=owner />' +
@@ -29,7 +29,7 @@
 shouldBe('document.getElementsByTagName("fieldset")[0].form', 'owner');
 shouldBe('document.getElementsByTagName("input")[0].form', 'owner');
 shouldBe('document.getElementsByTagName("keygen")[0].form', 'owner');
-shouldBe('document.getElementsByTagName("label")[0].form', 'owner');
+shouldBeNull('document.getElementsByTagName("label")[0].form');
 shouldBe('document.getElementsByTagName("object")[0].form', 'owner');
 shouldBe('document.getElementsByTagName("output")[0].form', 'owner');
 shouldBe('document.getElementsByTagName("select")[0].form', 'owner');
@@ -40,7 +40,7 @@
 container.innerHTML = '<form id=owner></form>' +
     '<form id=shouldNotBeOwner>' +
     '    <input id=inputElement name=victim form=owner />' +
-    '    <label id=labelElement name=victim form=owner />' +
+    '    <label id=labelElement name=victim for=inputElement />' +
     '</form>';
 owner = document.getElementById('owner');
 var inputElement = document.getElementById('inputElement');
@@ -69,9 +69,9 @@
 shouldBe('inputElement1.form', 'owner');
 shouldBe('inputElement2.form', 'owner');
 shouldBe('inputElement3.form', 'owner');
-shouldBe('labelElement1.form', 'owner');
-shouldBe('labelElement2.form', 'owner');
-shouldBe('labelElement3.form', 'owner');
+shouldBeNull('labelElement1.form');
+shouldBeNull('labelElement2.form');
+shouldBeNull('labelElement3.form');
 
 debug('');
 debug('- Ensures that the form attribute points the form owner even if the form element is nested another form element.');
@@ -96,16 +96,15 @@
 shouldBe('inputElement1.form', 'owner');
 shouldBe('inputElement2.form', 'owner');
 shouldBe('inputElement3.form', 'owner');
-shouldBe('labelElement1.form', 'owner');
-shouldBe('labelElement2.form', 'owner');
-shouldBe('labelElement3.form', 'owner');
+shouldBeNull('labelElement1.form');
+shouldBeNull('labelElement2.form');
+shouldBeNull('labelElement3.form');
 
 debug('');
 debug('- Ensures whether the form owner is set correctly when the value of form attribute of a form-associated element changed.');
 container.innerHTML = '<form id=form1></form>' +
     '<form id=form2></form>' +
     '<input id=inputElement name=victim form=form1 />' +
-    '<label id=labelElement name=victim form=form1 />' +
     '<object id=objectElement name=victim form=form1></object>';
 var form1 = document.getElementById('form1');
 var form2 = document.getElementById('form2');
@@ -114,12 +113,6 @@
 inputElement.attributes['form'].value = 'form2';
 shouldBe('inputElement.form', 'form2');
 
-// HTMLabelElement has its own implementation of formAttr processing and so needs its own test.
-labelElement = document.getElementById('labelElement');
-shouldBe('labelElement.form', 'form1');
-labelElement.attributes['form'].value = 'form2';
-shouldBe('labelElement.form', 'form2');
-
 // HTMLObjectElement has its own implementation of formAttr processing and so needs its own test.
 objectElement = document.getElementById('objectElement');
 shouldBe('objectElement.form', 'form1');
@@ -130,7 +123,6 @@
 debug('- Ensures whether the form owner is set correctly when the value of form attribute is added/removed.');
 container.innerHTML = '<form id=owner name=firstOwner></form>' +
     '<input id=inputElement name=victim />' +
-    '<label id=labelElement name=victim />' +
     '<object id=objectElement name=victim></object>';
 owner = document.getElementById('owner');
 inputElement = document.getElementById('inputElement');
@@ -141,14 +133,6 @@
 inputElement.removeAttribute('form');
 shouldBe('inputElement.form', 'null');
 
-// HTMLLabelElement has its own implementation of formAttr processing and so needs its own test.
-labelElement = document.getElementById('labelElement');
-shouldBe('labelElement.form', 'null');
-labelElement.setAttribute('form', 'owner');
-shouldBe('labelElement.form', 'owner');
-labelElement.removeAttribute('form');
-shouldBe('labelElement.form', 'null');
-
 // HTMLObjectElement has its own implementation of formAttr processing and so needs its own test.
 objectElement = document.getElementById('objectElement');
 shouldBe('objectElement.form', 'null');
@@ -161,23 +145,18 @@
 debug('- Ensures whether the form owner is set correctly when the form owner is added/removed.');
 container.innerHTML = '<form id=owner name=firstOwner></form>' +
     '<form id=owner name=secondOwner></form>' +
-    '<input id=inputElement name=victim form=owner />' +
-    '<label id=labelElement name=victim form=owner />';
+    '<input id=inputElement name=victim form=owner />';
 owner = document.getElementById('owner');
 shouldBeEqualToString('owner.name', 'firstOwner');
 inputElement = document.getElementById('inputElement');
-labelElement = document.getElementById('labelElement');
 container.removeChild(owner);
 owner = document.getElementById('owner');
 shouldBeEqualToString('owner.name', 'secondOwner');
 shouldBe('inputElement.form', 'owner');
-shouldBe('labelElement.form', 'owner');
 container.removeChild(owner);
 shouldBe('inputElement.form', 'null');
-shouldBe('labelElement.form', 'null');
 container.appendChild(owner);
 shouldBe('inputElement.form', 'owner');
-shouldBe('labelElement.form', 'owner');
 
 debug('');
 debug('- Check if a form and a control are disassociated when they are removed from the document together.');
diff --git a/third_party/WebKit/LayoutTests/fast/html/a-click.html b/third_party/WebKit/LayoutTests/fast/html/a-click.html
new file mode 100644
index 0000000..e829228
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/html/a-click.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<body/>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<a id="target" href="#abc" title="This should appear as a tooltip">Hello.</a>
+<script>
+function doubleClickNoNavigation() {
+  document.getElementById('target').dispatchEvent(new MouseEvent("click", {detail: 2}));
+  assert_equals(window.location.hash, "", "There should be no navigation on double click");
+}
+
+test(doubleClickNoNavigation, "Double Click No Navigation");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/js/constructor-length-expected.txt b/third_party/WebKit/LayoutTests/fast/js/constructor-length-expected.txt
index 9bdfc352..309a8ab 100644
--- a/third_party/WebKit/LayoutTests/fast/js/constructor-length-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/js/constructor-length-expected.txt
@@ -7,7 +7,7 @@
 PASS AudioContext.length is 0
 PASS Blob.length is 0
 PASS CloseEvent.length is 1
-FAIL CustomEvent.length should be 1. Was 0.
+PASS CustomEvent.length is 1
 FAIL DOMFormData.length should be 0. Threw exception ReferenceError: DOMFormData is not defined
 PASS DOMParser.length is 0
 PASS DataView.length is 3
diff --git a/third_party/WebKit/LayoutTests/fast/js/constructor-length.html b/third_party/WebKit/LayoutTests/fast/js/constructor-length.html
index 106bd07..2168ca45 100644
--- a/third_party/WebKit/LayoutTests/fast/js/constructor-length.html
+++ b/third_party/WebKit/LayoutTests/fast/js/constructor-length.html
@@ -11,8 +11,6 @@
 shouldBe('AudioContext.length', '0');
 shouldBe('Blob.length', '0');
 shouldBe('CloseEvent.length', '1');
-// TODO(bashi): CustomEvent.length == 0 since it uses custom constructor.
-// Fix this regression once http://crbug.com/529941 is fixed.
 shouldBe('CustomEvent.length', '1');
 shouldBe('DOMFormData.length', '0');
 shouldBe('DOMParser.length', '0');
diff --git a/third_party/WebKit/LayoutTests/fast/loader/repeat-same-document-navigation.html b/third_party/WebKit/LayoutTests/fast/loader/repeat-same-document-navigation.html
index 8e66fe0f..709767e9 100644
--- a/third_party/WebKit/LayoutTests/fast/loader/repeat-same-document-navigation.html
+++ b/third_party/WebKit/LayoutTests/fast/loader/repeat-same-document-navigation.html
@@ -8,9 +8,7 @@
 
 function clickLink() {
     var link = document.getElementById("anchorLink");
-    eventSender.mouseMoveTo(link.offsetLeft + 2, link.offsetTop + 2);
-    eventSender.mouseDown(); 
-    eventSender.mouseUp(); 
+    link.click();
 }
 
 function run() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints-expected.txt
new file mode 100644
index 0000000..5ab1c18
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints-expected.txt
@@ -0,0 +1,20 @@
+Tests fetch() breakpoints.
+
+
+Running: testFetchBreakpoint
+Script execution paused.
+Call stack:
+    0) sendRequest (fetch-breakpoints.html:9)
+    1)  (:1)
+Script execution resumed.
+
+Running: testPauseOnAnyFetch
+Script execution paused.
+Script execution resumed.
+Script execution paused.
+Script execution resumed.
+
+Running: testDisableBreakpoint
+Script execution paused.
+Script execution resumed.
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html
new file mode 100644
index 0000000..689d3d1d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html
@@ -0,0 +1,102 @@
+<html>
+<head>
+<script src="../inspector-test.js"></script>
+<script src="../debugger-test.js"></script>
+<script>
+
+function sendRequest(url)
+{
+    fetch(url);
+}
+
+function test()
+{
+    var pane = WebInspector.panels.sources.sidebarPanes.xhrBreakpoints;
+    InspectorTest.runDebuggerTestSuite([
+        function testFetchBreakpoint(next)
+        {
+            pane._setBreakpoint("foo", true);
+            InspectorTest.waitUntilPaused(step1);
+            InspectorTest.evaluateInPageWithTimeout("sendRequest('/foo?a=b')");
+
+            function step1(callFrames)
+            {
+                InspectorTest.captureStackTrace(callFrames);
+                InspectorTest.resumeExecution(step2);
+            }
+
+            function step2()
+            {
+                InspectorTest.evaluateInPage("sendRequest('/bar?a=b')", step3);
+            }
+
+            function step3()
+            {
+                pane._removeBreakpoint("foo");
+                InspectorTest.evaluateInPage("sendRequest('/foo?a=b')", next);
+            }
+        },
+
+        function testPauseOnAnyFetch(next)
+        {
+            pane._setBreakpoint("", true);
+            InspectorTest.waitUntilPaused(pausedFoo);
+            InspectorTest.evaluateInPageWithTimeout("sendRequest('/foo?a=b')");
+
+            function pausedFoo(callFrames)
+            {
+                function resumed()
+                {
+                    InspectorTest.waitUntilPaused(pausedBar);
+                    InspectorTest.evaluateInPage("sendRequest('/bar?a=b')");
+                }
+                InspectorTest.resumeExecution(resumed);
+            }
+
+            function pausedBar(callFrames)
+            {
+                function resumed()
+                {
+                    pane._removeBreakpoint("");
+                    InspectorTest.evaluateInPage("sendRequest('/baz?a=b')", next);
+                }
+                InspectorTest.resumeExecution(resumed);
+            }
+        },
+
+        function testDisableBreakpoint(next)
+        {
+            pane._setBreakpoint("", true);
+            InspectorTest.waitUntilPaused(paused);
+            InspectorTest.evaluateInPage("sendRequest('/foo')");
+
+            function paused(callFrames)
+            {
+                function resumed()
+                {
+                    pane._breakpointElements.get("")._checkboxElement.click();
+                    InspectorTest.waitUntilPaused(pausedAgain);
+                    InspectorTest.evaluateInPage("sendRequest('/foo')", next);
+                }
+                InspectorTest.resumeExecution(resumed);
+            }
+
+            function pausedAgain(callFrames)
+            {
+                InspectorTest.addResult("Fail, paused again after breakpoint was removed.");
+                next();
+            }
+        }
+    ]);
+}
+
+</script>
+</head>
+
+<body onload="runTest()">
+<p>
+Tests fetch() breakpoints.
+</p>
+
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/multiple-policies-with-nonce.php b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/multiple-policies-with-nonce.php
index cae0821..f321562d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/multiple-policies-with-nonce.php
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/multiple-policies-with-nonce.php
@@ -1,5 +1,7 @@
 <?php
-header("Content-Security-Policy: script-src 'nonce-abcd1234'");
+# Note that the frame-ancestors directive is part of a *second* header and
+# policy, not the first policy with the script-src.
+header("Content-Security-Policy: script-src 'nonce-abcd1234', frame-ancestors 'self'");
 header("Content-Security-Policy-Report-Only: script-src 'self'");
 ?>
 <!DOCTYPE html>
@@ -11,5 +13,5 @@
 <script nonce="abcd1234">
     test(_ => {
       assert_true(true);
-    }, "This script block has a matching nonce, and should execute.");  
+    }, "This script block has a matching nonce, and should execute.");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/FileAPI/url/url_xmlhttprequest-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/FileAPI/url/url_xmlhttprequest-expected.txt
index decd914b..d2036bc1 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/FileAPI/url/url_xmlhttprequest-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/FileAPI/url/url_xmlhttprequest-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL FileAPI Test: Creating Blob URL via XMLHttpRequest Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided.
+FAIL FileAPI Test: Creating Blob URL via XMLHttpRequest assert_equals: The status is 200 expected 200 but got 0
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbcursor_update_index8.htm b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbcursor_update_index8.htm
new file mode 100644
index 0000000..27b17f6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbcursor_update_index8.htm
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>IDBCursor.update() - index - throw InvalidStateError when the cursor is being iterated</title>
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://www.w3.org/TR/IndexedDB/#widl-IDBCursor-update-IDBRequest-any-value">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+<div id="log"></div>
+<script>
+    var db,
+        t = async_test(),
+        records = [ { pKey: "primaryKey_0", iKey: "indexKey_0" },
+                    { pKey: "primaryKey_1", iKey: "indexKey_1" } ];
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function(e) {
+        db = e.target.result;
+
+        var objStore = db.createObjectStore("store", { keyPath: "pKey" });
+        objStore.createIndex("index", "iKey");
+
+        for (var i = 0; i < records.length; i++)
+            objStore.add(records[i]);
+    };
+
+    open_rq.onsuccess = function(e) {
+        var cursor_rq = db.transaction("store", "readwrite")
+                          .objectStore("store")
+                          .index("index")
+                          .openCursor();
+
+        cursor_rq.onsuccess = t.step_func(function(e) {
+            var cursor = e.target.result;
+            assert_true(cursor instanceof IDBCursor, "cursor exists");
+
+            cursor.continue();
+            assert_throws("InvalidStateError", function() {
+                cursor.update({ pKey: "primaryKey_0", iKey: "indexKey_0_updated" });
+            });
+
+            t.done();
+        });
+    }
+</script>
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbcursor_update_objectstore9.htm b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbcursor_update_objectstore9.htm
new file mode 100644
index 0000000..329b8e3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbcursor_update_objectstore9.htm
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>IDBCursor.update() - object store - throw InvalidStateError when the cursor is being iterated</title>
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://www.w3.org/TR/IndexedDB/#widl-IDBCursor-update-IDBRequest-any-value">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+<div id="log"></div>
+<script>
+    var db,
+        t = async_test(),
+        records = [{ pKey: "primaryKey_0", value: "value_0" },
+                   { pKey: "primaryKey_1", value: "value_1" }];
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (event) {
+        db = event.target.result;
+
+        var objStore = db.createObjectStore("store", {keyPath : "pKey"});
+
+        for (var i = 0; i < records.length; i++) {
+            objStore.add(records[i]);
+        }
+    }
+
+    open_rq.onsuccess = function(e) {
+        var cursor_rq = db.transaction("store", "readwrite")
+                          .objectStore("store")
+                          .openCursor();
+
+        cursor_rq.onsuccess = t.step_func(function(event) {
+            var cursor = event.target.result;
+            assert_true(cursor instanceof IDBCursor, "cursor exists");
+
+            cursor.continue();
+            assert_throws("InvalidStateError", function() {
+                cursor.update({ pKey: "primaryKey_0", value: "value_0_updated" });
+            });
+
+            t.done();
+        });
+    }
+</script>
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbobjectstore_createIndex14-exception_order-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbobjectstore_createIndex14-exception_order-expected.txt
new file mode 100644
index 0000000..87dad7a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbobjectstore_createIndex14-exception_order-expected.txt
@@ -0,0 +1,9 @@
+This is a testharness.js-based test.
+PASS InvalidStateError(Incorrect mode) vs. TransactionInactiveError 
+PASS InvalidStateError(Deleted ObjectStore) vs. TransactionInactiveError 
+PASS TransactionInactiveError vs. ConstraintError 
+FAIL ConstraintError vs. SyntaxError assert_throws: Index name check should precede syntax check of the key path function "function () {
+            store.createIndex("index", "inv..." threw object "SyntaxError: Failed to execute 'createIndex' on 'IDBObjec..." that is not a DOMException ConstraintError: property "code" is equal to 12, expected 0
+PASS SyntaxError vs. InvalidAccessError 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbobjectstore_createIndex14-exception_order.htm b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbobjectstore_createIndex14-exception_order.htm
new file mode 100644
index 0000000..2e83bd5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/idbobjectstore_createIndex14-exception_order.htm
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<title>IndexedDB: Exception Order of IDBObjectStore.createIndex()</title>
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="http://w3c.github.io/IndexedDB/#dom-idbobjectstore-createindex">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script>
+
+function indexeddb_test(description, upgrade_func, open_func = null) {
+    async_test(function(t) {
+        var dbname = document.location + "-" + t.name;
+        var del = indexedDB.deleteDatabase(dbname);
+        del.onerror = t.unreached_func("deleteDatabase should succeed");
+        var open = indexedDB.open(dbname, 1);
+        open.onerror = t.unreached_func("open should succeed");
+        open.onupgradeneeded = t.step_func(function() {
+            var db = open.result;
+            var tx = open.transaction;
+            upgrade_func(t, db, tx);
+        });
+        if (open_func) {
+            open.onsuccess = t.step_func(function() {
+                var db = open.result;
+                open_func(t, db);
+            });
+        }
+    }, description);
+}
+
+indexeddb_test(
+    "InvalidStateError(Incorrect mode) vs. TransactionInactiveError",
+    function(t, db, txn) {
+        var store = db.createObjectStore("s");
+    },
+    function(t, db) {
+        var txn = db.transaction("s");
+        var store = txn.objectStore("s");
+        txn.oncomplete = function() {
+            assert_throws("InvalidStateError", function() {
+                store.createIndex("index", "foo");
+            }, "Mode check should precede state check of the transaction");
+            t.done();
+        };
+    }
+);
+
+var gDeletedObjectStore;
+indexeddb_test(
+    "InvalidStateError(Deleted ObjectStore) vs. TransactionInactiveError",
+    function(t, db, txn) {
+        gDeletedObjectStore = db.createObjectStore("s");
+        db.deleteObjectStore("s");
+        txn.oncomplete = function() {
+            assert_throws("InvalidStateError", function() {
+                gDeletedObjectStore.createIndex("index", "foo");
+            }, "Deletion check should precede transaction-state check");
+            t.done();
+        };
+    }
+);
+
+indexeddb_test(
+    "TransactionInactiveError vs. ConstraintError",
+    function(t, db, txn) {
+        var store = db.createObjectStore("s");
+        store.createIndex("index", "foo");
+        txn.oncomplete = function() {
+            assert_throws("TransactionInactiveError", function() {
+                store.createIndex("index", "foo");
+            }, "Transaction-state check should precede index name check");
+            t.done();
+        };
+    }
+);
+
+indexeddb_test(
+    "ConstraintError vs. SyntaxError",
+    function(t, db) {
+        var store = db.createObjectStore("s");
+        store.createIndex("index", "foo");
+        assert_throws("ConstraintError", function() {
+            store.createIndex("index", "invalid key path");
+        }, "Index name check should precede syntax check of the key path");
+        assert_throws("ConstraintError", function() {
+            store.createIndex("index",
+                              ["invalid key path 1", "invalid key path 2"]);
+        }, "Index name check should precede syntax check of the key path");
+        t.done();
+    }
+);
+
+indexeddb_test(
+    "SyntaxError vs. InvalidAccessError",
+    function(t, db) {
+        var store = db.createObjectStore("s");
+        assert_throws("SyntaxError", function() {
+            store.createIndex("index",
+                              ["invalid key path 1", "invalid key path 2"],
+                              { multiEntry: true });
+        }, "Syntax check should precede multiEntry check of the key path");
+        t.done();
+    }
+);
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces-expected.txt
index 3d42193..8bef3615 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces-expected.txt
@@ -93,7 +93,7 @@
 PASS IDBObjectStore interface object name 
 FAIL IDBObjectStore interface: existence and properties of interface prototype object assert_equals: class string of IDBObjectStore.prototype expected "[object IDBObjectStorePrototype]" but got "[object IDBObjectStore]"
 PASS IDBObjectStore interface: existence and properties of interface prototype object's "constructor" property 
-PASS IDBObjectStore interface: attribute name 
+FAIL IDBObjectStore interface: attribute name assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined"
 PASS IDBObjectStore interface: attribute keyPath 
 PASS IDBObjectStore interface: attribute indexNames 
 PASS IDBObjectStore interface: attribute transaction 
@@ -113,7 +113,7 @@
 PASS IDBIndex interface object name 
 FAIL IDBIndex interface: existence and properties of interface prototype object assert_equals: class string of IDBIndex.prototype expected "[object IDBIndexPrototype]" but got "[object IDBIndex]"
 PASS IDBIndex interface: existence and properties of interface prototype object's "constructor" property 
-PASS IDBIndex interface: attribute name 
+FAIL IDBIndex interface: attribute name assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined"
 PASS IDBIndex interface: attribute objectStore 
 PASS IDBIndex interface: attribute keyPath 
 PASS IDBIndex interface: attribute multiEntry 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces.idl b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces.idl
index 055e62f..6eee5f4 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces.idl
+++ b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces.idl
@@ -88,7 +88,7 @@
 };
 
 interface IDBObjectStore {
-    readonly    attribute DOMString      name;
+    attribute DOMString name;
     readonly    attribute any            keyPath;
     readonly    attribute DOMStringList  indexNames;
     readonly    attribute IDBTransaction transaction;
@@ -106,7 +106,7 @@
 };
 
 interface IDBIndex {
-    readonly    attribute DOMString      name;
+    attribute DOMString name;
     readonly    attribute IDBObjectStore objectStore;
     readonly    attribute any            keyPath;
     readonly    attribute boolean        multiEntry;
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces.worker.js b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces.worker.js
index 5da0590..161acca 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces.worker.js
+++ b/third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/interfaces.worker.js
@@ -11,13 +11,11 @@
   var idls = request.responseText;
 
   idlArray.add_untested_idls("interface WorkerGlobalScope {};");
-  idlArray.add_untested_idls("interface WorkerUtils {};");
-  idlArray.add_untested_idls("WorkerGlobalScope implements WorkerUtils;");
   idlArray.add_untested_idls("interface Event { };");
   idlArray.add_untested_idls("interface EventTarget { };");
 
   // From Indexed DB:
-  idlArray.add_idls("WorkerUtils implements IDBEnvironment;");
+  idlArray.add_idls("WorkerGlobalScope implements IDBEnvironment;");
   idlArray.add_idls(idls);
 
   idlArray.add_objects({
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-frame.css b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-frame.css
new file mode 100644
index 0000000..0c97a68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-frame.css
@@ -0,0 +1,21 @@
+body {
+    font-size: small;
+    font-family: sans-serif;
+}
+
+p {
+    line-height: 0;
+}
+
+p:first-child {
+    display: inline;
+}
+
+h1 {
+    display: inline;
+}
+
+iframe, object {
+    border: 1px black solid;
+    margin: 2px;
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-index.css b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-index.css
new file mode 100644
index 0000000..ef35864b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-index.css
@@ -0,0 +1,31 @@
+body {
+    font-size: small;
+    font-family: sans-serif;
+}
+
+a {
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+h3 {
+    display: inline;
+    font-size: medium;
+}
+
+h3 + p {
+    display: inline;
+    margin-left: 0.5em;
+}
+
+li {
+    list-style-type: none;
+}
+
+ul {
+    padding-left: 2em;
+    margin-left: 0;
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-spec.css b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-spec.css
new file mode 100644
index 0000000..5882acb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-spec.css
@@ -0,0 +1,50 @@
+.testrefs {
+    font-size: small;
+    margin-left: 0.2em;
+    margin-right: 0.2em;
+    border-bottom: none !important;
+
+    font-weight: normal;
+    font-style: normal;
+    white-space: normal;
+    font-family: sans-serif;
+}
+
+.kw-must, .kw-required {
+    background: #fda;
+}
+
+.kw-should {
+    background: #ffa;
+}
+
+.kw-none {
+    background: #dfa;
+}
+
+
+pre.idl .testrefs :link {
+    color: #00c;
+}
+
+pre.idl .testrefs :visited {
+    color: #609;
+}
+
+.testrefs a:hover {
+    background: transparent;
+    text-decoration: none;
+}
+
+.testrefs:before {
+    content: '[';
+}
+
+.testrefs:after {
+    content: ']';
+}
+
+.testrefs a:first-child {
+    font-weight: bold;
+    text-decoration: none;
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-tests.css b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-tests.css
new file mode 100644
index 0000000..e006e81
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-tests.css
@@ -0,0 +1,134 @@
+html.fail {
+    background: #f66;
+}
+html.pass {
+    background: #6f6;
+}
+html.needs_check {
+    background: #99f;
+}
+
+body {
+    font-size: small;
+    font-family: sans-serif;
+    color: black;
+}
+
+a:link {
+    color: #00c;
+}
+a:visited {
+    color: #808;
+}
+
+body.framed {
+    font-size: x-small;
+}
+
+h1 {
+    font-size: larger;
+    margin: 0;
+    padding-left: 0.5em;
+    text-indent: -0.5em;
+}
+
+p {
+    margin: 0;
+}
+
+p.notes {
+    margin-bottom: 0.5em;
+    font-style: italic;
+}
+
+ul {
+    margin: 0;
+    margin-bottom: 0.5em;
+    padding: 0;
+    padding-left: 1em;
+}
+
+.refs {
+    font-style: italic;
+    margin-bottom: 0.5em;
+}
+
+.refs ul {
+    display: inline;
+    margin: 0;
+    padding: 0;
+}
+
+.refs li {
+    display: inline;
+    list-style-type: none;
+    margin: 0;
+    padding: 0;
+}
+
+canvas {
+    display: none;
+    visibility: hidden;
+    border: 2px #f0f solid;
+    background: url(../images/background.png);
+}
+
+img.expected {
+    display: none;
+    border: 2px #f0f solid;
+    background: url(../images/background.png);
+}
+
+iframe {
+    border: 2px #f0f solid;
+}
+
+.output {
+    display: none;
+}
+
+.show_output .output, .needs_check .output  {
+    display: block !important;
+    visibility: visible !important;
+}
+
+.show_output #show_output {
+    display: none;
+}
+
+.resource {
+    visibility: hidden;
+    height: 0;
+}
+
+.fallback {
+    font-size: 2em;
+    font-weight: bold;
+    color: #a00;
+}
+
+
+html.minimal body {
+    color: white;
+}
+html.fail.minimal {
+    background: #f00;
+}
+html.pass.minimal {
+    background: #080;
+}
+html.needs_check.minimal {
+    background: #008;
+}
+.minimal #d {
+    display: none !important;
+}
+.minimal .expectedtext {
+    visibility: hidden !important;
+}
+#passtext, #failtext {
+    display: none;
+}
+.minimal.pass #passtext, .minimal.fail #failtext {
+    display: block;
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-tests.js b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-tests.js
new file mode 100644
index 0000000..07b3170
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/canvas-tests.js
@@ -0,0 +1,86 @@
+function _valToString(val)
+{
+    if (val === undefined || val === null)
+        return '[' + typeof(val) + ']';
+    return val.toString() + '[' + typeof(val) + ']';
+}
+
+function _assert(cond, text)
+{
+    assert_true(!!cond, text);
+}
+
+function _assertSame(a, b, text_a, text_b)
+{
+    var msg = text_a + ' === ' + text_b + ' (got ' + _valToString(a) +
+              ', expected ' + _valToString(b) + ')';
+    assert_equals(a, b, msg);
+}
+
+function _assertDifferent(a, b, text_a, text_b)
+{
+    var msg = text_a + ' !== ' + text_b + ' (got ' + _valToString(a) +
+              ', expected not ' + _valToString(b) + ')';
+    assert_not_equals(a, b, msg);
+}
+
+
+function _getPixel(canvas, x,y)
+{
+    var ctx = canvas.getContext('2d');
+    var imgdata = ctx.getImageData(x, y, 1, 1);
+    return [ imgdata.data[0], imgdata.data[1], imgdata.data[2], imgdata.data[3] ];
+}
+
+function _assertPixel(canvas, x,y, r,g,b,a, pos, colour)
+{
+    var c = _getPixel(canvas, x,y);
+    assert_equals(c[0], r, 'Red channel of the pixel at (' + x + ', ' + y + ')');
+    assert_equals(c[1], g, 'Green channel of the pixel at (' + x + ', ' + y + ')');
+    assert_equals(c[2], b, 'Blue channel of the pixel at (' + x + ', ' + y + ')');
+    assert_equals(c[3], a, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');
+}
+
+function _assertPixelApprox(canvas, x,y, r,g,b,a, pos, colour, tolerance)
+{
+    var c = _getPixel(canvas, x,y);
+    assert_approx_equals(c[0], r, tolerance, 'Red channel of the pixel at (' + x + ', ' + y + ')');
+    assert_approx_equals(c[1], g, tolerance, 'Green channel of the pixel at (' + x + ', ' + y + ')');
+    assert_approx_equals(c[2], b, tolerance, 'Blue channel of the pixel at (' + x + ', ' + y + ')');
+    assert_approx_equals(c[3], a, tolerance, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');
+}
+
+function _addTest(testFn)
+{
+    var deferred = false;
+    window.deferTest = function () { deferred = true; };
+    on_event(window, "load", function()
+    {
+        t.step(function() {
+            var canvas = document.getElementById('c');
+            var ctx = canvas.getContext('2d');
+            t.step(testFn, window, canvas, ctx);
+        });
+
+        if (!deferred) {
+            t.done();
+        }
+    });
+}
+
+function _assertGreen(ctx, canvasWidth, canvasHeight)
+{
+    var testColor = function(d, idx, expected) {
+        assert_equals(d[idx], expected, "d[" + idx + "]", String(expected));
+    };
+    var imagedata = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
+    var w = imagedata.width, h = imagedata.height, d = imagedata.data;
+    for (var i = 0; i < h; ++i) {
+        for (var j = 0; j < w; ++j) {
+            testColor(d, 4 * (w * i + j) + 0, 0);
+            testColor(d, 4 * (w * i + j) + 1, 255);
+            testColor(d, 4 * (w * i + j) + 2, 0);
+            testColor(d, 4 * (w * i + j) + 3, 255);
+        }
+    }
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/css-red.txt b/third_party/WebKit/LayoutTests/imported/wpt/common/css-red.txt
new file mode 100644
index 0000000..9ef04cb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/css-red.txt
@@ -0,0 +1 @@
+html { color: red; }
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/form-submission.py b/third_party/WebKit/LayoutTests/imported/wpt/common/form-submission.py
new file mode 100644
index 0000000..eb9c6544
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/form-submission.py
@@ -0,0 +1,12 @@
+def main(request, response):
+    if request.headers.get('Content-Type') == 'application/x-www-form-urlencoded':
+        if request.body == 'foo=bara':
+            return 'OK'
+        else:
+            return 'FAIL'
+    else:
+        if request.POST.first('foo') == 'bar':
+            return 'OK'
+        else:
+            return 'FAIL'
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/large.py b/third_party/WebKit/LayoutTests/imported/wpt/common/large.py
new file mode 100644
index 0000000..0db4e4bb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/large.py
@@ -0,0 +1,45 @@
+def main(request, response):
+    """Code for generating large responses where the actual response data
+    isn't very important.
+
+    Two request parameters:
+    size (required): An integer number of bytes (no suffix) or kilobytes
+                     ("kb" suffix) or megabytes ("Mb" suffix).
+    string (optional): The string to repeat in the response. Defaults to "a".
+
+    Example:
+        /resources/large.py?size=32Mb&string=ab
+    """
+    if not "size" in request.GET:
+        400, "Need an integer bytes parameter"
+
+    bytes_value = request.GET.first("size")
+
+    chunk_size = 1024
+
+    multipliers = {"kb": 1024,
+                   "Mb": 1024*1024}
+
+    suffix = bytes_value[-2:]
+    if suffix in multipliers:
+        multiplier = multipliers[suffix]
+        bytes_value = bytes_value[:-2] * multiplier
+
+    try:
+        num_bytes = int(bytes_value)
+    except ValueError:
+        return 400, "Bytes must be an integer possibly with a kb or Mb suffix"
+
+    string = str(request.GET.first("string", "a"))
+
+    chunk = string * chunk_size
+
+    def content():
+        bytes_sent = 0
+        while bytes_sent < num_bytes:
+            if num_bytes - bytes_sent < len(chunk):
+                yield chunk[num_bytes - bytes_sent]
+            else:
+                yield chunk
+            bytes_sent += len(chunk)
+    return [("Content-Type", "text/plain")], content()
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/media.js b/third_party/WebKit/LayoutTests/imported/wpt/common/media.js
new file mode 100644
index 0000000..6bddea5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/media.js
@@ -0,0 +1,35 @@
+//
+// Returns the URI of a supported video source based on the user agent
+//
+function getVideoURI(base)
+{
+    var extension = '.mp4';
+
+    var videotag = document.createElement("video");
+
+    if ( videotag.canPlayType  &&
+         videotag.canPlayType('video/ogg; codecs="theora, vorbis"') )
+    {
+        extension = '.ogv';
+    }
+
+    return base + extension;
+}
+
+//
+// Returns the URI of a supported audio source based on the user agent
+//
+function getAudioURI(base)
+{
+    var extension = '.mp3';
+
+    var audiotag = document.createElement("audio");
+
+    if ( audiotag.canPlayType &&
+         audiotag.canPlayType('audio/ogg') )
+    {
+        extension = '.oga';
+    }
+
+    return base + extension;
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/redirect.py b/third_party/WebKit/LayoutTests/imported/wpt/common/redirect.py
new file mode 100644
index 0000000..3f15eff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/redirect.py
@@ -0,0 +1,19 @@
+def main(request, response):
+    """Simple handler that causes redirection.
+
+    The request should typically have two query parameters:
+    status - The status to use for the redirection. Defaults to 302.
+    location - The resource to redirect to.
+    """
+    status = 302
+    if "status" in request.GET:
+        try:
+            status = int(request.GET.first("status"))
+        except ValueError:
+            pass
+
+    response.status = status
+
+    location = request.GET.first("location")
+
+    response.headers.set("Location", location)
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/reftest-wait.js b/third_party/WebKit/LayoutTests/imported/wpt/common/reftest-wait.js
new file mode 100644
index 0000000..87816f83
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/reftest-wait.js
@@ -0,0 +1,9 @@
+function takeScreenshot() {
+    document.documentElement.classList.remove("reftest-wait");
+}
+
+function takeScreenshotDelayed(timeout) {
+    setTimeout(function() {
+        takeScreenshot();
+    }, timeout);
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/stringifiers.js b/third_party/WebKit/LayoutTests/imported/wpt/common/stringifiers.js
new file mode 100644
index 0000000..b59ca9c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/stringifiers.js
@@ -0,0 +1,52 @@
+// Tests <http://heycam.github.io/webidl/#es-stringifier>.
+function test_stringifier_attribute(aObject, aAttribute, aIsUnforgeable) {
+  // Step 1.
+  test(function() {
+    [null, undefined].forEach(function(v) {
+      assert_throws(new TypeError(), function() {
+        aObject.toString.call(v);
+      });
+    });
+  });
+
+  // TODO Step 2: security check.
+
+  // Step 3.
+  test(function() {
+    assert_false("Window" in window && aObject instanceof window.Window);
+    [{}, window].forEach(function(v) {
+      assert_throws(new TypeError(), function() {
+        aObject.toString.call(v)
+      });
+    });
+  });
+
+  // Step 4-6.
+  var expected_value;
+  test(function() {
+    expected_value = aObject[aAttribute];
+    assert_equals(aObject[aAttribute], expected_value,
+                  "The attribute " + aAttribute + " should be pure.");
+  });
+
+  var test_error = { name: "test" };
+  test(function() {
+    if (!aIsUnforgeable) {
+      Object.defineProperty(aObject, aAttribute, {
+        configurable: true,
+        get: function() { throw test_error; }
+      });
+    }
+    assert_equals(aObject.toString(), expected_value);
+  });
+
+  test(function() {
+    if (!aIsUnforgeable) {
+      Object.defineProperty(aObject, aAttribute, {
+        configurable: true,
+        value: { toString: function() { throw test_error; } }
+      });
+    }
+    assert_equals(aObject.toString(), expected_value);
+  });
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/text-plain.txt b/third_party/WebKit/LayoutTests/imported/wpt/common/text-plain.txt
new file mode 100644
index 0000000..97ca870b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/text-plain.txt
@@ -0,0 +1,4 @@
+This is a sample text/plain document.
+
+This is not an HTML document.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/utils.js b/third_party/WebKit/LayoutTests/imported/wpt/common/utils.js
new file mode 100644
index 0000000..bcdc256
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/utils.js
@@ -0,0 +1,80 @@
+function make_absolute_url(options) {
+    var loc = window.location;
+    var protocol = get(options, "protocol", loc.protocol);
+    if (protocol[protocol.length - 1] != ":") {
+        protocol += ":";
+    }
+
+    var hostname = get(options, "hostname", loc.hostname);
+
+    var subdomain = get(options, "subdomain");
+    if (subdomain) {
+        hostname = subdomain + "." + hostname;
+    }
+
+    var port = get(options, "port", loc.port)
+    var path = get(options, "path", loc.pathname);
+    var query = get(options, "query", loc.search);
+    var hash = get(options, "hash", loc.hash)
+
+    var url = protocol + "//" + hostname;
+    if (port) {
+        url += ":" + port;
+    }
+
+    if (path[0] != "/") {
+        url += "/";
+    }
+    url += path;
+    if (query) {
+        if (query[0] != "?") {
+            url += "?";
+        }
+        url += query;
+    }
+    if (hash) {
+        if (hash[0] != "#") {
+            url += "#";
+        }
+        url += hash;
+    }
+    return url;
+}
+
+function get(obj, name, default_val) {
+    if (obj.hasOwnProperty(name)) {
+        return obj[name];
+    }
+    return default_val;
+}
+
+function token() {
+    var uuid = [to_hex(rand_int(32), 8),
+                to_hex(rand_int(16), 4),
+                to_hex(0x4000 | rand_int(12), 4),
+                to_hex(0x8000 | rand_int(14), 4),
+                to_hex(rand_int(48), 12)].join("-")
+    return uuid;
+}
+
+function rand_int(bits) {
+    if (bits < 1 || bits > 53) {
+        throw new TypeError();
+    } else {
+        if (bits >= 1 && bits <= 30) {
+            return 0 | ((1 << bits) * Math.random());
+        } else {
+            var high = (0 | ((1 << (bits - 30)) * Math.random())) * (1 << 30);
+            var low = 0 | ((1 << 30) * Math.random());
+            return  high + low;
+        }
+    }
+}
+
+function to_hex(x, length) {
+    var rv = x.toString(16);
+    while (rv.length < length) {
+        rv = "0" + rv;
+    }
+    return rv;
+}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/common/vendor-prefix.js b/third_party/WebKit/LayoutTests/imported/wpt/common/vendor-prefix.js
new file mode 100644
index 0000000..1a91632
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/common/vendor-prefix.js
@@ -0,0 +1,115 @@
+/* Use this script when you want to test APIs that use vendor prefixes
+   and define which objects need to be checked for prefixed versions, à la
+   <script src="vendor-prefix.js"
+     data-prefixed-objects='[{"ancestors":["navigator"], "name":"getUserMedia"}]'
+   data-prefixed-prototypes='[{"ancestors":["HTMLMediaElement"],"name":"srcObject"}]'></script>
+   data-prefixed-objects lets prefix objects in the global space
+   data-prefixed-prototypes adds prefixes to interfaces, for objects that
+   get created during the tests
+
+   NB: vendor prefixes are expected to go away in favor of putting
+   new features behind flag, so hopefully there will be only limited
+   need to use this
+*/
+
+(function () {
+    var aliases = {};
+    var documentingPrefixUsage = document.createElement('div');
+    var vendorPrefixes = ["moz", "ms", "o", "webkit", "Moz", "MS", "O", "WebKit", "op"];
+
+    function getParentObject(ancestors) {
+        var parent = window;
+        var currentName = "";
+        ancestors.forEach(function (p) {
+            currentName = currentName ? currentName + "." + p : p;
+            if (parent[p] === undefined) {
+                throw currentName + " is undefined, cannot set prefix alias on child object";
+            }
+            parent = parent[p];
+        });
+        return parent;
+    }
+
+    function prependPrefix(prefix, name) {
+        var newName = name[0].toUpperCase() + name.substr(1, name.length);
+        return prefix + newName;
+    }
+
+    function setPrototypeAlias(obj) {
+        var parent = getParentObject(obj.ancestors);
+        if (!parent.prototype.hasOwnProperty(obj.name)) {
+            vendorPrefixes.forEach(function (prefix) {
+                if (parent.prototype.hasOwnProperty(prependPrefix(prefix, obj.name))) {
+                    Object.defineProperty(parent.prototype, obj.name,
+                                          {get: function() {return this[prependPrefix(prefix, obj.name)];},
+                                           set: function(v) {this[prependPrefix(prefix, obj.name)] = v;}
+                                          });
+                    aliases[obj.ancestors.join(".") + ".prototype." + obj.name] = obj.ancestors.join(".") + ".prototype." + prependPrefix(prefix, obj.name);
+                    return;
+                }
+            });
+        }
+    }
+
+    function setAlias(obj) {
+        var parent = getParentObject(obj.ancestors);
+        if (parent[obj.name] === undefined) {
+            vendorPrefixes.forEach(function (prefix) {
+                if (parent[prependPrefix(prefix, obj.name)] !== undefined) {
+                    parent[obj.name] = parent[prependPrefix(prefix, obj.name)];
+                    aliases[obj.ancestors.join(".") + "." + obj.name] = obj.ancestors.join(".") + "." + prependPrefix(prefix, obj.name);
+                    return;
+                }
+            });
+        }
+    }
+
+    if (location.search.indexOf('usePrefixes=1') !== -1) {
+        if (document.querySelector("script[data-prefixed-objects]")) {
+            var prefixObjectsData = document.querySelector("script[data-prefixed-objects]").dataset["prefixedObjects"];
+            try {
+                var prefixedObjects = JSON.parse(prefixObjectsData);
+            } catch (e) {
+                throw "couldn't parse data-prefixed-objects as JSON:" + e;
+            }
+            prefixedObjects.forEach(setAlias);
+        }
+        if (document.querySelector("script[data-prefixed-prototypes]")) {
+            var prefixProtoData = document.querySelector("script[data-prefixed-prototypes]").dataset["prefixedPrototypes"];
+            try {
+                var prefixedPrototypes = JSON.parse(prefixProtoData);
+            } catch (e) {
+                throw "couldn't parse data-prefixed-prototypes as JSON:" + e;
+            }
+            prefixedPrototypes.forEach(setPrototypeAlias);
+        }
+        var ul = document.createElement("ul");
+        Object.keys(aliases).forEach(function (alias) {
+            var li = document.createElement("li");
+            li.appendChild(document.createTextNode(alias + " has been set to be an alias of vendor-prefixed " + aliases[alias]));
+            ul.appendChild(li);
+        });
+        documentingPrefixUsage.appendChild(ul);
+    } else {
+        // Document that the test can be run with prefixes enabled
+
+        var a = document.createElement('a');
+        var link = "";
+        if (location.search) {
+            link = location.search + "&usePrefixes=1";
+        } else {
+            link = "?usePrefixes=1";
+        }
+        a.setAttribute("href", link);
+        a.appendChild(document.createTextNode("with vendor prefixes enabled"));
+        documentingPrefixUsage.appendChild(document.createTextNode("The feature(s) tested here are known to have been made available via vendor prefixes; you can run this test "));
+        documentingPrefixUsage.appendChild(a);
+        documentingPrefixUsage.appendChild(document.createTextNode("."));
+    }
+    var log = document.getElementById('log');
+    if (log) {
+        log.parentNode.insertBefore(documentingPrefixUsage, log);
+    } else {
+        document.body.appendChild(documentingPrefixUsage);
+    }
+})();
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/custom-elements-registry/define-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/custom-elements-registry/define-expected.txt
new file mode 100644
index 0000000..dad6a37
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/custom-elements-registry/define-expected.txt
@@ -0,0 +1,95 @@
+This is a testharness.js-based test.
+PASS "window.customElements.define" should exists 
+PASS If no arguments, should throw a TypeError 
+PASS If one argument, should throw a TypeError 
+PASS If constructor is undefined, should throw a TypeError 
+PASS If constructor is null, should throw a TypeError 
+PASS If constructor is object, should throw a TypeError 
+PASS If constructor is string, should throw a TypeError 
+PASS If constructor is arrow function, should throw a TypeError 
+PASS If constructor is method, should throw a TypeError 
+PASS Element names: defining an element named a- should succeed 
+PASS Element names: defining an element named a-a should succeed 
+PASS Element names: defining an element named aa- should succeed 
+PASS Element names: defining an element named aa-a should succeed 
+PASS Element names: defining an element named a-.-_ should succeed 
+PASS Element names: defining an element named a-0123456789 should succeed 
+PASS Element names: defining an element named a-漢字 should succeed 
+PASS Element names: defining an element named a-𠀋 should succeed 
+PASS Element names: defining an element named undefined should throw a SyntaxError 
+PASS Element names: defining an element named null should throw a SyntaxError 
+PASS Element names: defining an element named  should throw a SyntaxError 
+PASS Element names: defining an element named - should throw a SyntaxError 
+PASS Element names: defining an element named a should throw a SyntaxError 
+PASS Element names: defining an element named input should throw a SyntaxError 
+PASS Element names: defining an element named mycustomelement should throw a SyntaxError 
+PASS Element names: defining an element named A should throw a SyntaxError 
+PASS Element names: defining an element named A- should throw a SyntaxError 
+PASS Element names: defining an element named 0- should throw a SyntaxError 
+PASS Element names: defining an element named a-A should throw a SyntaxError 
+PASS Element names: defining an element named a-Z should throw a SyntaxError 
+PASS Element names: defining an element named A-a should throw a SyntaxError 
+PASS Element names: defining an element named a-a× should throw a SyntaxError 
+PASS Element names: defining an element named a-a  should throw a SyntaxError 
+PASS Element names: defining an element named a-a󰀀 should throw a SyntaxError 
+PASS Element names: defining an element named annotation-xml should throw a SyntaxError 
+PASS Element names: defining an element named color-profile should throw a SyntaxError 
+PASS Element names: defining an element named font-face should throw a SyntaxError 
+PASS Element names: defining an element named font-face-src should throw a SyntaxError 
+PASS Element names: defining an element named font-face-uri should throw a SyntaxError 
+PASS Element names: defining an element named font-face-format should throw a SyntaxError 
+PASS Element names: defining an element named font-face-name should throw a SyntaxError 
+PASS Element names: defining an element named missing-glyph should throw a SyntaxError 
+PASS If the name is already defined, should throw a NotSupportedError 
+PASS If the constructor is already defined, should throw a NotSupportedError 
+FAIL If extends is a-, should throw a NotSupportedError assert_throws: function "() =>  {
+        customElements.define('test-define-exten..." did not throw
+PASS If extends is a-a, should throw a NotSupportedError 
+PASS If extends is aa-, should throw a NotSupportedError 
+PASS If extends is aa-a, should throw a NotSupportedError 
+PASS If extends is a-.-_, should throw a NotSupportedError 
+PASS If extends is a-0123456789, should throw a NotSupportedError 
+PASS If extends is a-漢字, should throw a NotSupportedError 
+PASS If extends is a-𠀋, should throw a NotSupportedError 
+FAIL If extends is bgsound, should throw a NotSupportedError assert_throws: function "() =>  {
+        customElements.define('test-define-exten..." did not throw
+FAIL If extends is blink, should throw a NotSupportedError assert_throws: function "() =>  {
+        customElements.define('test-define-exten..." did not throw
+FAIL If extends is isindex, should throw a NotSupportedError assert_throws: function "() =>  {
+        customElements.define('test-define-exten..." did not throw
+FAIL If extends is multicol, should throw a NotSupportedError assert_throws: function "() =>  {
+        customElements.define('test-define-exten..." did not throw
+FAIL If extends is nextid, should throw a NotSupportedError assert_throws: function "() =>  {
+        customElements.define('test-define-exten..." did not throw
+FAIL If extends is spacer, should throw a NotSupportedError assert_throws: function "() =>  {
+        customElements.define('test-define-exten..." did not throw
+FAIL If extends is elementnametobeunknownelement, should throw a NotSupportedError assert_throws: function "() =>  {
+        customElements.define('test-define-exten..." did not throw
+PASS If constructor.prototype throws, should rethrow 
+PASS If Type(constructor.prototype) is undefined, should throw a TypeError 
+PASS If Type(constructor.prototype) is string, should throw a TypeError 
+FAIL If constructor.prototype.observedAttributes throws, should rethrow assert_throws: function "() =>  {
+        customElements.define('test-define-const..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "[object Object]" ("rethrown")
+FAIL If constructor.prototype.connectedCallback throws, should rethrow assert_throws: function "() =>  {
+        customElements.define('test-define-const..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "[object Object]" ("rethrown")
+FAIL If constructor.prototype.disconnectedCallback throws, should rethrow assert_throws: function "() =>  {
+        customElements.define('test-define-const..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "[object Object]" ("rethrown")
+FAIL If constructor.prototype.attributeChangedCallback throws, should rethrow assert_throws: function "() =>  {
+        customElements.define('test-define-const..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "[object Object]" ("rethrown")
+FAIL If constructor.prototype.connectedCallback is undefined, should success Failed to execute 'define' on 'CustomElementsRegistry': "test-define-constructor-prototype-connectedCallback" is not a valid custom element name
+FAIL If constructor.prototype.connectedCallback is null, should throw a TypeError assert_throws: function "() =>  {
+          customElements.define('test-define-con..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "TypeError" ("TypeError")
+FAIL If constructor.prototype.connectedCallback is object, should throw a TypeError assert_throws: function "() =>  {
+          customElements.define('test-define-con..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "TypeError" ("TypeError")
+FAIL If constructor.prototype.disconnectedCallback is undefined, should success Failed to execute 'define' on 'CustomElementsRegistry': "test-define-constructor-prototype-disconnectedCallback" is not a valid custom element name
+FAIL If constructor.prototype.disconnectedCallback is null, should throw a TypeError assert_throws: function "() =>  {
+          customElements.define('test-define-con..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "TypeError" ("TypeError")
+FAIL If constructor.prototype.disconnectedCallback is object, should throw a TypeError assert_throws: function "() =>  {
+          customElements.define('test-define-con..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "TypeError" ("TypeError")
+FAIL If constructor.prototype.attributeChangedCallback is undefined, should success Failed to execute 'define' on 'CustomElementsRegistry': "test-define-constructor-prototype-attributeChangedCallback" is not a valid custom element name
+FAIL If constructor.prototype.attributeChangedCallback is null, should throw a TypeError assert_throws: function "() =>  {
+          customElements.define('test-define-con..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "TypeError" ("TypeError")
+FAIL If constructor.prototype.attributeChangedCallback is object, should throw a TypeError assert_throws: function "() =>  {
+          customElements.define('test-define-con..." threw object "SyntaxError: Failed to execute 'define' on 'CustomElement..." ("SyntaxError") expected object "TypeError" ("TypeError")
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/custom-elements-registry/define.html b/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/custom-elements-registry/define.html
new file mode 100644
index 0000000..b45b6d0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/custom-elements-registry/define.html
@@ -0,0 +1,250 @@
+<!DOCTYPE html>
+<title>Custom Elements: Element definition</title>
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<body>
+<div id="log"></div>
+<iframe id="iframe"></iframe>
+<script>
+'use strict';
+(() =>  {
+  // Element definition
+  // https://html.spec.whatwg.org/multipage/scripting.html#element-definition
+
+  // Use window from iframe to isolate the test.
+  const testWindow = iframe.contentDocument.defaultView;
+  const customElements = testWindow.customElements;
+
+  let testable = false;
+  test(() =>  {
+    assert_true('customElements' in testWindow, '"window.customElements" exists');
+    assert_true('define' in customElements, '"window.customElements.define" exists');
+    testable = true;
+  }, '"window.customElements.define" should exists');
+  if (!testable)
+    return;
+
+  const expectTypeError = TypeError.prototype;
+  // Following errors are DOMException, not JavaScript errors.
+  const expectSyntaxError = 'SYNTAX_ERR';
+  const expectNotSupportedError = 'NOT_SUPPORTED_ERR';
+
+  // 1. If IsConstructor(constructor) is false,
+  // then throw a TypeError and abort these steps.
+  test(() =>  {
+    assert_throws(expectTypeError, () =>  {
+      customElements.define();
+    });
+  }, 'If no arguments, should throw a TypeError');
+  test(() =>  {
+    assert_throws(expectTypeError, () =>  {
+      customElements.define('test-define-one-arg');
+    });
+  }, 'If one argument, should throw a TypeError');
+  [
+    [ 'undefined', undefined ],
+    [ 'null', null ],
+    [ 'object', {} ],
+    [ 'string', 'string' ],
+    [ 'arrow function', () => {} ], // IsConstructor returns false for arrow functions
+    [ 'method', ({ m() { } }).m ], // IsConstructor returns false for methods
+  ].forEach(t =>  {
+    test(() =>  {
+      assert_throws(expectTypeError, () =>  {
+        customElements.define(`test-define-constructor-${t[0]}`, t[1]);
+      });
+    }, `If constructor is ${t[0]}, should throw a TypeError`);
+  });
+
+  // 2. If name is not a valid custom element name,
+  // then throw a SyntaxError and abort these steps.
+  let validCustomElementNames = [
+    // [a-z] (PCENChar)* '-' (PCENChar)*
+    // https://html.spec.whatwg.org/multipage/scripting.html#valid-custom-element-name
+    'a-',
+    'a-a',
+    'aa-',
+    'aa-a',
+    'a-.-_',
+    'a-0123456789',
+    'a-\u6F22\u5B57', // Two CJK Unified Ideographs
+    'a-\uD840\uDC0B', // Surrogate pair U+2000B
+  ];
+  let invalidCustomElementNames = [
+    undefined,
+    null,
+    '',
+    '-',
+    'a',
+    'input',
+    'mycustomelement',
+    'A',
+    'A-',
+    '0-',
+    'a-A',
+    'a-Z',
+    'A-a',
+    'a-a\u00D7',
+    'a-a\u3000',
+    'a-a\uDB80\uDC00', // Surrogate pair U+F0000
+    // name must not be any of the hyphen-containing element names.
+    'annotation-xml',
+    'color-profile',
+    'font-face',
+    'font-face-src',
+    'font-face-uri',
+    'font-face-format',
+    'font-face-name',
+    'missing-glyph',
+  ];
+  validCustomElementNames.forEach(name =>  {
+    test(() =>  {
+      customElements.define(name, class {});
+    }, `Element names: defining an element named ${name} should succeed`);
+  });
+  invalidCustomElementNames.forEach(name =>  {
+    test(() =>  {
+      assert_throws(expectSyntaxError, () =>  {
+        customElements.define(name, class {});
+      });
+    }, `Element names: defining an element named ${name} should throw a SyntaxError`);
+  });
+
+  // 3. If this CustomElementsRegistry contains an entry with name name,
+  // then throw a NotSupportedError and abort these steps.
+  test(() =>  {
+    customElements.define('test-define-dup-name', class {});
+    assert_throws(expectNotSupportedError, () =>  {
+      customElements.define('test-define-dup-name', class {});
+    });
+  }, 'If the name is already defined, should throw a NotSupportedError');
+
+  // 4. If this CustomElementsRegistry contains an entry with constructor constructor,
+  // then throw a NotSupportedError and abort these steps.
+  test(() =>  {
+    class TestDupConstructor {};
+    customElements.define('test-define-dup-constructor', TestDupConstructor);
+    assert_throws(expectNotSupportedError, () =>  {
+      customElements.define('test-define-dup-ctor2', TestDupConstructor);
+    });
+  }, 'If the constructor is already defined, should throw a NotSupportedError');
+
+  // 7.1. If extends is a valid custom element name,
+  // then throw a NotSupportedError.
+  validCustomElementNames.forEach(name =>  {
+    test(() =>  {
+      assert_throws(expectNotSupportedError, () =>  {
+        customElements.define('test-define-extend-valid-name', class {}, { extends: name });
+      });
+    }, `If extends is ${name}, should throw a NotSupportedError`);
+  });
+
+  // 7.2. If the element interface for extends and the HTML namespace is HTMLUnknownElement
+  // (e.g., if extends does not indicate an element definition in this specification),
+  // then throw a NotSupportedError.
+  [
+    // https://html.spec.whatwg.org/multipage/dom.html#elements-in-the-dom:htmlunknownelement
+    'bgsound',
+    'blink',
+    'isindex',
+    'multicol',
+    'nextid',
+    'spacer',
+    'elementnametobeunknownelement',
+  ].forEach(name =>  {
+    test(() =>  {
+      assert_throws(expectNotSupportedError, () =>  {
+        customElements.define('test-define-extend-' + name, class {}, { extends: name });
+      });
+    }, `If extends is ${name}, should throw a NotSupportedError`);
+  });
+
+  // 8. Let observedAttributesIterable be Get(constructor, "observedAttributes").
+  // Rethrow any exceptions.
+  // See step 12 for rethrow tests.
+
+  // 10. Let prototype be Get(constructor, "prototype"). Rethrow any exceptions.
+  function assert_rethrown(func, description) {
+    assert_throws({ name: 'rethrown' }, func, description);
+  }
+  function throw_rethrown_error() {
+    const e = new Error('check this is rethrown');
+    e.name = 'rethrown';
+    throw e;
+  }
+  test(() =>  {
+    // Hack for prototype to throw while IsConstructor is true.
+    const BadConstructor = (function () { }).bind({});
+    Object.defineProperty(BadConstructor, 'prototype', {
+      get() { throw_rethrown_error(); }
+    });
+    assert_rethrown(() =>  {
+      customElements.define('test-define-constructor-prototype-rethrow', BadConstructor);
+    });
+  }, 'If constructor.prototype throws, should rethrow');
+  // 11. If Type(prototype) is not Object,
+  // then throw a TypeError exception.
+  test(() =>  {
+    const c = (function () { }).bind({}); // prototype is undefined.
+    assert_throws(expectTypeError, () =>  {
+      customElements.define('test-define-constructor-prototype-undefined', c);
+    });
+  }, 'If Type(constructor.prototype) is undefined, should throw a TypeError');
+  test(() =>  {
+    function c() {};
+    c.prototype = 'string';
+    assert_throws(expectTypeError, () =>  {
+      customElements.define('test-define-constructor-prototype-string', c);
+    });
+  }, 'If Type(constructor.prototype) is string, should throw a TypeError');
+
+  // 12. Let connectedCallback be Get(prototype, "connectedCallback"). Rethrow any exceptions.
+  // 13. If connectedCallback is not undefined, and IsCallable(connectedCallback) is false,
+  // then throw a TypeError exception.
+  // 14. Let disconnectedCallback be Get(prototype, "disconnectedCallback"). Rethrow any exceptions.
+  // 15. If disconnectedCallback is not undefined, and IsCallable(disconnectedCallback) is false,
+  // then throw a TypeError exception.
+  // 16. Let attributeChangedCallback be Get(prototype, "attributeChangedCallback"). Rethrow any exceptions.
+  // 17. If attributeChangedCallback is not undefined, and IsCallable(attributeChangedCallback) is false,
+  // then throw a TypeError exception.
+  [
+    'observedAttributes', // See step 8 above.
+    'connectedCallback',
+    'disconnectedCallback',
+    'attributeChangedCallback',
+  ].forEach(name =>  {
+    test(() =>  {
+      class C {
+        get [name]() { throw_rethrown_error(); }
+      }
+      assert_rethrown(() =>  {
+        customElements.define('test-define-constructor-rethrow-prototype-' + name, C);
+      });
+    }, `If constructor.prototype.${name} throws, should rethrow`);
+  });
+  [
+    'connectedCallback',
+    'disconnectedCallback',
+    'attributeChangedCallback',
+  ].forEach(name =>  {
+    test(() =>  {
+      class c {};
+      c.prototype[name] = undefined;
+      customElements.define('test-define-constructor-prototype-' + name, c);
+    }, `If constructor.prototype.${name} is undefined, should success`);
+    [
+      [ 'null', null ],
+      [ 'object', {} ],
+    ].forEach(value =>  {
+      test(() =>  {
+        class c {};
+        c.prototype[name] = value[1];
+        assert_throws(expectTypeError, () =>  {
+          customElements.define('test-define-constructor-prototype-' + name, c);
+        });
+      }, `If constructor.prototype.${name} is ${value[0]}, should throw a TypeError`);
+    })
+  });
+})();
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-bubbles-true-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-bubbles-true-expected.txt
new file mode 100644
index 0000000..dbee77a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-bubbles-true-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS In window.document with click event 
+PASS In window.document with load event 
+FAIL In window.document.cloneNode(true) assert_array_equals: targets lengths differ, expected 14 got 0
+FAIL In new Document() Illegal constructor
+PASS In DOMImplementation.createHTMLDocument() 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-bubbles-true.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-bubbles-true.html
new file mode 100644
index 0000000..c9e4e327
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-bubbles-true.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title> Event.bubbles attribute is set to false </title>
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-initevent">
+<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<div id=log></div>
+<table id="table" border="1" style="display: none">
+    <tbody id="table-body">
+    <tr id="table-row">
+        <td id="table-cell">Shady Grove</td>
+        <td>Aeolian</td>
+    </tr>
+    <tr id="parent">
+        <td id="target">Over the river, Charlie</td>
+        <td>Dorian</td>
+    </tr>
+    </tbody>
+</table>
+<script>
+function concatReverse(a) {
+    return a.concat(a.map(function(x) { return x }).reverse());
+}
+
+function targetsForDocumentChain(document) {
+    return [
+        document,
+        document.documentElement,
+        document.getElementsByTagName("body")[0],
+        document.getElementById("table"),
+        document.getElementById("table-body"),
+        document.getElementById("parent")
+    ];
+}
+
+function testChain(document, targetParents, phases, event_type) {
+    var target = document.getElementById("target");
+    var targets = targetParents.concat(target);
+    var expected_targets = concatReverse(targets);
+
+    var actual_targets = [], actual_phases = [];
+    var test_event = function(evt) {
+        actual_targets.push(evt.currentTarget);
+        actual_phases.push(evt.eventPhase);
+    }
+
+    for (var i = 0; i < targets.length; i++) {
+        targets[i].addEventListener(event_type, test_event, true);
+        targets[i].addEventListener(event_type, test_event, false);
+    }
+
+    var evt = document.createEvent("Event");
+    evt.initEvent(event_type, true, true);
+
+    target.dispatchEvent(evt);
+
+    assert_array_equals(actual_targets, expected_targets, "targets");
+    assert_array_equals(actual_phases, phases, "phases");
+}
+
+var phasesForDocumentChain = [
+    Event.CAPTURING_PHASE,
+    Event.CAPTURING_PHASE,
+    Event.CAPTURING_PHASE,
+    Event.CAPTURING_PHASE,
+    Event.CAPTURING_PHASE,
+    Event.CAPTURING_PHASE,
+    Event.AT_TARGET,
+    Event.AT_TARGET,
+    Event.BUBBLING_PHASE,
+    Event.BUBBLING_PHASE,
+    Event.BUBBLING_PHASE,
+    Event.BUBBLING_PHASE,
+    Event.BUBBLING_PHASE,
+    Event.BUBBLING_PHASE,
+];
+
+test(function () {
+    var chainWithWindow = [window].concat(targetsForDocumentChain(document));
+    var phases = [Event.CAPTURING_PHASE].concat(phasesForDocumentChain, Event.BUBBLING_PHASE);
+    testChain(document, chainWithWindow, phases, "click");
+}, "In window.document with click event");
+
+test(function () {
+    testChain(document, targetsForDocumentChain(document), phasesForDocumentChain, "load");
+}, "In window.document with load event")
+
+test(function () {
+    var documentClone = document.cloneNode(true);
+    testChain(
+        documentClone, targetsForDocumentChain(documentClone), phasesForDocumentChain, "click");
+}, "In window.document.cloneNode(true)");
+
+test(function () {
+    var newDocument = new Document();
+    newDocument.appendChild(document.documentElement.cloneNode(true));
+    testChain(
+        newDocument, targetsForDocumentChain(newDocument), phasesForDocumentChain, "click");
+}, "In new Document()");
+
+test(function () {
+    var HTMLDocument = document.implementation.createHTMLDocument();
+    HTMLDocument.body.appendChild(document.getElementById("table").cloneNode(true));
+    testChain(
+        HTMLDocument, targetsForDocumentChain(HTMLDocument), phasesForDocumentChain, "click");
+}, "In DOMImplementation.createHTMLDocument()");
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/ClickFakeEvent.nondocument.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-detached-click.html
similarity index 80%
rename from third_party/WebKit/LayoutTests/imported/wpt/uievents/ClickFakeEvent.nondocument.html
rename to third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-detached-click.html
index 042f08d..01cb7d7 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/ClickFakeEvent.nondocument.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-detached-click.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <title>Click event on an element not in the document</title>
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
 <div id=log></div>
 <script>
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-multiple-stopPropagation-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-multiple-stopPropagation-expected.txt
new file mode 100644
index 0000000..e7b4f8e5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-multiple-stopPropagation-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL  Multiple dispatchEvent() and stopPropagation()  assert_array_equals: lengths differ, expected 1 got 0
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-multiple-stopPropagation.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-multiple-stopPropagation.html
new file mode 100644
index 0000000..d65b5c0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-multiple-stopPropagation.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title> Multiple dispatchEvent() and stopPropagation() </title>
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id=log></div>
+
+<div id="parent" style="display: none">
+    <input id="target" type="hidden" value=""/>
+</div>
+
+<script>
+test(function() {
+    var event_type = "foo";
+    var target = document.getElementById("target");
+    var parent = document.getElementById("parent");
+    var actual_result;
+    var test_event = function(evt) {
+        actual_result.push(evt.currentTarget);
+
+        if (parent == evt.currentTarget) {
+            evt.stopPropagation();
+        }
+    };
+
+    var evt = document.createEvent("Event");
+    evt.initEvent(event_type, true, true);
+
+    target.addEventListener(event_type, test_event, false);
+    parent.addEventListener(event_type, test_event, false);
+    document.addEventListener(event_type, test_event, false);
+    window.addEventListener(event_type, test_event, false);
+
+    actual_result = [];
+    target.dispatchEvent(evt);
+    assert_array_equals(actual_result, [target, parent]);
+
+    actual_result = [];
+    parent.dispatchEvent(evt);
+    assert_array_equals(actual_result, [parent]);
+
+    actual_result = [];
+    document.dispatchEvent(evt);
+    assert_array_equals(actual_result, [document, window]);
+});
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/order-of-events/event-phases-order.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-order.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/imported/wpt/uievents/order-of-events/event-phases-order.html
rename to third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-order.html
index 46ae16d..6b6437eb 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/order-of-events/event-phases-order.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-order.html
@@ -1,5 +1,4 @@
 <!DOCTYPE html>
-<!--  Submitted from TestTWF Paris  -->
 <title>Event phases order</title>
 <script src="../../../../resources/testharness.js"></script>
 <script src="../../../../resources/testharnessreport.js"></script>
@@ -16,13 +15,12 @@
         child.addEventListener('click', this.step_func(function(){ order.push(2) }), false);
         parent.addEventListener('click', this.step_func(function(){ order.push(3) }), false);
 
-        child.click();
+        child.dispatchEvent(new Event('click', {bubbles: true}));
 
         assert_array_equals(order, [1, 2, 3]);
     }));
 }, "Event phases order");
 </script>
-
-    <div id="parent">
-        <div id="child"></div>
-    </div>
+<div id="parent">
+    <div id="child"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-throwing.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-throwing.html
new file mode 100644
index 0000000..eed1cb28f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-dispatch-throwing.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>Throwing in event listeners</title>
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+setup({allow_uncaught_exception:true})
+
+test(function() {
+    var errorEvents = 0;
+    window.onerror = this.step_func(function(e) {
+        assert_equals(typeof e, 'string');
+        ++errorEvents;
+    });
+
+    var element = document.createElement('div');
+
+    element.addEventListener('click', function() {
+        throw new Error('Error from only listener');
+    });
+
+    element.dispatchEvent(new Event('click'));
+
+    assert_equals(errorEvents, 1);
+}, "Throwing in event listener with a single listeners");
+
+test(function() {
+    var errorEvents = 0;
+    window.onerror = this.step_func(function(e) {
+        assert_equals(typeof e, 'string');
+        ++errorEvents;
+    });
+
+    var element = document.createElement('div');
+
+    var secondCalled = false;
+
+    element.addEventListener('click', function() {
+        throw new Error('Error from first listener');
+    });
+    element.addEventListener('click', this.step_func(function() {
+        secondCalled = true;
+    }), false);
+
+    element.dispatchEvent(new Event('click'));
+
+    assert_equals(errorEvents, 1);
+    assert_true(secondCalled);
+}, "Throwing in event listener with multiple listeners");
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/order-of-events/init-event-while-dispatching-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-init-while-dispatching-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/uievents/order-of-events/init-event-while-dispatching-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-init-while-dispatching-expected.txt
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/order-of-events/init-event-while-dispatching.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-init-while-dispatching.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/uievents/order-of-events/init-event-while-dispatching.html
rename to third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-init-while-dispatching.html
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/constructors/constructors-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-subclasses-constructors-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/uievents/constructors/constructors-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-subclasses-constructors-expected.txt
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/constructors/constructors.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-subclasses-constructors.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/uievents/constructors/constructors.html
rename to third_party/WebKit/LayoutTests/imported/wpt/dom/events/Event-subclasses-constructors.html
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/events/EventListener-handleEvent.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/EventListener-handleEvent.html
new file mode 100644
index 0000000..922322e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/EventListener-handleEvent.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>EventListener::handleEvent()</title>
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<div id=log></div>
+<table id="table" border="1" style="display: none">
+    <tbody id="table-body">
+    <tr id="table-row">
+        <td id="table-cell">Shady Grove</td>
+        <td>Aeolian</td>
+    </tr>
+    <tr id="parent">
+        <td id="target">Over the river, Charlie</td>
+        <td>Dorian</td>
+    </tr>
+    </tbody>
+</table>
+<script>
+test(function(t) {
+    var event = "foo";
+    var target = document.getElementById("target");
+
+    var event_listener = {
+        "handleEvent": function(evt) {
+            var that = this;
+            t.step(function() {
+                assert_equals(evt.type, event);
+                assert_equals(evt.target, target);
+                assert_equals(that, event_listener);
+            });
+        }
+    };
+
+    var evt = document.createEvent("Event");
+    evt.initEvent(event, true, true);
+
+    target.addEventListener(event, event_listener, true);
+    target.dispatchEvent(evt);
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/events/EventListenerOptions-capture.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/EventListenerOptions-capture.html
new file mode 100644
index 0000000..dc58ec6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/events/EventListenerOptions-capture.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>EventListenerOptions.capture</title>
+<link rel="author" title="Rick Byers" href="mailto:rbyers@chromium.org">
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-eventlisteneroptions-capture">
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<div id="log"></div>
+
+<script>
+
+function testCaptureValue(captureValue, expectedValue) {
+  var handlerPhase = undefined;
+  var handler = function handler(e) {
+    assert_equals(handlerPhase, undefined, "Handler invoked after remove");
+    handlerPhase = e.eventPhase;
+  }
+  document.addEventListener('test', handler, captureValue);
+  document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+  document.removeEventListener('test', handler, captureValue);
+  document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+  assert_equals(handlerPhase, expectedValue, "Incorrect event phase for value: " + JSON.stringify(captureValue));
+}
+
+test(function() {
+  testCaptureValue(true, Event.CAPTURING_PHASE);
+  testCaptureValue(false, Event.BUBBLING_PHASE);
+  testCaptureValue(null, Event.BUBBLING_PHASE);
+  testCaptureValue(undefined, Event.BUBBLING_PHASE);
+  testCaptureValue(2.3, Event.CAPTURING_PHASE);
+  testCaptureValue(-1000.3, Event.CAPTURING_PHASE);
+  testCaptureValue(NaN, Event.BUBBLING_PHASE);
+  testCaptureValue(+0.0, Event.BUBBLING_PHASE);
+  testCaptureValue(-0.0, Event.BUBBLING_PHASE);
+  testCaptureValue("", Event.BUBBLING_PHASE);
+  testCaptureValue("AAAA", Event.CAPTURING_PHASE);
+}, "Capture boolean should be honored correctly");
+
+test(function() {
+  testCaptureValue({}, Event.BUBBLING_PHASE);
+  testCaptureValue({capture:true}, Event.CAPTURING_PHASE);
+  testCaptureValue({capture:false}, Event.BUBBLING_PHASE);
+  testCaptureValue({capture:2}, Event.CAPTURING_PHASE);
+  testCaptureValue({capture:0}, Event.BUBBLING_PHASE);
+}, "Capture option should be honored correctly");
+
+test(function() {
+  var supportsCapture = false;
+  var query_options = {
+    get capture() {
+      supportsCapture = true;
+      return false;
+    },
+    get dummy() {
+      assert_unreached("dummy value getter invoked");
+      return false;
+    }
+  };
+
+  document.addEventListener('test_event', null, query_options);
+  assert_true(supportsCapture, "addEventListener doesn't support the capture option");
+  supportsCapture = false;
+  document.removeEventListener('test_event', null, query_options);
+  assert_true(supportsCapture, "removeEventListener doesn't support the capture option");
+}, "Supports capture option");
+
+function testOptionEquality(addOptionValue, removeOptionValue, expectedEquality) {
+  var handlerInvoked = false;
+  var handler = function handler(e) {
+    assert_equals(handlerInvoked, false, "Handler invoked multiple times");
+    handlerInvoked = true;
+  }
+  document.addEventListener('test', handler, addOptionValue);
+  document.removeEventListener('test', handler, removeOptionValue);
+  document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+  assert_equals(!handlerInvoked, expectedEquality, "equivalence of options " +
+    JSON.stringify(addOptionValue) + " and " + JSON.stringify(removeOptionValue));
+  if (handlerInvoked)
+    document.removeEventListener('test', handler, addOptionValue);
+}
+
+test(function() {
+  // Option values that should be treated as equivalent
+  testOptionEquality({}, false, true);
+  testOptionEquality({capture: false}, false, true);
+  testOptionEquality(true, {capture: true}, true);
+  testOptionEquality({capture: null}, undefined, true);
+  testOptionEquality({capture: true}, {dummy: false, capture: 1}, true);
+  testOptionEquality({dummy: true}, false, true);
+
+  // Option values that should be treated as distinct
+  testOptionEquality(true, false, false);
+  testOptionEquality(true, {capture:false}, false);
+  testOptionEquality({}, true, false);
+
+}, "Equivalence of option values");
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/dom/interfaces-expected.txt
index bce9d42..3b6d568 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/dom/interfaces-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/interfaces-expected.txt
@@ -70,7 +70,7 @@
             fn.apply(obj, args);
         }" did not throw
 PASS CustomEvent interface: existence and properties of interface object 
-FAIL CustomEvent interface object length assert_equals: wrong value for CustomEvent.length expected 1 but got 0
+PASS CustomEvent interface object length 
 PASS CustomEvent interface object name 
 FAIL CustomEvent interface: existence and properties of interface prototype object assert_equals: class string of CustomEvent.prototype expected "[object CustomEventPrototype]" but got "[object CustomEvent]"
 PASS CustomEvent interface: existence and properties of interface prototype object's "constructor" property 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/lists/DOMTokenList-coverage-for-attributes-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/dom/lists/DOMTokenList-coverage-for-attributes-expected.txt
index f980ab3..b4dee7a1 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/dom/lists/DOMTokenList-coverage-for-attributes-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/lists/DOMTokenList-coverage-for-attributes-expected.txt
@@ -69,41 +69,6 @@
 PASS output.dropzone in null namespace should be undefined. 
 PASS td.dropzone in null namespace should be undefined. 
 PASS th.dropzone in null namespace should be undefined. 
-PASS a.headers in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS area.headers in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS link.headers in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS iframe.headers in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS output.headers in http://www.w3.org/1999/xhtml namespace should be undefined. 
-FAIL td.headers in http://www.w3.org/1999/xhtml namespace should be DOMTokenList. assert_equals: expected "[object DOMTokenList]" but got "[object String]"
-FAIL th.headers in http://www.w3.org/1999/xhtml namespace should be DOMTokenList. assert_equals: expected "[object DOMTokenList]" but got "[object String]"
-PASS a.headers in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS area.headers in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS link.headers in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS iframe.headers in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS output.headers in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS td.headers in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS th.headers in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS a.headers in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS area.headers in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS link.headers in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS iframe.headers in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS output.headers in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS td.headers in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS th.headers in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS a.headers in http://example.com/ namespace should be undefined. 
-PASS area.headers in http://example.com/ namespace should be undefined. 
-PASS link.headers in http://example.com/ namespace should be undefined. 
-PASS iframe.headers in http://example.com/ namespace should be undefined. 
-PASS output.headers in http://example.com/ namespace should be undefined. 
-PASS td.headers in http://example.com/ namespace should be undefined. 
-PASS th.headers in http://example.com/ namespace should be undefined. 
-PASS a.headers in null namespace should be undefined. 
-PASS area.headers in null namespace should be undefined. 
-PASS link.headers in null namespace should be undefined. 
-PASS iframe.headers in null namespace should be undefined. 
-PASS output.headers in null namespace should be undefined. 
-PASS td.headers in null namespace should be undefined. 
-PASS th.headers in null namespace should be undefined. 
 PASS a.htmlFor in http://www.w3.org/1999/xhtml namespace should be undefined. 
 PASS area.htmlFor in http://www.w3.org/1999/xhtml namespace should be undefined. 
 PASS link.htmlFor in http://www.w3.org/1999/xhtml namespace should be undefined. 
@@ -139,41 +104,6 @@
 PASS output.htmlFor in null namespace should be undefined. 
 PASS td.htmlFor in null namespace should be undefined. 
 PASS th.htmlFor in null namespace should be undefined. 
-FAIL a.ping in http://www.w3.org/1999/xhtml namespace should be DOMTokenList. assert_equals: expected "[object DOMTokenList]" but got "[object String]"
-FAIL area.ping in http://www.w3.org/1999/xhtml namespace should be DOMTokenList. assert_equals: expected "[object DOMTokenList]" but got "[object String]"
-PASS link.ping in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS iframe.ping in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS output.ping in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS td.ping in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS th.ping in http://www.w3.org/1999/xhtml namespace should be undefined. 
-PASS a.ping in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS area.ping in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS link.ping in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS iframe.ping in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS output.ping in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS td.ping in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS th.ping in http://www.w3.org/2000/svg namespace should be undefined. 
-PASS a.ping in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS area.ping in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS link.ping in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS iframe.ping in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS output.ping in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS td.ping in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS th.ping in http://www.w3.org/1998/Math/MathML namespace should be undefined. 
-PASS a.ping in http://example.com/ namespace should be undefined. 
-PASS area.ping in http://example.com/ namespace should be undefined. 
-PASS link.ping in http://example.com/ namespace should be undefined. 
-PASS iframe.ping in http://example.com/ namespace should be undefined. 
-PASS output.ping in http://example.com/ namespace should be undefined. 
-PASS td.ping in http://example.com/ namespace should be undefined. 
-PASS th.ping in http://example.com/ namespace should be undefined. 
-PASS a.ping in null namespace should be undefined. 
-PASS area.ping in null namespace should be undefined. 
-PASS link.ping in null namespace should be undefined. 
-PASS iframe.ping in null namespace should be undefined. 
-PASS output.ping in null namespace should be undefined. 
-PASS td.ping in null namespace should be undefined. 
-PASS th.ping in null namespace should be undefined. 
 FAIL a.relList in http://www.w3.org/1999/xhtml namespace should be DOMTokenList. assert_equals: expected "[object DOMTokenList]" but got "[object Undefined]"
 FAIL area.relList in http://www.w3.org/1999/xhtml namespace should be DOMTokenList. assert_equals: expected "[object DOMTokenList]" but got "[object Undefined]"
 PASS link.relList in http://www.w3.org/1999/xhtml namespace should be DOMTokenList. 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/lists/DOMTokenList-coverage-for-attributes.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/lists/DOMTokenList-coverage-for-attributes.html
index 568b195..6b92890 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/dom/lists/DOMTokenList-coverage-for-attributes.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/lists/DOMTokenList-coverage-for-attributes.html
@@ -12,9 +12,7 @@
   {attr: "classList", sup: ["anyElement"]},
   // Defined in HTML
   {attr: "dropzone", sup: ["anyHTMLElement"]},
-  {attr: "headers", sup: ["td", "th"]},
   {attr: "htmlFor", sup: ["output"]},
-  {attr: "ping", sup: ["a", "area"]},
   {attr: "relList", sup: ["a", "area", "link"]},
   {attr: "sandbox", sup: ["iframe"]},
   {attr: "sizes", sup: ["link"]}
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Element-classlist-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Element-classlist-expected.txt
index 5ae14cc6..2a1ac5db 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Element-classlist-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Element-classlist-expected.txt
@@ -75,5 +75,7 @@
 FAIL classList.add should treat \f as a space assert_equals: expected "a b" but got "a\fb"
 PASS classList.length must be read-only 
 PASS classList must have [PutForwards=value] 
+FAIL classList.replace should work foo.classList.replace is not a function
+PASS classList.supports should throw 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Element-classlist.html b/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Element-classlist.html
index 2384c62..0c09299 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Element-classlist.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/dom/nodes/Element-classlist.html
@@ -377,6 +377,26 @@
   assert_equals(secondelem.classList[0],'foo');
   assert_equals(secondelem.classList[1],'bar');
 }, 'classList must have [PutForwards=value]');
+test(function () {
+  var foo = document.createElement('div');
+  foo.className = 'a';
+  foo.classList.replace('token1', 'token2');
+
+  assert_equals(foo.className, 'a');
+
+  foo.classList.replace('a', 'b');
+  assert_equals(foo.className, 'b');
+
+  assert_throws('SYNTAX_ERR', function () { foo.classList.replace('t with space', '') });
+  assert_throws('INVALID_CHARACTER_ERR', function () { foo.classList.replace('t with space', 'foo') });
+  assert_throws('SYNTAX_ERR', function () { foo.classList.replace('', 'foo') });
+}, 'classList.replace should work');
+
+test(function() {
+  var foo = document.createElement('div');
+  assert_throws(new TypeError(),
+                function() { foo.classList.supports('hello') });
+}, 'classList.supports should throw');
     </script>
   </head>
   <body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/hr-time/basic.html b/third_party/WebKit/LayoutTests/imported/wpt/hr-time/basic.html
index fe8a7e7..1ba4202 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/hr-time/basic.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/hr-time/basic.html
@@ -28,12 +28,12 @@
   // Check whether the performance.now() method is close to Date() within 30ms (due to inaccuracies)
   var initial_hrt = performance.now();
   var initial_date = Date.now();
-  setTimeout(this.step_func(function() {
+  this.step_timeout(function() {
     var final_hrt = performance.now();
     var final_date = Date.now();
     assert_approx_equals(final_hrt - initial_hrt, final_date - initial_date, 30, 'High resolution time value increased by approximately the same amount as time from date object');
     this.done();
-  }), 2000);
+  }, 2000);
 }, 'High resolution time has approximately the right relative magnitude');
 </script>
 </head>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/hr-time/test_cross_frame_start.html b/third_party/WebKit/LayoutTests/imported/wpt/hr-time/test_cross_frame_start.html
index 1221ad6..db1df69 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/hr-time/test_cross_frame_start.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/hr-time/test_cross_frame_start.html
@@ -12,13 +12,16 @@
         <script type="text/javascript">
             setup({explicit_done: true});
 
+            var setup_frame = async_test("Setup the frame");
+
             function start_test() {
-              setTimeout(function() {
+              setup_frame.step_timeout(function () {
                 var iframe = document.createElement('iframe');
                 iframe.id = 'frameContext';
                 iframe.onload = finish_test;
                 iframe.src = "resources/now_frame.html";
                 document.body.appendChild(iframe);
+                setup_frame.done();
               }, 1000);
             }
 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html
deleted file mode 100644
index 73ca6072..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html>
-<meta name=timeout content=long>
-<title>Precedence of scroll restoration mode over fragment scrolling in cross-origin history traversal</title>
-<style>
-  iframe {
-    height: 300px;
-    width: 300px;
-  }
-</style>
-
-<body>
-  <iframe></iframe>
-</body>
-
-<script src="../../../../../../../resources/testharness.js"></script>
-<script src="../../../../../../../resources/testharnessreport.js"></script>
-<script type="text/javascript">
-  'use strict';
-
-  // The test does the following navigation steps for iframe
-  // 1. load page-with-fragment.html#fragment
-  // 2. load blank1
-  // 3. go back to page-with-fragment.html
-  async_test(function(t) {
-    var iframe = document.querySelector('iframe');
-    var baseURL = location.href.substring(0, location.href.lastIndexOf('/'));
-
-    var steps = [
-      function() {
-        iframe.src = 'resources/page-with-fragment.html#fragment';
-      }, function() {
-        assert_equals(iframe.contentWindow.location.href, baseURL + '/resources/page-with-fragment.html#fragment', 'should be on page-with-fragment page');
-        // wait one animation frame to ensure layout is run and fragment scrolling is complete
-        iframe.contentWindow.requestAnimationFrame(function() {
-          assert_equals(iframe.contentWindow.scrollY, 800, 'should scroll to fragment');
-
-          iframe.contentWindow.history.scrollRestoration = 'manual';
-          assert_equals(iframe.contentWindow.history.scrollRestoration, 'manual');
-          setTimeout(next, 0);
-        });
-      }, function() {
-        // navigate to a new page from a different origin
-        iframe.src = iframe.src.replace("http://", "http://www.").replace("page-with-fragment.html#fragment", "blank1.html");
-      }, function() {
-        // going back causes the iframe to traverse back
-        history.back();
-      }, function() {
-        // coming back from history, scrollRestoration should be set to manual and respected
-        assert_equals(iframe.contentWindow.location.href, baseURL + '/resources/page-with-fragment.html#fragment', 'should be back on page-with-fragment page');
-        iframe.contentWindow.requestAnimationFrame(function() {
-          assert_equals(iframe.contentWindow.history.scrollRestoration, 'manual', 'navigating back should retain scrollRestoration value');
-          assert_equals(iframe.contentWindow.scrollX, 0, 'should not scroll to fragment');
-          assert_equals(iframe.contentWindow.scrollY, 0, 'should not scroll to fragment');
-          t.done();
-        });
-      }
-    ];
-
-    var stepCount = 0;
-    var next = t.step_func(function() {
-      steps[stepCount++]();
-    });
-
-    iframe.onload = next;
-    next();
-  }, 'Manual scroll restoration should take precedent over scrolling to fragment in cross origin navigation');
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-samedoc.html b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-samedoc.html
deleted file mode 100644
index 83ebe3d..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-samedoc.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!DOCTYPE html>
-<style>
-  body {
-    height: 2000px;
-    width: 2000px;
-  }
-
-  #fragment {
-    position: absolute;
-    top: 800px;
-    background-color: #faa;
-    display: block;
-    height: 100px;
-    width: 100px;
-  }
-</style>
-
-<body>
-  <a id="fragment" name="fragment" class='box'></a>
-</body>
-
-<script src="../../../../../../../resources/testharness.js"></script>
-<script src="../../../../../../../resources/testharnessreport.js"></script>
-<script type="text/javascript">
-  'use strict';
-
-  async_test(function(t) {
-    history.scrollRestoration = 'manual';
-    assert_equals(history.scrollRestoration, 'manual');
-
-    location.hash = '#fragment';
-    assert_equals(window.scrollY, 800, 'new navigations should scroll to fragment');
-
-    // create a new entry and reset the scroll before verification
-    history.pushState(null, null, '#done');
-    window.scrollTo(0, 0);
-    assert_equals(window.scrollY, 0, 'should reset scroll before verification');
-
-    setTimeout(function() {
-      // setup verification
-      window.addEventListener('hashchange', t.step_func(function() {
-        assert_equals(location.hash, '#fragment');
-        assert_equals(history.scrollRestoration, 'manual');
-        // navigating back should give precedent to history restoration which is 'manual'
-        assert_equals(window.scrollX, 0, 'should not scroll to fragment');
-        assert_equals(window.scrollY, 0, 'should not scroll to fragment');
-        t.done();
-      }));
-      // kick off verification
-      window.history.back();
-    }, 0);
-
-  }, 'Manual scroll restoration should take precedent over scrolling to fragment in cross doc navigation');
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-navigation-cross-origin.html b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-navigation-cross-origin.html
deleted file mode 100644
index 29b56d8..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-navigation-cross-origin.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE html>
-<meta name=timeout content=long>
-<title>Correct behaviour of scroll restoration mode is cross origin history traversal</title>
-
-<style>
-  iframe {
-    height: 300px;
-    width: 300px;
-  }
-</style>
-
-<body>
-  <iframe></iframe>
-</body>
-
-<script src="../../../../../../../resources/testharness.js"></script>
-<script src="../../../../../../../resources/testharnessreport.js"></script>
-<script type="text/javascript">
-  'use strict';
-
-  // The test does the following navigation steps for iframe
-  // 1. load blank1
-  // 2. load blank2
-  // 3. go back to blank1
-  async_test(function(t) {
-    var iframe = document.querySelector('iframe');
-    var baseURL = location.href.substring(0, location.href.lastIndexOf('/'));
-
-    var steps = [
-      function() {
-        iframe.src = 'resources/blank1.html';
-      },
-      function() {
-        assert_equals(iframe.contentWindow.location.href, baseURL + '/resources/blank1.html', 'should be on first blank page');
-        iframe.contentWindow.history.scrollRestoration = 'manual';
-        assert_equals(iframe.contentWindow.history.scrollRestoration, 'manual');
-        iframe.contentWindow.scrollTo(500, 500);
-        assert_equals(iframe.contentWindow.scrollX, 500, 'scripted scrolling should take effect');
-        assert_equals(iframe.contentWindow.scrollY, 500, 'scripted scrolling should take effect');
-        setTimeout(next, 0);
-      },
-      function() {
-        // navigate to new page
-        iframe.src = 'resources/blank2.html';
-      },
-      function() {
-        assert_equals(iframe.contentWindow.location.href, baseURL + '/resources/blank2.html', 'should be on second blank page');
-        assert_equals(iframe.contentWindow.history.scrollRestoration, 'auto', 'new page loads should set scrollRestoration to "auto"');
-        setTimeout(next, 0);
-      }, function() {
-        iframe.contentWindow.history.back();
-      }, function() {
-        // coming back scrollRestoration should be restored to 'manual' and respected
-        assert_equals(iframe.contentWindow.location.href, baseURL + '/resources/blank1.html', 'should be back on first blank page');
-        assert_equals(iframe.contentWindow.history.scrollRestoration, 'manual', 'navigating back should retain scrollRestoration value');
-        assert_equals(iframe.contentWindow.scrollX, 0, 'horizontal scroll offset should not be restored');
-        assert_equals(iframe.contentWindow.scrollY, 0, 'vertical scroll offset should not be restored');
-        t.done();
-      }
-    ];
-
-    var stepCount = 0;
-    var next = t.step_func(function() {
-      steps[stepCount++]();
-    });
-
-    iframe.onload = next;
-    next();
-  }, 'Navigating to new page should reset to "auto" and navigating back should restore and respect scroll restoration mode');
-
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref-expected.html b/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref-expected.html
deleted file mode 100644
index 9edfaa37..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref-expected.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!doctype html>
-<meta charset="utf-8">
-<title>Unrecognized type should fallback as text type</title>
-<link rel="match" href="unrecognized-type-should-fallback-as-text-type-ref.html">
-<body>
-  <input type="text">
-  <input type="text">
-</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref.html b/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref.html
deleted file mode 100644
index 9edfaa37..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!doctype html>
-<meta charset="utf-8">
-<title>Unrecognized type should fallback as text type</title>
-<link rel="match" href="unrecognized-type-should-fallback-as-text-type-ref.html">
-<body>
-  <input type="text">
-  <input type="text">
-</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-ref-expected.html b/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-expected.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-ref-expected.html
rename to third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-expected.html
index f662a68..fc66a0f 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-ref-expected.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-expected.html
@@ -2,7 +2,6 @@
 <html>
 <head>
 <meta charset=utf-8>
-<link rel="match" href="div-align-ref.html">
 <style>
 .test { width: 50px; background-color: yellow; }
 .center { text-align: center; }
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html b/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html
deleted file mode 100644
index f662a68..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html
+++ /dev/null
@@ -1,77 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset=utf-8>
-<link rel="match" href="div-align-ref.html">
-<style>
-.test { width: 50px; background-color: yellow; }
-.center { text-align: center; }
-.center .test { margin: 0 auto; }
-.left { text-align: left; }
-.left .test { margin-right: auto; }
-.right { text-align: right; }
-.right .test { margin-left: auto; }
-.rtl { direction: rtl; }
-.ltr { direction: ltr; }
-.left .margin { margin-left: 1em; }
-.right .margin { margin-right: 1em; }
-</style>
-</head>
-<body>
-<!--  Centered tests  -->
-<div class=center>
-<div class=test>t א</div>
-<div class="test rtl">t א</div>
-<div class="test margin">t א</div>
-</div>
-
-<div class=center>
-<div class="test left">t א</div>
-<div class="test right">t א</div>
-</div>
-
-<div class=left>
-<div class=center>
-<div class=test>t א</div>
-</div>
-</div>
-
-<!--  Left-aligned tests  -->
-<div class=left>
-<div class=test>t א</div>
-<div class="test rtl">t א</div>
-<div class="test margin">t א</div>
-</div>
-
-<div class="left rtl">
-<div class=test>t א</div>
-<div class="test ltr">t א</div>
-<div class="test margin">t א</div>
-</div>
-
-<div class=left>
-<div class="test center">t א</div>
-<div class="test right">t א</div>
-</div>
-
-<!--  Right-aligned tests  -->
-<div class=right>
-<div class=test>t א</div>
-<div class="test rtl">t א</div>
-<div class="test margin">t א</div>
-</div>
-
-<div class="right rtl">
-<div class=test>t א</div>
-<div class="test ltr">t א</div>
-<div class="test margin">t א</div>
-</div>
-
-<div class=right>
-<div class="test left">t א</div>
-<div class="test center">t א</div>
-</div>
-
-</body>
-</html>
-
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align.html b/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align.html
new file mode 100644
index 0000000..209678f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/rendering/non-replaced-elements/flow-content-0/div-align.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<link rel="match" href="div-align-ref.html">
+<style>
+.test { width: 50px; background-color: yellow; }
+.rtl { direction: rtl; }
+.ltr { direction: ltr; }
+[align=left] .margin { margin-left: 1em }
+[align=right] .margin { margin-right: 1em }
+</style>
+</head>
+<body>
+<!--  Centered tests  -->
+<div align=center>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=center>
+<div class=test align=left>t א</div>
+<div class=test align=right>t א</div>
+</div>
+
+<div align=left>
+<div align=center>
+<div class=test>t א</div>
+</div>
+</div>
+
+<!--  Left-aligned tests  -->
+<div align=left>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=left class=rtl>
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=left>
+<div class=test align=center>t א</div>
+<div class=test align=right>t א</div>
+</div>
+
+<!--  Right-aligned tests  -->
+<div align=right>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=right class=rtl>
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=right>
+<div class=test align=left>t א</div>
+<div class=test align=center>t א</div>
+</div>
+
+</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/resources/common.js b/third_party/WebKit/LayoutTests/imported/wpt/html/resources/common.js
index 5d3afd64..12e0fe77 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/resources/common.js
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/resources/common.js
@@ -32,7 +32,7 @@
 
 // https://html.spec.whatwg.org/multipage/multipage/forms.html#form-associated-element
 var HTML5_FORM_ASSOCIATED_ELEMENTS = [ 'button', 'fieldset', 'input', 'keygen',
-        'label', 'object', 'output', 'select', 'textarea' ];
+        'object', 'output', 'select', 'textarea' ];
 
 function newDocument() {
     var d = document.implementation.createDocument();
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-base-element/base_href_invalid-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-base-element/base_href_invalid-expected.txt
new file mode 100644
index 0000000..f6ccbfe0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-base-element/base_href_invalid-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL base element with unparseable href should have .href getter return attr value assert_equals: expected "//test:test" but got ""
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-base-element/base_href_invalid.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-base-element/base_href_invalid.html
new file mode 100644
index 0000000..12f55e5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-base-element/base_href_invalid.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>base element with unparseable href should have .href getter return attr value</title>
+<script src=../../../../../../resources/testharness.js></script>
+<script src=../../../../../../resources/testharnessreport.js></script>
+<script>
+test(function() {
+  var b = document.createElement("base");
+  b.setAttribute("href", "//test:test");
+  assert_equals(b.href, "//test:test");
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-link-element/link-rellist.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-link-element/link-rellist.html
index 9728991..9e62d87 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-link-element/link-rellist.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-link-element/link-rellist.html
@@ -19,5 +19,7 @@
   assert_equals(list.contains(NaN), true); //"NaN"
   assert_equals(list.contains(+Infinity), true); //"Infinity"
   assert_equals(list.contains(-Infinity), false); //"-Infinity"
+  assert_equals(list.supports("stylesheet"), true);
+  assert_equals(list.supports("nosuchrelvalueever"), false);
 });
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-style-element/style-error-01.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-style-element/style-error-01.html
deleted file mode 100644
index 398ac27..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/document-metadata/the-style-element/style-error-01.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html>
-<title>style: error events</title>
-<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
-<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-style-element">
-<script src="../../../../../../resources/testharness.js"></script>
-<script src="../../../../../../resources/testharnessreport.js"></script>
-<div id="log"></div>
-<div id="test">
-<script>
-//var t404 = async_test("Should get an error event for a 404 error.")
-//t404.step(function() {
-//  var elt = document.createElement("style");
-//  elt.onerror = t404.step_func(function() {
-//    assert_true(true, "Got error event for 404 error.")
-//    t404.done()
-//  })
-//  elt.appendChild(
-//    document.createTextNode('@import 404 error;'));
-//  document.getElementsByTagName("head")[0].appendChild(elt);
-//})
-var tText = async_test("Should get an error event for a text/plain response.")
-tText.step(function() {
-  var elt = document.createElement("style");
-  elt.onerror = tText.step_func(function() {
-    assert_true(true, "Got error event for 404 error.")
-    tText.done()
-  })
-  elt.appendChild(
-    document.createTextNode('@import "../../../../common/css-red.txt";'));
-  document.getElementsByTagName("head")[0].appendChild(elt);
-})
-</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind-expected.txt
deleted file mode 100644
index 14f5136..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind-expected.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-This is a testharness.js-based test.
-PASS HTMLTrackElement.kind missing value 
-FAIL HTMLTrackElement.kind invalid value in content attribute assert_equals: expected "subtitles" but got "metadata"
-PASS HTMLTrackElement.kind content attribute uppercase 
-FAIL HTMLTrackElement.kind content attribute with uppercase turkish I (with dot) assert_equals: expected "subtitles" but got "metadata"
-FAIL HTMLTrackElement.kind content attribute with lowercase turkish i (dotless) assert_equals: expected "subtitles" but got "metadata"
-PASS HTMLTrackElement.kind content attribute "subtitles" 
-PASS HTMLTrackElement.kind content attribute "captions" 
-PASS HTMLTrackElement.kind content attribute "descriptions" 
-PASS HTMLTrackElement.kind content attribute "chapters" 
-PASS HTMLTrackElement.kind content attribute "metadata" 
-FAIL HTMLTrackElement.kind content attribute "captions\u0000" assert_equals: expected "subtitles" but got "metadata"
-PASS HTMLTrackElement.kind setting IDL attribute to "subtitles" 
-PASS HTMLTrackElement.kind setting IDL attribute to "captions" 
-PASS HTMLTrackElement.kind setting IDL attribute to "descriptions" 
-PASS HTMLTrackElement.kind setting IDL attribute to "chapters" 
-PASS HTMLTrackElement.kind setting IDL attribute to "metadata" 
-PASS HTMLTrackElement.kind setting IDL attribute to "CAPTIONS" 
-FAIL HTMLTrackElement.kind setting IDL attribute with uppercase turkish I (with dot) assert_equals: expected "subtitles" but got "metadata"
-FAIL HTMLTrackElement.kind setting IDL attribute with lowercase turkish I (dotless) assert_equals: expected "subtitles" but got "metadata"
-FAIL HTMLTrackElement.kind setting IDL attribute with \u0000 assert_equals: expected "subtitles" but got "metadata"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html
index b59757d..2f10a11 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html
@@ -13,7 +13,7 @@
 test(function(){
     var track = document.createElement('track');
     track.setAttribute('kind', 'invalid');
-    assert_equals(track.kind, 'subtitles');
+    assert_equals(track.kind, 'metadata');
     assert_equals(track.getAttribute('kind'), 'invalid');
 }, document.title + ' invalid value in content attribute');
 
@@ -27,14 +27,14 @@
 test(function(){
     var track = document.createElement('track');
     track.setAttribute('kind', 'CAPT\u0130ONS');
-    assert_equals(track.kind, 'subtitles');
+    assert_equals(track.kind, 'metadata');
     assert_equals(track.getAttribute('kind'), 'CAPT\u0130ONS');
 }, document.title + ' content attribute with uppercase turkish I (with dot)');
 
 test(function(){
     var track = document.createElement('track');
     track.setAttribute('kind', 'capt\u0131ons');
-    assert_equals(track.kind, 'subtitles');
+    assert_equals(track.kind, 'metadata');
     assert_equals(track.getAttribute('kind'), 'capt\u0131ons');
 }, document.title + ' content attribute with lowercase turkish i (dotless)');
 
@@ -76,7 +76,7 @@
 test(function(){
     var track = document.createElement('track');
     track.setAttribute('kind', 'captions\u0000');
-    assert_equals(track.kind, 'subtitles');
+    assert_equals(track.kind, 'metadata');
     assert_equals(track.getAttribute('kind'), 'captions\u0000');
 }, document.title + ' content attribute "captions\\u0000"');
 
@@ -126,21 +126,21 @@
     var track = document.createElement('track');
     track.kind = 'CAPT\u0130ONS';
     assert_equals(track.getAttribute('kind'), 'CAPT\u0130ONS');
-    assert_equals(track.kind, 'subtitles');
+    assert_equals(track.kind, 'metadata');
 }, document.title + ' setting IDL attribute with uppercase turkish I (with dot)');
 
 test(function(){
     var track = document.createElement('track');
     track.kind = 'capt\u0131ons';
     assert_equals(track.getAttribute('kind'), 'capt\u0131ons');
-    assert_equals(track.kind, 'subtitles');
+    assert_equals(track.kind, 'metadata');
 }, document.title + ' setting IDL attribute with lowercase turkish I (dotless)');
 
 test(function(){
     var track = document.createElement('track');
     track.kind = 'captions\u0000';
     assert_equals(track.getAttribute('kind'), 'captions\u0000');
-    assert_equals(track.kind, 'subtitles');
+    assert_equals(track.kind, 'metadata');
 }, document.title + ' setting IDL attribute with \\u0000');
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind-expected.txt
deleted file mode 100644
index cb5797a5..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-PASS TextTrack.kind, addTextTrack 
-PASS TextTrack.kind, track element 
-FAIL TextTrack.kind, \u0000 assert_equals: expected "subtitles" but got "metadata"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html
index cd34fe1..12e432c 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html
@@ -26,6 +26,6 @@
 test(function(){
     var track = document.createElement('track');
     track.kind = 'captions\u0000';
-    assert_equals(track.track.kind, 'subtitles');
+    assert_equals(track.track.kind, 'metadata');
 }, document.title+', \\u0000');
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html
deleted file mode 100644
index 6922e51..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype html>
-<title>NOT invoking resource selection with new Audio() sans src</title>
-<script src="../../../../../../../resources/testharness.js"></script>
-<script src="../../../../../../../resources/testharnessreport.js"></script>
-<div id=log></div>
-<script>
-async_test(function(t) {
-  var a = new Audio();
-  assert_equals(a.networkState, a.NETWORK_EMPTY);
-  a.onloadstart = t.step_func(function() { assert_unreached(); });
-  window.onload = t.step_func(function() { t.done(); });
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html
deleted file mode 100644
index af5098b..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!doctype html>
-<title>NOT invoking resource selection by inserting &lt;source> in the wrong namespace</title>
-<script src="../../../../../../../resources/testharness.js"></script>
-<script src="../../../../../../../resources/testharnessreport.js"></script>
-<div id=log></div>
-<video></video>
-<script>
-async_test(function(t) {
-  var v = document.querySelector('video');
-  v.onloadstart = t.step_func(function() { assert_unreached(); });
-  v.appendChild(document.createElementNS('bogus','source'));
-  window.onload = t.step_func(function() { t.done(); });
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html
deleted file mode 100644
index 301754bc..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype html>
-<title>invoking load by setting src on video not in a document</title>
-<script src="../../../../../../../resources/testharness.js"></script>
-<script src="../../../../../../../resources/testharnessreport.js"></script>
-<div id=log></div>
-<script>
-async_test(function(t) {
-  var v = document.createElement('video');
-  v.onloadstart = t.step_func(function() { t.done(); });
-  v.setAttribute('src','');
-  window.onload = t.step_func(function() { assert_unreached(); });
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe-load-event-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe-load-event-expected.txt
new file mode 100644
index 0000000..b8ee307
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe-load-event-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+FAIL load event of blob URL assert_true: The iframe element should represent a nested browsing context. expected true got false
+FAIL load event of initial about:blank assert_true: The object element should represent a nested browsing context. expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html
new file mode 100644
index 0000000..244a740e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test some sanity behavior around iframe load/error events</title>
+<script src=../../../../../../resources/testharness.js></script>
+<script src=../../../../../../resources/testharnessreport.js></script>
+<body>
+<script>
+async_test(function(t) {
+  var obj = document.createElement("iframe");
+  obj.onload = t.step_func_done(function(e){
+    assert_true(obj.contentWindow instanceof Window, "The iframe element should represent a nested browsing context.")
+    assert_equals(Object.getPrototypeOf(e).constructor, Event, "The load event should use the Event interface.");
+    assert_true(e.isTrusted, "The load event should be a trusted event.");
+    assert_false(e.cancelable, "The load event should not be a cancelable event.");
+    assert_false(e.bubbles, "The load event should not be a bubble event.");
+    assert_equals(e.target, obj, "The load event target should be the corresponding object element.");
+  });
+
+  obj.onerror = t.step_func_done(function(e){
+    assert_unreached("The error event should not be fired.");
+  });
+
+  var url = URL.createObjectURL(new Blob([""], { type: "text/html" }));
+
+  obj.src = url;
+  document.body.appendChild(obj);
+}, "load event of blob URL");
+
+async_test(function(t) {
+  var obj = document.createElement("iframe");
+  obj.onload = t.step_func_done(function(e){
+    assert_true(obj.contentWindow instanceof Window, "The object element should represent a nested browsing context.")
+    assert_equals(Object.getPrototypeOf(e).constructor, Event, "The load event should use the Event interface.");
+    assert_true(e.isTrusted, "The load event should be a trusted event.");
+    assert_false(e.cancelable, "The load event should not be a cancelable event.");
+    assert_false(e.bubbles, "The load event should not be a bubble event.");
+    assert_equals(e.target, obj, "The load event target should be the corresponding object element.");
+  });
+
+  obj.onerror = t.step_func_done(function(e){
+    assert_unreached("The error event should not be fired.");
+  });
+
+  document.body.appendChild(obj);
+}, "load event of initial about:blank");
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/constraints/form-validation-validate-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/constraints/form-validation-validate-expected.txt
index ebe1363..0bde7bc 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/constraints/form-validation-validate-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/constraints/form-validation-validate-expected.txt
@@ -1,15 +1,15 @@
 CONSOLE WARNING: line 13: The specified value "abc" is not a valid email address.
 CONSOLE ERROR: line 79: An invalid form control with name='' is not focusable.
 CONSOLE ERROR: line 79: An invalid form control with name='' is not focusable.
-CONSOLE ERROR: line 103: An invalid form control with name='' is not focusable.
-CONSOLE ERROR: line 105: An invalid form control with name='' is not focusable.
+CONSOLE ERROR: line 108: An invalid form control with name='' is not focusable.
+CONSOLE ERROR: line 114: An invalid form control with name='' is not focusable.
 This is a testharness.js-based test.
 PASS If there is any invalid submittable element whose form owner is the form, the form.checkValidity must be false 
 PASS If there is any invalid submittable element whose form owner is the form, the form.reportValidity must be false 
 PASS If all of the submittable elements whose form owner is the form are valid, the form.checkValidity must be true 
 PASS If all of the submittable elements whose form owner is the form are valid, the form.reportValidity must be true 
 PASS Check the checkValidity method of the form element when it has a fieldset child 
-FAIL Check the reportValidity method of the form element when it has a fieldset child assert_true: The reportValidity method should be true. expected true got false
+PASS Check the reportValidity method of the form element when it has a fieldset child 
 PASS The invalid event must be fired at the invalid controls 
 PASS The invalid event must not be fired at the invalid controls 
 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/constraints/form-validation-validate.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/constraints/form-validation-validate.html
index 4cf399da..920da084 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/constraints/form-validation-validate.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/constraints/form-validation-validate.html
@@ -99,6 +99,11 @@
   }, "Check the checkValidity method of the form element when it has a fieldset child");
 
   test(function(){
+    // Restore the condition to default which was modified during the previous test.
+    document.getElementById("fs").disabled = false;
+    document.getElementById("inp1").value = "";
+    document.getElementById("inp1").type = "text";
+
     assert_true("reportValidity" in fm3, "The reportValidity method is not supported.");
     assert_false(fm3.reportValidity(), "The reportValidity method should be false.");
     document.getElementById("fs").disabled = true;
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/form-control-infrastructure/form-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/form-control-infrastructure/form-expected.txt
new file mode 100644
index 0000000..b0957f5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/form-control-infrastructure/form-expected.txt
@@ -0,0 +1,24 @@
+CONSOLE WARNING: The <keygen> element is deprecated and will be removed in M54, around October 2016. See https://www.chromestatus.com/features/5716060992962560 for more details.
+This is a testharness.js-based test.
+PASS button.form 
+PASS fieldset.form 
+PASS input.form 
+PASS keygen.form 
+PASS object.form 
+PASS output.form 
+PASS select.form 
+PASS textarea.form 
+PASS label.form 
+PASS label-form.form 
+PASS label-form-form2.form 
+PASS label-with-control.form 
+PASS label-for.form 
+FAIL label-with-progress.form assert_equals: Sanity check: label.control.form expected (object) null but got (undefined) undefined
+FAIL label-with-meter.form assert_equals: Sanity check: label.control.form expected (object) null but got (undefined) undefined
+PASS label-for-control-form-in-form.form 
+PASS label-for-control-form.form 
+PASS label-in-table.form 
+PASS label-in-table-with-control.form 
+PASS label-in-table-for.form 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/form-control-infrastructure/form.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/form-control-infrastructure/form.html
index aa32560f..637e449 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/form-control-infrastructure/form.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/form-control-infrastructure/form.html
@@ -10,37 +10,88 @@
 <p><fieldset id="fieldset">fieldset</fieldset>
 <p><input id="input">
 <p><keygen id="keygen">
-<p><label id="label">label</label>
 <p><object id="object">object</object>
 <p><output id="output">output</output>
 <p><select id="select"><option>select</option></select>
 <p><textarea id="textarea">textarea</textarea>
+
+<!--  label is special: label.form is an alias for label.control.form  -->
+<p><label id="label">label</label>
+<p><label id="label-form" form="form">label-form</label>
+<p><label id="label-form-form2" form="form2">label-form-form2</label>
+<p><label id="label-with-control">label-with-control <input></label>
+<p><label id="label-for" for="control-for-label">label-for</label> <input id="control-for-label">
+<p><label id="label-with-progress">label-with-progress <progress></progress></label>
+<p><label id="label-with-meter">label-with-meter <meter></meter></label>
+<p>
+ <input id="input-with-form-attr-in-form" form="form2">
+ <label id="label-for-control-form-in-form" for="input-with-form-attr-in-form">label-for-control-form-in-form</label>
+</p>
 </form>
+<form id="form2"></form>
+<p>
+ <input id="input-with-form-attr" form="form2">
+ <label id="label-for-control-form" for="input-with-form-attr">label-for-control-form</label>
+</p>
+<!--  misnested tags where form-association is set by the HTML parser  -->
+<table>
+ <form id="form3"><!--  self-closes but sets the form element pointer  -->
+ <tr>
+  <td><label id="label-in-table">label-in-table</label>
+  <td><label id="label-in-table-with-control">label-in-table <input></label>
+  <td><label id="label-in-table-for" for="input-in-table">label-in-table-for</label>
+  <td><input id="input-in-table"><!--  is associated with form3  -->
+ </tr>
+ </form>
+</table>
 <script>
 var form;
 setup(function() {
   form = document.getElementById("form");
-  if (!form) {
-    throw new TypeError("Didn't find form");
+  form2 = document.getElementById("form2");
+  form3 = document.getElementById("form3");
+  if (!form || !form2 || !form3) {
+    throw new TypeError("Didn't find all forms");
   }
 });
 
-var reassociateableElements = [
+var listedElements = [
   "button",
   "fieldset",
   "input",
   "keygen",
-  "label",
   "object",
   "output",
   "select",
   "textarea",
 ];
 
-reassociateableElements.forEach(function(localName) {
+listedElements.forEach(function(localName) {
   test(function() {
-    var button = document.getElementById(localName);
-    assert_equals(button.form, form);
+    var control = document.getElementById(localName);
+    assert_equals(control.form, form);
   }, localName + ".form");
 });
+
+// label
+function testLabel(id, expected) {
+  test(function() {
+    var label = document.getElementById(id);
+    assert_equals(label.control && label.control.form, expected, 'Sanity check: label.control.form');
+    assert_equals(label.form, expected, 'label.form');
+  }, id + ".form");
+}
+
+testLabel("label", null);
+testLabel("label-form", null);
+testLabel("label-form-form2", null);
+testLabel("label-with-control", form);
+testLabel("label-for", form);
+testLabel("label-with-progress", null);
+testLabel("label-with-meter", null);
+testLabel("label-for-control-form-in-form", form2);
+testLabel("label-for-control-form", form2);
+testLabel("label-in-table", null);
+testLabel("label-in-table-with-control", form3);
+testLabel("label-in-table-for", form3);
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/checkbox-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/checkbox-expected.txt
index f827fa0..8966898 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/checkbox-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/checkbox-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-FAIL click on mutable checkbox fires a click event, then an input event, then a change event assert_true: change event should fire after input event expected true got false
+FAIL click on mutable checkbox fires a click event, then an input event, then a change event e is not defined
 PASS click on non-mutable checkbox doesn't fire the input or change event 
 PASS pre-activation steps on unchecked checkbox 
 PASS pre-activation steps on checked checkbox 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/checkbox.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/checkbox.html
index 8f6609c7..ef0e41f 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/checkbox.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/checkbox.html
@@ -34,13 +34,14 @@
     c1_click_fired = true;
     assert_false(c1_input_fired, "click event should fire before input event");
     assert_false(c1_change_fired, "click event should fire before change event");
+    assert_false(e.isTrusted, "click()-initiated click event should not be trusted");
   });
   checkbox1.oninput = t1.step_func(function(e) {
     c1_input_fired = true;
     assert_true(c1_click_fired, "input event should fire after click event");
     assert_false(c1_change_fired, "input event should fire before change event");
     assert_true(e.bubbles, "event should bubble");
-    assert_false(e.isTrusted, "click()-initiated event should not be trusted");
+    assert_true(e.isTrusted, "click()-initiated event should be trusted");
     assert_false(e.cancelable, "event should not be cancelable");
     assert_true(checkbox1.checked, "checkbox is checked");
     assert_false(checkbox1.indeterminate, "checkbox is not indeterminate");
@@ -51,7 +52,7 @@
     assert_true(c1_click_fired, "change event should fire after click event");
     assert_true(c1_input_fired, "change event should fire after input event");
     assert_true(e.bubbles, "event should bubble")
-    assert_false(e.isTrusted, "click()-initiated event should not be trusted");
+    assert_true(e.isTrusted, "click()-initiated event should be trusted");
     assert_false(e.cancelable, "event should not be cancelable");
     assert_true(checkbox1.checked, "checkbox is checked");
     assert_false(checkbox1.indeterminate, "checkbox is not indeterminate");
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/radio.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/radio.html
index 39baf75..de475aa 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/radio.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/radio.html
@@ -83,6 +83,7 @@
     click_fired = true;
     assert_false(input_fired, "click event should fire before input event");
     assert_false(change_fired, "click event should fire before change event");
+    assert_false(e.isTrusted, "click()-initiated click event shouldn't be trusted");
   });
 
   radio5.oninput = t1.step_func(function(e) {
@@ -90,7 +91,7 @@
     assert_true(click_fired, "input event should fire after click event");
     assert_false(change_fired, "input event should fire before change event");
     assert_true(e.bubbles, "input event should bubble")
-    assert_false(e.isTrusted, "click()-initiated input event shouldn't be trusted");
+    assert_true(e.isTrusted, "input event should be trusted");
     assert_false(e.cancelable, "input event should not be cancelable");
   });
 
@@ -99,7 +100,7 @@
     assert_true(click_fired, "change event should fire after click event");
     assert_true(input_fired, "change event should fire after input event");
     assert_true(e.bubbles, "change event should bubble")
-    assert_false(e.isTrusted, "click()-initiated change event shouldn't be trusted");
+    assert_true(e.isTrusted, "change event should be trusted");
     assert_false(e.cancelable, "change event should not be cancelable");
   });
 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/selection-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/selection-expected.txt
index 76e45a2c..8d8a3386 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/selection-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/selection-expected.txt
@@ -28,22 +28,22 @@
 PASS input type url should support all selection attributes and methods 
 PASS input type tel should support all selection attributes and methods 
 PASS input type password should support all selection attributes and methods 
-PASS input type hidden should not support variable-length selections 
-PASS input type email should not support variable-length selections 
-PASS input type date should not support variable-length selections 
-PASS input type month should not support variable-length selections 
-PASS input type week should not support variable-length selections 
-PASS input type time should not support variable-length selections 
-PASS input type datetime-local should not support variable-length selections 
-PASS input type number should not support variable-length selections 
-PASS input type range should not support variable-length selections 
-PASS input type color should not support variable-length selections 
-PASS input type checkbox should not support variable-length selections 
-PASS input type radio should not support variable-length selections 
-PASS input type file should not support variable-length selections 
-PASS input type submit should not support variable-length selections 
-PASS input type image should not support variable-length selections 
-PASS input type reset should not support variable-length selections 
-PASS input type button should not support variable-length selections 
+FAIL input type hidden should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('hidden') does not support selection.
+FAIL input type email should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('email') does not support selection.
+FAIL input type date should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('date') does not support selection.
+FAIL input type month should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('month') does not support selection.
+FAIL input type week should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('week') does not support selection.
+FAIL input type time should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('time') does not support selection.
+FAIL input type datetime-local should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('datetime-local') does not support selection.
+FAIL input type number should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('number') does not support selection.
+FAIL input type range should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('range') does not support selection.
+FAIL input type color should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('color') does not support selection.
+FAIL input type checkbox should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('checkbox') does not support selection.
+FAIL input type radio should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('radio') does not support selection.
+FAIL input type file should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('file') does not support selection.
+FAIL input type submit should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('submit') does not support selection.
+FAIL input type image should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('image') does not support selection.
+FAIL input type reset should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('reset') does not support selection.
+FAIL input type button should not support variable-length selections Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('button') does not support selection.
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/selection.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/selection.html
index 74a7d194..58c6d990 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/selection.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-input-element/selection.html
@@ -105,6 +105,8 @@
       input.selectionStart = 0;
       a = input.selectionEnd;
       input.selectionEnd = 0;
+      a = input.selectionDirection;
+      input.selectionDirection = "none";
       input.setSelectionRange(0, 0);
       input.setRangeText('', 0, 0);
 
@@ -118,10 +120,12 @@
       input.type = type;
       assert_equals(input.type, type, "the given input type is not supported");
 
-      assert_throws("INVALID_STATE_ERR", function() { var a = input.selectionStart; });
+      assert_equals(input.selectionStart, null, 'getting input.selectionStart');
       assert_throws("INVALID_STATE_ERR", function() { input.selectionStart = 0; });
-      assert_throws("INVALID_STATE_ERR", function() { var a = input.selectionEnd; });
+      assert_equals(input.selectionEnd, null, 'getting input.selectionEnd');
       assert_throws("INVALID_STATE_ERR", function() { input.selectionEnd = 0; });
+      assert_equals(input.selectionDirection, null, 'getting input.selectionDirection');
+      assert_throws("INVALID_STATE_ERR", function() { input.selectionDirection = "none"; });
       assert_throws("INVALID_STATE_ERR", function() { input.setSelectionRange(0, 0); });
       assert_throws("INVALID_STATE_ERR", function() { input.setRangeText('', 0, 0); });
 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-label-element/label-attributes-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-label-element/label-attributes-expected.txt
index 9fb5a38..a3745238 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-label-element/label-attributes-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-label-element/label-attributes-expected.txt
@@ -9,8 +9,8 @@
 PASS A form control has an implicit label. 
 PASS A form control has no label 1. 
 PASS A form control has no label 2. 
-PASS A label's form attribute should return its form owner. 
-PASS Check that the labels property of a form control with no label returns a zero-length NodeList. 
+PASS A label in a form without a control 
+PASS A label outside a form with a control inside the form 
 PASS A label's htmlFor attribute must reflect the for content attribute 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-label-element/label-attributes.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-label-element/label-attributes.html
index 55ca767..565f89d8 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-label-element/label-attributes.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/forms/the-label-element/label-attributes.html
@@ -121,14 +121,14 @@
 
   // form attribute
   test(function () {
-    assert_equals(document.getElementById("lbl0").form, document.getElementById("fm"),
-                  "The 'form' property for a label with a form owner should return the form owner.");
-  }, "A label's form attribute should return its form owner.");
+    assert_equals(document.getElementById("lbl0").form, null,
+                  "The 'form' property for a label should return null if label.control is null.");
+  }, "A label in a form without a control");
 
   test(function () {
-    assert_equals(document.getElementById("lbl6").form, null,
-                  "The 'form' property for a label without a form owner should return null.");
-  }, "Check that the labels property of a form control with no label returns a zero-length NodeList.");
+    assert_equals(document.getElementById("lbl6").form, document.getElementById("fm"),
+                  "The 'form' property for a label should return label.control.form.");
+  }, "A label outside a form with a control inside the form");
 
   // htmlFor attribute
   test(function () {
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/checked.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/checked.html
index f6c4313..28ee5ef51 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/checked.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/checked.html
@@ -30,14 +30,14 @@
 </form>
 
 <script>
-  testSelector(":checked", ["option1", "checkbox1", "radio1", "menuitem1", "menuitem4"], "':checked' matches checked <input>/<menuitem> in checkbox and radio button states, selected <option>s");
+  testSelectorIdsMatch(":checked", ["option1", "checkbox1", "radio1", "menuitem1", "menuitem4"], "':checked' matches checked <input>/<menuitem> in checkbox and radio button states, selected <option>s");
 
   document.getElementById("checkbox1").removeAttribute("type");  // change type of input
   document.getElementById("radio1").removeAttribute("type");  // change type of input
-  testSelector(":checked", ["option1", "menuitem1", "menuitem4"], "':checked' should no longer match <input>s whose type checkbox/radio has been removed");
+  testSelectorIdsMatch(":checked", ["option1", "menuitem1", "menuitem4"], "':checked' should no longer match <input>s whose type checkbox/radio has been removed");
 
   document.getElementById("option2").selected = "selected";  // select option2
   document.getElementById("checkbox2").click();  // check chekbox2
   document.getElementById("radio2").click();  // check radio2
-  testSelector(":checked", ["option2", "checkbox2", "radio2", "menuitem1", "menuitem4"], "':checked' matches clicked checkbox and radio buttons");
+  testSelectorIdsMatch(":checked", ["option2", "checkbox2", "radio2", "menuitem1", "menuitem4"], "':checked' matches clicked checkbox and radio buttons");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/default.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/default.html
index c6ba644..a696e51a 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/default.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/default.html
@@ -56,9 +56,9 @@
 
 
 <script>
-  testSelector(":default", ["button2", "button4", "input3", "input5", "input7", "checkbox1", "radio1", "option2", "button6", "button8"], "':default' matches <button>s that are their form's default button, <input>s of type submit/image that are their form's default button, checked <input>s and selected <option>s");
+  testSelectorIdsMatch(":default", ["button2", "button4", "input3", "input5", "input7", "checkbox1", "radio1", "option2", "button6", "button8"], "':default' matches <button>s that are their form's default button, <input>s of type submit/image that are their form's default button, checked <input>s and selected <option>s");
 
   document.getElementById("button1").type = "submit"; // change the form's default button
-  testSelector(":default", ["button1", "button4", "input3", "input5", "input7", "checkbox1", "radio1", "option2", "button6", "button8"], "':default' matches dynamically changed form's default buttons");
+  testSelectorIdsMatch(":default", ["button1", "button4", "input3", "input5", "input7", "checkbox1", "radio1", "option2", "button6", "button8"], "':default' matches dynamically changed form's default buttons");
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/dir.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/dir.html
index 1c9d329e..aefaa092 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/dir.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/dir.html
@@ -1,36 +1,46 @@
 <!DOCTYPE html>
-<meta charset=utf-8 id=meta>
-<title id=title>Selector: pseudo-classes (:dir(ltr), :dir(rtl))</title>
-<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
-<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
-<script src="../../../../../../resources/testharness.js" id=script1></script>
-<script src="../../../../../../resources/testharnessreport.js" id=script2></script>
-<script src="utils.js" id=script3></script>
-<style id=style>
-  #span1 {direction: rtl;}
-  #span5, #span6 {display: none;}
-</style>
-<div id="log"></div>
-<bdo dir="rtl" id=bdo1>WERBEH</bdo>
-<bdo dir="ltr" id=bdo2>HEBREW</bdo>
-<bdi id=bdi1>HEBREW</bdi>
-<bdi dir="rtl" id=bdi2>WERBEH</bdi>
-<bdi dir="ltr" id=bdi3>HEBREW</bdi>
-<span id=span1>WERBEH</span>
-<span dir="rtl" id=span2>WERBEH</span>
-<span dir="ltr" id=span3>HEBREW</span>
-&#x202E;<span id=span4>WERBEH</span>&#x202C;
-<span dir="rtl" id=span5>WERBEH</span>
-<span dir="ltr" id=span6>HEBREW</span>
-<bdo dir="auto" id=bdo3>HEBREW</bdo>
-<bdo dir="auto" id=bdo4>إيان</bdo>
-<bdo dir="ltr" id=bdo5>עברית</bdo>
+<html id=html>
+  <head id=head>
+    <meta charset=utf-8 id=meta>
+    <title id=title>Selector: pseudo-classes (:dir(ltr), :dir(rtl))</title>
+    <link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+    <link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+    <script src="../../../../../../resources/testharness.js" id=script1></script>
+    <script src="../../../../../../resources/testharnessreport.js" id=script2></script>
+    <script src="utils.js" id=script3></script>
+    <style id=style>
+      #span1 {direction: rtl;}
+      #span5, #span6 {display: none;}
+    </style>
+  </head>
+  <body id=body>
+    <div id="log"></div>
+    <bdo dir="rtl" id=bdo1>WERBEH</bdo>
+    <bdo dir="ltr" id=bdo2>HEBREW</bdo>
+    <bdi id=bdi1>HEBREW</bdi>
+    <bdi dir="rtl" id=bdi2>WERBEH</bdi>
+    <bdi dir="ltr" id=bdi3>HEBREW</bdi>
+    <bdi id=bdi4>إيان</bdi>
+    <span id=span1>WERBEH</span>
+    <span dir="rtl" id=span2>WERBEH</span>
+    <span dir="ltr" id=span3>HEBREW</span>
+    &#x202E;<span id=span4>WERBEH</span>&#x202C;
+    <span dir="rtl" id=span5>WERBEH</span>
+    <span dir="ltr" id=span6>HEBREW</span>
+    <bdo dir="auto" id=bdo3>HEBREW</bdo>
+    <bdo dir="auto" id=bdo4>إيان</bdo>
+    <bdo dir="ltr" id=bdo5>עברית</bdo>
 
-<script>
-  testSelector(":dir(rtl)", ["bdo1", "bdi2", "span1", "span2", "span4", "span5", "bdo4"], "':dir(rtl)' matches all elements whose directionality is 'rtl'.");
-  testSelector(":dir(ltr)", ["html", "head", "body", "meta", "title", "link1", "link2", "script1", "script2", "script3", "stlyle", "log", "bdo2", "bdi3", "span3", "span6", "bdo3", "bdo5"], "':dir(ltr)' matches all elements whose directionality is 'ltr'.");
+    <script id=script4>
+      testSelectorIdsMatch(":dir(rtl)", ["bdo1", "bdi2", "bdi4", "span2", "span5", "bdo4"], "':dir(rtl)' matches all elements whose directionality is 'rtl'.");
 
-  var bdo = document.createElement("bdo");
-  bdo.setAttribute("dir", "ltr");
-  testSelector(":dir(ltr)", ["meta", "title", "link1", "link2", "script1", "script2", "script3", "stlyle", "log", "bdo2", "bdi3", "span3", "span6", "bdo3"], "':dir(ltr)' doesn't match elements not in the document.");
-</script>
+      var ltrElements = ["html", "head", "meta", "title", "link1", "link2", "script1", "script2", "script3", "style", "body", "log", "bdo2", "bdi1", "bdi3", "span1", "span3", "span4", "span6", "bdo3", "bdo5", "script4"];
+
+      testSelectorIdsMatch(":dir(ltr)", ltrElements, "':dir(ltr)' matches all elements whose directionality is 'ltr'.");
+
+      var bdo = document.createElement("bdo");
+      bdo.setAttribute("dir", "ltr");
+      testSelectorIdsMatch(":dir(ltr)", ltrElements, "':dir(ltr)' doesn't match elements not in the document.");
+    </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/dir01.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/dir01.html
index c029b14..0253941 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/dir01.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/dir01.html
@@ -14,5 +14,5 @@
   var ltr = new Array(),
       all = document.querySelectorAll('*');
   for(var i = all.length; i--; ltr.unshift(all[i]));
-  testSelector(":dir(ltr)", ltr, "direction doesn't affect :dir()");
+  testSelectorElementsMatch(":dir(ltr)", ltr, "direction doesn't affect :dir()");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/disabled.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/disabled.html
index 1a06e28..8e568b30 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/disabled.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/disabled.html
@@ -40,21 +40,21 @@
 <progress disabled></progress>
 
 <script>
-  testSelector(":disabled", ["button2", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should match only disabled elements");
+  testSelectorIdsMatch(":disabled", ["button2", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should match only disabled elements");
 
   document.getElementById("button2").removeAttribute("disabled");
-  testSelector(":disabled", ["input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements whose disabled attribute has been removed");
+  testSelectorIdsMatch(":disabled", ["input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements whose disabled attribute has been removed");
 
   document.getElementById("button1").setAttribute("disabled", "disabled");
-  testSelector(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set");
+  testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set");
 
   document.getElementById("button1").setAttribute("disabled", "disabled");
-  testSelector(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set twice");
+  testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set twice");
 
   document.getElementById("input2").setAttribute("type", "submit"); // change input type to submit
-  testSelector(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match disabled elements whose type has changed");
+  testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match disabled elements whose type has changed");
 
   var input = document.createElement("input");
   input.setAttribute("disabled", "disabled");
-  testSelector(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements not in the document");
+  testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements not in the document");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/enabled.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/enabled.html
index f93356b..1c55fc2a 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/enabled.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/enabled.html
@@ -38,5 +38,5 @@
 <fieldset disabled id=fieldset2></fieldset>
 
 <script>
-  testSelector(":enabled", ["button1", "input1", "select1", "optgroup1", "option1", "textarea1", "submitbutton", "menuitem1", "fieldset1"], "':enabled' elements that are not disabled");
+  testSelectorIdsMatch(":enabled", ["button1", "input1", "select1", "optgroup1", "option1", "textarea1", "submitbutton", "menuitem1", "fieldset1"], "':enabled' elements that are not disabled");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/indeterminate.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/indeterminate.html
index 3eff488..4b49e7f4 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/indeterminate.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/indeterminate.html
@@ -18,20 +18,20 @@
 <progress id="progress2" value=10></progress>
 
 <script>
-  testSelector(":indeterminate", ["radio2", "radio3", "radio4", "radio5", "progress1"], "':progress' matches <input>s radio buttons whose radio button group contains no checked input and <progress> elements without value attribute");
+  testSelectorIdsMatch(":indeterminate", ["radio2", "radio3", "radio4", "radio5", "progress1"], "':progress' matches <input>s radio buttons whose radio button group contains no checked input and <progress> elements without value attribute");
 
   document.getElementById("radio2").setAttribute("checked", "checked");
-  testSelector(":indeterminate", ["radio4", "radio5", "progress1"], "dynamically check a radio input in a radio button group");
+  testSelectorIdsMatch(":indeterminate", ["radio4", "radio5", "progress1"], "dynamically check a radio input in a radio button group");
 
   document.getElementById("radio4").click();
-  testSelector(":indeterminate", ["checkbox1", "progress2"], "click on radio4 which is in the indeterminate state");
+  testSelectorIdsMatch(":indeterminate", ["checkbox1", "progress2"], "click on radio4 which is in the indeterminate state");
 
   document.getElementById("progress1").setAttribute("value", "20");
-  testSelector(":indeterminate", [], "adding a value to progress1 should put it in a determinate state");
+  testSelectorIdsMatch(":indeterminate", [], "adding a value to progress1 should put it in a determinate state");
 
   document.getElementById("progress2").removeAttribute("value");
-  testSelector(":indeterminate", ["progress2"], "removing progress2's value should put it in an indeterminate state");
+  testSelectorIdsMatch(":indeterminate", ["progress2"], "removing progress2's value should put it in an indeterminate state");
 
   document.getElementById("checkbox1").indeterminate = true; // set checkbox1 in the indeterminate state
-  testSelector(":indeterminate", ["checkbox1", "progress2"], "':progress' also matches <input> checkbox whose indeterminate IDL is set to true");
+  testSelectorIdsMatch(":indeterminate", ["checkbox1", "progress2"], "':progress' also matches <input> checkbox whose indeterminate IDL is set to true");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/inrange-outofrange.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/inrange-outofrange.html
index fc900b53..9db49a57 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/inrange-outofrange.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/inrange-outofrange.html
@@ -70,15 +70,15 @@
 <input min="1" value="0" type="reset">
 
 <script>
-  testSelector(":in-range", ["number1", "datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' matches all elements that are candidates for constraint validation, have range limitations, and that are neither suffering from an underflow nor suffering from an overflow");
+  testSelectorIdsMatch(":in-range", ["number1", "datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' matches all elements that are candidates for constraint validation, have range limitations, and that are neither suffering from an underflow nor suffering from an overflow");
 
-  testSelector(":out-of-range", ["number3", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' matches all elements that are candidates for constraint validation, have range limitations, and that are either suffering from an underflow or suffering from an overflow");
+  testSelectorIdsMatch(":out-of-range", ["number3", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' matches all elements that are candidates for constraint validation, have range limitations, and that are either suffering from an underflow or suffering from an overflow");
 
   document.getElementById("number1").value = -10;
-  testSelector(":in-range", ["datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' update number1's value < min");
-  testSelector(":out-of-range", ["number1", "number3", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' update number1's value < min");
+  testSelectorIdsMatch(":in-range", ["datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' update number1's value < min");
+  testSelectorIdsMatch(":out-of-range", ["number1", "number3", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' update number1's value < min");
 
   document.getElementById("number3").min = 0;
-  testSelector(":in-range", ["number3", "datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' update number3's min < value");
-  testSelector(":out-of-range", ["number1", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' update number3's min < value");
+  testSelectorIdsMatch(":in-range", ["number3", "datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' update number3's min < value");
+  testSelectorIdsMatch(":out-of-range", ["number1", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' update number3's min < value");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/link.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/link.html
index 1ab7879c..4ad9774 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/link.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/link.html
@@ -16,8 +16,8 @@
 <a href="http://[" id=link10></a>
 
 <script>
-  testSelector(":link", ["link1", "link2", "link3", "link7", "link8", "link9", "link10"], "Only <a>s, <area>s and <link>s that have a href attribute match ':link'");
+  testSelectorIdsMatch(":link", ["link1", "link2", "link3", "link7", "link8", "link9", "link10"], "Only <a>s, <area>s and <link>s that have a href attribute match ':link'");
 
   document.getElementById("link9").removeAttribute("href");
-  testSelector(":link", ["link1", "link2", "link3", "link7", "link8", "link10"], "':link' doesn't match elements whos href attribute has been removed");
+  testSelectorIdsMatch(":link", ["link1", "link2", "link3", "link7", "link8", "link10"], "':link' doesn't match elements whos href attribute has been removed");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/readwrite-readonly.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/readwrite-readonly.html
index 8fc80cb9..43294eb 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/readwrite-readonly.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/readwrite-readonly.html
@@ -45,45 +45,45 @@
 </div>
 
 <script>
-  testSelector("#set0 :read-write", [], "The :read-write pseudo-class must not match input elements to which the readonly attribute does not apply");
+  testSelectorIdsMatch("#set0 :read-write", [], "The :read-write pseudo-class must not match input elements to which the readonly attribute does not apply");
 
-  testSelector("#set0 :read-only", ["checkbox1", "hidden1", "range1", "color1", "radio1", "file1", "submit1", "image1", "button1", "reset1"], "The :read-only pseudo-class must match input elements to which the readonly attribute does not apply");
+  testSelectorIdsMatch("#set0 :read-only", ["checkbox1", "hidden1", "range1", "color1", "radio1", "file1", "submit1", "image1", "button1", "reset1"], "The :read-only pseudo-class must match input elements to which the readonly attribute does not apply");
 
-  testSelector("#set1 :read-write", ["input1"], "The :read-write pseudo-class must match input elements to which the readonly attribute applies, and that are mutable");
+  testSelectorIdsMatch("#set1 :read-write", ["input1"], "The :read-write pseudo-class must match input elements to which the readonly attribute applies, and that are mutable");
 
-  testSelector("#set1 :read-only", ["input2"], "The :read-only pseudo-class must not match input elements to which the readonly attribute applies, and that are mutable");
+  testSelectorIdsMatch("#set1 :read-only", ["input2"], "The :read-only pseudo-class must not match input elements to which the readonly attribute applies, and that are mutable");
 
   document.getElementById("input1").setAttribute("readonly", "readonly");
-  testSelector("#set1 :read-write", [], "The :read-write pseudo-class must not match input elements after the readonly attribute has been added");
+  testSelectorIdsMatch("#set1 :read-write", [], "The :read-write pseudo-class must not match input elements after the readonly attribute has been added");
 
-  testSelector("#set1 :read-only", ["input1", "input2"], "The :read-only pseudo-class must match input elements after the readonly attribute has been added");
+  testSelectorIdsMatch("#set1 :read-only", ["input1", "input2"], "The :read-only pseudo-class must match input elements after the readonly attribute has been added");
 
   document.getElementById("input1").removeAttribute("readonly");
-  testSelector("#set1 :read-write", ["input1"], "The :read-write pseudo-class must not match input elements after the readonly attribute has been removed");
+  testSelectorIdsMatch("#set1 :read-write", ["input1"], "The :read-write pseudo-class must not match input elements after the readonly attribute has been removed");
 
-  testSelector("#set1 :read-only", ["input2"], "The :read-only pseudo-class must match input elements after the readonly attribute has been removed");
+  testSelectorIdsMatch("#set1 :read-only", ["input2"], "The :read-only pseudo-class must match input elements after the readonly attribute has been removed");
 
-  testSelector("#set2 :read-write", ["textarea1"], "The :read-write pseudo-class must match textarea elements that do not have a readonly attribute, and that are not disabled");
+  testSelectorIdsMatch("#set2 :read-write", ["textarea1"], "The :read-write pseudo-class must match textarea elements that do not have a readonly attribute, and that are not disabled");
 
-  testSelector("#set2 :read-only", ["textarea2"], "The :read-only pseudo-class must match textarea elements that have a readonly attribute, or that are disabled");
+  testSelectorIdsMatch("#set2 :read-only", ["textarea2"], "The :read-only pseudo-class must match textarea elements that have a readonly attribute, or that are disabled");
 
   document.getElementById("textarea1").setAttribute("readonly", "readonly");
-  testSelector("#set2 :read-write", [], "The :read-write pseudo-class must match textarea elements after the readonly attribute has been added");
+  testSelectorIdsMatch("#set2 :read-write", [], "The :read-write pseudo-class must match textarea elements after the readonly attribute has been added");
 
-  testSelector("#set2 :read-only", ["textarea1", "textarea2"], "The :read-only pseudo-class must match textarea elements after the readonly attribute has been added");
+  testSelectorIdsMatch("#set2 :read-only", ["textarea1", "textarea2"], "The :read-only pseudo-class must match textarea elements after the readonly attribute has been added");
 
-  testSelector("#set3 :read-write", ["textarea3"], "The :read-write pseudo-class must not match textarea elements that are disabled");
+  testSelectorIdsMatch("#set3 :read-write", ["textarea3"], "The :read-write pseudo-class must not match textarea elements that are disabled");
 
-  testSelector("#set3 :read-only", ["textarea4"], "The :read-only pseudo-class must match textarea elements that are disabled");
+  testSelectorIdsMatch("#set3 :read-only", ["textarea4"], "The :read-only pseudo-class must match textarea elements that are disabled");
 
-  testSelector("#set4 :read-write", ["p2"], "The :read-write pseudo-class must match elements that are editable");
+  testSelectorIdsMatch("#set4 :read-write", ["p2"], "The :read-write pseudo-class must match elements that are editable");
 
-  testSelector("#set4 :read-only", ["p1"], "The :read-only pseudo-class must not match elements that are editable");
+  testSelectorIdsMatch("#set4 :read-only", ["p1"], "The :read-only pseudo-class must not match elements that are editable");
 
   document.designMode = "on";
 
-  testSelector("#set4 :read-write", ["p1", "p2"], "The :read-write pseudo-class must match elements that are editing hosts");
+  testSelectorIdsMatch("#set4 :read-write", ["p1", "p2"], "The :read-write pseudo-class must match elements that are editing hosts");
 
-  testSelector("#set4 :read-only", [], "The :read-only pseudo-class must not match elements that are editing hosts");
+  testSelectorIdsMatch("#set4 :read-only", [], "The :read-only pseudo-class must not match elements that are editing hosts");
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/required-optional.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/required-optional.html
index 89192ce63..9a08c14e 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/required-optional.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/required-optional.html
@@ -22,14 +22,14 @@
 <textarea id=textarea2>textarea2</textarea>
 
 <script>
-  testSelector(":required", ["text1", "text2", "select1", "textarea1"], "':required' matches required <input>s, <select>s and <textarea>s");
-  testSelector(":optional", ["text3", "select2", "textarea2"], "':optional' matches elements <input>s, <select>s and <textarea>s that are not required");
+  testSelectorIdsMatch(":required", ["text1", "text2", "select1", "textarea1"], "':required' matches required <input>s, <select>s and <textarea>s");
+  testSelectorIdsMatch(":optional", ["text3", "select2", "textarea2"], "':optional' matches elements <input>s, <select>s and <textarea>s that are not required");
 
   document.getElementById("text1").removeAttribute("required");
-  testSelector(":required", ["text2", "select1", "textarea1"], "':required' doesn't match elements whose required attribute has been removed");
-  testSelector(":optional", ["text1", "text3", "select2", "textarea2"], "':optional' matches elements whose required attribute has been removed");
+  testSelectorIdsMatch(":required", ["text2", "select1", "textarea1"], "':required' doesn't match elements whose required attribute has been removed");
+  testSelectorIdsMatch(":optional", ["text1", "text3", "select2", "textarea2"], "':optional' matches elements whose required attribute has been removed");
 
   document.getElementById("select2").setAttribute("required", "required");
-  testSelector(":required", ["text2", "select1", "select2", "textarea1"], "':required' matches elements whose required attribute has been added");
-  testSelector(":optional", ["text1", "text3", "textarea2"], "':optional' doesn't match elements whose required attribute has been added");
+  testSelectorIdsMatch(":required", ["text2", "select1", "select2", "textarea1"], "':required' matches elements whose required attribute has been added");
+  testSelectorIdsMatch(":optional", ["text1", "text3", "textarea2"], "':optional' doesn't match elements whose required attribute has been added");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/utils.js b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/utils.js
index 8f5497e..a8b1cd6 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/utils.js
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/utils.js
@@ -6,9 +6,15 @@
   return result;
 }
 
-function testSelector(selector, expected, testName) {
+function testSelectorIdsMatch(selector, ids, testName) {
   test(function(){
     var elements = document.querySelectorAll(selector);
-    assert_array_equals(elements, getElementsByIds(expected));
+    assert_array_equals(elements, getElementsByIds(ids));
+  }, testName);
+}
+
+function testSelectorElementsMatch(selector, elements, testName) {
+  test(function(){
+    assert_array_equals(document.querySelectorAll(selector), elements);
   }, testName);
 }
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/valid-invalid.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/valid-invalid.html
index 56c6a75e..e5b9066 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/valid-invalid.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/selectors/pseudo-classes/valid-invalid.html
@@ -37,32 +37,32 @@
 </div>
 
 <script>
-  testSelector("#simpleConstraints :valid", ["text1"], "':valid' matches elements that satisfy their constraints");
+  testSelectorIdsMatch("#simpleConstraints :valid", ["text1"], "':valid' matches elements that satisfy their constraints");
 
-  testSelector("#FormSelection :valid", ["form1", "text3"], "':valid' matches form elements that are not the form owner of any elements that themselves are candidates for constraint validation but do not satisfy their constraints");
+  testSelectorIdsMatch("#FormSelection :valid", ["form1", "text3"], "':valid' matches form elements that are not the form owner of any elements that themselves are candidates for constraint validation but do not satisfy their constraints");
 
-  testSelector("#FieldSetSelection :valid", ["fieldset1", "text5"], "':valid' matches fieldset elements that have no descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints");
+  testSelectorIdsMatch("#FieldSetSelection :valid", ["fieldset1", "text5"], "':valid' matches fieldset elements that have no descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints");
 
-  testSelector("#patternConstraints :valid", [ "text8" ], "':valid' matches elements that satisfy their pattern constraints");
+  testSelectorIdsMatch("#patternConstraints :valid", [ "text8" ], "':valid' matches elements that satisfy their pattern constraints");
 
-  testSelector("#numberConstraints :valid", [ "number2" ], "':valid' matches elements that satisfy their number constraints");
+  testSelectorIdsMatch("#numberConstraints :valid", [ "number2" ], "':valid' matches elements that satisfy their number constraints");
 
 
-  testSelector("#simpleConstraints :invalid", ["text2"], "':invalid' matches elements that do not satisfy their simple text  constraints");
+  testSelectorIdsMatch("#simpleConstraints :invalid", ["text2"], "':invalid' matches elements that do not satisfy their simple text  constraints");
 
-  testSelector("#FormSelection :invalid", ["form2", "text4"], "':invalid' matches form elements that are the form owner of one or more elements that themselves are candidates for constraint validation but do not satisfy their constraints");
+  testSelectorIdsMatch("#FormSelection :invalid", ["form2", "text4"], "':invalid' matches form elements that are the form owner of one or more elements that themselves are candidates for constraint validation but do not satisfy their constraints");
 
-  testSelector("#FieldSetSelection :invalid", ["fieldset2", "text6"], "':invalid' matches fieldset elements that have of one or more descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints");
+  testSelectorIdsMatch("#FieldSetSelection :invalid", ["fieldset2", "text6"], "':invalid' matches fieldset elements that have of one or more descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints");
 
-  testSelector("#patternConstraints :invalid", ["text7"], "':invalid' matches elements that do not satisfy their pattern constraints");
+  testSelectorIdsMatch("#patternConstraints :invalid", ["text7"], "':invalid' matches elements that do not satisfy their pattern constraints");
 
-  testSelector("#numberConstraints :invalid", ["number1"], "':invalid' matches elements that do not satisfy their number constraints");
+  testSelectorIdsMatch("#numberConstraints :invalid", ["number1"], "':invalid' matches elements that do not satisfy their number constraints");
 
   document.getElementById("text7").value="0BBB";
-  testSelector("#patternConstraints :valid", [ "text7", "text8" ], "':valid' matches new elements that satisfy their constraints");
-  testSelector("#patternConstraints :invalid", [], "':invalid' doesn't match new elements that satisfy their constraints");
+  testSelectorIdsMatch("#patternConstraints :valid", [ "text7", "text8" ], "':valid' matches new elements that satisfy their constraints");
+  testSelectorIdsMatch("#patternConstraints :invalid", [], "':invalid' doesn't match new elements that satisfy their constraints");
 
   document.getElementById("text8").value="BBB";
-  testSelector("#patternConstraints :valid", ["text7"], "':valid' doesn't match new elements that do not satisfy their constraints");
-  testSelector("#patternConstraints :invalid", ["text8"], "':invalid' matches new elements that do not satisfy their constraints");
+  testSelectorIdsMatch("#patternConstraints :valid", ["text7"], "':valid' doesn't match new elements that do not satisfy their constraints");
+  testSelectorIdsMatch("#patternConstraints :invalid", ["text8"], "':invalid' matches new elements that do not satisfy their constraints");
 </script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/tabular-data/the-table-element/table-rows.html b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/tabular-data/the-table-element/table-rows.html
index 43fe783..0cc32210 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/tabular-data/the-table-element/table-rows.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/semantics/tabular-data/the-table-element/table-rows.html
@@ -34,6 +34,14 @@
   assert_equals(table.rows.bar, bar1);
   assert_equals(table.rows["bar"], bar1);
   assert_equals(table.rows.namedItem("bar"), bar1);
+  assert_array_equals(Object.getOwnPropertyNames(table.rows), [
+    "0",
+    "1",
+    "2",
+    "3",
+    "foo",
+    "bar"
+  ]);
 }
 test(function() {
   var table = document.createElement("table");
@@ -145,6 +153,46 @@
     foot2row1,
     foot2row2
   ]);
+  assert_array_equals(Object.getOwnPropertyNames(table.rows), [
+    "0",
+    "1",
+    "2",
+    "3",
+    "4",
+    "5",
+    "6",
+    "7",
+    "8",
+    "9",
+    "10",
+    "11",
+    "12",
+    "13",
+    "14",
+    "15",
+    "16",
+    "17",
+    "18",
+    "head1row1",
+    "head1row2",
+    "head2row1",
+    "head2row2",
+    "orphan1",
+    "orphan2",
+    "orphan3",
+    "body1row1",
+    "body1row2",
+    "orphan4",
+    "body2row1",
+    "body2row2",
+    "orphan5",
+    "orphan6",
+    "orphan7",
+    "foot1row1",
+    "foot1row2",
+    "foot2row1",
+    "foot2row2"
+  ]);
 
   var ids = [
     "orphan1",
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/syntax/serializing-html-fragments/serializing-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/syntax/serializing-html-fragments/serializing-expected.txt
new file mode 100644
index 0000000..63a3c10
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/syntax/serializing-html-fragments/serializing-expected.txt
@@ -0,0 +1,246 @@
+CONSOLE WARNING: line 248: The <keygen> element is deprecated and will be removed in M54, around October 2016. See https://www.chromestatus.com/features/5716060992962560 for more details.
+This is a testharness.js-based test.
+PASS innerHTML 0  
+PASS innerHTML 1 <a></a> 
+PASS innerHTML 2 <a b="c"></a> 
+PASS innerHTML 3 <a b="c"></a> 
+PASS innerHTML 4 <a b="&amp;"></a> 
+PASS innerHTML 5 <a b="&nbsp;"></a> 
+PASS innerHTML 6 <a b="&quot;"></a> 
+PASS innerHTML 7 <a b="<"></a> 
+PASS innerHTML 8 <a b=">"></a> 
+FAIL innerHTML 9 <svg xlink:href="a"></svg> assert_equals: expected "<svg xlink:href=\"a\"></svg>" but got "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"a\"></svg>"
+PASS innerHTML 10 <svg xmlns:svg="test"></svg> 
+PASS innerHTML 11 a 
+PASS innerHTML 12 &amp; 
+PASS innerHTML 13 &nbsp; 
+PASS innerHTML 14 &lt; 
+PASS innerHTML 15 &gt; 
+PASS innerHTML 16 " 
+PASS innerHTML 17 <style><&></style> 
+PASS innerHTML 18 <script type="test"><&></script> 
+PASS innerHTML 19 <xmp><&></xmp> 
+FAIL innerHTML 20 <iframe><&></iframe> assert_equals: expected "<iframe><&></iframe>" but got "<iframe>&lt;&amp;&gt;</iframe>"
+FAIL innerHTML 21 <noembed><&></noembed> assert_equals: expected "<noembed><&></noembed>" but got "<noembed>&lt;&amp;&gt;</noembed>"
+FAIL innerHTML 22 <noframes><&></noframes> assert_equals: expected "<noframes><&></noframes>" but got "<noframes>&lt;&amp;&gt;</noframes>"
+FAIL innerHTML 23 <noscript><&></noscript> assert_equals: expected "<noscript><&></noscript>" but got "<noscript>&lt;&amp;&gt;</noscript>"
+FAIL innerHTML 24 <!--data--> assert_equals: expected "<!--data-->" but got "<!-- data -->"
+PASS innerHTML 25 <a><b><c></c></b><d>e</d><f><g>h</g></f></a> 
+PASS innerHTML 26  
+PASS outerHTML 0 <span></span> 
+PASS outerHTML 1 <span><a></a></span> 
+PASS outerHTML 2 <span><a b="c"></a></span> 
+PASS outerHTML 3 <span><a b="c"></a></span> 
+PASS outerHTML 4 <span><a b="&amp;"></a></span> 
+PASS outerHTML 5 <span><a b="&nbsp;"></a></span> 
+PASS outerHTML 6 <span><a b="&quot;"></a></span> 
+PASS outerHTML 7 <span><a b="<"></a></span> 
+PASS outerHTML 8 <span><a b=">"></a></span> 
+FAIL outerHTML 9 <span><svg xlink:href="a"></svg></span> assert_equals: expected "<span><svg xlink:href=\"a\"></svg></span>" but got "<span><svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"a\"></svg></span>"
+PASS outerHTML 10 <span><svg xmlns:svg="test"></svg></span> 
+PASS outerHTML 11 <span>a</span> 
+PASS outerHTML 12 <span>&amp;</span> 
+PASS outerHTML 13 <span>&nbsp;</span> 
+PASS outerHTML 14 <span>&lt;</span> 
+PASS outerHTML 15 <span>&gt;</span> 
+PASS outerHTML 16 <span>"</span> 
+PASS outerHTML 17 <span><style><&></style></span> 
+PASS outerHTML 18 <span><script type="test"><&></script></span> 
+PASS outerHTML 19 <span><xmp><&></xmp></span> 
+FAIL outerHTML 20 <span><iframe><&></iframe></span> assert_equals: expected "<span><iframe><&></iframe></span>" but got "<span><iframe>&lt;&amp;&gt;</iframe></span>"
+FAIL outerHTML 21 <span><noembed><&></noembed></span> assert_equals: expected "<span><noembed><&></noembed></span>" but got "<span><noembed>&lt;&amp;&gt;</noembed></span>"
+FAIL outerHTML 22 <span><noframes><&></noframes></span> assert_equals: expected "<span><noframes><&></noframes></span>" but got "<span><noframes>&lt;&amp;&gt;</noframes></span>"
+FAIL outerHTML 23 <span><noscript><&></noscript></span> assert_equals: expected "<span><noscript><&></noscript></span>" but got "<span><noscript>&lt;&amp;&gt;</noscript></span>"
+FAIL outerHTML 24 <span><!--data--></span> assert_equals: expected "<span><!--data--></span>" but got "<span><!-- data --></span>"
+PASS outerHTML 25 <span><a><b><c></c></b><d>e</d><f><g>h</g></f></a></span> 
+PASS outerHTML 26 <span b="c"></span> 
+PASS innerHTML Attribute in the XML namespace 
+FAIL innerHTML Attribute in the XML namespace with the prefix not set to xml: assert_equals: expected "<svg xml:foo=\"test\"></svg>" but got "<svg abc:foo=\"test\"></svg>"
+PASS innerHTML Non-'xmlns' attribute in the xmlns namespace 
+PASS innerHTML 'xmlns' attribute in the xmlns namespace 
+FAIL innerHTML Attribute in non-standard namespace assert_equals: expected "<svg abc:def=\"test\"></svg>" but got "<svg def=\"test\"></svg>"
+PASS innerHTML <span> starting with U+000A 
+PASS outerHTML Attribute in the XML namespace 
+FAIL outerHTML Attribute in the XML namespace with the prefix not set to xml: assert_equals: expected "<span><svg xml:foo=\"test\"></svg></span>" but got "<span><svg abc:foo=\"test\"></svg></span>"
+PASS outerHTML Non-'xmlns' attribute in the xmlns namespace 
+PASS outerHTML 'xmlns' attribute in the xmlns namespace 
+FAIL outerHTML Attribute in non-standard namespace assert_equals: expected "<span><svg abc:def=\"test\"></svg></span>" but got "<span><svg def=\"test\"></svg></span>"
+PASS outerHTML <span> starting with U+000A 
+PASS innerHTML <pre> context starting with U+000A 
+PASS innerHTML <textarea> context starting with U+000A 
+PASS innerHTML <listing> context starting with U+000A 
+PASS innerHTML <pre> context not starting with U+000A 
+PASS innerHTML <textarea> context not starting with U+000A 
+PASS innerHTML <listing> context not starting with U+000A 
+FAIL innerHTML <pre> non-context starting with U+000A assert_equals: expected "<pre>\n\n</%text>" but got "<pre>\n</pre>"
+FAIL innerHTML <textarea> non-context starting with U+000A assert_equals: expected "<textarea>\n\n</%text>" but got "<textarea>\n</textarea>"
+FAIL innerHTML <listing> non-context starting with U+000A assert_equals: expected "<listing>\n\n</%text>" but got "<listing>\n</listing>"
+FAIL innerHTML <pre> non-context not starting with U+000A assert_equals: expected "<pre>a\n</%text>" but got "<pre>a\n</pre>"
+FAIL innerHTML <textarea> non-context not starting with U+000A assert_equals: expected "<textarea>a\n</%text>" but got "<textarea>a\n</textarea>"
+FAIL innerHTML <listing> non-context not starting with U+000A assert_equals: expected "<listing>a\n</%text>" but got "<listing>a\n</listing>"
+FAIL outerHTML <pre> context starting with U+000A assert_equals: expected "<pre>\n\n</%text>" but got "<pre>\n</pre>"
+FAIL outerHTML <textarea> context starting with U+000A assert_equals: expected "<textarea>\n\n</%text>" but got "<textarea>\n</textarea>"
+FAIL outerHTML <listing> context starting with U+000A assert_equals: expected "<listing>\n\n</%text>" but got "<listing>\n</listing>"
+FAIL outerHTML <pre> context not starting with U+000A assert_equals: expected "<pre>a\n</%text>" but got "<pre>a\n</pre>"
+FAIL outerHTML <textarea> context not starting with U+000A assert_equals: expected "<textarea>a\n</%text>" but got "<textarea>a\n</textarea>"
+FAIL outerHTML <listing> context not starting with U+000A assert_equals: expected "<listing>a\n</%text>" but got "<listing>a\n</listing>"
+FAIL outerHTML <pre> non-context starting with U+000A assert_equals: expected "<span><pre>\n\n</%text></span>" but got "<span><pre>\n</pre></span>"
+FAIL outerHTML <textarea> non-context starting with U+000A assert_equals: expected "<span><textarea>\n\n</%text></span>" but got "<span><textarea>\n</textarea></span>"
+FAIL outerHTML <listing> non-context starting with U+000A assert_equals: expected "<span><listing>\n\n</%text></span>" but got "<span><listing>\n</listing></span>"
+FAIL outerHTML <pre> non-context not starting with U+000A assert_equals: expected "<span><pre>a\n</%text></span>" but got "<span><pre>a\n</pre></span>"
+FAIL outerHTML <textarea> non-context not starting with U+000A assert_equals: expected "<span><textarea>a\n</%text></span>" but got "<span><textarea>a\n</textarea></span>"
+FAIL outerHTML <listing> non-context not starting with U+000A assert_equals: expected "<span><listing>a\n</%text></span>" but got "<span><listing>a\n</listing></span>"
+PASS innerHTML Void context node area 
+PASS innerHTML Void context node base 
+PASS innerHTML Void context node basefont 
+FAIL innerHTML Void context node bgsound assert_equals: expected "" but got "<a><!--abc--></a><b><c>abc</c></b>"
+PASS innerHTML Void context node br 
+PASS innerHTML Void context node col 
+PASS innerHTML Void context node embed 
+PASS innerHTML Void context node frame 
+PASS innerHTML Void context node hr 
+PASS innerHTML Void context node img 
+PASS innerHTML Void context node input 
+PASS innerHTML Void context node keygen 
+PASS innerHTML Void context node link 
+PASS innerHTML Void context node menuitem 
+PASS innerHTML Void context node meta 
+PASS innerHTML Void context node param 
+PASS innerHTML Void context node source 
+PASS innerHTML Void context node track 
+PASS innerHTML Void context node wbr 
+FAIL innerHTML void as first child with following siblings area assert_equals: expected "<area><a>test</a><b></b>" but got "<area></area><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings base assert_equals: expected "<base><a>test</a><b></b>" but got "<base></base><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings basefont assert_equals: expected "<basefont><a>test</a><b></b>" but got "<basefont></basefont><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings bgsound assert_equals: expected "<bgsound><a>test</a><b></b>" but got "<bgsound><a><!--abc--></a><b><c>abc</c></b></bgsound><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings br assert_equals: expected "<br><a>test</a><b></b>" but got "<br></br><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings col assert_equals: expected "<col><a>test</a><b></b>" but got "<col></col><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings embed assert_equals: expected "<embed><a>test</a><b></b>" but got "<embed></embed><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings frame assert_equals: expected "<frame><a>test</a><b></b>" but got "<frame></frame><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings hr assert_equals: expected "<hr><a>test</a><b></b>" but got "<hr></hr><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings img assert_equals: expected "<img><a>test</a><b></b>" but got "<img></img><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings input assert_equals: expected "<input><a>test</a><b></b>" but got "<input></input><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings keygen assert_equals: expected "<keygen><a>test</a><b></b>" but got "<keygen></keygen><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings link assert_equals: expected "<link><a>test</a><b></b>" but got "<link></link><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings menuitem assert_equals: expected "<menuitem><a>test</a><b></b>" but got "<menuitem></menuitem><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings meta assert_equals: expected "<meta><a>test</a><b></b>" but got "<meta></meta><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings param assert_equals: expected "<param><a>test</a><b></b>" but got "<param></param><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings source assert_equals: expected "<source><a>test</a><b></b>" but got "<source></source><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings track assert_equals: expected "<track><a>test</a><b></b>" but got "<track></track><a>test</a><b></b>"
+FAIL innerHTML void as first child with following siblings wbr assert_equals: expected "<wbr><a>test</a><b></b>" but got "<wbr></wbr><a>test</a><b></b>"
+FAIL innerHTML void as second child with following siblings area assert_equals: expected "<a>test</a><area><b></b>" but got "<a>test</a><area></area><b></b>"
+FAIL innerHTML void as second child with following siblings base assert_equals: expected "<a>test</a><base><b></b>" but got "<a>test</a><base></base><b></b>"
+FAIL innerHTML void as second child with following siblings basefont assert_equals: expected "<a>test</a><basefont><b></b>" but got "<a>test</a><basefont></basefont><b></b>"
+FAIL innerHTML void as second child with following siblings bgsound assert_equals: expected "<a>test</a><bgsound><b></b>" but got "<a>test</a><bgsound><a><!--abc--></a><b><c>abc</c></b></bgsound><b></b>"
+FAIL innerHTML void as second child with following siblings br assert_equals: expected "<a>test</a><br><b></b>" but got "<a>test</a><br></br><b></b>"
+FAIL innerHTML void as second child with following siblings col assert_equals: expected "<a>test</a><col><b></b>" but got "<a>test</a><col></col><b></b>"
+FAIL innerHTML void as second child with following siblings embed assert_equals: expected "<a>test</a><embed><b></b>" but got "<a>test</a><embed></embed><b></b>"
+FAIL innerHTML void as second child with following siblings frame assert_equals: expected "<a>test</a><frame><b></b>" but got "<a>test</a><frame></frame><b></b>"
+FAIL innerHTML void as second child with following siblings hr assert_equals: expected "<a>test</a><hr><b></b>" but got "<a>test</a><hr></hr><b></b>"
+FAIL innerHTML void as second child with following siblings img assert_equals: expected "<a>test</a><img><b></b>" but got "<a>test</a><img></img><b></b>"
+FAIL innerHTML void as second child with following siblings input assert_equals: expected "<a>test</a><input><b></b>" but got "<a>test</a><input></input><b></b>"
+FAIL innerHTML void as second child with following siblings keygen assert_equals: expected "<a>test</a><keygen><b></b>" but got "<a>test</a><keygen></keygen><b></b>"
+FAIL innerHTML void as second child with following siblings link assert_equals: expected "<a>test</a><link><b></b>" but got "<a>test</a><link></link><b></b>"
+FAIL innerHTML void as second child with following siblings menuitem assert_equals: expected "<a>test</a><menuitem><b></b>" but got "<a>test</a><menuitem></menuitem><b></b>"
+FAIL innerHTML void as second child with following siblings meta assert_equals: expected "<a>test</a><meta><b></b>" but got "<a>test</a><meta></meta><b></b>"
+FAIL innerHTML void as second child with following siblings param assert_equals: expected "<a>test</a><param><b></b>" but got "<a>test</a><param></param><b></b>"
+FAIL innerHTML void as second child with following siblings source assert_equals: expected "<a>test</a><source><b></b>" but got "<a>test</a><source></source><b></b>"
+FAIL innerHTML void as second child with following siblings track assert_equals: expected "<a>test</a><track><b></b>" but got "<a>test</a><track></track><b></b>"
+FAIL innerHTML void as second child with following siblings wbr assert_equals: expected "<a>test</a><wbr><b></b>" but got "<a>test</a><wbr></wbr><b></b>"
+FAIL innerHTML void as last child with preceding siblings area assert_equals: expected "<a>test</a><b></b><area>" but got "<a>test</a><b></b><area></area>"
+FAIL innerHTML void as last child with preceding siblings base assert_equals: expected "<a>test</a><b></b><base>" but got "<a>test</a><b></b><base></base>"
+FAIL innerHTML void as last child with preceding siblings basefont assert_equals: expected "<a>test</a><b></b><basefont>" but got "<a>test</a><b></b><basefont></basefont>"
+FAIL innerHTML void as last child with preceding siblings bgsound assert_equals: expected "<a>test</a><b></b><bgsound>" but got "<a>test</a><b></b><bgsound><a><!--abc--></a><b><c>abc</c></b></bgsound>"
+FAIL innerHTML void as last child with preceding siblings br assert_equals: expected "<a>test</a><b></b><br>" but got "<a>test</a><b></b><br></br>"
+FAIL innerHTML void as last child with preceding siblings col assert_equals: expected "<a>test</a><b></b><col>" but got "<a>test</a><b></b><col></col>"
+FAIL innerHTML void as last child with preceding siblings embed assert_equals: expected "<a>test</a><b></b><embed>" but got "<a>test</a><b></b><embed></embed>"
+FAIL innerHTML void as last child with preceding siblings frame assert_equals: expected "<a>test</a><b></b><frame>" but got "<a>test</a><b></b><frame></frame>"
+FAIL innerHTML void as last child with preceding siblings hr assert_equals: expected "<a>test</a><b></b><hr>" but got "<a>test</a><b></b><hr></hr>"
+FAIL innerHTML void as last child with preceding siblings img assert_equals: expected "<a>test</a><b></b><img>" but got "<a>test</a><b></b><img></img>"
+FAIL innerHTML void as last child with preceding siblings input assert_equals: expected "<a>test</a><b></b><input>" but got "<a>test</a><b></b><input></input>"
+FAIL innerHTML void as last child with preceding siblings keygen assert_equals: expected "<a>test</a><b></b><keygen>" but got "<a>test</a><b></b><keygen></keygen>"
+FAIL innerHTML void as last child with preceding siblings link assert_equals: expected "<a>test</a><b></b><link>" but got "<a>test</a><b></b><link></link>"
+FAIL innerHTML void as last child with preceding siblings menuitem assert_equals: expected "<a>test</a><b></b><menuitem>" but got "<a>test</a><b></b><menuitem></menuitem>"
+FAIL innerHTML void as last child with preceding siblings meta assert_equals: expected "<a>test</a><b></b><meta>" but got "<a>test</a><b></b><meta></meta>"
+FAIL innerHTML void as last child with preceding siblings param assert_equals: expected "<a>test</a><b></b><param>" but got "<a>test</a><b></b><param></param>"
+FAIL innerHTML void as last child with preceding siblings source assert_equals: expected "<a>test</a><b></b><source>" but got "<a>test</a><b></b><source></source>"
+FAIL innerHTML void as last child with preceding siblings track assert_equals: expected "<a>test</a><b></b><track>" but got "<a>test</a><b></b><track></track>"
+FAIL innerHTML void as last child with preceding siblings wbr assert_equals: expected "<a>test</a><b></b><wbr>" but got "<a>test</a><b></b><wbr></wbr>"
+FAIL outerHTML Void context node area assert_equals: expected "<area>" but got "<area></area>"
+FAIL outerHTML Void context node base assert_equals: expected "<base>" but got "<base></base>"
+FAIL outerHTML Void context node basefont assert_equals: expected "<basefont>" but got "<basefont></basefont>"
+FAIL outerHTML Void context node bgsound assert_equals: expected "<bgsound>" but got "<bgsound><a><!--abc--></a><b><c>abc</c></b></bgsound>"
+FAIL outerHTML Void context node br assert_equals: expected "<br>" but got "<br></br>"
+FAIL outerHTML Void context node col assert_equals: expected "<col>" but got "<col></col>"
+FAIL outerHTML Void context node embed assert_equals: expected "<embed>" but got "<embed></embed>"
+FAIL outerHTML Void context node frame assert_equals: expected "<frame>" but got "<frame></frame>"
+FAIL outerHTML Void context node hr assert_equals: expected "<hr>" but got "<hr></hr>"
+FAIL outerHTML Void context node img assert_equals: expected "<img>" but got "<img></img>"
+FAIL outerHTML Void context node input assert_equals: expected "<input>" but got "<input></input>"
+FAIL outerHTML Void context node keygen assert_equals: expected "<keygen>" but got "<keygen></keygen>"
+FAIL outerHTML Void context node link assert_equals: expected "<link>" but got "<link></link>"
+FAIL outerHTML Void context node menuitem assert_equals: expected "<menuitem>" but got "<menuitem></menuitem>"
+FAIL outerHTML Void context node meta assert_equals: expected "<meta>" but got "<meta></meta>"
+FAIL outerHTML Void context node param assert_equals: expected "<param>" but got "<param></param>"
+FAIL outerHTML Void context node source assert_equals: expected "<source>" but got "<source></source>"
+FAIL outerHTML Void context node track assert_equals: expected "<track>" but got "<track></track>"
+FAIL outerHTML Void context node wbr assert_equals: expected "<wbr>" but got "<wbr></wbr>"
+FAIL outerHTML void as first child with following siblings area assert_equals: expected "<span><area><a>test</a><b></b></span>" but got "<span><area></area><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings base assert_equals: expected "<span><base><a>test</a><b></b></span>" but got "<span><base></base><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings basefont assert_equals: expected "<span><basefont><a>test</a><b></b></span>" but got "<span><basefont></basefont><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings bgsound assert_equals: expected "<span><bgsound><a>test</a><b></b></span>" but got "<span><bgsound><a><!--abc--></a><b><c>abc</c></b></bgsound><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings br assert_equals: expected "<span><br><a>test</a><b></b></span>" but got "<span><br></br><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings col assert_equals: expected "<span><col><a>test</a><b></b></span>" but got "<span><col></col><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings embed assert_equals: expected "<span><embed><a>test</a><b></b></span>" but got "<span><embed></embed><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings frame assert_equals: expected "<span><frame><a>test</a><b></b></span>" but got "<span><frame></frame><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings hr assert_equals: expected "<span><hr><a>test</a><b></b></span>" but got "<span><hr></hr><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings img assert_equals: expected "<span><img><a>test</a><b></b></span>" but got "<span><img></img><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings input assert_equals: expected "<span><input><a>test</a><b></b></span>" but got "<span><input></input><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings keygen assert_equals: expected "<span><keygen><a>test</a><b></b></span>" but got "<span><keygen></keygen><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings link assert_equals: expected "<span><link><a>test</a><b></b></span>" but got "<span><link></link><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings menuitem assert_equals: expected "<span><menuitem><a>test</a><b></b></span>" but got "<span><menuitem></menuitem><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings meta assert_equals: expected "<span><meta><a>test</a><b></b></span>" but got "<span><meta></meta><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings param assert_equals: expected "<span><param><a>test</a><b></b></span>" but got "<span><param></param><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings source assert_equals: expected "<span><source><a>test</a><b></b></span>" but got "<span><source></source><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings track assert_equals: expected "<span><track><a>test</a><b></b></span>" but got "<span><track></track><a>test</a><b></b></span>"
+FAIL outerHTML void as first child with following siblings wbr assert_equals: expected "<span><wbr><a>test</a><b></b></span>" but got "<span><wbr></wbr><a>test</a><b></b></span>"
+FAIL outerHTML void as second child with following siblings area assert_equals: expected "<span><a>test</a><area><b></b></span>" but got "<span><a>test</a><area></area><b></b></span>"
+FAIL outerHTML void as second child with following siblings base assert_equals: expected "<span><a>test</a><base><b></b></span>" but got "<span><a>test</a><base></base><b></b></span>"
+FAIL outerHTML void as second child with following siblings basefont assert_equals: expected "<span><a>test</a><basefont><b></b></span>" but got "<span><a>test</a><basefont></basefont><b></b></span>"
+FAIL outerHTML void as second child with following siblings bgsound assert_equals: expected "<span><a>test</a><bgsound><b></b></span>" but got "<span><a>test</a><bgsound><a><!--abc--></a><b><c>abc</c></b></bgsound><b></b></span>"
+FAIL outerHTML void as second child with following siblings br assert_equals: expected "<span><a>test</a><br><b></b></span>" but got "<span><a>test</a><br></br><b></b></span>"
+FAIL outerHTML void as second child with following siblings col assert_equals: expected "<span><a>test</a><col><b></b></span>" but got "<span><a>test</a><col></col><b></b></span>"
+FAIL outerHTML void as second child with following siblings embed assert_equals: expected "<span><a>test</a><embed><b></b></span>" but got "<span><a>test</a><embed></embed><b></b></span>"
+FAIL outerHTML void as second child with following siblings frame assert_equals: expected "<span><a>test</a><frame><b></b></span>" but got "<span><a>test</a><frame></frame><b></b></span>"
+FAIL outerHTML void as second child with following siblings hr assert_equals: expected "<span><a>test</a><hr><b></b></span>" but got "<span><a>test</a><hr></hr><b></b></span>"
+FAIL outerHTML void as second child with following siblings img assert_equals: expected "<span><a>test</a><img><b></b></span>" but got "<span><a>test</a><img></img><b></b></span>"
+FAIL outerHTML void as second child with following siblings input assert_equals: expected "<span><a>test</a><input><b></b></span>" but got "<span><a>test</a><input></input><b></b></span>"
+FAIL outerHTML void as second child with following siblings keygen assert_equals: expected "<span><a>test</a><keygen><b></b></span>" but got "<span><a>test</a><keygen></keygen><b></b></span>"
+FAIL outerHTML void as second child with following siblings link assert_equals: expected "<span><a>test</a><link><b></b></span>" but got "<span><a>test</a><link></link><b></b></span>"
+FAIL outerHTML void as second child with following siblings menuitem assert_equals: expected "<span><a>test</a><menuitem><b></b></span>" but got "<span><a>test</a><menuitem></menuitem><b></b></span>"
+FAIL outerHTML void as second child with following siblings meta assert_equals: expected "<span><a>test</a><meta><b></b></span>" but got "<span><a>test</a><meta></meta><b></b></span>"
+FAIL outerHTML void as second child with following siblings param assert_equals: expected "<span><a>test</a><param><b></b></span>" but got "<span><a>test</a><param></param><b></b></span>"
+FAIL outerHTML void as second child with following siblings source assert_equals: expected "<span><a>test</a><source><b></b></span>" but got "<span><a>test</a><source></source><b></b></span>"
+FAIL outerHTML void as second child with following siblings track assert_equals: expected "<span><a>test</a><track><b></b></span>" but got "<span><a>test</a><track></track><b></b></span>"
+FAIL outerHTML void as second child with following siblings wbr assert_equals: expected "<span><a>test</a><wbr><b></b></span>" but got "<span><a>test</a><wbr></wbr><b></b></span>"
+FAIL outerHTML void as last child with preceding siblings area assert_equals: expected "<span><a>test</a><b></b><area></span>" but got "<span><a>test</a><b></b><area></area></span>"
+FAIL outerHTML void as last child with preceding siblings base assert_equals: expected "<span><a>test</a><b></b><base></span>" but got "<span><a>test</a><b></b><base></base></span>"
+FAIL outerHTML void as last child with preceding siblings basefont assert_equals: expected "<span><a>test</a><b></b><basefont></span>" but got "<span><a>test</a><b></b><basefont></basefont></span>"
+FAIL outerHTML void as last child with preceding siblings bgsound assert_equals: expected "<span><a>test</a><b></b><bgsound></span>" but got "<span><a>test</a><b></b><bgsound><a><!--abc--></a><b><c>abc</c></b></bgsound></span>"
+FAIL outerHTML void as last child with preceding siblings br assert_equals: expected "<span><a>test</a><b></b><br></span>" but got "<span><a>test</a><b></b><br></br></span>"
+FAIL outerHTML void as last child with preceding siblings col assert_equals: expected "<span><a>test</a><b></b><col></span>" but got "<span><a>test</a><b></b><col></col></span>"
+FAIL outerHTML void as last child with preceding siblings embed assert_equals: expected "<span><a>test</a><b></b><embed></span>" but got "<span><a>test</a><b></b><embed></embed></span>"
+FAIL outerHTML void as last child with preceding siblings frame assert_equals: expected "<span><a>test</a><b></b><frame></span>" but got "<span><a>test</a><b></b><frame></frame></span>"
+FAIL outerHTML void as last child with preceding siblings hr assert_equals: expected "<span><a>test</a><b></b><hr></span>" but got "<span><a>test</a><b></b><hr></hr></span>"
+FAIL outerHTML void as last child with preceding siblings img assert_equals: expected "<span><a>test</a><b></b><img></span>" but got "<span><a>test</a><b></b><img></img></span>"
+FAIL outerHTML void as last child with preceding siblings input assert_equals: expected "<span><a>test</a><b></b><input></span>" but got "<span><a>test</a><b></b><input></input></span>"
+FAIL outerHTML void as last child with preceding siblings keygen assert_equals: expected "<span><a>test</a><b></b><keygen></span>" but got "<span><a>test</a><b></b><keygen></keygen></span>"
+FAIL outerHTML void as last child with preceding siblings link assert_equals: expected "<span><a>test</a><b></b><link></span>" but got "<span><a>test</a><b></b><link></link></span>"
+FAIL outerHTML void as last child with preceding siblings menuitem assert_equals: expected "<span><a>test</a><b></b><menuitem></span>" but got "<span><a>test</a><b></b><menuitem></menuitem></span>"
+FAIL outerHTML void as last child with preceding siblings meta assert_equals: expected "<span><a>test</a><b></b><meta></span>" but got "<span><a>test</a><b></b><meta></meta></span>"
+FAIL outerHTML void as last child with preceding siblings param assert_equals: expected "<span><a>test</a><b></b><param></span>" but got "<span><a>test</a><b></b><param></param></span>"
+FAIL outerHTML void as last child with preceding siblings source assert_equals: expected "<span><a>test</a><b></b><source></span>" but got "<span><a>test</a><b></b><source></source></span>"
+FAIL outerHTML void as last child with preceding siblings track assert_equals: expected "<span><a>test</a><b></b><track></span>" but got "<span><a>test</a><b></b><track></track></span>"
+FAIL outerHTML void as last child with preceding siblings wbr assert_equals: expected "<span><a>test</a><b></b><wbr></span>" but got "<span><a>test</a><b></b><wbr></wbr></span>"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/syntax/serializing-html-fragments/serializing.html b/third_party/WebKit/LayoutTests/imported/wpt/html/syntax/serializing-html-fragments/serializing.html
new file mode 100644
index 0000000..6f105e77
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/syntax/serializing-html-fragments/serializing.html
@@ -0,0 +1,332 @@
+<!DOCTYPE html>
+<title>innerHTML in HTML</title>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<div id="log"></div>
+
+<!--  test elments. Each has an expected innerHTML and outerHTML in an array in the <script> -->
+<div id="test" style="display:none">
+<span></span>
+<span><a></a></span>
+<span><a b=c></a></span>
+<span><a b='c'></a></span>
+<span><a b='&'></a></span>
+<span><a b='&nbsp;'></a></span>
+<span><a b='"'></a></span>
+<span><a b="<"></a></span>
+<span><a b=">"></a></span>
+<span><svg xlink:href="a"></svg></span>
+<span><svg xmlns:svg="test"></svg></span>
+<span>a</span>
+<span>&amp;</span>
+<span>&nbsp;</span>
+<span>&lt;</span>
+<span>&gt;</span>
+<span>&quot;</span>
+<span><style><&></style></span>
+<span><script type="test"><&></script></span>
+<span><xmp><&></xmp></span>
+<span><iframe><&></iframe></span>
+<span><noembed><&></noembed></span>
+<span><noframes><&></noframes></span>
+<span><noscript><&></noscript></span>
+<span><!-- data --></span>
+<span><a><b><c></c></b><d>e</d><f><g>h</g></f></a></span>
+<span b=c></span>
+</div>
+<!--  TODO: template element  -->
+<script>
+
+var test_data = document.getElementById("test").getElementsByTagName("span");
+var expected = [
+["", "<span></span>"],
+["<a></a>", "<span><a></a></span>"],
+["<a b=\"c\"></a>", "<span><a b=\"c\"></a></span>"],
+["<a b=\"c\"></a>", "<span><a b=\"c\"></a></span>"],
+["<a b=\"&amp;\"></a>", "<span><a b=\"&amp;\"></a></span>"],
+["<a b=\"&nbsp;\"></a>", "<span><a b=\"&nbsp;\"></a></span>"],
+["<a b=\"&quot;\"></a>", "<span><a b=\"&quot;\"></a></span>"],
+["<a b=\"<\"></a>", "<span><a b=\"<\"></a></span>"],
+["<a b=\">\"></a>", "<span><a b=\">\"></a></span>"],
+["<svg xlink:href=\"a\"></svg>", "<span><svg xlink:href=\"a\"></svg></span>"],
+["<svg xmlns:svg=\"test\"></svg>", "<span><svg xmlns:svg=\"test\"></svg></span>"],
+["a", "<span>a</span>"],
+["&amp;", "<span>&amp;</span>"],
+["&nbsp;", "<span>&nbsp;</span>"],
+["&lt;", "<span>&lt;</span>"],
+["&gt;", "<span>&gt;</span>"],
+["\"", "<span>\"</span>"],
+["<style><&></style>", "<span><style><&></style></span>"],
+["<script type=\"test\"><&><\/script>", "<span><script type=\"test\"><&><\/script></span>"],
+["<xmp><&></xmp>", "<span><xmp><&></xmp></span>"],
+["<iframe><&></iframe>", "<span><iframe><&></iframe></span>"],
+["<noembed><&></noembed>", "<span><noembed><&></noembed></span>"],
+["<noframes><&></noframes>", "<span><noframes><&></noframes></span>"],
+["<noscript><&></noscript>", "<span><noscript><&></noscript></span>"],
+["<!--data-->", "<span><!--data--></span>"],
+["<a><b><c></c></b><d>e</d><f><g>h</g></f></a>", "<span><a><b><c></c></b><d>e</d><f><g>h</g></f></a></span>"],
+["", "<span b=\"c\"></span>"]
+];
+
+var dom_tests = [
+ ["Attribute in the XML namespace",
+  function() {
+       var span = document.createElement("span");
+       var svg = document.createElement("svg");
+       svg.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:foo", "test");
+       span.appendChild(svg);
+       return span;
+  },
+  '<svg xml:foo="test"></svg>',
+  '<span><svg xml:foo="test"></svg></span>'],
+
+ ["Attribute in the XML namespace with the prefix not set to xml:",
+  function() {
+       var span = document.createElement("span");
+       var svg = document.createElement("svg");
+       svg.setAttributeNS("http://www.w3.org/XML/1998/namespace", "abc:foo", "test");
+       span.appendChild(svg);
+       return span;
+  },
+  '<svg xml:foo="test"></svg>',
+  '<span><svg xml:foo="test"></svg></span>'],
+
+  ["Non-'xmlns' attribute in the xmlns namespace",
+   function() {
+       var span = document.createElement("span");
+       var svg = document.createElement("svg");
+       svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "test")
+       span.appendChild(svg);
+       return span;
+  },
+  '<svg xmlns:foo="test"></svg>',
+  '<span><svg xmlns:foo="test"></svg></span>'],
+
+  ["'xmlns' attribute in the xmlns namespace",
+   function() {
+       var span = document.createElement("span");
+       var svg = document.createElement("svg");
+       svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "test")
+       span.appendChild(svg);
+       return span;
+  },
+  '<svg xmlns="test"></svg>',
+  '<span><svg xmlns="test"></svg></span>'],
+
+ ["Attribute in non-standard namespace",
+   function() {
+       var span = document.createElement("span");
+       var svg = document.createElement("svg");
+       svg.setAttributeNS("fake_ns", "abc:def", "test")
+       span.appendChild(svg);
+       return span;
+  },
+  '<svg abc:def="test"></svg>',
+  '<span><svg abc:def="test"></svg></span>'],
+
+ ["<span> starting with U+000A",
+  function() {
+      var elem = document.createElement("span");
+      elem.appendChild(document.createTextNode("\x0A"));
+      return elem;
+  },
+  "\x0A",
+  "<span>\x0A</span>"],
+
+   //TODO: Processing instructions
+]
+
+var text_elements = ["pre", "textarea", "listing"];
+
+var text_tests = [
+ ["<%text> context starting with U+000A",
+  function(elem) {
+      elem.appendChild(document.createTextNode("\x0A"));
+      return elem;
+  },
+  "\x0A",
+  "<%text>\x0A\x0A</%text>"],
+
+ ["<%text> context not starting with U+000A",
+  function(elem) {
+      elem.appendChild(document.createTextNode("a\x0A"));
+      return elem;
+  },
+  "a\x0A",
+  "<%text>a\x0A</%text>"],
+
+ ["<%text> non-context starting with U+000A",
+  function(elem) {
+      var span = document.createElement("span");
+      elem.appendChild(document.createTextNode("\x0A"));
+      span.appendChild(elem);
+      return span;
+  },
+  "<%text>\x0A\x0A</%text>",
+  "<span><%text>\x0A\x0A</%text></span>"],
+
+ ["<%text> non-context not starting with U+000A",
+  function(elem) {
+      var span = document.createElement("span");
+      elem.appendChild(document.createTextNode("a\x0A"));
+      span.appendChild(elem);
+      return span;
+  },
+  "<%text>a\x0A</%text>",
+  "<span><%text>a\x0A</%text></span>"],
+]
+
+var void_elements = [
+  "area", "base", "basefont", "bgsound", "br", "col", "embed",
+  "frame", "hr", "img", "input", "keygen", "link", "menuitem",
+  "meta", "param", "source", "track", "wbr"
+];
+
+var void_tests = [
+ ["Void context node",
+  function (void_elem) {
+       return void_elem;
+  },
+  "",
+  "<%void>"
+ ],
+ ["void as first child with following siblings",
+  function (void_elem) {
+       var span = document.createElement("span");
+       span.appendChild(void_elem);
+       span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test"));
+       span.appendChild(document.createElement("b"))
+       return span
+  },
+  "<%void><a>test</a><b></b>",
+  "<span><%void><a>test</a><b></b></span>"
+ ],
+ ["void as second child with following siblings",
+  function (void_elem) {
+       var span = document.createElement("span");
+       span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test"));
+       span.appendChild(void_elem);
+       span.appendChild(document.createElement("b"))
+       return span;
+  },
+  "<a>test</a><%void><b></b>",
+  "<span><a>test</a><%void><b></b></span>"
+ ],
+ ["void as last child with preceding siblings",
+  function (void_elem) {
+        var span = document.createElement("span");
+        span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test"));
+        span.appendChild(document.createElement("b"))
+        span.appendChild(void_elem);
+        return span;
+  },
+  "<a>test</a><b></b><%void>",
+  "<span><a>test</a><b></b><%void></span>"
+ ],
+]
+
+function cross_map(a1, a2, f) {
+    var rv = [];
+    a1.forEach(function(a1_elem) {
+        a2.forEach(function(a2_elem) {
+            rv.push(f(a1_elem, a2_elem));
+        })
+    });
+    return rv;
+}
+
+function innerHTML_test(func, elem, expected) {
+    assert_equals(func(elem).innerHTML, expected);
+}
+
+function outerHTML_test(func, elem, expected) {
+    assert_equals(func(elem).outerHTML, expected);
+}
+
+
+function make_void(name) {
+    var rv = document.createElement(name);
+    rv.appendChild(document.createElement("a")).appendChild(document.createComment("abc"))
+    rv.appendChild(document.createElement("b")).
+        appendChild(document.createElement("c")).
+        appendChild(document.createTextNode("abc"))
+    return rv;
+}
+
+function make_text(name) {
+    return document.createElement(name);
+}
+
+generate_tests(innerHTML_test,
+               expected.map(function(item, i) {
+                                return ["innerHTML " + i + " " + expected[i][0],
+                                        function() {return test_data[i]},
+                                        null,
+                                        item[0]];
+                            }))
+
+generate_tests(outerHTML_test,
+               expected.map(function(item, i) {
+                                return ["outerHTML " + i + " " + expected[i][1],
+                                        function() {return test_data[i]},
+                                        null,
+                                        item[1]];
+                            }))
+
+generate_tests(innerHTML_test,
+               dom_tests.map(function(item) {
+                                return ["innerHTML " + item[0],
+                                        item[1],
+                                        null,
+                                        item[2]];
+                            }))
+
+generate_tests(outerHTML_test,
+               dom_tests.map(function(item) {
+                                return ["outerHTML " + item[0],
+                                        item[1],
+                                        null,
+                                        item[3]];
+                            }))
+
+generate_tests(innerHTML_test,
+               cross_map(text_tests, text_elements,
+                         function(test_data, elem_name) {
+                             var rv = ["innerHTML " + test_data[0].replace("%text", elem_name, "g"),
+                                       test_data[1],
+                                       document.createElement(elem_name),
+                                       test_data[2].replace("%text", elem_name, "g")];
+                             return rv;
+                         }))
+
+generate_tests(outerHTML_test,
+               cross_map(text_tests, text_elements,
+                         function(test_data, elem_name) {
+                             var rv = ["outerHTML " + test_data[0].replace("%text", elem_name, "g"),
+                                       test_data[1],
+                                       document.createElement(elem_name),
+                                       test_data[3].replace("%text", elem_name, "g")];
+                             return rv;
+                         }))
+
+generate_tests(innerHTML_test,
+               cross_map(void_tests, void_elements,
+                         function(test_data, elem_name) {
+                             var rv = ["innerHTML " + test_data[0] + " " + elem_name,
+                                       test_data[1],
+                                       make_void(elem_name),
+                                       test_data[2].replace("%void", elem_name, "g")];
+                             return rv;
+                         }))
+
+generate_tests(outerHTML_test,
+               cross_map(void_tests, void_elements,
+                         function(test_data, elem_name) {
+                             var rv = ["outerHTML " + test_data[0] + " " + elem_name,
+                                       test_data[1],
+                                       make_void(elem_name),
+                                       test_data[3].replace("%void", elem_name, "g")];
+                             return rv;
+                         }))
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/anim-gr.gif b/third_party/WebKit/LayoutTests/imported/wpt/images/anim-gr.gif
new file mode 100644
index 0000000..45263e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/anim-gr.gif
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/anim-gr.png b/third_party/WebKit/LayoutTests/imported/wpt/images/anim-gr.png
new file mode 100644
index 0000000..925e2ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/anim-gr.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/anim-poster-gr.png b/third_party/WebKit/LayoutTests/imported/wpt/images/anim-poster-gr.png
new file mode 100644
index 0000000..6941207
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/anim-poster-gr.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/background.png b/third_party/WebKit/LayoutTests/imported/wpt/images/background.png
new file mode 100644
index 0000000..6db6c6b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/background.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/black-rectangle.png b/third_party/WebKit/LayoutTests/imported/wpt/images/black-rectangle.png
new file mode 100644
index 0000000..a0bf1fe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/black-rectangle.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/blue-area.png b/third_party/WebKit/LayoutTests/imported/wpt/images/blue-area.png
new file mode 100644
index 0000000..570ae0f2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/blue-area.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/blue-border.png b/third_party/WebKit/LayoutTests/imported/wpt/images/blue-border.png
new file mode 100644
index 0000000..8f8e41c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/blue-border.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/blue.png b/third_party/WebKit/LayoutTests/imported/wpt/images/blue.png
new file mode 100644
index 0000000..4498dd2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/blue.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/blue96x96.png b/third_party/WebKit/LayoutTests/imported/wpt/images/blue96x96.png
new file mode 100644
index 0000000..820f8cace
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/blue96x96.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/broken.png b/third_party/WebKit/LayoutTests/imported/wpt/images/broken.png
new file mode 100644
index 0000000..f2581017
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/broken.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/canvas-line.png b/third_party/WebKit/LayoutTests/imported/wpt/images/canvas-line.png
new file mode 100644
index 0000000..30f8f45
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/canvas-line.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/fail.gif b/third_party/WebKit/LayoutTests/imported/wpt/images/fail.gif
new file mode 100644
index 0000000..c4addcf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/fail.gif
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/ggrr-256x256.png b/third_party/WebKit/LayoutTests/imported/wpt/images/ggrr-256x256.png
new file mode 100644
index 0000000..0342e4a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/ggrr-256x256.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/green-100x50.png b/third_party/WebKit/LayoutTests/imported/wpt/images/green-100x50.png
new file mode 100644
index 0000000..2b7577d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/green-100x50.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/green-16x16.png b/third_party/WebKit/LayoutTests/imported/wpt/images/green-16x16.png
new file mode 100644
index 0000000..e19a3ff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/green-16x16.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/green-1x1.png b/third_party/WebKit/LayoutTests/imported/wpt/images/green-1x1.png
new file mode 100644
index 0000000..862d1dd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/green-1x1.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/green-256x256.png b/third_party/WebKit/LayoutTests/imported/wpt/images/green-256x256.png
new file mode 100644
index 0000000..b06945c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/green-256x256.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/green-2x2.png b/third_party/WebKit/LayoutTests/imported/wpt/images/green-2x2.png
new file mode 100644
index 0000000..adc0594
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/green-2x2.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/green.png b/third_party/WebKit/LayoutTests/imported/wpt/images/green.png
new file mode 100644
index 0000000..28a1faa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/green.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/green.svg b/third_party/WebKit/LayoutTests/imported/wpt/images/green.svg
new file mode 100644
index 0000000..d91971f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/green.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="50">
+  <rect fill="lime" width="100" height="50"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/grgr-256x256.png b/third_party/WebKit/LayoutTests/imported/wpt/images/grgr-256x256.png
new file mode 100644
index 0000000..b8c7189
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/grgr-256x256.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/movie_300_frame_0.png b/third_party/WebKit/LayoutTests/imported/wpt/images/movie_300_frame_0.png
new file mode 100644
index 0000000..b7128250
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/movie_300_frame_0.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/red-16x16.png b/third_party/WebKit/LayoutTests/imported/wpt/images/red-16x16.png
new file mode 100644
index 0000000..9038fef7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/red-16x16.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/red-zeroheight.svg b/third_party/WebKit/LayoutTests/imported/wpt/images/red-zeroheight.svg
new file mode 100644
index 0000000..de378d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/red-zeroheight.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="0">
+  <rect fill="red" width="100" height="100"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/red-zerosize.svg b/third_party/WebKit/LayoutTests/imported/wpt/images/red-zerosize.svg
new file mode 100644
index 0000000..dcd3317
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/red-zerosize.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
+  <rect fill="red" width="100" height="100"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/red-zerowidth.svg b/third_party/WebKit/LayoutTests/imported/wpt/images/red-zerowidth.svg
new file mode 100644
index 0000000..66cff81
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/red-zerowidth.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="0" height="100">
+  <rect fill="red" width="100" height="100"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/red.png b/third_party/WebKit/LayoutTests/imported/wpt/images/red.png
new file mode 100644
index 0000000..a6e195d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/red.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/redtransparent.png b/third_party/WebKit/LayoutTests/imported/wpt/images/redtransparent.png
new file mode 100644
index 0000000..75da08c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/redtransparent.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/rgrg-256x256.png b/third_party/WebKit/LayoutTests/imported/wpt/images/rgrg-256x256.png
new file mode 100644
index 0000000..e6fba3da
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/rgrg-256x256.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/rrgg-256x256.png b/third_party/WebKit/LayoutTests/imported/wpt/images/rrgg-256x256.png
new file mode 100644
index 0000000..7f635156
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/rrgg-256x256.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/smiley.png b/third_party/WebKit/LayoutTests/imported/wpt/images/smiley.png
new file mode 100644
index 0000000..640a2238
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/smiley.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/threecolors.png b/third_party/WebKit/LayoutTests/imported/wpt/images/threecolors.png
new file mode 100644
index 0000000..0643e6e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/threecolors.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/transparent.png b/third_party/WebKit/LayoutTests/imported/wpt/images/transparent.png
new file mode 100644
index 0000000..2b49869
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/transparent.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/transparent50.png b/third_party/WebKit/LayoutTests/imported/wpt/images/transparent50.png
new file mode 100644
index 0000000..55f8e69
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/transparent50.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/yellow.png b/third_party/WebKit/LayoutTests/imported/wpt/images/yellow.png
new file mode 100644
index 0000000..51e8aaf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/yellow.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/images/yellow75.png b/third_party/WebKit/LayoutTests/imported/wpt/images/yellow75.png
new file mode 100644
index 0000000..2bb82c9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/images/yellow75.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/HTMLSlotElement-interface-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/HTMLSlotElement-interface-expected.txt
new file mode 100644
index 0000000..b1761816
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/HTMLSlotElement-interface-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+PASS HTMLSlotElement must be defined on window 
+PASS "name" attribute on HTMLSlotElement must reflect "name" attribute 
+PASS assignedNodes() on a HTMLSlotElement must return an empty array when the slot element is not in a tree or in a document tree 
+PASS assignedNodes({"flattened":false}) on a HTMLSlotElement must return an empty array when the slot element is not in a tree or in a document tree 
+PASS assignedNodes({"flattened":true}) on a HTMLSlotElement must return an empty array when the slot element is not in a tree or in a document tree 
+PASS assignedNodes() must return the list of assigned nodes when none of the assigned nodes themselves are slots 
+PASS assignedNodes({"flattened":false}) must return the list of assigned nodes when none of the assigned nodes themselves are slots 
+PASS assignedNodes({"flattened":true}) must return the list of assigned nodes when none of the assigned nodes themselves are slots 
+PASS assignedNodes() must update when slot and name attributes are modified 
+PASS assignedNodes({"flattened":false}) must update when slot and name attributes are modified 
+PASS assignedNodes({"flattened":true}) must update when slot and name attributes are modified 
+PASS assignedNodes must update when a default slot is introduced dynamically by a slot rename 
+PASS assignedNodes must update when a default slot is introduced dynamically by a slot rename 
+PASS assignedNodes must update when a default slot is introduced dynamically by a slot rename 
+FAIL assignedNodes must update when slot elements are inserted or removed assert_array_equals: assignedNodes on a detached formerly-default slot must return an empty array lengths differ, expected 0 got 3
+FAIL assignedNodes must update when slot elements are inserted or removed assert_array_equals: assignedNodes on a detached formerly-default slot must return an empty array lengths differ, expected 0 got 3
+FAIL assignedNodes must update when slot elements are inserted or removed assert_array_equals: assignedNodes on a detached formerly-default slot must return an empty array lengths differ, expected 0 got 3
+FAIL assignedNodes({flatten: true}) must return the distributed nodes, and assignedNodes() and assignedNodes({flatten: false}) must returned the assigned nodes assert_array_equals: assignedNodes() must return an empty array when the slot element is not in any tree lengths differ, expected 0 got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/HTMLSlotElement-interface.html b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/HTMLSlotElement-interface.html
new file mode 100644
index 0000000..2a246c8a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/HTMLSlotElement-interface.html
@@ -0,0 +1,269 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Shadow DOM: HTMLSlotElement interface</title>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="HTMLSlotElement must exist on window with name attribute and getAssignedNode() method">
+<link rel="help" href="https://w3c.github.io/webcomponents/spec/shadow/#the-slot-element">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+test(function () {
+    assert_true('HTMLSlotElement' in window, 'HTMLSlotElement must be defined on window');
+    assert_equals(HTMLSlotElement.prototype.__proto__, HTMLElement.prototype, 'HTMLSlotElement should inherit from HTMLElement');
+    assert_true(document.createElement('slot') instanceof HTMLSlotElement, 'slot element should be an instance of HTMLSlotElement');
+    assert_true(document.createElement('slot') instanceof HTMLElement, 'slot element should be an instance of HTMLElement');
+}, 'HTMLSlotElement must be defined on window');
+
+test(function () {
+    assert_true('name' in HTMLSlotElement.prototype, '"name" attribute must be defined on HTMLSlotElement.prototype');
+
+    var slotElement = document.createElement('slot');
+    assert_equals(slotElement.name, '', '"name" attribute must return the empty string when "name" content attribute is not set');
+
+    slotElement.setAttribute('name', 'foo');
+    assert_equals(slotElement.name, 'foo', '"name" attribute must return the value of the "name" content attribute');
+
+    slotElement.name = 'bar';
+    assert_equals(slotElement.name, 'bar', '"name" attribute must return the assigned value');
+    assert_equals(slotElement.getAttribute('name'), 'bar', '"name" attribute must update the "name" content attribute');
+}, '"name" attribute on HTMLSlotElement must reflect "name" attribute');
+
+function testSlotOutsideShadowTree(options)
+{
+    test(function () {
+        assert_true('assignedNodes' in HTMLSlotElement.prototype, '"assignedNodes" method must be defined on HTMLSlotElement.prototype');
+
+        var slotElement = document.createElement('slot');
+        assert_array_equals(slotElement.assignedNodes(options), [], 'assignedNodes() must return an empty array when the slot element is not in any tree');
+
+        document.body.appendChild(slotElement);
+        assert_array_equals(slotElement.assignedNodes(options), [], 'assignedNodes() must return an empty array when the slot element is in a document tree');
+
+    }, 'assignedNodes(' + (options ? JSON.stringify(options) : '')
+        + ') on a HTMLSlotElement must return an empty array when the slot element is not in a tree or in a document tree');
+}
+
+testSlotOutsideShadowTree(null);
+testSlotOutsideShadowTree({flattened: false});
+testSlotOutsideShadowTree({flattened: true});
+
+function testSingleLevelOfSlotting(options)
+{
+    test(function () {
+        assert_true('assignedNodes' in HTMLSlotElement.prototype, '"assignedNodes" method must be defined on HTMLSlotElement.prototype');
+
+        var shadowHost = document.createElement('div');
+        var child = document.createElement('p');
+
+        var shadowRoot = shadowHost.attachShadow({mode: 'open'});
+        var slotElement = document.createElement('slot');
+        shadowRoot.appendChild(slotElement);
+
+        assert_array_equals(slotElement.assignedNodes(options), [], 'assignedNodes() must return an empty array when there are no nodes in the shadow tree');
+
+        shadowHost.appendChild(child);
+        assert_array_equals(slotElement.assignedNodes(options), [child], 'assignedNodes() on a default slot must return an element without slot element');
+
+        child.setAttribute('slot', 'foo');
+        assert_array_equals(slotElement.assignedNodes(options), [], 'assignedNodes() on a default slot must not return an element with non-empty slot attribute');
+
+        child.setAttribute('slot', '');
+        assert_array_equals(slotElement.assignedNodes(options), [child], 'assignedNodes() on a default slot must return an element with empty slot attribute');
+
+        slotElement.setAttribute('name', 'bar');
+        assert_array_equals(slotElement.assignedNodes(options), [], 'assignedNodes() on a named slot must not return an element with empty slot attribute');
+
+        slotElement.setAttribute('name', '');
+        assert_array_equals(slotElement.assignedNodes(options), [child], 'assignedNodes() on an empty name slot must return an element with empty slot attribute');
+
+    }, 'assignedNodes(' + (options ? JSON.stringify(options) : '') + ') must return the list of assigned nodes when none of the assigned nodes themselves are slots');
+}
+
+testSingleLevelOfSlotting(null);
+testSingleLevelOfSlotting({flattened: false});
+testSingleLevelOfSlotting({flattened: true});
+
+function testMutatingSlottedContents(options)
+{
+    test(function () {
+        var shadowHost = document.createElement('div');
+        var p = document.createElement('p');
+        var b = document.createElement('b');
+        shadowHost.appendChild(p);
+        shadowHost.appendChild(b);
+
+        var shadowRoot = shadowHost.attachShadow({mode: 'open'});
+        var slotElement = document.createElement('slot');
+        shadowRoot.appendChild(slotElement);
+
+        assert_array_equals(slotElement.assignedNodes(options), [p, b], 'assignedNodes must return the distributed nodes');
+
+        slotElement.name = 'foo';
+        assert_array_equals(slotElement.assignedNodes(options), [], 'assignedNodes must be empty when there are no matching elements for the slot name');
+
+        b.slot = 'foo';
+        assert_array_equals(slotElement.assignedNodes(options), [b], 'assignedNodes must return the nodes with the matching slot name');
+
+        p.slot = 'foo';
+        assert_array_equals(slotElement.assignedNodes(options), [p, b], 'assignedNodes must return the nodes with the matching slot name in the tree order');
+
+        slotElement.removeAttribute('name');
+        assert_array_equals(slotElement.assignedNodes(options), [], 'assignedNodes must be empty for a default slot when all elements have "slot" attributes specified');
+
+    }, 'assignedNodes(' + (options ? JSON.stringify(options) : '') + ') must update when slot and name attributes are modified');
+}
+
+testMutatingSlottedContents(null);
+testMutatingSlottedContents({flattened: false});
+testMutatingSlottedContents({flattened: true});
+
+function testMutatingSlotName(options)
+{
+    test(function () {
+        var shadowHost = document.createElement('div');
+        var child = document.createElement('span');
+        shadowHost.appendChild(child);
+
+        var shadowRoot = shadowHost.attachShadow({mode: 'open'});
+        var slotElement = document.createElement('slot');
+        slotElement.name = 'foo';
+        shadowRoot.appendChild(slotElement);
+
+        assert_array_equals(slotElement.assignedNodes(options), [], 'assignedNodes must be empty when there are no matching elements for the slot name');
+
+        slotElement.removeAttribute('name');
+        assert_array_equals(slotElement.assignedNodes(options), [child], 'assignedNodes must be empty when there are no matching elements for the slot name');
+
+    }, 'assignedNodes must update when a default slot is introduced dynamically by a slot rename');
+}
+
+testMutatingSlotName(null);
+testMutatingSlotName({flattened: false});
+testMutatingSlotName({flattened: true});
+
+function testInsertingAndRemovingSlots(options)
+{
+    test(function () {
+        var shadowHost = document.createElement('div');
+        var p = document.createElement('p');
+        var text = document.createTextNode('');
+        var comment = document.createComment('');
+        var processingInstruction = document.createProcessingInstruction('target', 'data');
+        var b = document.createElement('b');
+        shadowHost.appendChild(p);
+        shadowHost.appendChild(text);
+        shadowHost.appendChild(comment);
+        shadowHost.appendChild(processingInstruction);
+        shadowHost.appendChild(b);
+
+        var shadowRoot = shadowHost.attachShadow({mode: 'open'});
+
+        var firstSlotElement = document.createElement('slot');
+        shadowRoot.appendChild(firstSlotElement);
+
+        var secondSlotElement = document.createElement('slot');
+        shadowRoot.appendChild(secondSlotElement);
+
+        assert_array_equals(firstSlotElement.assignedNodes(options), [p, text, b],
+            'assignedNodes on a default slot must return the elements without slot attributes and text nodes');
+        assert_array_equals(secondSlotElement.assignedNodes(options), [],
+            'assignedNodes on the second unnamed slot element must return an empty array');
+
+        shadowRoot.removeChild(firstSlotElement);
+        assert_array_equals(firstSlotElement.assignedNodes(options), [],
+            'assignedNodes on a detached formerly-default slot must return an empty array');
+        assert_array_equals(secondSlotElement.assignedNodes(options), [p, text, b],
+            'assignedNodes on the second unnamed slot element after removing the first must return the elements without slot attributes and text nodes');
+
+        shadowRoot.removeChild(secondSlotElement);
+        shadowRoot.appendChild(secondSlotElement);
+        assert_array_equals(firstSlotElement.assignedNodes(options), [],
+            'Removing and re-inserting a default slot must not change the result of assignedNodes on a detached slot');
+        assert_array_equals(secondSlotElement.assignedNodes(options), [p, text, b],
+            'Removing and re-inserting a default slot must not change the result of assignedNodes');
+
+        shadowRoot.insertBefore(firstSlotElement, secondSlotElement);
+        assert_array_equals(firstSlotElement.assignedNodes(options), [p, text, b],
+            'assignedNodes on a newly inserted unnamed slot element must return the elements without slot attributes and text nodes');
+        assert_array_equals(secondSlotElement.assignedNodes(options), [],
+            'assignedNodes on formerly-first but now second unnamed slot element must return an empty array');
+
+    }, 'assignedNodes must update when slot elements are inserted or removed');
+}
+
+testInsertingAndRemovingSlots(null);
+testInsertingAndRemovingSlots({flattened: false});
+testInsertingAndRemovingSlots({flattened: true});
+
+test(function () {
+    var outerHost = document.createElement('div');
+    var outerChild = document.createElement('span');
+    outerHost.appendChild(outerChild);
+
+    var outerShadow = outerHost.attachShadow({mode: 'closed'});
+    var innerHost = document.createElement('div');
+    var outerSlot = document.createElement('slot');
+    var innerChild = document.createElement('b');
+    outerShadow.appendChild(innerHost);
+    innerHost.appendChild(outerSlot);
+    innerHost.appendChild(innerChild);
+
+    var innerShadow = innerHost.attachShadow({mode: 'closed'});
+    var innerSlot = document.createElement('slot');
+    innerShadow.appendChild(innerSlot);
+
+    assert_array_equals(outerSlot.assignedNodes(), [outerChild], 'assignedNodes() on a default slot must return the assigned nodes');
+    assert_array_equals(outerSlot.assignedNodes({flatten: false}), [outerChild], 'assignedNodes({flatten: false}) on a default slot must return the assigned nodes');
+    assert_array_equals(outerSlot.assignedNodes({flatten: true}), [outerChild], 'assignedNodes({flatten: true}) on a default slot must return the assigned nodes if they are not themselves slots');
+
+    assert_array_equals(innerSlot.assignedNodes(), [outerSlot, innerChild], 'assignedNodes() on a default slot must return the assigned nodes');
+    assert_array_equals(innerSlot.assignedNodes({flatten: false}), [outerSlot, innerChild], 'assignedNodes({flatten: false}) on a default slot must return the assigned nodes');
+    assert_array_equals(innerSlot.assignedNodes({flatten: true}), [outerChild, innerChild], 'assignedNodes({flatten: true}) on a default slot must return the distributed nodes');
+
+    outerSlot.name = 'foo';
+    assert_array_equals(outerSlot.assignedNodes(), [], 'assignedNodes() on a named slot must return an empty array if there are no matching elements');
+    assert_array_equals(outerSlot.assignedNodes({flatten: false}), [], 'assignedNodes({flatten: false}) on a named slot must return an empty array if there are no matching elements');
+    assert_array_equals(outerSlot.assignedNodes({flatten: true}), [], 'assignedNodes({flatten: true}) on a named slot must return an empty array if there are no matching elements');
+
+    assert_array_equals(innerSlot.assignedNodes(), [outerSlot, innerChild], 'assignedNodes() on a default slot must return the assigned nodes');
+    assert_array_equals(innerSlot.assignedNodes({flatten: false}), [outerSlot, innerChild], 'assignedNodes({flatten: false}) on a default slot must return the assigned nodes');
+    assert_array_equals(innerSlot.assignedNodes({flatten: true}), [innerChild], 'assignedNodes({flatten: true}) on a default slot must return the distributed nodes');
+
+    outerChild.slot = 'foo';
+    assert_array_equals(outerSlot.assignedNodes(), [outerChild], 'assignedNodes() on a named slot must return matching elements');
+    assert_array_equals(outerSlot.assignedNodes({flatten: false}), [outerChild], 'assignedNodes({flatten: false}) on a named slot must return matching elements');
+    assert_array_equals(outerSlot.assignedNodes({flatten: true}), [outerChild], 'assignedNodes({flatten: true}) on a named slot must return matching elements');
+
+    assert_array_equals(innerSlot.assignedNodes(), [outerSlot, innerChild], 'assignedNodes() on a default slot must return the assigned nodes');
+    assert_array_equals(innerSlot.assignedNodes({flatten: false}), [outerSlot, innerChild], 'assignedNodes({flatten: false}) on a default slot must return the assigned nodes');
+    assert_array_equals(innerSlot.assignedNodes({flatten: true}), [outerChild, innerChild], 'assignedNodes({flatten: true}) on a default slot must return the distributed nodes');
+
+    var newInnerSlot = document.createElement('slot');
+    innerShadow.insertBefore(newInnerSlot, innerSlot);
+    assert_array_equals(newInnerSlot.assignedNodes(), [outerSlot, innerChild], 'assignedNodes() on a default slot must return the assigned nodes');
+    assert_array_equals(newInnerSlot.assignedNodes({flatten: false}), [outerSlot, innerChild], 'assignedNodes({flatten: false}) on a default slot must return the assigned nodes');
+    assert_array_equals(newInnerSlot.assignedNodes({flatten: true}), [outerChild, innerChild], 'assignedNodes({flatten: true}) on a default slot must return the distributed nodes');
+
+    assert_array_equals(innerSlot.assignedNodes(), [], 'assignedNodes() on a nameless slot element which appears after a default slot must return an empty array');
+    assert_array_equals(innerSlot.assignedNodes({flatten: false}), [], 'assignedNodes({flatten: false}) on a nameless slot element which appears after a default slot must return an empty array');
+    assert_array_equals(innerSlot.assignedNodes({flatten: true}), [], 'assignedNodes({flatten: true}) on a nameless slot element which appears after a default slot must return an empty array');
+
+    innerShadow.removeChild(newInnerSlot);
+    assert_array_equals(newInnerSlot.assignedNodes(), [], 'assignedNodes() must return an empty array when the slot element is not in any tree');
+    assert_array_equals(newInnerSlot.assignedNodes({flatten: false}), [], 'assignedNodes({flatten: false}) must return an empty array when the slot element is not in any tree');
+    assert_array_equals(newInnerSlot.assignedNodes({flatten: true}), [], 'assignedNodes({flatten: true}) must return an empty array when the slot element is not in any tree');
+
+    assert_array_equals(innerSlot.assignedNodes(), [outerSlot, innerChild], 'assignedNodes() on a default slot must return the assigned nodes');
+    assert_array_equals(innerSlot.assignedNodes({flatten: false}), [outerSlot, innerChild], 'assignedNodes({flatten: false}) on a default slot must return the assigned nodes');
+    assert_array_equals(innerSlot.assignedNodes({flatten: true}), [outerChild, innerChild], 'assignedNodes({flatten: true}) on a default slot must return the distributed nodes');
+
+}, 'assignedNodes({flatten: true}) must return the distributed nodes, and assignedNodes() and assignedNodes({flatten: false}) must returned the assigned nodes');
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/leaktests/get-elements.html b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/leaktests/get-elements.html
new file mode 100644
index 0000000..27689b9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/leaktests/get-elements.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name='author' title='Google' href='http://www.google.com'>
+<meta name='assert' content='getElement* API in document should not leak any node in shadow tree.'>
+<link rel='help' href='https://w3c.github.io/webcomponents/spec/shadow/'>
+<script src='../../../../resources/testharness.js'></script>
+<script src='../../../../resources/testharnessreport.js'></script>
+</head>
+<body>
+
+<!--  This template will be filled in '#doc', '#host-open', and '#host-closed' below  -->
+<template id='domtree-template'>
+  <span id='foo'></span>
+  <div class='bar'></div>
+  <form name='baz'></form>
+  <my-element></my-element>
+</template>
+
+<div id='doc'>
+  <div id='host-open'></div>
+  <div id='host-closed'></div>
+</div>
+
+</body>
+<script>
+'use strict';
+
+function fillTemplate(root, prefix) {
+    var tmpl = document.getElementById('domtree-template');
+    root.appendChild(document.importNode(tmpl.content, true));
+    for (var i = 0; i < root.childNodes.length; ++i) {
+        var el = root.childNodes[i];
+        if (el.nodeType != 1)
+            continue;
+        el.setAttribute('label', prefix + el.tagName.toLowerCase());
+    }
+
+    root.appendChild(document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient'));
+}
+
+// Construct subtree with 'doc-*' ids.
+var doc = document.getElementById('doc');
+fillTemplate(doc, 'doc-');
+
+// Construct shadow subtree with 'shadow-*' ids.
+var hostOpen = document.getElementById('host-open');
+var shadowOpen = hostOpen.attachShadow({mode: 'open'});
+fillTemplate(shadowOpen, 'shadow-open-');
+
+var hostClosed = document.getElementById('host-closed');
+var shadowClosed = hostClosed.attachShadow({mode: 'closed'});
+fillTemplate(shadowClosed, 'shadow-closed-');
+
+test(function() {
+    // getElementById() (NonElementParentNode)
+    assert_equals(document.querySelectorAll('#foo').length, 1);
+    assert_equals(document.getElementById('foo').getAttribute('label'), 'doc-span');
+    assert_equals(document.querySelector('#foo').getAttribute('label'), 'doc-span');
+
+    assert_equals(doc.querySelectorAll('#foo').length, 1);
+    assert_equals(doc.querySelector('#foo').getAttribute('label'), 'doc-span');
+
+    assert_equals(hostOpen.querySelectorAll('#foo').length, 0);
+
+    assert_equals(shadowOpen.querySelectorAll('#foo').length, 1);
+    assert_equals(shadowOpen.getElementById('foo').getAttribute('label'), 'shadow-open-span');
+    assert_equals(shadowOpen.querySelector('#foo').getAttribute('label'), 'shadow-open-span');
+
+    assert_equals(hostClosed.querySelectorAll('#foo').length, 0);
+
+    assert_equals(shadowClosed.querySelectorAll('#foo').length, 1);
+    assert_equals(shadowClosed.getElementById('foo').getAttribute('label'), 'shadow-closed-span');
+    assert_equals(shadowClosed.querySelector('#foo').getAttribute('label'), 'shadow-closed-span');
+}, 'getElementsById() should not leak nodes in shadow tree');
+
+test(function() {
+    // getElementsByClassName() (Element, Document)
+    assert_equals(document.getElementsByClassName('bar').length, 1);
+    assert_equals(document.getElementsByClassName('bar')[0].getAttribute('label'), 'doc-div');
+    assert_equals(document.getElementsByClassName('bar').length, 1);
+    assert_equals(document.getElementsByClassName('bar')[0].getAttribute('label'), 'doc-div');
+    assert_equals(document.querySelectorAll('.bar').length, 1);
+
+    assert_equals(doc.querySelectorAll('.bar').length, 1);
+    assert_equals(doc.getElementsByClassName('bar')[0].getAttribute('label'), 'doc-div');
+
+    assert_array_equals(hostOpen.querySelectorAll('.bar').length, 0);
+
+    assert_equals(shadowOpen.querySelectorAll('.bar').length, 1);
+    assert_equals(shadowOpen.querySelectorAll('.bar')[0].getAttribute('label'), 'shadow-open-div');
+
+    assert_array_equals(hostClosed.querySelectorAll('.bar').length, 0);
+
+    assert_equals(shadowClosed.querySelectorAll('.bar').length, 1);
+    assert_equals(shadowClosed.querySelectorAll('.bar')[0].getAttribute('label'), 'shadow-closed-div');
+}, 'getElementsByClassName() should not leak nodes in shadow tree');
+
+test(function() {
+    // getElementsByName (Document)
+    assert_equals(document.getElementsByName('baz').length, 1);
+    assert_equals(document.getElementsByName('baz')[0].getAttribute('label'), 'doc-form');
+    assert_equals(document.getElementsByName('baz').length, 1);
+    assert_equals(document.getElementsByName('baz')[0].getAttribute('label'), 'doc-form');
+    assert_equals(document.querySelectorAll('[name=baz]').length, 1);
+
+    assert_equals(doc.querySelectorAll('[name=baz]').length, 1);
+
+    assert_array_equals(hostOpen.querySelectorAll('[name=baz]').length, 0);
+    assert_equals(shadowOpen.querySelectorAll('[name=baz]').length, 1);
+    assert_equals(shadowOpen.querySelectorAll('[name=baz]')[0].getAttribute('label'), 'shadow-open-form');
+
+    assert_array_equals(hostClosed.querySelectorAll('[name=baz]').length, 0);
+    assert_equals(shadowClosed.querySelectorAll('[name=baz]').length, 1);
+    assert_equals(shadowClosed.querySelectorAll('[name=baz]')[0].getAttribute('label'), 'shadow-closed-form');
+}, 'getElementsByName() should not leak nodes in shadow tree');
+
+test(function() {
+    // getElementsByTagName (Element, Document)
+    assert_equals(document.getElementsByTagName('my-element').length, 1);
+    assert_equals(document.getElementsByTagName('my-element')[0].getAttribute('label'), 'doc-my-element');
+    assert_equals(document.getElementsByTagName('my-element').length, 1);
+    assert_equals(document.getElementsByTagName('my-element')[0].getAttribute('label'), 'doc-my-element');
+    assert_equals(document.querySelectorAll('my-element').length, 1);
+
+    assert_equals(doc.querySelectorAll('my-element').length, 1);
+    assert_equals(doc.getElementsByTagName('my-element')[0].getAttribute('label'), 'doc-my-element');
+
+    assert_array_equals(hostOpen.querySelectorAll('my-element').length, 0);
+    // ShadowRoot isn't an Element, does not have getElementsByTagName().
+    assert_equals(shadowOpen.querySelectorAll('my-element').length, 1);
+    assert_equals(shadowOpen.querySelectorAll('my-element')[0].getAttribute('label'), 'shadow-open-my-element');
+
+    assert_array_equals(hostClosed.querySelectorAll('my-element').length, 0);
+    assert_equals(shadowClosed.querySelectorAll('my-element').length, 1);
+    assert_equals(shadowClosed.querySelectorAll('my-element')[0].getAttribute('label'), 'shadow-closed-my-element');
+}, 'getElementsByTagName() should not leak nodes in shadow tree');
+
+test(function() {
+    // getElementsByTagNameNS (Element, Document)
+    assert_equals(document.getElementsByTagName('lineargradient').length, 0);
+    assert_equals(document.getElementsByTagNameNS('*', 'lineargradient').length, 0);
+    assert_equals(document.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'lineargradient').length, 0);
+    assert_equals(document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'lineargradient').length, 0);
+
+    assert_equals(document.getElementsByTagName('linearGradient').length, 1);
+    assert_equals(document.getElementsByTagNameNS('*', 'linearGradient').length, 1);
+    assert_equals(document.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'linearGradient').length, 1);
+    assert_equals(document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'linearGradient').length, 0);
+
+    assert_equals(doc.getElementsByTagName('lineargradient').length, 0);
+    assert_equals(doc.getElementsByTagNameNS('*', 'lineargradient').length, 0);
+    assert_equals(doc.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'lineargradient').length, 0);
+    assert_equals(doc.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'lineargradient').length, 0);
+
+    assert_equals(doc.getElementsByTagName('linearGradient').length, 1);
+    assert_equals(doc.getElementsByTagNameNS('*', 'linearGradient').length, 1);
+    assert_equals(doc.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'linearGradient').length, 1);
+    assert_equals(doc.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'linearGradient').length, 0);
+
+    assert_equals(hostOpen.getElementsByTagName('linearGradient').length, 0);
+    assert_equals(hostOpen.getElementsByTagNameNS('*', 'linearGradient').length, 0);
+    assert_equals(hostOpen.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'linearGradient').length, 0);
+    assert_equals(hostOpen.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'linearGradient').length, 0);
+
+    assert_equals(hostClosed.getElementsByTagName('linearGradient').length, 0);
+    assert_equals(hostClosed.getElementsByTagNameNS('*', 'linearGradient').length, 0);
+    assert_equals(hostClosed.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'linearGradient').length, 0);
+    assert_equals(hostClosed.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'linearGradient').length, 0);
+
+    // ShadowRoot isn't an Element, does not have getElementsByTagNameNS().
+}, 'getElementsByTagNameNS() should not leak nodes in shadow tree');
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/leaktests/window-frames.html b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/leaktests/window-frames.html
new file mode 100644
index 0000000..561cdf89
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/leaktests/window-frames.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name='author' title='Google' href='http://www.google.com'>
+<meta name='assert' content='Shadow DOM should not leak via window.frames.'>
+<link rel='help' href='https://w3c.github.io/webcomponents/spec/shadow/'>
+<script src='../../../../resources/testharness.js'></script>
+<script src='../../../../resources/testharnessreport.js'></script>
+</head>
+<body>
+<div id='log'></div>
+<iframe src='about:blank' name='mainFrame1'></iframe>
+<div id='host-open'></div>
+<div id='host-closed'></div>
+</body>
+<script>
+'use strict';
+
+var host_open = document.getElementById('host-open');
+var root_open = host_open.attachShadow({mode: 'open'});
+root_open.innerHTML = '<iframe src="about:blank" name="shadowFrame1"></iframe>';
+
+var host_closed = document.getElementById('host-closed');
+var root_closed = host_closed.attachShadow({mode: 'closed'});
+root_closed.innerHTML = '<iframe src="about:blank" name="shadowFrame2"></iframe>';
+
+test(() => {
+  assert_equals(window.frames.length, 1, 'window.frames should return only frames in document.');
+  assert_equals(window.frames[0].name, 'mainFrame1', 'window.frames[0] should be mainFrame1.');
+  assert_equals(window.frames['mainFrame1'], window.frames[0], 'window.frames[\'mainFrame1\'] should be equal to mainFrame1.');
+  assert_equals(window.frames['shadowFrame1'], undefined, 'shadowFrame1 should not leak.');
+  assert_equals(window.frames['shadowFrame2'], undefined, 'shadowFrame2 should not leak.');
+
+}, 'window.frames should not leak frames in Shadow DOM.');
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/scroll-to-the-fragment-in-shadow-tree.html b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/scroll-to-the-fragment-in-shadow-tree.html
new file mode 100644
index 0000000..b245782
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/shadow-dom/scroll-to-the-fragment-in-shadow-tree.html
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Shadow DOM: The indicated part of the document should not match an element inside a shadow tree</title>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="An element inside a shadow tree should not be the indicated part of the document even if its ID is exactly equal to the decoded fragid or its name attribute is exactly equal to the fragid">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/browsers.html#scroll-to-the-fragment-identifier">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<div id="testContainer"></div>
+<script>
+
+var tests = [
+    {test: async_test('The user agent scroll to the fragment when there is an element with an ID exactly equal to the decoded fragid'),
+        execute: testScrollingToElementInDocumentTree.bind(this, 'div')},
+    {test: async_test('The user agent scroll to the fragment when there is an anchor element with a name attribute exactly equal to the decoded fragid'),
+        execute: testScrollingToElementInDocumentTree.bind(this, 'a')},
+
+    {test: async_test('The user agent should not scroll to an element with an ID exactly equal to the decoded fragid in an open shadow tree'),
+        execute: testScrollingToElementInShadowTree.bind(this, 'div', 'open')},
+    {test: async_test('The user agent should not scroll to an element with an ID exactly equal to the decoded fragid in a closed shadow tree'),
+        execute: testScrollingToElementInShadowTree.bind(this, 'div', 'closed')},
+    {test: async_test('The user agent should not scroll to an anchor element with a name attribute exactly equal to the decoded fragid in an open shadow tree'),
+        execute: testScrollingToElementInShadowTree.bind(this, 'a', 'open')},
+    {test: async_test('The user agent should not scroll to an anchor element with a name attribute exactly equal to the decoded fragid in a closed shadow tree'),
+        execute: testScrollingToElementInShadowTree.bind(this, 'a', 'closed')},
+
+    {test: async_test('The user agent should scroll to an element with an ID exactly equal to the decoded fragid in the document tree'
+        + ' even if there was another element with the same ID inside an open shadow tree earlier in tree order'),
+        execute: testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID.bind(this, 'div', 'open')},
+    {test: async_test('The user agent should scroll to an element with an ID exactly equal to the decoded fragid in the document tree'
+        + ' even if there was another element with the same ID inside a closed shadow tree earlier in tree order'),
+        execute: testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID.bind(this, 'div', 'closed')},
+    {test: async_test('The user agent should scroll to an anchor element with a name attribute exactly equal to the decoded fragid in the document tree'
+        + ' even if there was another element with the same ID inside an open shadow tree earlier in tree order'),
+        execute: testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID.bind(this, 'a', 'open')},
+    {test: async_test('The user agent should scroll to an anchor element with a name attribute exactly equal to the decoded fragid in the document tree'
+        + ' even if there was another element with the same ID inside a closed shadow tree earlier in tree order'),
+        execute: testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID.bind(this, 'a', 'closed')},
+];
+
+function executeNextTest()
+{
+    window.scrollTo(0, 0);
+
+    currentFragIdSuffix++;
+    var nextTest = tests.shift();
+    if (!nextTest)
+        return;
+    setTimeout(function () {
+        nextTest.execute(nextTest.test);
+    }, 0);
+}
+
+var testContainer = document.getElementById('testContainer');
+var currentFragIdSuffix = 0;
+
+function tallElementMarkup()
+{
+    return '<div style="height: ' + (window.innerHeight * 2) + 'px"><a href="#fragid' + currentFragIdSuffix + '">Go to fragment</a></div>';
+}
+
+function targetMarkup(elementType)
+{
+    return elementType == 'div' ? ('<div id="fragid' + currentFragIdSuffix + '">hello</div>') : ('<a name="fragid' + currentFragIdSuffix + '">hello</a>');
+}
+
+function clickFirstAnchorAndRunStep(test, step)
+{
+    setTimeout(function () {
+        testContainer.querySelector('a').click();
+        setTimeout(function () {
+            test.step(step);
+            testContainer.innerHTML = '';
+            test.done();
+            executeNextTest();
+        }, 0);
+    }, 0);
+}
+
+function testScrollingToElementInDocumentTree(elementType, test)
+{
+    test.step(function () {
+        testContainer.innerHTML = tallElementMarkup() + targetMarkup(elementType);
+        assert_equals(window.pageYOffset, 0);
+    });
+    clickFirstAnchorAndRunStep(test, function () {
+        assert_not_equals(window.pageYOffset, 0);
+    });
+}
+
+function testScrollingToElementInShadowTree(elementType, mode, test)
+{
+    test.step(function () {
+        testContainer.innerHTML = tallElementMarkup() + '<div id="host"></div>';
+        var host = document.querySelector('#host');
+        var shadowRoot = host.attachShadow({mode: mode});
+        shadowRoot.innerHTML = targetMarkup(elementType);
+        assert_equals(window.pageYOffset, 0);
+    });
+    clickFirstAnchorAndRunStep(test, function () {
+        assert_equals(window.pageYOffset, 0);
+    });
+}
+
+function testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID(elementType, mode, test)
+{
+    test.step(function () {
+        testContainer.innerHTML = tallElementMarkup() + '<div id="host"></div>' + tallElementMarkup() + targetMarkup(elementType);
+        var host = document.querySelector('#host');
+        var shadowRoot = host.attachShadow({mode: mode});
+        shadowRoot.innerHTML = targetMarkup(elementType);
+        assert_equals(window.pageYOffset, 0);
+    });
+    clickFirstAnchorAndRunStep(test, function () {
+        assert_true(window.pageYOffset > testContainer.querySelector('#host').offsetTop);
+    });
+}
+
+executeNextTest();
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/DOM.event.flow.html b/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/DOM.event.flow.html
deleted file mode 100644
index 513ab79..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/DOM.event.flow.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title> Event dispatch and DOM event flow </title>
-<script src="../../../../../resources/testharness.js"></script>
-<script src="../../../../../resources/testharnessreport.js"></script>
-</head>
-<body>
-<div id=log></div>
-
-<table id="table" border="1" style="display: none">
-    <tbody id="table-body">
-    <tr id="table-row">
-        <td id="table-cell">Shady Grove</td>
-        <td>Aeolian</td>
-    </tr>
-    <tr id="parent">
-        <td id="target">Over the river, Charlie</td>
-        <td>Dorian</td>
-    </tr>
-    </tbody>
-</table>
-
-<script>
-    var EVENT = "foo";
-    var TARGET = document.getElementById("target");
-    var PARENT = document.getElementById("parent");
-    var TBODY = document.getElementById("table-body");
-    var TABLE = document.getElementById("table");
-    var BODY = document.body;
-    var HTML = document.documentElement;
-    var CurrentTargets = [window, document, HTML, BODY, TABLE, TBODY, PARENT, TARGET];
-    var ExpectResult = CurrentTargets.concat([TARGET, PARENT, TBODY, TABLE, BODY, HTML, document, window]);
-    var ActualResult = [];
-    var ExpectPhases = [1,1,1,1,1,1,1,2,2,3,3,3,3,3,3,3,];
-    var ActualPhases = [];
-
-    var description = "Test Description: Dispatch an event in a DOM tree using the DOM event flow.";
-
-    test(function()
-    {
-        for (var i=0; i < CurrentTargets.length; i++)
-        {
-            CurrentTargets[i].addEventListener(EVENT, TestEvent, true);
-            CurrentTargets[i].addEventListener(EVENT, TestEvent, false);
-        }
-
-        var evt = document.createEvent("Event");
-        evt.initEvent(EVENT, true, true);
-        TARGET.dispatchEvent(evt);
-
-        assert_array_equals(ActualResult, ExpectResult, "ActualResult");
-        assert_array_equals(ActualPhases, ExpectPhases, "ActualPhases");
-
-    }, description);
-
-    function TestEvent(evt)
-    {
-        ActualResult.push(evt.currentTarget);
-        ActualPhases.push(evt.eventPhase);
-    }
-</script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventListener.eventHandler.html b/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventListener.eventHandler.html
deleted file mode 100644
index 5df58b95..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventListener.eventHandler.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title> EventLister member: handleEvent() </title>
-<script src="../../../../../resources/testharness.js"></script>
-<script src="../../../../../resources/testharnessreport.js"></script>
-</head>
-<body>
-<div id=log></div>
-
-<table id="table" border="1" style="display: none">
-    <tbody id="table-body">
-    <tr id="table-row">
-        <td id="table-cell">Shady Grove</td>
-        <td>Aeolian</td>
-    </tr>
-    <tr id="parent">
-        <td id="target">Over the river, Charlie</td>
-        <td>Dorian</td>
-    </tr>
-    </tbody>
-</table>
-
-<script>
-    var EVENT = "foo";
-    var TARGET = document.getElementById("target");
-    var TestResult = false;
-
-    var description = "Test Description: " +
-                      "handleEvent - This method shall be called whenever an event occurs of the event type for " +
-                      "which the EventListener interface was registered.";
-
-    var EventListener = {};
-    EventListener.handleEvent = function(evt)
-    {
-        if ((EVENT == evt.type) && (TARGET == evt.target) && (this === EventListener))
-        {
-            TestResult = true;
-        }
-        else
-        {
-            TestResult = false;
-        }
-    }
-
-    test(function()
-    {
-        var evt = document.createEvent("Event");
-        evt.initEvent(EVENT, true, true);
-
-        TARGET.addEventListener(EVENT, EventListener, true);
-        TARGET.dispatchEvent(evt);
-        TARGET.removeEventListener(EVENT, EventListener, true);
-
-        assert_true(TestResult);
-
-    }, description);
-</script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventObject.multiple.dispatchEvent-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventObject.multiple.dispatchEvent-expected.txt
deleted file mode 100644
index 2ee74a0..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventObject.multiple.dispatchEvent-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test Description: An event object may be properly dispatched multiple times while also allowing to prevent the event objects propagation prior to the event dispatch. assert_array_equals: lengths differ, expected 5 got 2
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventObject.multiple.dispatchEvent.html b/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventObject.multiple.dispatchEvent.html
deleted file mode 100644
index 2ddaf70..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/legacy-domevents-tests/approved/EventObject.multiple.dispatchEvent.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title> Multiple dispatchEvent() and stopPropagation() </title>
-<script src="../../../../../resources/testharness.js"></script>
-<script src="../../../../../resources/testharnessreport.js"></script>
-</head>
-<body>
-<div id=log></div>
-
-<div id="parent" style="display: none">
-    <input id="target" type="hidden" value=""/>
-</div>
-
-<script>
-    var EVENT = "foo";
-    var TARGET = document.getElementById("target");
-    var PARENT = document.getElementById("parent");
-    var ExpectResult = [TARGET, PARENT, PARENT, document, window];
-    var ActualResult = [];
-
-    var description = "Test Description: " +
-                      "An event object may be properly dispatched multiple times while also allowing to prevent the event objects " +
-                      "propagation prior to the event dispatch.";
-
-    test(function()
-    {
-        var evt = document.createEvent("Event");
-        evt.initEvent(EVENT, true, true);
-
-        TARGET.addEventListener(EVENT, TestEvent, false);
-        PARENT.addEventListener(EVENT, TestEvent, false);
-        document.addEventListener(EVENT, TestEvent, false);
-        window.addEventListener(EVENT, TestEvent, false);
-
-        TARGET.dispatchEvent(evt);
-        PARENT.dispatchEvent(evt);
-        document.dispatchEvent(evt);
-
-        assert_array_equals(ActualResult, ExpectResult);
-
-    }, description);
-
-    function TestEvent(evt)
-    {
-        ActualResult.push(evt.currentTarget);
-
-        if (PARENT == evt.currentTarget)
-        {
-            evt.stopPropagation();
-        }
-    }
-</script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-and-window-error-event-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-and-window-error-event-expected.txt
deleted file mode 100644
index 2b6afc3..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-and-window-error-event-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CONSOLE ERROR: line 22: Uncaught Error: Error from listener
-This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = Uncaught Error: Error from listener
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-and-window-error-event.html b/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-and-window-error-event.html
deleted file mode 100644
index 17523d0f..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-and-window-error-event.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<meta charset="UTF-8">
-<title>Throwing in event listener generates an error event on the window object</title>
-
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
-<div id="log"></div>
-
-<script>
-    var t = async_test("Throwing in event listener generates an error event on the window object");
-
-    var errorEvent = false;
-
-    window.onerror = function(e) {
-        errorEvent = e;
-    }
-
-    document.addEventListener('DOMContentLoaded', t.step_func(function(){
-        var element = document.getElementById('bim');
-
-        element.addEventListener('click', function(){
-            throw new Error('Error from listener');
-        });
-
-        element.click();
-
-        assert_equals(typeof errorEvent, 'string');
-        t.done();
-    }));
-</script>
-
-<div id="bim">
-</div>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-when-all-have-not-run-yet.html b/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-when-all-have-not-run-yet.html
deleted file mode 100644
index 7becbb1..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/uievents/throwing-in-listener-when-all-have-not-run-yet.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<meta charset="UTF-8">
-<title>Throwing in event listener</title>
-
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
-<div id="log"></div>
-
-<script>
-    setup({allow_uncaught_exception:true})
-    var t = async_test("Throwing in event listener");
-
-    document.addEventListener('DOMContentLoaded', t.step_func(function(){
-        var element = document.getElementById('bim');
-
-        var secondCalled = false;
-
-        element.addEventListener('click', function(){
-            throw new Error('Error from listener');
-        });
-        element.addEventListener('click', t.step_func(function(){ secondCalled = true; }), false);
-
-        element.click();
-
-        assert_true(secondCalled);
-        t.done();
-    }));
-</script>
-
-<div id="bim">
-</div>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/README.md b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/README.md
index 7afc875..ca01178a 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/README.md
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/README.md
@@ -1,4 +1,107 @@
-Web Animations Tests
-====================
+Web Animations Test Suite
+=========================
 
-Specification: http://w3c.github.io/web-animations/
+Specification: https://w3c.github.io/web-animations/
+
+
+Guidelines for writing tests
+----------------------------
+
+*   Try to follow the spec outline where possible.
+
+    For example, if you want to test setting the start time, you might be
+    tempted to put all the tests in:
+
+    > `/web-animations/Animation/startTime.html`
+
+    However, in the spec most of the logic is in the &ldquo;Set the animation
+    start time&ldquo; procedure in the &ldquo;Timing model&rdquo; section.
+
+    Instead, try something like:
+
+    > *   `/web-animations/timing-model/animation/set-the-animation-start-time.html`<br>
+    >     Tests all the branches and inputs to the procedure as defined in the
+    >     spec (using the `Animation.startTime` API).
+    > *   `/web-animations/Animation/startTime.html`<br>
+    >     Tests API-layer specific issues like mapping unresolved values to
+    >      null, etc.
+
+    On that note, two levels of subdirectories is enough even if the spec has
+    deeper nesting.
+
+    Note that most of the existing tests in the suite _don't_ do this well yet.
+    That's the direction we're heading, however.
+
+*   Test the spec.
+
+    *   If the spec defines a timing calculation that is directly
+        reflected in the iteration progress
+        (i.e. `anim.effect.getComputedTiming().progress`), test that instead
+        of calling `getComputedStyle(elem).marginLeft`.
+
+    *   Likewise, don't add needless tests for `anim.playbackState`.
+        The playback state is a calculated value based on other values.
+        It's rarely necessary to test directly unless you need, for example,
+        to check that a pending task is scheduled (which isn't observable
+        elsewhere other than waiting for the corresponding promise to
+        complete).
+
+*   Try to keep tests as simple and focused as possible.
+
+    e.g.
+
+    ```javascript
+  test(function(t) {
+    var anim = createDiv(t).animate(null);
+    assert_class_string(anim, 'Animation', 'Returned object is an Animation');
+  }, 'Element.animate() creates an Animation object');
+    ```
+
+    ```javascript
+  test(function(t) {
+    assert_throws({ name: 'TypeError' }, function() {
+      createDiv(t).animate(null, -1);
+    });
+  }, 'Setting a negative duration throws a TypeError');
+    ```
+
+    ```javascript
+  promise_test(function(t) {
+    var animation = createDiv(t).animate(null, 100 * MS_PER_SEC);
+    return animation.ready.then(function() {
+      assert_greater_than(animation.startTime, 0, 'startTime when running');
+    });
+  }, 'startTime is resolved when running');
+    ```
+
+    If you're generating complex test loops and factoring out utility functions
+    that affect the logic of the test (other than, say, simple assertion utility
+    functions), you're probably doing it wrong.
+
+    It should be possible to understand exactly what the test is doing at a
+    glance without having to scroll up and down the test file and refer to
+    other files.
+
+    See Justin Searls' presentation, [&ldquo;How to stop hating your
+    tests&rdquo;](http://blog.testdouble.com/posts/2015-11-16-how-to-stop-hating-your-tests.html)
+    for some tips on making your tests simpler.
+
+*   Assume tests will run on under-performing hardware where the time between
+    animation frames might run into 10s of seconds.
+    As a result, animations that are expected to still be running during
+    the test should be at least 100s in length.
+
+*   Avoid using `GLOBAL_CONSTS` that make the test harder to read.
+    It's fine to repeat the the same parameter values like `100 * MS_PER_SEC`
+    over and over again since it makes it easy to read and debug a test in
+    isolation.
+    Remember, even if we do need to make all tests take, say 200s each, text
+    editors are very good at search and replace.
+
+*   Use the `assert_times_equal` assertion for comparing calculated times.
+    It tests times are equal using the precision recommended in the spec whilst
+    allowing implementations to override the function to meet their own
+    precision requirements.
+
+*   There are quite a few bad tests in the repository. We're learning as
+    we go. Don't just copy them blindly&mdash;please fix them!
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animatable/animate-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animatable/animate-expected.txt
deleted file mode 100644
index d5b5f82c..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animatable/animate-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Element.animate() creates an Animation object 
-PASS Element.animate() creates an Animation object with a KeyframeEffect 
-FAIL Element.animate() accepts a property-indexed keyframe specification anim.effect.getFrames is not a function
-FAIL Element.animate() accepts a frame-indexed keyframe specification anim.effect.getFrames is not a function
-FAIL Element.animate() accepts a single-valued keyframe specification anim.effect.getFrames is not a function
-PASS Element.animate() accepts a double as an options argument 
-PASS Element.animate() accepts a KeyframeAnimationOptions argument 
-PASS Element.animate() accepts an absent options argument 
-PASS Element.animate() correctly sets the id attribute when no id is specified 
-PASS Element.animate() correctly sets the id attribute 
-FAIL Element.animate() correctly sets the Animation's timeline assert_equals: expected (object) object "[object AnimationTimeline]" but got (undefined) undefined
-FAIL Element.animate() correctly sets the Animation's timeline when triggered on an element in a different document assert_equals: expected (object) object "[object AnimationTimeline]" but got (undefined) undefined
-PASS Element.animate() calls play on the Animation 
-FAIL CSSPseudoElement.animate() creates an Animation object document.getAnimations is not a function
-FAIL CSSPseudoElement.animate() creates an Animation object targeting to the correct CSSPseudoElement object document.getAnimations is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/animation-types/not-animatable-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/animation-types/not-animatable-expected.txt
deleted file mode 100644
index bc24356..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/animation-types/not-animatable-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL 'display' property cannot be animated using property-indexed notation anim.effect.getFrames is not a function
-FAIL 'display' property cannot be animated using a keyframe sequence anim.effect.getFrames is not a function
-FAIL CSS animations and CSS transitions properties cannot be animated using property-indexed notation anim.effect.getFrames is not a function
-FAIL CSS animations and CSS transitions properties cannot be animated using a sequence of keyframes anim.effect.getFrames is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/animation-types/not-animatable.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/animation-types/not-animatable.html
deleted file mode 100644
index 8210937c..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/animation-types/not-animatable.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Tests for not animatable properties</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#not-animatable-section">
-<script src="../../../../../resources/testharness.js"></script>
-<script src="../../../../../resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<script>
-'use strict';
-
-test(function(t) {
-  var div = createDiv(t);
-  var anim = div.animate({ display: [ 'inline', 'inline-block' ] }, 1000);
-
-  assert_equals(anim.effect.getFrames().length, 0,
-                'Animation specified using property-indexed notation but'
-                + ' consisting of only non-animatable properties should not'
-                + ' contain any keyframes');
-}, '\'display\' property cannot be animated using property-indexed notation');
-
-test(function(t) {
-  var div = createDiv(t);
-  var anim = div.animate([ { display: 'inline' }, { display: 'inline-block' } ],
-                         1000);
-
-  assert_equals(anim.effect.getFrames().length, 2,
-                'Animation specified using a keyframe sequence where each'
-                + ' keyframe contains only non-animatable properties should'
-                + ' return an equal number of (empty) keyframes');
-  assert_false(anim.effect.getFrames()[0].hasOwnProperty('display'),
-               'Initial keyframe should not have the \'display\' property');
-  assert_false(anim.effect.getFrames()[1].hasOwnProperty('display'),
-               'Final keyframe should not have the \'display\' property');
-}, '\'display\' property cannot be animated using a keyframe sequence');
-
-test(function(t) {
-  var properties = {
-    // CSS Animations properties
-    animation:                [ 'anim 1s', 'anim 2s' ],
-    animationName:            [ 'abc', 'xyz' ],
-    animationTimingFunction:  [ 'ease', 'steps(2)' ],
-    animationDelay:           [ '1s', '2s' ],
-    animationIterationCount:  [ 1, 2 ],
-    animationDirection:       [ 'normal', 'reverse' ],
-    animationFillMode:        [ 'forwards', 'backwards' ],
-    animationPlayState:       [ 'paused', 'running' ],
-
-    // CSS Transitions properties
-    transition:               [ 'all 1s', 'all 2s' ],
-    transitionDelay:          [ '1s', '2s' ],
-    transitionDuration:       [ '1s', '2s' ],
-    transitionProperty:       [ 'all', 'opacity' ],
-    transitionTimingFunction: [ 'ease', 'ease-out' ]
-  };
-
-  var div = createDiv(t);
-  var anim = div.animate(properties, 1000);
-
-  assert_equals(anim.effect.getFrames().length, 0,
-                'Animation specified using property-indexed notation but'
-                + ' consisting of only non-animatable properties should not'
-                + ' contain any keyframes');
-}, 'CSS animations and CSS transitions properties cannot be animated using'
-   + ' property-indexed notation');
-
-test(function(t) {
-  var frames = [
-    {
-      animation:                'anim 1s',
-      animationName:            'abc',
-      animationTimingFunction:  'ease',
-      animationDelay:           '1s',
-      animationIterationCount:  1,
-      animationDirection:       'normal',
-      animationFillMode:        'forwards',
-      animationPlayState:       'paused',
-      transition:               'all 1s',
-      transitionDelay:          '1s',
-      transitionDuration:       '1s',
-      transitionProperty:       'opacity',
-      transitionTimingFunction: 'ease'
-    },
-    {
-      animation:                'anim 2s',
-      animationName:            'xyz',
-      animationTimingFunction:  'steps(2)',
-      animationDelay:           '2s',
-      animationIterationCount:  2,
-      animationDirection:       'reverse',
-      animationFillMode:        'backwards',
-      animationPlayState:       'running',
-      transition:               'all 2s',
-      transitionDelay:          '2s',
-      transitionDuration:       '2s',
-      transitionProperty:       'all',
-      transitionTimingFunction: 'ease-out'
-    }
-  ];
-  var defaultKeyframeProperties = [ 'computedOffset', 'easing', 'offset' ];
-
-  var div = createDiv(t);
-  var anim = div.animate(frames, 1000);
-
-  assert_equals(anim.effect.getFrames().length, 2,
-                'Animation specified using a keyframe sequence where each'
-                + ' keyframe contains only non-animatable properties should'
-                + ' return an equal number of (empty) keyframes');
-  assert_array_equals(Object.keys(anim.effect.getFrames()[0]),
-                      defaultKeyframeProperties,
-                      'Initial keyframe should not contain any properties other'
-                      + ' than the default keyframe properties');
-  assert_array_equals(Object.keys(anim.effect.getFrames()[1]),
-                      defaultKeyframeProperties,
-                      'Final keyframe should not contain any properties other'
-                      + ' than the default keyframe properties');
-}, 'CSS animations and CSS transitions properties cannot be animated using'
-   + ' a sequence of keyframes');
-</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/keyframes/effect-value-context.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/keyframe-effects/effect-value-context.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/keyframes/effect-value-context.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/keyframe-effects/effect-value-context.html
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/keyframe-handling.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/keyframe-effects/the-effect-value-of-a-keyframe-effect.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/keyframe-handling.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/keyframe-effects/the-effect-value-of-a-keyframe-effect.html
index 2267503d..c1db4c7 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/keyframe-handling.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-model/keyframe-effects/the-effect-value-of-a-keyframe-effect.html
@@ -2,10 +2,9 @@
 <meta charset=utf-8>
 <title>Keyframe handling tests</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#the-effect-value-of-a-keyframe-animation-effect">
-<link rel="author" title="Brian Birtles" href="mailto:bbirtles@mozilla.com">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <div id="target"></div>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finished-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finished-expected.txt
deleted file mode 100644
index d18904c..0000000
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finished-expected.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-This is a testharness.js-based test.
-PASS Test pausing then playing does not change the finished promise 
-PASS Test restarting a finished animation 
-PASS Test restarting a reversed finished animation 
-PASS Test redundant finishing of animation 
-PASS Finished promise does not resolve when paused 
-PASS Finished promise does not resolve when pause-pending 
-PASS The finished promise is fulfilled with its Animation 
-PASS finished promise is rejected when an animation is cancelled by calling cancel() 
-PASS cancelling an already-finished animation replaces the finished promise 
-FAIL cancelling an idle animation still replaces the finished promise assert_not_equals: A redundant call to cancel() should still generate a new finished promise got disallowed value object "[object Promise]"
-FAIL Test finished promise changes for animation duration changes assert_false: shortening of the animation duration should resolve the finished promise expected false got true
-PASS Test finished promise changes when playbackRate == 0 
-PASS Test finished promise resolves when reaching to the natural boundary. 
-PASS Test finished promise changes when a prior finished promise resolved and the animation falls out finished state 
-PASS Test no new finished promise generated when finished state is checked asynchronously 
-PASS Test new finished promise generated when finished state is checked synchronously 
-PASS Test synchronous finished promise resolved even if finished state is changed soon 
-PASS Test synchronous finished promise resolved even if asynchronous finished promise happens just before synchronous promise 
-FAIL Test finished promise is not resolved when the animation falls out finished state immediately assert_unreached: Animation.finished should not be resolved Reached unreachable code
-FAIL Test finished promise is not resolved once the animation falls out finished state even though the current finished promise is generated soon after animation state became finished assert_unreached: Animation.finished should not be resolved Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animatable/animate-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animatable/animate-expected.txt
new file mode 100644
index 0000000..a9edabc5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animatable/animate-expected.txt
@@ -0,0 +1,60 @@
+This is a testharness.js-based test.
+PASS Element.animate() creates an Animation object 
+PASS Element.animate() creates an Animation object with a KeyframeEffect 
+FAIL Element.animate() accepts a one property two value property-indexed keyframes specification anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one shorthand property two value property-indexed keyframes specification anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property two value property-indexed keyframes specification anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property property-indexed keyframes specification with different numbers of values anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a property-indexed keyframes specification with an invalid value anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property two value property-indexed keyframes specification that needs to stringify its values anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a property-indexed keyframes specification with a CSS variable reference anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a property-indexed keyframes specification with a CSS variable reference in a shorthand property anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property one value property-indexed keyframes specification anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property one non-array value property-indexed keyframes specification anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property two value property-indexed keyframes specification where the first value is invalid anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property two value property-indexed keyframes specification where the second value is invalid anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property one keyframe sequence anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property two keyframe sequence anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property two keyframe sequence anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one shorthand property two keyframe sequence anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property (a shorthand and one of its component longhands) two keyframe sequence anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence with duplicate values for a given interior offset anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence with duplicate values for offsets 0 and 1 anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property four keyframe sequence anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a single keyframe sequence with omitted offsets anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property keyframe sequence with some omitted offsets anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property keyframe sequence with some omitted offsets anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property keyframe sequence with all omitted offsets anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence with different easing values, but the same easing value for a given offset anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence with different composite values, but the same composite value for a given offset anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a one property two keyframe sequence that needs to stringify its values anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence with a CSS variable reference anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence with a CSS variable reference in a shorthand property anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence where shorthand precedes longhand anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence where longhand precedes shorthand anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence where lesser shorthand precedes greater shorthand anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence where greater shorthand precedes lesser shorthand anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property keyframe sequence where one property is missing from the first keyframe anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a two property keyframe sequence where one property is missing from the last keyframe anim.effect.getKeyframes is not a function
+FAIL Element.animate() accepts a keyframe sequence with repeated values at offset 1 with different easings anim.effect.getKeyframes is not a function
+PASS Element.animate() does not accept keyframes with an out-of-bounded positive offset 
+PASS Element.animate() does not accept keyframes with an out-of-bounded negative offset 
+PASS Element.animate() does not accept keyframes not loosely sorted by offset 
+PASS Element.animate() does not accept property-indexed keyframes with an invalid easing value 
+PASS Element.animate() does not accept a keyframe sequence with an invalid easing value 
+FAIL Element.animate() does not accept keyframes with an invalid composite value assert_throws: function "function () {
+      div.animate(subtest.input, 2000);
+    }" did not throw
+PASS Element.animate() accepts a double as an options argument 
+PASS Element.animate() accepts a KeyframeAnimationOptions argument 
+PASS Element.animate() accepts an absent options argument 
+PASS Element.animate() correctly sets the id attribute when no id is specified 
+PASS Element.animate() correctly sets the id attribute 
+FAIL Element.animate() correctly sets the Animation's timeline assert_equals: expected (object) object "[object AnimationTimeline]" but got (undefined) undefined
+FAIL Element.animate() correctly sets the Animation's timeline when triggered on an element in a different document assert_equals: expected (object) object "[object AnimationTimeline]" but got (undefined) undefined
+PASS Element.animate() calls play on the Animation 
+FAIL CSSPseudoElement.animate() creates an Animation object document.getAnimations is not a function
+FAIL CSSPseudoElement.animate() creates an Animation object targeting to the correct CSSPseudoElement object document.getAnimations is not a function
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animatable/animate.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animatable/animate.html
similarity index 62%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animatable/animate.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animatable/animate.html
index 2cf3ef2..9e571cb 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animatable/animate.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animatable/animate.html
@@ -1,62 +1,55 @@
 <!DOCTYPE html>
 <meta charset=utf-8>
 <title>Animatable.animate tests</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#dom-animatable-animate">
-<link rel="author" title="Brian Birtles" href="mailto:bbirtles@mozilla.com">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animatable-animate">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<script src="../../resources/keyframe-utils.js"></script>
 <body>
 <div id="log"></div>
 <script>
 'use strict';
 
+// Tests on Element
+
 test(function(t) {
   var div = createDiv(t);
-  var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+  var anim = div.animate(null);
   assert_class_string(anim, 'Animation', 'Returned object is an Animation');
 }, 'Element.animate() creates an Animation object');
 
 test(function(t) {
   var div = createDiv(t);
-  var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+  var anim = div.animate(null);
   assert_class_string(anim.effect, 'KeyframeEffect',
                       'Returned Animation has a KeyframeEffect');
 }, 'Element.animate() creates an Animation object with a KeyframeEffect');
 
-// Animatable.animate() passes its |frames| argument to the KeyframeEffect
-// constructor. As a result, detailed tests of the handling of that argument
-// are found in the tests for that constructor. Here we just check that the
-// different types of arguments are correctly passed along.
+gPropertyIndexedKeyframesTests.forEach(function(subtest) {
+  test(function(t) {
+    var div = createDiv(t);
+    var anim = div.animate(subtest.input, 2000);
+    assert_frame_lists_equal(anim.effect.getKeyframes(), subtest.output);
+  }, 'Element.animate() accepts ' + subtest.desc);
+});
 
-test(function(t) {
-  var div = createDiv(t);
-  var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
-  assert_equals(anim.effect.getFrames().length, 2);
-  assert_equals(anim.effect.getFrames()[0].opacity, '0');
-  assert_equals(anim.effect.getFrames()[1].opacity, '1');
-}, 'Element.animate() accepts a property-indexed keyframe specification');
+gKeyframeSequenceTests.forEach(function(subtest) {
+  test(function(t) {
+    var div = createDiv(t);
+    var anim = div.animate(subtest.input, 2000);
+    assert_frame_lists_equal(anim.effect.getKeyframes(), subtest.output);
+  }, 'Element.animate() accepts ' + subtest.desc);
+});
 
-test(function(t) {
-  var div = createDiv(t);
-  var anim = div.animate([ { opacity: 0 }, { opacity: 1 } ], 2000);
-  assert_equals(anim.effect.getFrames().length, 2);
-  assert_equals(anim.effect.getFrames()[0].opacity, '0');
-  assert_equals(anim.effect.getFrames()[1].opacity, '1');
-}, 'Element.animate() accepts a frame-indexed keyframe specification');
-
-test(function(t) {
-  var div = createDiv(t);
-  var anim = div.animate({ opacity: 0 }, 2000);
-  assert_equals(anim.effect.getFrames().length, 1);
-  assert_equals(anim.effect.getFrames()[0].opacity, '0');
-}, 'Element.animate() accepts a single-valued keyframe specification');
-
-// As with the |frames| argument, Animatable.animate() passes its |options|
-// argument to the KeyframeEffect constructor as well. As a result, detailed
-// tests of the handling of that argument are found in the tests for that
-// constructor. Here we just check that the different types of arguments are
-// correctly passed along.
+gInvalidKeyframesTests.forEach(function(subtest) {
+  test(function(t) {
+    var div = createDiv(t);
+    assert_throws(subtest.expected, function() {
+      div.animate(subtest.input, 2000);
+    });
+  }, 'Element.animate() does not accept ' + subtest.desc);
+});
 
 test(function(t) {
   var div = createDiv(t);
@@ -127,13 +120,13 @@
 
 test(function(t) {
   var pseudoTarget = createPseudo(t, 'before');
-  var anim = pseudoTarget.animate({ opacity: [ 0, 1 ] }, 2000);
+  var anim = pseudoTarget.animate(null);
   assert_class_string(anim, 'Animation', 'The returned object is an Animation');
 }, 'CSSPseudoElement.animate() creates an Animation object');
 
 test(function(t) {
   var pseudoTarget = createPseudo(t, 'before');
-  var anim = pseudoTarget.animate({ opacity: [ 0, 1 ] }, 2000);
+  var anim = pseudoTarget.animate(null);
   assert_equals(anim.effect.target, pseudoTarget,
                 'The returned Animation targets to the correct object');
 }, 'CSSPseudoElement.animate() creates an Animation object targeting ' +
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/cancel.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/cancel.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/cancel.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/cancel.html
index 4edba6e..50382dd 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/cancel.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/cancel.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.cancel()</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-cancel">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/constructor.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/constructor.html
similarity index 67%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/constructor.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/constructor.html
index 2ea07710..08c392f 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/constructor.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/constructor.html
@@ -3,9 +3,9 @@
 <title>Animation constructor tests</title>
 <link rel="help" href="http://w3c.github.io/web-animations/#dom-animation-animation">
 <link rel="author" title="Hiroyuki Ikezoe" href="mailto:hiikezoe@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <div id="target"></div>
@@ -55,5 +55,19 @@
   }, "Animation can be constructed " + args.description);
 });
 
+test(function(t) {
+  var effect = new KeyframeEffectReadOnly(null,
+                                          { left: ["10px", "20px"] },
+                                          { duration: 10000,
+                                            fill: "forwards" });
+  var anim = new Animation(effect, document.timeline);
+  anim.pause();
+  assert_equals(effect.getComputedTiming().progress, 0.0);
+  anim.currentTime += 5000;
+  assert_equals(effect.getComputedTiming().progress, 0.5);
+  anim.finish();
+  assert_equals(effect.getComputedTiming().progress, 1.0);
+}, "Animation constructed by an effect with null target runs normally");
+
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finish-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finish-expected.txt
similarity index 78%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finish-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finish-expected.txt
index 677e358..419c385 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finish-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finish-expected.txt
@@ -12,5 +12,7 @@
 PASS Test finish() during aborted pause 
 PASS Test resetting of computed style 
 PASS Test finish() resolves finished promise synchronously 
+FAIL Test finish() resolves finished promise synchronously with an animation without a target KeyframeEffectReadOnly is not defined
+FAIL Test normally finished animation resolves finished promise synchronously with an animation without a target KeyframeEffectReadOnly is not defined
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finish.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finish.html
similarity index 74%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finish.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finish.html
index 8238b50..9a82c9f 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finish.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finish.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.finish()</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-finish">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
@@ -96,11 +96,10 @@
     assert_equals(animation.playState, 'finished',
                   'The play state of a paused animation should become ' +
                   '"finished" after finish() is called');
-    assert_approx_equals(animation.startTime,
-                         animation.timeline.currentTime - 100 * MS_PER_SEC,
-                         0.0001,
-                         'The start time of a paused animation should be set ' +
-                         'after calling finish()');
+    assert_times_equal(animation.startTime,
+                       animation.timeline.currentTime - 100 * MS_PER_SEC,
+                       'The start time of a paused animation should be set ' +
+                       'after calling finish()');
   });
 }, 'Test finish() while paused');
 
@@ -117,11 +116,10 @@
   assert_equals(animation.playState, 'finished',
                 'The play state of a pause-pending animation should become ' +
                 '"finished" after finish() is called');
-  assert_approx_equals(animation.startTime,
-                       animation.timeline.currentTime - 100 * MS_PER_SEC / 2,
-                       0.0001,
-                       'The start time of a pause-pending animation should ' +
-                       'be set after calling finish()');
+  assert_times_equal(animation.startTime,
+                     animation.timeline.currentTime - 100 * MS_PER_SEC / 2,
+                     'The start time of a pause-pending animation should ' +
+                     'be set after calling finish()');
 }, 'Test finish() while pause-pending with positive playbackRate');
 
 test(function(t) {
@@ -148,11 +146,10 @@
   assert_equals(animation.playState, 'finished',
                 'The play state of a play-pending animation should become ' +
                 '"finished" after finish() is called');
-  assert_approx_equals(animation.startTime,
-                       animation.timeline.currentTime - 100 * MS_PER_SEC / 0.5,
-                       0.0001,
-                       'The start time of a play-pending animation should ' +
-                       'be set after calling finish()');
+  assert_times_equal(animation.startTime,
+                     animation.timeline.currentTime - 100 * MS_PER_SEC / 0.5,
+                     'The start time of a play-pending animation should ' +
+                     'be set after calling finish()');
 }, 'Test finish() while play-pending');
 
 // FIXME: Add a test for when we are play-pending without an active timeline.
@@ -206,5 +203,45 @@
       'Animation.finish()');
   });
 }, 'Test finish() resolves finished promise synchronously');
+
+promise_test(function(t) {
+  var effect = new KeyframeEffectReadOnly(null, gKeyFrames, 100 * MS_PER_SEC);
+  var animation = new Animation(effect, document.timeline);
+  var resolvedFinished = false;
+  animation.finished.then(function() {
+    resolvedFinished = true;
+  });
+
+  return animation.ready.then(function() {
+    animation.finish();
+  }).then(function() {
+    assert_true(resolvedFinished,
+                'Animation.finished should be resolved soon after ' +
+                'Animation.finish()');
+  });
+}, 'Test finish() resolves finished promise synchronously with an animation ' +
+   'without a target');
+
+promise_test(function(t) {
+  var effect = new KeyframeEffectReadOnly(null, gKeyFrames, 100 * MS_PER_SEC);
+  var animation = new Animation(effect, document.timeline);
+  animation.play();
+
+  var resolvedFinished = false;
+  animation.finished.then(function() {
+    resolvedFinished = true;
+  });
+
+  return animation.ready.then(function() {
+    animation.currentTime = animation.effect.getComputedTiming().endTime - 1;
+    return waitForAnimationFrames(2);
+  }).then(function() {
+    assert_true(resolvedFinished,
+                'Animation.finished should be resolved soon after ' +
+                'Animation finishes normally');
+  });
+}, 'Test normally finished animation resolves finished promise synchronously ' +
+   'with an animation without a target');
+
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finished.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finished.html
similarity index 97%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finished.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finished.html
index dfd65816..4abbac4 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/finished.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/finished.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.finished</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-finished">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/id.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/id.html
similarity index 68%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/id.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/id.html
index 1b42c65a..f3ff6e0 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/id.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/id.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.id</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-id">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/oncancel.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/oncancel.html
similarity index 77%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/oncancel.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/oncancel.html
index ac8ca38..2949c448 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/oncancel.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/oncancel.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.oncancel</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-oncancel">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/onfinish.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/onfinish.html
similarity index 93%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/onfinish.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/onfinish.html
index 320a995..84b7eb7 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/onfinish.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/onfinish.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.onfinish</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-onfinish">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/pause.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/pause.html
similarity index 92%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/pause.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/pause.html
index d601967..f3444c28 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/pause.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/pause.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.pause()</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-pause">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/play.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/play.html
similarity index 80%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/play.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/play.html
index e210106..c78ed278 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/play.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/play.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.play()</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-play">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/playState.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/playState.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/playState.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/playState.html
index 7b2badc..d1e3408d 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/playState.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/playState.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.playState</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-playstate">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/playbackRate-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/playbackRate-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/playbackRate-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/playbackRate-expected.txt
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/playbackRate.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/playbackRate.html
similarity index 92%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/playbackRate.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/playbackRate.html
index 020e56e..c50b7a00 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/playbackRate.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/playbackRate.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.playbackRate</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-playbackrate">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/ready.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/ready.html
similarity index 92%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/ready.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/ready.html
index 8e43673..94ae3bff 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/ready.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/ready.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.ready</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-ready">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/reverse.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/reverse.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/reverse.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/reverse.html
index d92db14..22772ecd 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation/reverse.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/reverse.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>Animation.reverse()</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-reverse">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/startTime-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/startTime-expected.txt
new file mode 100644
index 0000000..a445c4f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/startTime-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL startTime of a newly created (idle) animation is unresolved Animation is not defined
+FAIL startTime of a play-pending animation is unresolved Animation is not defined
+FAIL startTime of a pause-pending animation is unresolved Animation is not defined
+PASS startTime of a play-pending animation created using Element.animate shortcut is unresolved 
+PASS startTime is resolved when running 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/startTime.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/startTime.html
new file mode 100644
index 0000000..d08af91
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Animation/startTime.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.startTime tests</title>
+<link rel="help"
+href="https://w3c.github.io/web-animations/#dom-animation-starttime">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
+                                document.timeline);
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a newly created (idle) animation is unresolved');
+
+test(function(t) {
+  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
+                                document.timeline);
+  animation.play();
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a play-pending animation is unresolved');
+
+test(function(t) {
+  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
+                                document.timeline);
+  animation.pause();
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a pause-pending animation is unresolved');
+
+test(function(t) {
+  var animation = createDiv(t).animate(null);
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a play-pending animation created using Element.animate'
+   + ' shortcut is unresolved');
+
+promise_test(function(t) {
+  var animation = createDiv(t).animate(null, 100 * MS_PER_SEC);
+  return animation.ready.then(function() {
+    assert_greater_than(animation.startTime, 0, 'startTime when running');
+  });
+}, 'startTime is resolved when running');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/delay.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/delay.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/delay.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/delay.html
index 25b2113..f257ca2 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/delay.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/delay.html
@@ -3,10 +3,10 @@
 <title>delay tests</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-delay">
 <link rel="author" title="Daisuke Akatsuka" href="mailto:daisuke@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/direction.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/direction.html
similarity index 74%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/direction.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/direction.html
index 83fb0fa0..9faea89 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/direction.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/direction.html
@@ -3,10 +3,10 @@
 <title>direction tests</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-direction">
 <link rel="author" title="Ryo Kato" href="mailto:foobar094@gmail.com">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/duration.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/duration.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/duration.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/duration.html
index 662ff40..30b143c 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/duration.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/duration.html
@@ -3,9 +3,9 @@
 <title>duration tests</title>
 <link rel="help" href="http://w3c.github.io/web-animations/#dom-animationeffecttiming-duration">
 <link rel="author" title="Ryo Motozawa" href="mailto:motozawa@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <script>
@@ -15,11 +15,10 @@
   var div = createDiv(t);
   var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
   anim.effect.timing.duration = 123.45;
-  assert_approx_equals(anim.effect.timing.duration, 123.45, 0.000001,
-                       'set duration 123.45');
-  assert_approx_equals(anim.effect.getComputedTiming().duration, 123.45,
-                       0.000001,
-                       'getComputedTiming() after set duration 123.45');
+  assert_times_equal(anim.effect.timing.duration, 123.45,
+                     'set duration 123.45');
+  assert_times_equal(anim.effect.getComputedTiming().duration, 123.45,
+                     'getComputedTiming() after set duration 123.45');
 }, 'set duration 123.45');
 
 test(function(t) {
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/easing.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/easing.html
similarity index 92%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/easing.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/easing.html
index 51c21dd..06c3b9f 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/easing.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/easing.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>easing tests</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-easing">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<script src="../resources/effect-easing-tests.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<script src="../../resources/effect-easing-tests.js"></script>
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/endDelay.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/endDelay.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/endDelay.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/endDelay.html
index c41bd697..175474b8 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/endDelay.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/endDelay.html
@@ -3,9 +3,9 @@
 <title>endDelay tests</title>
 <link rel="help" href="http://w3c.github.io/web-animations/#dom-animationeffecttiming-enddelay">
 <link rel="author" title="Ryo Motozawa" href="mailto:motozawa@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <script>
@@ -15,11 +15,10 @@
   var div = createDiv(t);
   var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
   anim.effect.timing.endDelay = 123.45;
-  assert_approx_equals(anim.effect.timing.endDelay, 123.45, 0.000001,
-                       'set endDelay 123.45');
-  assert_approx_equals(anim.effect.getComputedTiming().endDelay, 123.45,
-                       0.000001,
-                       'getComputedTiming() after set endDelay 123.45');
+  assert_times_equal(anim.effect.timing.endDelay, 123.45,
+                     'set endDelay 123.45');
+  assert_times_equal(anim.effect.getComputedTiming().endDelay, 123.45,
+                     'getComputedTiming() after set endDelay 123.45');
 }, 'set endDelay 123.45');
 
 test(function(t) {
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/fill.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/fill.html
similarity index 72%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/fill.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/fill.html
index d01fa03a..29ed7ae 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/fill.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/fill.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>fill tests</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-fill">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/getAnimations.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/getAnimations.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/getAnimations.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/getAnimations.html
index bc3f69eb..ba6da9e1 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/getAnimations.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/getAnimations.html
@@ -3,9 +3,9 @@
 <title>Element.getAnimations tests</title>
 <link rel="help" href="http://w3c.github.io/web-animations/#animationeffecttiming">
 <link rel="author" title="Ryo Motozawa" href="mailto:motozawa@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/getComputedStyle.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/getComputedStyle.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/getComputedStyle.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/getComputedStyle.html
index 0eae355..c9bf443 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/getComputedStyle.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/getComputedStyle.html
@@ -3,9 +3,9 @@
 <title>getComputedStyle tests</title>
 <link rel="help" href="http://w3c.github.io/web-animations/#animationeffecttiming">
 <link rel="author" title="Ryo Motozawa" href="mailto:motozawa@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/iterationStart-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/iterationStart-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/iterationStart-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/iterationStart-expected.txt
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/iterationStart.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/iterationStart.html
similarity index 93%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/iterationStart.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/iterationStart.html
index 21e73e1..0c92f2a5 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/iterationStart.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/iterationStart.html
@@ -3,9 +3,9 @@
 <title>iterationStart tests</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-iterationstart">
 <link rel="author" title="Daisuke Akatsuka" href="mailto:daisuke@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/iterations.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/iterations.html
similarity index 87%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/iterations.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/iterations.html
index 7e2eb05..4bdcd22 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-effect-timing/iterations.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationEffectTiming/iterations.html
@@ -2,10 +2,10 @@
 <meta charset=utf-8>
 <title>iterations tests</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-iterations">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<link rel="stylesheet" href="../../../../resources/testharness.css">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-timeline/document-timeline.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationTimeline/document-timeline.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-timeline/document-timeline.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationTimeline/document-timeline.html
index 8d61c3d..d6be9522a 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-timeline/document-timeline.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationTimeline/document-timeline.html
@@ -1,8 +1,8 @@
 <!doctype html>
 <meta charset=utf-8>
 <title>Web Animations API: DocumentTimeline tests</title>
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
 <div id="log"></div>
 <iframe width="10" height="10" id="iframe"></iframe>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-timeline/idlharness-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationTimeline/idlharness-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-timeline/idlharness-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationTimeline/idlharness-expected.txt
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-timeline/idlharness.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationTimeline/idlharness.html
similarity index 68%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-timeline/idlharness.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationTimeline/idlharness.html
index 7ca3530..d33a1404 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/animation-timeline/idlharness.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/AnimationTimeline/idlharness.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <meta charset=utf-8>
 <title>Web Animations API: DocumentTimeline tests</title>
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../../../../resources/WebIDLParser.js"></script>
-<script src="../../../../resources/idlharness.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../../../../resources/WebIDLParser.js"></script>
+<script src="../../../../../resources/idlharness.js"></script>
 <div id="log"></div>
 <script type="text/plain" id="DocumentTimeline-IDL">
 interface AnimationTimeline {
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Document/getAnimations-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Document/getAnimations-expected.txt
new file mode 100644
index 0000000..46f0fcd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Document/getAnimations-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL Test document.getAnimations for non-animated content document.getAnimations is not a function
+FAIL Test document.getAnimations for script-generated animations document.getAnimations is not a function
+FAIL Test the order of document.getAnimations with script generated animations document.getAnimations is not a function
+FAIL Test document.getAnimations with null target KeyframeEffectReadOnly is not defined
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Document/getAnimations.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Document/getAnimations.html
new file mode 100644
index 0000000..d7d8ec6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/Document/getAnimations.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>document.getAnimations tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-document-getanimations">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<div id="target"></div>
+<script>
+"use strict";
+
+var gKeyFrames = { 'marginLeft': ['100px', '200px'] };
+
+test(function(t) {
+  assert_equals(document.getAnimations().length, 0,
+                'getAnimations returns an empty sequence for a document ' +
+                'with no animations');
+}, 'Test document.getAnimations for non-animated content');
+
+test(function(t) {
+  var div = createDiv(t);
+  var anim1 = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+  var anim2 = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+  assert_equals(document.getAnimations().length, 2,
+                'getAnimation returns running animations');
+
+  anim1.finish();
+  anim2.finish();
+  assert_equals(document.getAnimations().length, 0,
+                'getAnimation only returns running animations');
+}, 'Test document.getAnimations for script-generated animations')
+
+test(function(t) {
+  var div = createDiv(t);
+  var anim1 = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+  var anim2 = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+  assert_array_equals(document.getAnimations(),
+                      [ anim1, anim2 ],
+                      'getAnimations() returns running animations');
+}, 'Test the order of document.getAnimations with script generated animations')
+
+test(function(t) {
+  var effect = new KeyframeEffectReadOnly(null, gKeyFrames, 100 * MS_PER_SEC);
+  var anim = new Animation(effect, document.timeline);
+  anim.play();
+
+  assert_equals(document.getAnimations().length, 0,
+                'document.getAnimations() only returns animations targeting ' +
+                'elements in this document');
+}, 'Test document.getAnimations with null target');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/constructor-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/constructor-expected.txt
similarity index 79%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/constructor-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/constructor-expected.txt
index 6e3616ee..7a013e9 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/constructor-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/constructor-expected.txt
@@ -20,6 +20,10 @@
 FAIL a KeyframeEffectReadOnly constructed with a property-indexed keyframes specification with an invalid value roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a one property two value property-indexed keyframes specification that needs to stringify its values KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a one property two value property-indexed keyframes specification that needs to stringify its values roundtrips KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a property-indexed keyframes specification with a CSS variable reference KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a property-indexed keyframes specification with a CSS variable reference roundtrips KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a property-indexed keyframes specification with a CSS variable reference in a shorthand property KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a property-indexed keyframes specification with a CSS variable reference in a shorthand property roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a one property one value property-indexed keyframes specification KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a one property one value property-indexed keyframes specification roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a one property one non-array value property-indexed keyframes specification KeyframeEffectReadOnly is not defined
@@ -28,13 +32,9 @@
 FAIL a KeyframeEffectReadOnly constructed with a one property two value property-indexed keyframes specification where the first value is invalid roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a one property two value property-indexed keyframes specification where the second value is invalid KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a one property two value property-indexed keyframes specification where the second value is invalid roundtrips KeyframeEffectReadOnly is not defined
-FAIL a KeyframeEffectReadOnly can be constructed with a two property property-indexed keyframes specification where one property is missing from the first keyframe KeyframeEffectReadOnly is not defined
-FAIL a KeyframeEffectReadOnly constructed with a two property property-indexed keyframes specification where one property is missing from the first keyframe roundtrips KeyframeEffectReadOnly is not defined
-FAIL a KeyframeEffectReadOnly can be constructed with a two property property-indexed keyframes specification where one property is missing from the last keyframe KeyframeEffectReadOnly is not defined
-FAIL a KeyframeEffectReadOnly constructed with a two property property-indexed keyframes specification where one property is missing from the last keyframe roundtrips KeyframeEffectReadOnly is not defined
-FAIL a KeyframeEffectReadOnly can be constructed with a property-indexed keyframes specification with repeated values at offset 0 with different easings KeyframeEffectReadOnly is not defined
-FAIL a KeyframeEffectReadOnly constructed with a property-indexed keyframes specification with repeated values at offset 0 with different easings roundtrips KeyframeEffectReadOnly is not defined
 FAIL the KeyframeEffectReadOnly constructor reads keyframe properties in the expected order KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a one property one keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a one property one keyframe sequence roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a one property two keyframe sequence KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a one property two keyframe sequence roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a two property two keyframe sequence KeyframeEffectReadOnly is not defined
@@ -49,6 +49,8 @@
 FAIL a KeyframeEffectReadOnly constructed with a keyframe sequence with duplicate values for offsets 0 and 1 roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a two property four keyframe sequence KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a two property four keyframe sequence roundtrips KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a single keyframe sequence with omitted offsets KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a single keyframe sequence with omitted offsets roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a one property keyframe sequence with some omitted offsets KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a one property keyframe sequence with some omitted offsets roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a two property keyframe sequence with some omitted offsets KeyframeEffectReadOnly is not defined
@@ -61,6 +63,10 @@
 FAIL a KeyframeEffectReadOnly constructed with a keyframe sequence with different composite values, but the same composite value for a given offset roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a one property two keyframe sequence that needs to stringify its values KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a one property two keyframe sequence that needs to stringify its values roundtrips KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a keyframe sequence with a CSS variable reference KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a keyframe sequence with a CSS variable reference roundtrips KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a keyframe sequence with a CSS variable reference in a shorthand property KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a keyframe sequence with a CSS variable reference in a shorthand property roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a keyframe sequence where shorthand precedes longhand KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a keyframe sequence where shorthand precedes longhand roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a keyframe sequence where longhand precedes shorthand KeyframeEffectReadOnly is not defined
@@ -69,6 +75,24 @@
 FAIL a KeyframeEffectReadOnly constructed with a keyframe sequence where lesser shorthand precedes greater shorthand roundtrips KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly can be constructed with a keyframe sequence where greater shorthand precedes lesser shorthand KeyframeEffectReadOnly is not defined
 FAIL a KeyframeEffectReadOnly constructed with a keyframe sequence where greater shorthand precedes lesser shorthand roundtrips KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a two property keyframe sequence where one property is missing from the first keyframe KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a two property keyframe sequence where one property is missing from the first keyframe roundtrips KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a two property keyframe sequence where one property is missing from the last keyframe KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a two property keyframe sequence where one property is missing from the last keyframe roundtrips KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly can be constructed with a keyframe sequence with repeated values at offset 1 with different easings KeyframeEffectReadOnly is not defined
+FAIL a KeyframeEffectReadOnly constructed with a keyframe sequence with repeated values at offset 1 with different easings roundtrips KeyframeEffectReadOnly is not defined
+FAIL KeyframeEffectReadOnly constructor throws with keyframes with an out-of-bounded positive offset assert_throws: function "function () {
+      new KeyframeEffectReadOnly(target, su..." threw object "ReferenceError: KeyframeEffectReadOnly is not defined" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL KeyframeEffectReadOnly constructor throws with keyframes with an out-of-bounded negative offset assert_throws: function "function () {
+      new KeyframeEffectReadOnly(target, su..." threw object "ReferenceError: KeyframeEffectReadOnly is not defined" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL KeyframeEffectReadOnly constructor throws with keyframes not loosely sorted by offset assert_throws: function "function () {
+      new KeyframeEffectReadOnly(target, su..." threw object "ReferenceError: KeyframeEffectReadOnly is not defined" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL KeyframeEffectReadOnly constructor throws with property-indexed keyframes with an invalid easing value assert_throws: function "function () {
+      new KeyframeEffectReadOnly(target, su..." threw object "ReferenceError: KeyframeEffectReadOnly is not defined" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL KeyframeEffectReadOnly constructor throws with a keyframe sequence with an invalid easing value assert_throws: function "function () {
+      new KeyframeEffectReadOnly(target, su..." threw object "ReferenceError: KeyframeEffectReadOnly is not defined" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL KeyframeEffectReadOnly constructor throws with keyframes with an invalid composite value assert_throws: function "function () {
+      new KeyframeEffectReadOnly(target, su..." threw object "ReferenceError: KeyframeEffectReadOnly is not defined" ("ReferenceError") expected object "[object Object]" ("TypeError")
 FAIL Invalid easing [a blank easing] in keyframe sequence should be thrown assert_throws: function "function () {
       new KeyframeEffectReadOnly(target, su..." threw object "ReferenceError: KeyframeEffectReadOnly is not defined" ("ReferenceError") expected object "TypeError" ("TypeError")
 FAIL Invalid easing [an unrecognized easing] in keyframe sequence should be thrown assert_throws: function "function () {
@@ -139,6 +163,7 @@
 FAIL Invalid KeyframeEffectReadOnly option by a multi-value easing assert_throws: function "function () {
       new KeyframeEffectReadOnly(target,
   ..." threw object "ReferenceError: KeyframeEffectReadOnly is not defined" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL a KeyframeEffectReadOnly constructed with null target KeyframeEffectReadOnly is not defined
 PASS KeyframeEffect constructor creates an AnimationEffectTiming timing object 
 PASS KeyframeEffect constructor propagates exceptions generated by accessing the options object 
 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/constructor.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/constructor.html
new file mode 100644
index 0000000..17bb26de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/constructor.html
@@ -0,0 +1,278 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>KeyframeEffectReadOnly constructor tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#the-keyframeeffect-interfaces">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<script src="../../resources/keyframe-utils.js"></script>
+<body>
+<div id="log"></div>
+<div id="target"></div>
+<style>
+#target {
+  border-style: solid;  /* so border-*-width values don't compute to 0 */
+}
+</style>
+<script>
+"use strict";
+
+var target = document.getElementById("target");
+
+test(function(t) {
+  gEmptyKeyframeListTests.forEach(function(frames) {
+    assert_equals(new KeyframeEffectReadOnly(target, frames)
+                        .getKeyframes().length,
+                  0, "number of frames for " + JSON.stringify(frames));
+  });
+}, "a KeyframeEffectReadOnly can be constructed with no frames");
+
+test(function(t) {
+  gEasingValueTests.forEach(function(subtest) {
+    var easing = subtest[0];
+    var expected = subtest[1];
+    var effect = new KeyframeEffectReadOnly(target, {
+      left: ["10px", "20px"],
+      easing: easing
+    });
+    assert_equals(effect.getKeyframes()[0].easing, expected,
+                  "resulting easing for '" + easing + "'");
+  });
+}, "easing values are parsed correctly when passed to the " +
+   "KeyframeEffectReadOnly constructor in a property-indexed keyframe");
+
+test(function(t) {
+  gEasingValueTests.forEach(function(subtest) {
+    var easing = subtest[0];
+    var expected = subtest[1];
+    var effect = new KeyframeEffectReadOnly(target, [
+      { offset: 0, left: "10px", easing: easing },
+      { offset: 1, left: "20px" }
+    ]);
+    assert_equals(effect.getKeyframes()[0].easing, expected,
+                  "resulting easing for '" + easing + "'");
+  });
+}, "easing values are parsed correctly when passed to the " +
+   "KeyframeEffectReadOnly constructor in regular keyframes");
+
+test(function(t) {
+  gEasingValueTests.forEach(function(subtest) {
+    var easing = subtest[0];
+    var expected = subtest[1];
+    var effect = new KeyframeEffectReadOnly(target, {
+      left: ["10px", "20px"]
+    }, { easing: easing });
+    assert_equals(effect.timing.easing, expected,
+                  "resulting easing for '" + easing + "'");
+  });
+}, "easing values are parsed correctly when passed to the " +
+   "KeyframeEffectReadOnly constructor in KeyframeTimingOptions");
+
+test(function(t) {
+  var getKeyframe = function(composite) {
+    return { left: [ "10px", "20px" ], composite: composite };
+  };
+  gGoodKeyframeCompositeValueTests.forEach(function(composite) {
+    var effect = new KeyframeEffectReadOnly(target, getKeyframe(composite));
+    assert_equals(effect.getKeyframes()[0].composite, composite,
+                  "resulting composite for '" + composite + "'");
+  });
+  gBadCompositeValueTests.forEach(function(composite) {
+    assert_throws(new TypeError, function() {
+      new KeyframeEffectReadOnly(target, getKeyframe(composite));
+    });
+  });
+}, "composite values are parsed correctly when passed to the " +
+   "KeyframeEffectReadOnly constructor in property-indexed keyframes");
+
+test(function(t) {
+  var getKeyframes = function(composite) {
+    return [
+      { offset: 0, left: "10px", composite: composite },
+      { offset: 1, left: "20px" }
+    ];
+  };
+  gGoodKeyframeCompositeValueTests.forEach(function(composite) {
+    var effect = new KeyframeEffectReadOnly(target, getKeyframes(composite));
+    assert_equals(effect.getKeyframes()[0].composite, composite,
+                  "resulting composite for '" + composite + "'");
+  });
+  gBadCompositeValueTests.forEach(function(composite) {
+    assert_throws(new TypeError, function() {
+      new KeyframeEffectReadOnly(target, getKeyframes(composite));
+    });
+  });
+}, "composite values are parsed correctly when passed to the " +
+   "KeyframeEffectReadOnly constructor in regular keyframes");
+
+test(function(t) {
+  gGoodOptionsCompositeValueTests.forEach(function(composite) {
+    var effect = new KeyframeEffectReadOnly(target, {
+      left: ["10px", "20px"]
+    }, { composite: composite });
+    assert_equals(effect.getKeyframes()[0].composite, composite,
+                  "resulting composite for '" + composite + "'");
+  });
+  gBadCompositeValueTests.forEach(function(composite) {
+    assert_throws(new TypeError, function() {
+      new KeyframeEffectReadOnly(target, {
+        left: ["10px", "20px"]
+      }, { composite: composite });
+    });
+  });
+}, "composite values are parsed correctly when passed to the " +
+   "KeyframeEffectReadOnly constructor in KeyframeTimingOptions");
+
+gPropertyIndexedKeyframesTests.forEach(function(subtest) {
+  test(function(t) {
+    var effect = new KeyframeEffectReadOnly(target, subtest.input);
+    assert_frame_lists_equal(effect.getKeyframes(), subtest.output);
+  }, "a KeyframeEffectReadOnly can be constructed with " + subtest.desc);
+
+  test(function(t) {
+    var effect = new KeyframeEffectReadOnly(target, subtest.input);
+    var secondEffect =
+      new KeyframeEffectReadOnly(target, effect.getKeyframes());
+    assert_frame_lists_equal(secondEffect.getKeyframes(),
+                             effect.getKeyframes());
+  }, "a KeyframeEffectReadOnly constructed with " + subtest.desc +
+     " roundtrips");
+});
+
+test(function(t) {
+  var expectedOrder = ["composite", "easing", "offset", "left", "marginLeft"];
+  var actualOrder = [];
+  var kf1 = {};
+  var kf2 = { marginLeft: "10px", left: "20px", offset: 1 };
+  [{ p: "marginLeft", v: "10px" },
+   { p: "left",       v: "20px" },
+   { p: "offset",     v: "0" },
+   { p: "easing",     v: "linear" },
+   { p: "composite",  v: "replace" }].forEach(function(e) {
+    Object.defineProperty(kf1, e.p, {
+      enumerable: true,
+      get: function() { actualOrder.push(e.p); return e.v; }
+    });
+  });
+  new KeyframeEffectReadOnly(target, [kf1, kf2]);
+  assert_array_equals(actualOrder, expectedOrder, "property access order");
+}, "the KeyframeEffectReadOnly constructor reads keyframe properties in the " +
+   "expected order");
+
+gKeyframeSequenceTests.forEach(function(subtest) {
+  test(function(t) {
+    var effect = new KeyframeEffectReadOnly(target, subtest.input);
+    assert_frame_lists_equal(effect.getKeyframes(), subtest.output);
+  }, "a KeyframeEffectReadOnly can be constructed with " + subtest.desc);
+
+  test(function(t) {
+    var effect = new KeyframeEffectReadOnly(target, subtest.input);
+    var secondEffect =
+      new KeyframeEffectReadOnly(target, effect.getKeyframes());
+    assert_frame_lists_equal(secondEffect.getKeyframes(),
+                             effect.getKeyframes());
+  }, "a KeyframeEffectReadOnly constructed with " + subtest.desc +
+     " roundtrips");
+});
+
+gInvalidKeyframesTests.forEach(function(subtest) {
+  test(function(t) {
+    assert_throws(subtest.expected, function() {
+      new KeyframeEffectReadOnly(target, subtest.input);
+    });
+  }, "KeyframeEffectReadOnly constructor throws with " + subtest.desc);
+});
+
+gInvalidEasingInKeyframeSequenceTests.forEach(function(subtest) {
+  test(function(t) {
+    assert_throws(new TypeError, function() {
+      new KeyframeEffectReadOnly(target, subtest.input);
+    });
+  }, "Invalid easing [" + subtest.desc + "] in keyframe sequence " +
+     "should be thrown");
+});
+
+test(function(t) {
+  var effect = new KeyframeEffectReadOnly(target,
+                                          { left: ["10px", "20px"] });
+
+  var timing = effect.timing;
+  assert_equals(timing.delay, 0, "default delay");
+  assert_equals(timing.endDelay, 0, "default endDelay");
+  assert_equals(timing.fill, "auto", "default fill");
+  assert_equals(timing.iterations, 1.0, "default iterations");
+  assert_equals(timing.iterationStart, 0.0, "default iterationStart");
+  assert_equals(timing.duration, "auto", "default duration");
+  assert_equals(timing.direction, "normal", "default direction");
+  assert_equals(timing.easing, "linear", "default easing");
+
+  assert_equals(effect.composite, "replace", "default composite");
+  assert_equals(effect.iterationComposite, "replace",
+                "default iterationComposite");
+  assert_equals(effect.spacing, "distribute",
+                "default spacing");
+}, "a KeyframeEffectReadOnly constructed without any " +
+   "KeyframeEffectOptions object");
+
+gKeyframeEffectOptionTests.forEach(function(stest) {
+  test(function(t) {
+    var effect = new KeyframeEffectReadOnly(target,
+                                            { left: ["10px", "20px"] },
+                                            stest.input);
+
+    // Helper function to provide default expected values when the test does
+    // not supply them.
+    var expected = function(field, defaultValue) {
+      return field in stest.expected ? stest.expected[field] : defaultValue;
+    };
+
+    var timing = effect.timing;
+    assert_equals(timing.delay, expected("delay", 0),
+                  "timing delay");
+    assert_equals(timing.fill, expected("fill", "auto"),
+                  "timing fill");
+    assert_equals(timing.iterations, expected("iterations", 1),
+                  "timing iterations");
+    assert_equals(timing.duration, expected("duration", "auto"),
+                  "timing duration");
+    assert_equals(timing.direction, expected("direction", "normal"),
+                  "timing direction");
+
+  }, "a KeyframeEffectReadOnly constructed by " + stest.desc);
+});
+
+gInvalidKeyframeEffectOptionTests.forEach(function(stest) {
+  test(function(t) {
+    assert_throws(stest.expected, function() {
+      new KeyframeEffectReadOnly(target,
+                                 { left: ["10px", "20px"] },
+                                 stest.input);
+    });
+  }, "Invalid KeyframeEffectReadOnly option by " + stest.desc);
+});
+
+test(function(t) {
+  var effect = new KeyframeEffectReadOnly(null,
+                                          { left: ["10px", "20px"] },
+                                          { duration: 100 * MS_PER_SEC,
+                                            fill: "forwards" });
+  assert_equals(effect.target, null,
+                "Effect created with null target has correct target");
+}, "a KeyframeEffectReadOnly constructed with null target");
+
+test(function(t) {
+  var effect = new KeyframeEffect(target, null);
+  assert_class_string(effect, "KeyframeEffect");
+  assert_class_string(effect.timing, "AnimationEffectTiming");
+}, "KeyframeEffect constructor creates an AnimationEffectTiming timing object");
+
+test(function(t) {
+  var test_error = { name: "test" };
+
+  assert_throws(test_error, function() {
+    new KeyframeEffect(target, { get left() { throw test_error }})
+  });
+}, "KeyframeEffect constructor propagates exceptions generated by accessing"
+   + " the options object");
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/effect-easing-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/effect-easing-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/effect-easing-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/effect-easing-expected.txt
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/effect-easing.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/effect-easing.html
similarity index 98%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/effect-easing.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/effect-easing.html
index a788f65..9261cd6 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/effect-easing.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/effect-easing.html
@@ -3,10 +3,10 @@
 <title>Effect-level easing tests</title>
 <link rel="help" href="http://w3c.github.io/web-animations/#calculating-the-transformed-time">
 <link rel="author" title="Hiroyuki Ikezoe" href="mailto:hiikezoe@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<script src="../resources/effect-easing-tests.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<script src="../../resources/effect-easing-tests.js"></script>
 <body>
 <div id="log"></div>
 <div id="target"></div>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/getComputedTiming-expected.txt
similarity index 97%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/getComputedTiming-expected.txt
index e5882c0..0bf4fdd0 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/getComputedTiming-expected.txt
@@ -23,7 +23,6 @@
 FAIL getComputedTiming().activeDuration for an infinite duration and zero iteration count KeyframeEffectReadOnly is not defined
 FAIL getComputedTiming().activeDuration for an infinite duration and fractional iteration count KeyframeEffectReadOnly is not defined
 FAIL getComputedTiming().activeDuration for an infinite duration and infinite iteration count KeyframeEffectReadOnly is not defined
-FAIL getComputedTiming().activeDuration for an infinite duration and zero iteration count KeyframeEffectReadOnly is not defined
 FAIL getComputedTiming().endTime for an empty KeyframeEffectOptions object KeyframeEffectReadOnly is not defined
 FAIL getComputedTiming().endTime for a non-zero duration and default iteration count KeyframeEffectReadOnly is not defined
 FAIL getComputedTiming().endTime for a non-zero duration and non-default iteration count KeyframeEffectReadOnly is not defined
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/getComputedTiming.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/getComputedTiming.html
index 5641b20..d00b266 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/getComputedTiming.html
@@ -3,9 +3,9 @@
 <title>KeyframeEffectReadOnly getComputedTiming() tests</title>
 <link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffectreadonly-getcomputedtiming">
 <link rel="author" title="Boris Chiou" href="mailto:boris.chiou@gmail.com">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <div id="target"></div>
@@ -141,9 +141,6 @@
   { desc:     "an infinite duration and infinite iteration count",
     input:    { duration: Infinity, iterations: Infinity },
     expected: Infinity },
-  { desc:     "an infinite duration and zero iteration count",
-    input:    { duration: Infinity, iterations: 0 },
-    expected: 0 }
 ];
 
 gActiveDurationTests.forEach(function(stest) {
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-expected.txt
new file mode 100644
index 0000000..70a2f00
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-expected.txt
@@ -0,0 +1,35 @@
+This is a testharness.js-based test.
+FAIL non-animatable property 'animation' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationDelay' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationDirection' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationDuration' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationFillMode' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationIterationCount' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationName' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationPlayState' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationTimingFunction' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transition' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transitionDelay' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transitionDuration' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transitionProperty' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transitionTimingFunction' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'display' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'unsupportedProperty' is not accessed when using a property-indexed keyframe object KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animation' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationDelay' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationDirection' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationDuration' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationFillMode' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationIterationCount' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationName' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationPlayState' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'animationTimingFunction' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transition' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transitionDelay' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transitionDuration' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transitionProperty' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'transitionTimingFunction' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'display' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+FAIL non-animatable property 'unsupportedProperty' is not accessed when using a keyframe sequence KeyframeEffectReadOnly is not defined
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument.html
new file mode 100644
index 0000000..322f16a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>KeyframeEffectReadOnly constructor tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#processing-a-keyframes-argument">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<div id="target"></div>
+<script>
+'use strict';
+
+// Test the "process a keyframe-like object" procedure.
+//
+// This file only tests the KeyframeEffectReadOnly constructor since it is
+// assumed that the implementation of the KeyframeEffect constructor,
+// Animatable.animate() method, and KeyframeEffect.setKeyframes() method will
+// all share common machinery and it is not necessary to test each method.
+
+// Test that only animatable properties are accessed
+
+var gNonAnimatableProps = [
+  'animation', // Shorthands where all the longhand sub-properties are not
+               // animatable, are also not animatable.
+  'animationDelay',
+  'animationDirection',
+  'animationDuration',
+  'animationFillMode',
+  'animationIterationCount',
+  'animationName',
+  'animationPlayState',
+  'animationTimingFunction',
+  'transition',
+  'transitionDelay',
+  'transitionDuration',
+  'transitionProperty',
+  'transitionTimingFunction',
+  'display',
+  'unsupportedProperty',
+];
+
+function TestKeyframe(testProp) {
+  var _propAccessCount = 0;
+
+  Object.defineProperty(this, testProp, {
+    get: function() { _propAccessCount++; },
+    enumerable: true
+  });
+
+  Object.defineProperty(this, 'propAccessCount', {
+    get: function() { return _propAccessCount; }
+  });
+}
+
+function GetTestKeyframeSequence(testProp) {
+  return [ new TestKeyframe(testProp) ]
+}
+
+gNonAnimatableProps.forEach(function(prop) {
+  test(function(t) {
+    var testKeyframe = new TestKeyframe(prop);
+
+    new KeyframeEffectReadOnly(null, testKeyframe);
+
+    assert_equals(testKeyframe.propAccessCount, 0, 'Accessor not called');
+  }, 'non-animatable property \'' + prop + '\' is not accessed when using'
+     + ' a property-indexed keyframe object');
+});
+
+gNonAnimatableProps.forEach(function(prop) {
+  test(function(t) {
+    var testKeyframes = GetTestKeyframeSequence(prop);
+
+    new KeyframeEffectReadOnly(null, testKeyframes);
+
+    assert_equals(testKeyframes[0].propAccessCount, 0, 'Accessor not called');
+  }, 'non-animatable property \'' + prop + '\' is not accessed when using'
+     + ' a keyframe sequence');
+});
+
+// FIXME: Test that non-enumerable properties are not accessed
+
+// FIXME: Test that properties are accessed in ascending order by Unicode
+//        codepoint
+//        (There is an existing test for this in
+//        keyframe-effect/constructor.html that should be moved here.)
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt
new file mode 100644
index 0000000..c065f06
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt
@@ -0,0 +1,47 @@
+This is a testharness.js-based test.
+FAIL Keyframes can be replaced with an empty keyframe effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one shorthand property two value property-indexed keyframes specification effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property two value property-indexed keyframes specification effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property property-indexed keyframes specification with different numbers of values effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a property-indexed keyframes specification with an invalid value effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification that needs to stringify its values effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference in a shorthand property effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property one value property-indexed keyframes specification effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property one non-array value property-indexed keyframes specification effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification where the first value is invalid effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification where the second value is invalid effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property one keyframe sequence effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property two keyframe sequence effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property two keyframe sequence effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one shorthand property two keyframe sequence effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property (a shorthand and one of its component longhands) two keyframe sequence effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence with duplicate values for a given interior offset effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence with duplicate values for offsets 0 and 1 effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property four keyframe sequence effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a single keyframe sequence with omitted offsets effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property keyframe sequence with some omitted offsets effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property keyframe sequence with some omitted offsets effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property keyframe sequence with all omitted offsets effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence with different easing values, but the same easing value for a given offset effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence with different composite values, but the same composite value for a given offset effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a one property two keyframe sequence that needs to stringify its values effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence with a CSS variable reference effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence with a CSS variable reference in a shorthand property effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence where shorthand precedes longhand effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence where longhand precedes shorthand effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence where lesser shorthand precedes greater shorthand effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence where greater shorthand precedes lesser shorthand effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property keyframe sequence where one property is missing from the first keyframe effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a two property keyframe sequence where one property is missing from the last keyframe effect.setKeyframes is not a function
+FAIL Keyframes can be replaced with a keyframe sequence with repeated values at offset 1 with different easings effect.setKeyframes is not a function
+PASS KeyframeEffect constructor throws with keyframes with an out-of-bounded positive offset 
+PASS KeyframeEffect constructor throws with keyframes with an out-of-bounded negative offset 
+PASS KeyframeEffect constructor throws with keyframes not loosely sorted by offset 
+PASS KeyframeEffect constructor throws with property-indexed keyframes with an invalid easing value 
+PASS KeyframeEffect constructor throws with a keyframe sequence with an invalid easing value 
+PASS KeyframeEffect constructor throws with keyframes with an invalid composite value 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes.html
new file mode 100644
index 0000000..b82cb3d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>KeyframeEffect setKeyframes() tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-keyframeeffect-setkeyframes">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<script src="../../resources/keyframe-utils.js"></script>
+<body>
+<div id="log"></div>
+<div id="target"></div>
+<script>
+'use strict';
+
+var target = document.getElementById('target');
+
+test(function(t) {
+  gEmptyKeyframeListTests.forEach(function(frame) {
+    var effect = new KeyframeEffect(target, {});
+    effect.setKeyframes(frame);
+    assert_frame_lists_equal(effect.getKeyframes(), []);
+  });
+}, 'Keyframes can be replaced with an empty keyframe');
+
+gPropertyIndexedKeyframesTests.forEach(function(subtest) {
+  test(function(t) {
+    var effect = new KeyframeEffect(target, {});
+    effect.setKeyframes(subtest.input);
+    assert_frame_lists_equal(effect.getKeyframes(), subtest.output);
+  }, 'Keyframes can be replaced with ' + subtest.desc);
+});
+
+gKeyframeSequenceTests.forEach(function(subtest) {
+  test(function(t) {
+    var effect = new KeyframeEffect(target, {});
+    effect.setKeyframes(subtest.input);
+    assert_frame_lists_equal(effect.getKeyframes(), subtest.output);
+  }, 'Keyframes can be replaced with ' + subtest.desc);
+});
+
+gInvalidKeyframesTests.forEach(function(subtest) {
+  test(function(t) {
+    var effect = new KeyframeEffect(target, {});
+    assert_throws(subtest.expected, function() {
+      effect.setKeyframes(subtest.input);
+    });
+  }, 'KeyframeEffect constructor throws with ' + subtest.desc);
+});
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setTarget-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setTarget-expected.txt
new file mode 100644
index 0000000..271de512
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setTarget-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL Test setting target before constructing the associated animation Animation is not defined
+FAIL Test setting target from null to a valid target Animation is not defined
+FAIL Test setting target from a valid target to null assert_equals: Value after clearing the target expected "10px" but got "50px"
+FAIL Test setting target from a valid target to another target assert_equals: Value of 1st element (currently not targeted) after changing the effect target expected "10px" but got "50px"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setTarget.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setTarget.html
new file mode 100644
index 0000000..240cb3e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/interfaces/KeyframeEffect/setTarget.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Writable effect.target tests</title>
+<link rel="help"
+  href="https://w3c.github.io/web-animations/#dom-keyframeeffect-target">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+var gKeyFrames = { 'marginLeft': ['0px', '100px'] };
+
+test(function(t) {
+  var div = createDiv(t);
+  var effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
+  effect.target = div;
+
+  var anim = new Animation(effect, document.timeline);
+  anim.play();
+
+  anim.currentTime = 50 * MS_PER_SEC;
+  assert_equals(getComputedStyle(div).marginLeft, '50px',
+                'Value at 50% progress');
+}, 'Test setting target before constructing the associated animation');
+
+test(function(t) {
+  var div = createDiv(t);
+  div.style.marginLeft = '10px';
+  var effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
+  var anim = new Animation(effect, document.timeline);
+  anim.play();
+
+  anim.currentTime = 50 * MS_PER_SEC;
+  assert_equals(getComputedStyle(div).marginLeft, '10px',
+                'Value at 50% progress before setting new target');
+  effect.target = div;
+  assert_equals(getComputedStyle(div).marginLeft, '50px',
+                'Value at 50% progress after setting new target');
+}, 'Test setting target from null to a valid target');
+
+test(function(t) {
+  var div = createDiv(t);
+  div.style.marginLeft = '10px';
+  var anim = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+
+  anim.currentTime = 50 * MS_PER_SEC;
+  assert_equals(getComputedStyle(div).marginLeft, '50px',
+                'Value at 50% progress before clearing the target')
+
+  anim.effect.target = null;
+  assert_equals(getComputedStyle(div).marginLeft, '10px',
+                'Value after clearing the target')
+}, 'Test setting target from a valid target to null');
+
+test(function(t) {
+  var a = createDiv(t);
+  var b = createDiv(t);
+  a.style.marginLeft = '10px';
+  b.style.marginLeft = '20px';
+  var anim = a.animate(gKeyFrames, 100 * MS_PER_SEC);
+
+  anim.currentTime = 50 * MS_PER_SEC;
+  assert_equals(getComputedStyle(a).marginLeft, '50px',
+                'Value of 1st element (currently targeted) before ' +
+                'changing the effect target');
+  assert_equals(getComputedStyle(b).marginLeft, '20px',
+                'Value of 2nd element (currently not targeted) before ' +
+                'changing the effect target');
+  anim.effect.target = b;
+  assert_equals(getComputedStyle(a).marginLeft, '10px',
+                'Value of 1st element (currently not targeted) after ' +
+                'changing the effect target');
+  assert_equals(getComputedStyle(b).marginLeft, '50px',
+                'Value of 2nd element (currently targeted) after ' +
+                'changing the effect target');
+
+  // This makes sure the animation property is changed correctly on new
+  // targeted element.
+  anim.currentTime = 75 * MS_PER_SEC;
+  assert_equals(getComputedStyle(b).marginLeft, '75px',
+                'Value of 2nd target (currently targeted) after ' +
+                'changing the animation current time.');
+}, 'Test setting target from a valid target to another target');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/constructor.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/resources/keyframe-utils.js
similarity index 66%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/constructor.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/resources/keyframe-utils.js
index 2733fa8..5278ad5 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/constructor.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/resources/keyframe-utils.js
@@ -1,24 +1,24 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>KeyframeEffectReadOnly constructor tests</title>
-<link rel="help" href="http://w3c.github.io/web-animations/#the-keyframeeffect-interfaces">
-<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<div id="target"></div>
-<style>
-#target {
-  border-style: solid;  /* so border-*-width values don't compute to 0 */
-}
-</style>
-<script>
 "use strict";
 
-var target = document.getElementById("target");
+// Utility functions and common keyframe test data.
 
+// ------------------------------
+//  Helper functions
+// ------------------------------
+
+/**
+ * Test equality between two lists of computed keyframes
+ * @param {Array.<ComputedKeyframe>} a - actual computed keyframes
+ * @param {Array.<ComputedKeyframe>} b - expected computed keyframes
+ */
+function assert_frame_lists_equal(a, b) {
+  assert_equals(a.length, b.length, "number of frames");
+  for (var i = 0; i < Math.min(a.length, b.length); i++) {
+    assert_frames_equal(a[i], b[i], "ComputedKeyframe #" + i);
+  }
+}
+
+/** Helper */
 function assert_frames_equal(a, b, name) {
   assert_equals(Object.keys(a).sort().toString(),
                 Object.keys(b).sort().toString(),
@@ -28,25 +28,9 @@
   }
 }
 
-function assert_frame_lists_equal(a, b) {
-  assert_equals(a.length, b.length, "number of frames");
-  for (var i = 0; i < Math.min(a.length, b.length); i++) {
-    assert_frames_equal(a[i], b[i], "ComputedKeyframe #" + i);
-  }
-}
-
-var gEmptyKeyframeListTests = [
-  [],
-  null,
-  undefined,
-];
-
-test(function(t) {
-  gEmptyKeyframeListTests.forEach(function(frames) {
-    assert_equals(new KeyframeEffectReadOnly(target, frames).getFrames().length,
-                  0, "number of frames for " + JSON.stringify(frames));
-  });
-}, "a KeyframeEffectReadOnly can be constructed with no frames");
+// ------------------------------
+//  Easing values
+// ------------------------------
 
 // [specified easing value, expected easing value]
 var gEasingValueTests = [
@@ -56,46 +40,24 @@
   ["ease /**/", "ease"],
 ];
 
-test(function(t) {
-  gEasingValueTests.forEach(function(subtest) {
-    var easing = subtest[0];
-    var expected = subtest[1];
-    var effect = new KeyframeEffectReadOnly(target, {
-      left: ["10px", "20px"],
-      easing: easing
-    });
-    assert_equals(effect.getFrames()[0].easing, expected,
-                  "resulting easing for '" + easing + "'");
-  });
-}, "easing values are parsed correctly when passed to the " +
-   "KeyframeEffectReadOnly constructor in a property-indexed keyframe");
+var gInvalidEasingInKeyframeSequenceTests = [
+  { desc:   "a blank easing",
+    input:  [{ easing: "" }] },
+  { desc:   "an unrecognized easing",
+    input:  [{ easing: "unrecognized" }] },
+  { desc:   "an 'initial' easing",
+    input:  [{ easing: "initial" }] },
+  { desc:   "an 'inherit' easing",
+    input:  [{ easing: "inherit" }] },
+  { desc:   "a variable easing",
+    input:  [{ easing: "var(--x)" }] },
+  { desc:   "a multi-value easing",
+    input:  [{ easing: "ease-in-out, ease-out" }] }
+];
 
-test(function(t) {
-  gEasingValueTests.forEach(function(subtest) {
-    var easing = subtest[0];
-    var expected = subtest[1];
-    var effect = new KeyframeEffectReadOnly(target, [
-      { offset: 0, left: "10px", easing: easing },
-      { offset: 1, left: "20px" }
-    ]);
-    assert_equals(effect.getFrames()[0].easing, expected,
-                  "resulting easing for '" + easing + "'");
-  });
-}, "easing values are parsed correctly when passed to the " +
-   "KeyframeEffectReadOnly constructor in regular keyframes");
-
-test(function(t) {
-  gEasingValueTests.forEach(function(subtest) {
-    var easing = subtest[0];
-    var expected = subtest[1];
-    var effect = new KeyframeEffectReadOnly(target, {
-      left: ["10px", "20px"]
-    }, { easing: easing });
-    assert_equals(effect.timing.easing, expected,
-                  "resulting easing for '" + easing + "'");
-  });
-}, "easing values are parsed correctly when passed to the " +
-   "KeyframeEffectReadOnly constructor in KeyframeTimingOptions");
+// ------------------------------
+//  Composite values
+// ------------------------------
 
 var gGoodKeyframeCompositeValueTests = [
   "replace", "add", "accumulate", undefined
@@ -109,60 +71,15 @@
   "unrecognised", "replace ", "Replace", null
 ];
 
-test(function(t) {
-  var getFrame = function(composite) {
-    return { left: [ "10px", "20px" ], composite: composite };
-  };
-  gGoodKeyframeCompositeValueTests.forEach(function(composite) {
-    var effect = new KeyframeEffectReadOnly(target, getFrame(composite));
-    assert_equals(effect.getFrames()[0].composite, composite,
-                  "resulting composite for '" + composite + "'");
-  });
-  gBadCompositeValueTests.forEach(function(composite) {
-    assert_throws(new TypeError, function() {
-                    new KeyframeEffectReadOnly(target, getFrame(composite));
-                  });
-  });
-}, "composite values are parsed correctly when passed to the " +
-   "KeyframeEffectReadOnly constructor in property-indexed keyframes");
+// ------------------------------
+//  Keyframes
+// ------------------------------
 
-test(function(t) {
-  var getFrames = function(composite) {
-    return [
-      { offset: 0, left: "10px", composite: composite },
-      { offset: 1, left: "20px" }
-    ];
-  };
-  gGoodKeyframeCompositeValueTests.forEach(function(composite) {
-    var effect = new KeyframeEffectReadOnly(target, getFrames(composite));
-    assert_equals(effect.getFrames()[0].composite, composite,
-                  "resulting composite for '" + composite + "'");
-  });
-  gBadCompositeValueTests.forEach(function(composite) {
-    assert_throws(new TypeError, function() {
-                    new KeyframeEffectReadOnly(target, getFrames(composite));
-                  });
-  });
-}, "composite values are parsed correctly when passed to the " +
-   "KeyframeEffectReadOnly constructor in regular keyframes");
-
-test(function(t) {
-  gGoodOptionsCompositeValueTests.forEach(function(composite) {
-    var effect = new KeyframeEffectReadOnly(target, {
-      left: ["10px", "20px"]
-    }, { composite: composite });
-    assert_equals(effect.getFrames()[0].composite, composite,
-                  "resulting composite for '" + composite + "'");
-  });
-  gBadCompositeValueTests.forEach(function(composite) {
-    assert_throws(new TypeError, function() {
-                                   new KeyframeEffectReadOnly(target, {
-                                     left: ["10px", "20px"]
-                                   }, { composite: composite });
-                                 });
-  });
-}, "composite values are parsed correctly when passed to the " +
-   "KeyframeEffectReadOnly constructor in KeyframeTimingOptions");
+var gEmptyKeyframeListTests = [
+  [],
+  null,
+  undefined,
+];
 
 var gPropertyIndexedKeyframesTests = [
   { desc:   "a one property two value property-indexed keyframes specification",
@@ -223,6 +140,20 @@
                opacity: "0" },
              { offset: null, computedOffset: 1, easing: "linear",
                opacity: "1" }] },
+  { desc:   "a property-indexed keyframes specification with a CSS variable"
+            + " reference",
+    input:  { left: [ "var(--dist)", "calc(var(--dist) + 100px)" ] },
+    output: [{ offset: null, computedOffset: 0.0, easing: "linear",
+               left: "var(--dist)" },
+             { offset: null, computedOffset: 1.0, easing: "linear",
+               left: "calc(var(--dist) + 100px)" }] },
+  { desc:   "a property-indexed keyframes specification with a CSS variable"
+            + " reference in a shorthand property",
+    input:  { margin: [ "var(--dist)", "calc(var(--dist) + 100px)" ] },
+    output: [{ offset: null, computedOffset: 0.0, easing: "linear",
+               margin: "var(--dist)" },
+             { offset: null, computedOffset: 1.0, easing: "linear",
+               margin: "calc(var(--dist) + 100px)" }] },
   { desc:   "a one property one value property-indexed keyframes specification",
     input:  { left: ["10px"] },
     output: [{ offset: null, computedOffset: 1, easing: "linear",
@@ -246,75 +177,13 @@
                left: "10px" },
              { offset: null, computedOffset: 1, easing: "linear",
                left: "invalid" }] },
-  { desc:   "a two property property-indexed keyframes specification where one"
-            + " property is missing from the first keyframe",
-    input:  [{ offset: 0, left: "10px" },
-             { offset: 1, left: "20px", top: "30px" }],
-    output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
-             { offset: 1, computedOffset: 1, easing: "linear",
-               left: "20px", top: "30px" }] },
-  { desc:   "a two property property-indexed keyframes specification where one"
-            + " property is missing from the last keyframe",
-    input:  [{ offset: 0, left: "10px", top: "20px" },
-             { offset: 1, left: "30px" }],
-    output: [{ offset: 0, computedOffset: 0, easing: "linear",
-               left: "10px" , top: "20px" },
-             { offset: 1, computedOffset: 1, easing: "linear",
-               left: "30px" }] },
-  { desc:   "a property-indexed keyframes specification with repeated values"
-            + " at offset 0 with different easings",
-    input:  [{ offset: 0.0, left: "100px", easing: "ease" },
-             { offset: 0.0, left: "200px", easing: "ease" },
-             { offset: 0.5, left: "300px", easing: "linear" },
-             { offset: 1.0, left: "400px", easing: "ease-out" },
-             { offset: 1.0, left: "500px", easing: "step-end" }],
-    output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease",
-               left: "100px" },
-             { offset: 0.0, computedOffset: 0.0, easing: "ease",
-               left: "200px" },
-             { offset: 0.5, computedOffset: 0.5, easing: "linear",
-               left: "300px" },
-             { offset: 1.0, computedOffset: 1.0, easing: "ease-out",
-               left: "400px" },
-             { offset: 1.0, computedOffset: 1.0, easing: "step-end",
-               left: "500px" }] },
 ];
 
-gPropertyIndexedKeyframesTests.forEach(function(subtest) {
-  test(function(t) {
-    var effect = new KeyframeEffectReadOnly(target, subtest.input);
-    assert_frame_lists_equal(effect.getFrames(), subtest.output);
-  }, "a KeyframeEffectReadOnly can be constructed with " + subtest.desc);
-
-  test(function(t) {
-    var effect = new KeyframeEffectReadOnly(target, subtest.input);
-    var secondEffect = new KeyframeEffectReadOnly(target, effect.getFrames());
-    assert_frame_lists_equal(secondEffect.getFrames(), effect.getFrames());
-  }, "a KeyframeEffectReadOnly constructed with " + subtest.desc +
-     " roundtrips");
-});
-
-test(function(t) {
-  var expectedOrder = ["composite", "easing", "offset", "left", "marginLeft"];
-  var actualOrder = [];
-  var kf1 = {};
-  var kf2 = { marginLeft: "10px", left: "20px", offset: 1 };
-  [{ p: "marginLeft", v: "10px" },
-   { p: "left",       v: "20px" },
-   { p: "offset",     v: "0" },
-   { p: "easing",     v: "linear" },
-   { p: "composite",  v: "replace" }].forEach(function(e) {
-    Object.defineProperty(kf1, e.p, {
-      enumerable: true,
-      get: function() { actualOrder.push(e.p); return e.v; }
-    });
-  });
-  new KeyframeEffectReadOnly(target, [kf1, kf2]);
-  assert_array_equals(actualOrder, expectedOrder, "property access order");
-}, "the KeyframeEffectReadOnly constructor reads keyframe properties in the " +
-   "expected order");
-
 var gKeyframeSequenceTests = [
+  { desc:   "a one property one keyframe sequence",
+    input:  [{ offset: 1, left: "10px" }],
+    output: [{ offset: null, computedOffset: 1, easing: "linear",
+               left: "10px" }] },
   { desc:   "a one property two keyframe sequence",
     input:  [{ offset: 0, left: "10px" },
              { offset: 1, left: "20px" }],
@@ -384,6 +253,10 @@
              { offset: 1, computedOffset: 1, easing: "linear", top: "30px" },
              { offset: 1, computedOffset: 1, easing: "linear", left: "40px" }]
   },
+  { desc:   "a single keyframe sequence with omitted offsets",
+    input:  [{ left: "10px" }],
+    output: [{ offset: null, computedOffset: 1, easing: "linear",
+               left: "10px" }] },
   { desc:   "a one property keyframe sequence with some omitted offsets",
     input:  [{ offset: 0.00, left: "10px" },
              { offset: 0.25, left: "20px" },
@@ -479,6 +352,21 @@
     output: [{ offset: 0, computedOffset: 0, easing: "linear", opacity: "0" },
              { offset: 1, computedOffset: 1, easing: "linear", opacity: "1" }]
   },
+  { desc:   "a keyframe sequence with a CSS variable reference",
+    input:  [{ left: "var(--dist)" },
+             { left: "calc(var(--dist) + 100px)" }],
+    output: [{ offset: null, computedOffset: 0.0, easing: "linear",
+               left: "var(--dist)" },
+             { offset: null, computedOffset: 1.0, easing: "linear",
+               left: "calc(var(--dist) + 100px)" }] },
+  { desc:   "a keyframe sequence with a CSS variable reference in a shorthand"
+            + " property",
+    input:  [{ margin: "var(--dist)" },
+             { margin: "calc(var(--dist) + 100px)" }],
+    output: [{ offset: null, computedOffset: 0.0, easing: "linear",
+               margin: "var(--dist)" },
+             { offset: null, computedOffset: 1.0, easing: "linear",
+               margin: "calc(var(--dist) + 100px)" }] },
   { desc:   "a keyframe sequence where shorthand precedes longhand",
     input:  [{ offset: 0, margin: "10px", marginRight: "20px" },
              { offset: 1, margin: "30px" }],
@@ -514,67 +402,72 @@
                borderLeft: "1px solid rgb(1, 2, 3)" },
              { offset: 1, computedOffset: 1, easing: "linear",
                border: "3px dashed rgb(7, 8, 9)" }] },
+  { desc:   "a two property keyframe sequence where one property is missing"
+            + " from the first keyframe",
+    input:  [{ offset: 0, left: "10px" },
+             { offset: 1, left: "20px", top: "30px" }],
+    output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
+             { offset: 1, computedOffset: 1, easing: "linear",
+               left: "20px", top: "30px" }] },
+  { desc:   "a two property keyframe sequence where one property is missing"
+            + " from the last keyframe",
+    input:  [{ offset: 0, left: "10px", top: "20px" },
+             { offset: 1, left: "30px" }],
+    output: [{ offset: 0, computedOffset: 0, easing: "linear",
+               left: "10px" , top: "20px" },
+             { offset: 1, computedOffset: 1, easing: "linear",
+               left: "30px" }] },
+  { desc:   "a keyframe sequence with repeated values at offset 1 with"
+            + " different easings",
+    input:  [{ offset: 0.0, left: "100px", easing: "ease" },
+             { offset: 0.0, left: "200px", easing: "ease" },
+             { offset: 0.5, left: "300px", easing: "linear" },
+             { offset: 1.0, left: "400px", easing: "ease-out" },
+             { offset: 1.0, left: "500px", easing: "step-end" }],
+    output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease",
+               left: "100px" },
+             { offset: 0.0, computedOffset: 0.0, easing: "ease",
+               left: "200px" },
+             { offset: 0.5, computedOffset: 0.5, easing: "linear",
+               left: "300px" },
+             { offset: 1.0, computedOffset: 1.0, easing: "ease-out",
+               left: "400px" },
+             { offset: 1.0, computedOffset: 1.0, easing: "step-end",
+               left: "500px" }] },
 ];
 
-gKeyframeSequenceTests.forEach(function(subtest) {
-  test(function(t) {
-    var effect = new KeyframeEffectReadOnly(target, subtest.input);
-    assert_frame_lists_equal(effect.getFrames(), subtest.output);
-  }, "a KeyframeEffectReadOnly can be constructed with " + subtest.desc);
-
-  test(function(t) {
-    var effect = new KeyframeEffectReadOnly(target, subtest.input);
-    var secondEffect = new KeyframeEffectReadOnly(target, effect.getFrames());
-    assert_frame_lists_equal(secondEffect.getFrames(), effect.getFrames());
-  }, "a KeyframeEffectReadOnly constructed with " + subtest.desc +
-     " roundtrips");
-});
-
-var gInvalidEasingInKeyframeSequenceTests = [
-  { desc:   "a blank easing",
-    input:  [{ easing: "" }] },
-  { desc:   "an unrecognized easing",
-    input:  [{ easing: "unrecognized" }] },
-  { desc:   "an 'initial' easing",
-    input:  [{ easing: "initial" }] },
-  { desc:   "an 'inherit' easing",
-    input:  [{ easing: "inherit" }] },
-  { desc:   "a variable easing",
-    input:  [{ easing: "var(--x)" }] },
-  { desc:   "a multi-value easing",
-    input:  [{ easing: "ease-in-out, ease-out" }] }
+var gInvalidKeyframesTests = [
+  { desc:     "keyframes with an out-of-bounded positive offset",
+    input:    [ { opacity: 0 },
+                { opacity: 0.5, offset: 2 },
+                { opacity: 1 } ],
+    expected: { name: "TypeError" } },
+  { desc:     "keyframes with an out-of-bounded negative offset",
+    input:    [ { opacity: 0 },
+                { opacity: 0.5, offset: -1 },
+                { opacity: 1 } ],
+    expected: { name: "TypeError" } },
+  { desc:     "keyframes not loosely sorted by offset",
+    input:    [ { opacity: 0, offset: 1 },
+                { opacity: 1, offset: 0 } ],
+    expected: { name: "TypeError" } },
+  { desc:     "property-indexed keyframes with an invalid easing value",
+    input:    { opacity: [ 0, 0.5, 1 ],
+                easing: "inherit" },
+    expected: { name: "TypeError" } },
+  { desc:     "a keyframe sequence with an invalid easing value",
+    input:    [ { opacity: 0, easing: "jumpy" },
+                { opacity: 1 } ],
+    expected: { name: "TypeError" } },
+  { desc:     "keyframes with an invalid composite value",
+    input:    [ { opacity: 0, composite: "alternate" },
+                { opacity: 1 } ],
+    expected: { name: "TypeError" } }
 ];
 
-gInvalidEasingInKeyframeSequenceTests.forEach(function(subtest) {
-  test(function(t) {
-    assert_throws(new TypeError, function() {
-      new KeyframeEffectReadOnly(target, subtest.input);
-    });
-  }, "Invalid easing [" + subtest.desc + "] in keyframe sequence " +
-     "should be thrown");
-});
-
-test(function(t) {
-  var effect = new KeyframeEffectReadOnly(target,
-                                          {left: ["10px", "20px"]});
-
-  var timing = effect.timing;
-  assert_equals(timing.delay, 0, "default delay");
-  assert_equals(timing.endDelay, 0, "default endDelay");
-  assert_equals(timing.fill, "auto", "default fill");
-  assert_equals(timing.iterations, 1.0, "default iterations");
-  assert_equals(timing.iterationStart, 0.0, "default iterationStart");
-  assert_equals(timing.duration, "auto", "default duration");
-  assert_equals(timing.direction, "normal", "default direction");
-  assert_equals(timing.easing, "linear", "default easing");
-
-  assert_equals(effect.composite, "replace", "default composite");
-  assert_equals(effect.iterationComposite, "replace",
-                "default iterationComposite");
-  assert_equals(effect.spacing, "distribute",
-                "default spacing");
-}, "a KeyframeEffectReadOnly constructed without any " +
-   "KeyframeEffectOptions object");
+// ------------------------------
+//  KeyframeEffectOptions
+// ------------------------------
 
 var gKeyframeEffectOptionTests = [
   { desc:     "an empty KeyframeEffectOptions object",
@@ -614,33 +507,6 @@
     expected: { fill: "forwards" } }
 ];
 
-gKeyframeEffectOptionTests.forEach(function(stest) {
-  test(function(t) {
-    var effect = new KeyframeEffectReadOnly(target,
-                                            {left: ["10px", "20px"]},
-                                            stest.input);
-
-    // Helper function to provide default expected values when the test does
-    // not supply them.
-    var expected = function(field, defaultValue) {
-      return field in stest.expected ? stest.expected[field] : defaultValue;
-    };
-
-    var timing = effect.timing;
-    assert_equals(timing.delay, expected("delay", 0),
-                  "timing delay");
-    assert_equals(timing.fill, expected("fill", "auto"),
-                  "timing fill");
-    assert_equals(timing.iterations, expected("iterations", 1),
-                  "timing iterations");
-    assert_equals(timing.duration, expected("duration", "auto"),
-                  "timing duration");
-    assert_equals(timing.direction, expected("direction", "normal"),
-                  "timing direction");
-
-  }, "a KeyframeEffectReadOnly constructed by " + stest.desc);
-});
-
 var gInvalidKeyframeEffectOptionTests = [
   { desc:     "-Infinity",
     input:    -Infinity,
@@ -691,34 +557,3 @@
     input:    { easing: "ease-in-out, ease-out" },
     expected: { name: "TypeError" } }
 ];
-
-gInvalidKeyframeEffectOptionTests.forEach(function(stest) {
-  test(function(t) {
-    assert_throws(stest.expected, function() {
-      new KeyframeEffectReadOnly(target,
-                                 { left: ["10px", "20px"] },
-                                 stest.input);
-    });
-  }, "Invalid KeyframeEffectReadOnly option by " + stest.desc);
-});
-
-test(function(t) {
-  var effect = new KeyframeEffect(target,
-                                  { left: ["10px", "20px"] });
-
-  assert_class_string(effect, "KeyframeEffect");
-  assert_class_string(effect.timing, "AnimationEffectTiming");
-}, "KeyframeEffect constructor creates an AnimationEffectTiming timing object");
-
-test(function(t) {
-  var test_error = { name: "test" };
-
-  assert_throws(test_error, function() {
-    new KeyframeEffect(target, { get left() { throw test_error }})
-  });
-}, "KeyframeEffect constructor propagates exceptions generated by accessing"
-   + " the options object");
-
-done();
-</script>
-</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/testcommon.js b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/testcommon.js
index ab54202f..5ba0308 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/testcommon.js
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/testcommon.js
@@ -8,9 +8,23 @@
 [3] http://www.w3.org/2004/10/27-testcases
  */
 
-"use strict";
+'use strict';
+
 var MS_PER_SEC = 1000;
 
+// The recommended minimum precision to use for time values[1].
+//
+// [1] https://w3c.github.io/web-animations/#precision-of-time-values
+var TIME_PRECISION = 0.0005; // ms
+
+// Allow implementations to substitute an alternative method for comparing
+// times based on their precision requirements.
+if (!window.assert_times_equal) {
+  window.assert_times_equal = function(actual, expected, description) {
+    assert_approx_equals(actual, expected, TIME_PRECISION, description);
+  }
+}
+
 // creates div element, appends it to the document body and
 // removes the created element during test cleanup
 function createDiv(test, doc) {
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/active-time.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/active-time.html
new file mode 100644
index 0000000..a7f84a7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/active-time.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Active time tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#active-time">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+async_test(function(t) {
+  var div = createDiv(t);
+  var anim = div.animate({ opacity: [ 0, 1 ] }, { delay: 1 });
+  assert_equals(anim.effect.getComputedTiming().progress, null);
+  anim.finished.then(t.step_func(function() {
+    assert_equals(anim.effect.getComputedTiming().progress, null);
+    t.done();
+  }));
+}, 'Test progress during before and after phase when fill is none');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-currentIteration-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/current-iteration-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-currentIteration-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/current-iteration-expected.txt
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-currentIteration.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/current-iteration.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-currentIteration.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/current-iteration.html
index e951bfd1..30ee8c7 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-currentIteration.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/current-iteration.html
@@ -1,11 +1,10 @@
 <!DOCTYPE html>
 <meta charset=utf-8>
-<title>currentIteration of KeyframeEffectReadOnly getComputedTiming() tests</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffectreadonly-getcomputedtiming">
-<link rel="author" title="Daisuke Akatsuka" href="mailto:daisuke@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<title>Current iteration tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#current-iteration">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-progress-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/simple-iteration-progress-expected.txt
similarity index 97%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-progress-expected.txt
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/simple-iteration-progress-expected.txt
index 44a3f6f..a8d3eed 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-progress-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/simple-iteration-progress-expected.txt
@@ -1,5 +1,4 @@
 This is a testharness.js-based test.
-PASS Test progress during before and after phase when fill is none 
 PASS Test zero iterations: iterations:0 iterationStart:0 duration:0 delay:1 fill:both 
 PASS Test zero iterations: iterations:0 iterationStart:0 duration:100 delay:1 fill:both 
 PASS Test zero iterations: iterations:0 iterationStart:0 duration:Infinity delay:1 fill:both 
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-progress.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/simple-iteration-progress.html
similarity index 91%
rename from third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-progress.html
rename to third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/simple-iteration-progress.html
index 4cecc1d..4a2069c 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/getComputedTiming-progress.html
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animation-effects/simple-iteration-progress.html
@@ -1,11 +1,11 @@
 <!DOCTYPE html>
 <meta charset=utf-8>
-<title>progress of KeyframeEffectReadOnly getComputedTiming() tests</title>
-<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffectreadonly-getcomputedtiming">
-<link rel="author" title="Daisuke Akatsuka" href="mailto:daisuke@mozilla-japan.org">
-<script src="../../../../resources/testharness.js"></script>
-<script src="../../../../resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<title>Simple iteration progress tests</title>
+<link rel="help"
+      href="https://w3c.github.io/web-animations/#simple-iteration-progress">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
 <body>
 <div id="log"></div>
 <script>
@@ -34,16 +34,6 @@
   });
 }
 
-async_test(function(t) {
-  var div = createDiv(t);
-  var anim = div.animate({ opacity: [ 0, 1 ] }, { delay: 1 });
-  assert_equals(anim.effect.getComputedTiming().progress, null);
-  anim.finished.then(t.step_func(function() {
-    assert_equals(anim.effect.getComputedTiming().progress, null);
-    t.done();
-  }));
-}, 'Test progress during before and after phase when fill is none');
-
 var gTests_zero_iterations = [
   {
     input:    { iterations: 0,
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt
new file mode 100644
index 0000000..b74e20b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt
@@ -0,0 +1,10 @@
+This is a testharness.js-based test.
+FAIL Setting the start time of an animation without an active timeline Animation is not defined
+FAIL Setting an unresolved start time an animation without an active timeline does not clear the current time Animation is not defined
+FAIL Setting the start time clears the hold time Animation is not defined
+FAIL Setting an unresolved start time sets the hold time Animation is not defined
+FAIL Setting the start time resolves a pending ready promise Animation is not defined
+FAIL Setting the start time resolves a pending pause task Animation is not defined
+FAIL Setting the start time updates the finished state Animation is not defined
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animations/set-the-animation-start-time.html b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animations/set-the-animation-start-time.html
new file mode 100644
index 0000000..0e1e9a6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/wpt/web-animations/timing-model/animations/set-the-animation-start-time.html
@@ -0,0 +1,205 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Setting the start time tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#set-the-animation-start-time">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t)
+{
+  // It should only be possible to set *either* the start time or the current
+  // time for an animation that does not have an active timeline.
+
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC));
+
+  assert_equals(animation.currentTime, null, 'Intial current time');
+  assert_equals(animation.startTuime, null, 'Intial start time');
+
+  animation.currentTime = 1000;
+  assert_equals(animation.currentTime, 1000,
+                'Setting the current time succeeds');
+  assert_equals(animation.startTime, null,
+                'Start time remains null after setting current time');
+
+  animation.startTime = 1000;
+  assert_equals(animation.startTime, 1000,
+                'Setting the start time succeeds');
+  assert_equals(animation.currentTime, null,
+                'Setting the start time clears the current time');
+
+  animation.startTime = null;
+  assert_equals(animation.startTime, null,
+                'Setting the start time to an unresolved time succeeds');
+  assert_equals(animation.currentTime, null, 'The current time is unaffected');
+
+}, 'Setting the start time of an animation without an active timeline');
+
+test(function(t)
+{
+  // Setting an unresolved start time on an animation without an active
+  // timeline should not clear the current time.
+
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC));
+
+  assert_equals(animation.currentTime, null, 'Intial current time');
+  assert_equals(animation.startTuime, null, 'Intial start time');
+
+  animation.currentTime = 1000;
+  assert_equals(animation.currentTime, 1000,
+                'Setting the current time succeeds');
+  assert_equals(animation.startTime, null,
+                'Start time remains null after setting current time');
+
+  animation.startTime = null;
+  assert_equals(animation.startTime, null, 'Start time remains unresolved');
+  assert_equals(animation.currentTime, 1000, 'Current time is unaffected');
+
+}, 'Setting an unresolved start time an animation without an active timeline'
+   + ' does not clear the current time');
+
+test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  // So long as a hold time is set, querying the current time will return
+  // the hold time.
+
+  // Since the start time is unresolved at this point, setting the current time
+  // will set the hold time
+  animation.currentTime = 1000;
+  assert_equals(animation.currentTime, 1000,
+                'The current time is calculated from the hold time');
+
+  // If we set the start time, however, we should clear the hold time.
+  animation.startTime = document.timeline.currentTime - 2000;
+  assert_times_equal(animation.currentTime, 2000,
+                     'The current time is calculated from the start time,'
+                     + ' not the hold time');
+
+  // Sanity check
+  assert_equals(animation.playState, 'running',
+                'Animation reports it is running after setting a resolved'
+                + ' start time');
+}, 'Setting the start time clears the hold time');
+
+test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  // Set up a running animation (i.e. both start time and current time
+  // are resolved).
+  animation.startTime = document.timeline.currentTime - 1000;
+  assert_equals(animation.playState, 'running');
+  assert_times_equal(animation.currentTime, 1000,
+                     'Current time is resolved for a running animation')
+
+  // Clear start time
+  animation.startTime = null;
+  assert_times_equal(animation.currentTime, 1000,
+                     'Hold time is set after start time is made unresolved');
+  assert_equals(animation.playState, 'paused',
+                'Animation reports it is paused after setting an unresolved'
+                + ' start time');
+}, 'Setting an unresolved start time sets the hold time');
+
+promise_test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  var readyPromiseCallbackCalled = false;
+  animation.ready.then(function() { readyPromiseCallbackCalled = true; } );
+
+  // Put the animation in the play-pending state
+  animation.play();
+
+  // Sanity check
+  assert_equals(animation.playState, 'pending',
+                'Animation is in play-pending state');
+
+  // Setting the start time should resolve the 'ready' promise, i.e.
+  // it should schedule a microtask to run the promise callbacks.
+  animation.startTime = document.timeline.currentTime;
+  assert_false(readyPromiseCallbackCalled,
+               'Ready promise callback is not called synchronously');
+
+  // If we schedule another microtask then it should run immediately after
+  // the ready promise resolution microtask.
+  return Promise.resolve().then(function() {
+    assert_true(readyPromiseCallbackCalled,
+                'Ready promise callback called after setting startTime');
+  });
+}, 'Setting the start time resolves a pending ready promise');
+
+promise_test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  var readyPromiseCallbackCalled = false;
+  animation.ready.then(function() { readyPromiseCallbackCalled = true; } );
+
+  // Put the animation in the pause-pending state
+  animation.startTime = document.timeline.currentTime;
+  animation.pause();
+
+  // Sanity check
+  assert_equals(animation.playState, 'pending',
+                'Animation is in pause-pending state');
+
+  // Setting the start time should resolve the 'ready' promise although
+  // the resolution callbacks when be run in a separate microtask.
+  animation.startTime = null;
+  assert_false(readyPromiseCallbackCalled,
+               'Ready promise callback is not called synchronously');
+
+  return Promise.resolve().then(function() {
+    assert_true(readyPromiseCallbackCalled,
+                'Ready promise callback called after setting startTime');
+  });
+}, 'Setting the start time resolves a pending pause task');
+
+promise_test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  // Set start time such that the current time is past the end time
+  animation.startTime = document.timeline.currentTime
+                        - 110 * MS_PER_SEC;
+  assert_equals(animation.playState, 'finished',
+                'Seeked to finished state using the startTime');
+
+  // If the 'did seek' flag is true, the current time should be greater than
+  // the effect end.
+  assert_greater_than(animation.currentTime,
+                      animation.effect.getComputedTiming().endTime,
+                      'Setting the start time updated the finished state with'
+                      + ' the \'did seek\' flag set to true');
+
+  // Furthermore, that time should persist if we have correctly updated
+  // the hold time
+  var finishedCurrentTime = animation.currentTime;
+  return waitForAnimationFrames(1).then(function() {
+    assert_equals(animation.currentTime, finishedCurrentTime,
+                  'Current time does not change after seeking past the effect'
+                  + ' end time by setting the current time');
+  });
+}, 'Setting the start time updates the finished state');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/inspector/cookie-resource-match.html b/third_party/WebKit/LayoutTests/inspector/cookie-resource-match.html
index 4b9036d..cd2f5f1 100644
--- a/third_party/WebKit/LayoutTests/inspector/cookie-resource-match.html
+++ b/third_party/WebKit/LayoutTests/inspector/cookie-resource-match.html
@@ -12,12 +12,12 @@
         createCookie("secureOnlyWebkitPath", "bar", true, "webkit.org", "/path"),
         createCookie("secureAllWebkit", "foo", true, ".webkit.org", "/"),
         createCookie("secureAllWebkitPath", "foo", true, ".webkit.org", "/path"),
-        createCookie("insecureOnlyWebkitPort", "1234567890", false, "webkit.org", "/", 80),
-        createCookie("insecureAllWebkitPort", "1234567890123456", false, ".webkit.org", "/", 80),
-        createCookie("insecureAllWebkitPathPort", "1234567890123456", false, ".webkit.org", "/path", 80),
-        createCookie("secureOnlyWebkitPathPort", "bar", true, "webkit.org", "/path", 80),
-        createCookie("secureAllWebkitPort", "foo", true, ".webkit.org", "/", 80),
-        createCookie("secureAllWebkitPathPort", "foo", true, ".webkit.org", "/path", 80),
+        createCookie("insecureOnlyWebkitPort", "1234567890", false, "webkit.org", "/", "80"),
+        createCookie("insecureAllWebkitPort", "1234567890123456", false, ".webkit.org", "/", "80"),
+        createCookie("insecureAllWebkitPathPort", "1234567890123456", false, ".webkit.org", "/path", "80"),
+        createCookie("secureOnlyWebkitPathPort", "bar", true, "webkit.org", "/path", "80"),
+        createCookie("secureAllWebkitPort", "foo", true, ".webkit.org", "/", "80"),
+        createCookie("secureAllWebkitPathPort", "foo", true, ".webkit.org", "/path", "80"),
         createCookie("nonMatching1", "bar", false, "webkit.zoo", "/"),
         createCookie("nonMatching2", "bar", false, "webkit.org", "/badPath"),
         createCookie("nonMatching3", "bar", true, ".moo.com", "/")
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/selection/transformed-selection-rects-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/transformed-selection-rects-expected.txt
index c674a16..8442e4f1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/selection/transformed-selection-rects-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/transformed-selection-rects-expected.txt
@@ -1,5 +1,3 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/threaded/printing/list-item-with-empty-first-line-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
deleted file mode 100644
index da2c5549..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/threaded/printing/list-item-with-empty-first-line-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
deleted file mode 100644
index da2c5549..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/threaded/printing/list-item-with-empty-first-line-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
deleted file mode 100644
index da2c5549..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.txt
index f2f1fad..7d3f3a0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.txt
@@ -1,6 +1,3 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/selection/transformed-selection-rects-expected.txt b/third_party/WebKit/LayoutTests/platform/win/editing/selection/transformed-selection-rects-expected.txt
index d7e9b50..62405ae4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/editing/selection/transformed-selection-rects-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/editing/selection/transformed-selection-rects-expected.txt
@@ -1,5 +1,3 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
diff --git a/third_party/WebKit/LayoutTests/platform/win7/printing/list-item-with-empty-first-line-expected.png b/third_party/WebKit/LayoutTests/platform/win7/printing/list-item-with-empty-first-line-expected.png
new file mode 100644
index 0000000..12854fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/printing/list-item-with-empty-first-line-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/printing/list-item-with-empty-first-line-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/printing/list-item-with-empty-first-line-expected.txt
deleted file mode 100644
index e15dca6..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/printing/list-item-with-empty-first-line-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-layer at (0,0) size 1066x799
-  LayoutView at (0,0) size 1066x799
-layer at (0,0) size 1066x120
-  LayoutBlockFlow {HTML} at (0,0) size 1066x120
-    LayoutBlockFlow {BODY} at (8,8) size 1050x96
-      LayoutBlockFlow (anonymous) at (0,0) size 1050x20
-        LayoutText {#text} at (0,0) size 390x19
-          text run at (0,0) width 390: "Passes if both 'first' (with a line break) and 'second' have a bullet."
-      LayoutBlockFlow {UL} at (0,36) size 1050x60
-        LayoutListItem {LI} at (40,0) size 1010x40
-          LayoutListMarker (anonymous) at (-18,0) size 7x19: bullet
-          LayoutBR {BR} at (0,0) size 0x19
-          LayoutText {#text} at (0,20) size 22x19
-            text run at (0,20) width 22: "first"
-        LayoutListItem {LI} at (40,40) size 1010x20
-          LayoutListMarker (anonymous) at (-18,0) size 7x19: bullet
-          LayoutText {#text} at (0,0) size 43x19
-            text run at (0,0) width 43: "second"
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
index cad65fc2..12854fa 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.txt
deleted file mode 100644
index e15dca6..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/list-item-with-empty-first-line-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-layer at (0,0) size 1066x799
-  LayoutView at (0,0) size 1066x799
-layer at (0,0) size 1066x120
-  LayoutBlockFlow {HTML} at (0,0) size 1066x120
-    LayoutBlockFlow {BODY} at (8,8) size 1050x96
-      LayoutBlockFlow (anonymous) at (0,0) size 1050x20
-        LayoutText {#text} at (0,0) size 390x19
-          text run at (0,0) width 390: "Passes if both 'first' (with a line break) and 'second' have a bullet."
-      LayoutBlockFlow {UL} at (0,36) size 1050x60
-        LayoutListItem {LI} at (40,0) size 1010x40
-          LayoutListMarker (anonymous) at (-18,0) size 7x19: bullet
-          LayoutBR {BR} at (0,0) size 0x19
-          LayoutText {#text} at (0,20) size 22x19
-            text run at (0,20) width 22: "first"
-        LayoutListItem {LI} at (40,40) size 1010x20
-          LayoutListMarker (anonymous) at (-18,0) size 7x19: bullet
-          LayoutText {#text} at (0,0) size 43x19
-            text run at (0,0) width 43: "second"
diff --git a/third_party/WebKit/LayoutTests/svg/custom/animate-initial-pause-unpause-expected.txt b/third_party/WebKit/LayoutTests/svg/custom/animate-initial-pause-unpause-expected.txt
deleted file mode 100644
index db9481e..0000000
--- a/third_party/WebKit/LayoutTests/svg/custom/animate-initial-pause-unpause-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-CONSOLE WARNING: SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead.
-PASS
diff --git a/third_party/WebKit/LayoutTests/svg/custom/animate-initial-pause-unpause.html b/third_party/WebKit/LayoutTests/svg/custom/animate-initial-pause-unpause.html
index f975c3e..15b77a07 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/animate-initial-pause-unpause.html
+++ b/third_party/WebKit/LayoutTests/svg/custom/animate-initial-pause-unpause.html
@@ -1,36 +1,31 @@
 <!DOCTYPE HTML>
-<html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <!--
     Test for WK89943: pausing and unpausing an animation before it starts should have no effect.
 -->
-<body>
-    <svg id="svg" width="400" height="400">
-        <rect x="0" y="0" width="100" height="100" fill="red"/>
-        <rect id="rect" x="100" y="0" width="100" height="100" fill="green">
-            <set attributeName="x" to="0" begin="0.01s" fill="freeze"/>
-        </rect>
-    </svg>
-    <script>
-        if (window.testRunner) {
-            testRunner.waitUntilDone();
-            testRunner.dumpAsText();
-        }
+<svg id="svg" width="400" height="400">
+  <rect x="0" y="0" width="100" height="100" fill="red"/>
+  <rect id="rect" x="100" y="0" width="100" height="100" fill="green">
+    <set attributeName="x" to="0" begin="0.01s" fill="freeze"/>
+  </rect>
+</svg>
+<script>
+async_test(function(t) {
+  var svg = document.getElementById("svg");
 
-        var svg = document.getElementById("svg");
-        var rect = document.getElementById("rect");
+  svg.pauseAnimations();
+  svg.unpauseAnimations();
 
-        svg.pauseAnimations();
-        svg.unpauseAnimations();
+  var endStep = t.step_func_done(function() {
+    var rect = document.getElementById("rect");
+    assert_equals(rect.x.animVal.value, 0, "<set> is applied");
+  });
 
-        setTimeout(function() {
-            if (rect.x.animVal.value == 0)
-                document.body.innerHTML = "PASS";
-            else
-                document.body.innerHTML = "FAIL : rect.x.animVal.value was " + rect.x.animVal.value + " but we expected 0.";
-
-            if (window.testRunner)
-                testRunner.notifyDone();
-        }, 50);
-    </script>
-</body>
-</html>
+  window.onload = function() {
+    requestAnimationFrame(function() {
+      setTimeout(endStep, 50);
+    });
+  };
+}, "Pausing and unpausing an animation before it starts should have no effect");
+</script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-constructor-expected.txt b/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-constructor-expected.txt
index dcb80873..7633da3a 100644
--- a/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-constructor-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-constructor-expected.txt
@@ -24,7 +24,12 @@
 PASS context.length is 512
 PASS context = new OfflineAudioContext(2, 512, 96000) did not throw exception.
 PASS context = new OfflineAudioContext(1, 0, NaN) threw exception TypeError: Failed to construct 'OfflineAudioContext': The provided float value is non-finite..
-PASS context = new OfflineAudioContext(1, 0, Infinite) threw exception ReferenceError: Infinite is not defined.
+PASS context = new OfflineAudioContext(1, 0, Infinity) threw exception TypeError: Failed to construct 'OfflineAudioContext': The provided float value is non-finite..
+PASS context = new OfflineAudioContext(7, 512, 48000) did not throw exception.
+PASS context.destination.channelCount is 7
+PASS context.destination.maxChannelCount is 7
+PASS context.destination.channelCountMode is "explicit"
+PASS context.destination.channelInterpretation is "speakers"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-constructor.html b/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-constructor.html
index 3e3aa27..8f0332fb 100644
--- a/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-constructor.html
+++ b/third_party/WebKit/LayoutTests/webaudio/offlineaudiocontext-constructor.html
@@ -34,7 +34,13 @@
 shouldNotThrow("context = new OfflineAudioContext(2, 512, 96000)");
 // Make sure we throw exceptions for non-finite sample rates.
 shouldThrow("context = new OfflineAudioContext(1, 0, NaN)");
-shouldThrow("context = new OfflineAudioContext(1, 0, Infinite)");
+shouldThrow("context = new OfflineAudioContext(1, 0, Infinity)");
+// Verify channel counts and other destination attributes are set correctly.
+shouldNotThrow("context = new OfflineAudioContext(7, 512, 48000)");
+shouldBeEqualToNumber("context.destination.channelCount", 7);
+shouldBeEqualToNumber("context.destination.maxChannelCount", 7);
+shouldBeEqualToString("context.destination.channelCountMode", "explicit");
+shouldBeEqualToString("context.destination.channelInterpretation", "speakers");
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
index 0124b08..70b9ea11 100644
--- a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
@@ -5,7 +5,6 @@
 #include "bindings/core/v8/RejectedPromises.h"
 
 #include "bindings/core/v8/ScopedPersistent.h"
-#include "bindings/core/v8/ScriptCallStack.h"
 #include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/ScriptValue.h"
 #include "bindings/core/v8/V8Binding.h"
@@ -27,9 +26,9 @@
 
 class RejectedPromises::Message final {
 public:
-    static PassOwnPtr<Message> create(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<v8::Value> exception, const String& errorMessage, const String& resourceName, int scriptId, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
+    static PassOwnPtr<Message> create(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<v8::Value> exception, const String& errorMessage, PassOwnPtr<SourceLocation> location, AccessControlStatus corsStatus)
     {
-        return adoptPtr(new Message(scriptState, promise, exception, errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack, corsStatus));
+        return adoptPtr(new Message(scriptState, promise, exception, errorMessage, std::move(location), corsStatus));
     }
 
     bool isCollected()
@@ -86,12 +85,12 @@
             else if (embedderErrorMessage.startsWith("Uncaught "))
                 embedderErrorMessage.insert(" (in promise)", 8);
 
-            ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, embedderErrorMessage, m_resourceName, m_lineNumber, m_columnNumber, m_callStack, m_scriptId, arguments);
+            ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, embedderErrorMessage, std::move(m_location), arguments);
             m_consoleMessageId = consoleMessage->assignMessageId();
             executionContext->addConsoleMessage(consoleMessage);
         }
 
-        m_callStack.clear();
+        m_location.clear();
     }
 
     void revoke()
@@ -146,16 +145,13 @@
     }
 
 private:
-    Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<v8::Value> exception, const String& errorMessage, const String& resourceName, int scriptId, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
+    Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<v8::Value> exception, const String& errorMessage, PassOwnPtr<SourceLocation> location, AccessControlStatus corsStatus)
         : m_scriptState(scriptState)
         , m_promise(scriptState->isolate(), promise)
         , m_exception(scriptState->isolate(), exception)
         , m_errorMessage(errorMessage)
-        , m_resourceName(resourceName)
-        , m_scriptId(scriptId)
-        , m_lineNumber(lineNumber)
-        , m_columnNumber(columnNumber)
-        , m_callStack(callStack)
+        , m_resourceName(location->url())
+        , m_location(std::move(location))
         , m_consoleMessageId(0)
         , m_collected(false)
         , m_shouldLogToConsole(true)
@@ -179,10 +175,7 @@
     ScopedPersistent<v8::Value> m_exception;
     String m_errorMessage;
     String m_resourceName;
-    int m_scriptId;
-    int m_lineNumber;
-    int m_columnNumber;
-    RefPtr<ScriptCallStack> m_callStack;
+    OwnPtr<SourceLocation> m_location;
     unsigned m_consoleMessageId;
     bool m_collected;
     bool m_shouldLogToConsole;
@@ -197,9 +190,9 @@
 {
 }
 
-void RejectedPromises::rejectedWithNoHandler(ScriptState* scriptState, v8::PromiseRejectMessage data, const String& errorMessage, const String& resourceName, int scriptId, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
+void RejectedPromises::rejectedWithNoHandler(ScriptState* scriptState, v8::PromiseRejectMessage data, const String& errorMessage, PassOwnPtr<SourceLocation> location, AccessControlStatus corsStatus)
 {
-    m_queue.append(Message::create(scriptState, data.GetPromise(), data.GetValue(), errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack, corsStatus));
+    m_queue.append(Message::create(scriptState, data.GetPromise(), data.GetValue(), errorMessage, std::move(location), corsStatus));
 }
 
 void RejectedPromises::handlerAdded(v8::PromiseRejectMessage data)
diff --git a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.h b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.h
index d86d4b4..5fd0239f 100644
--- a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.h
+++ b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.h
@@ -5,6 +5,7 @@
 #ifndef RejectedPromises_h
 #define RejectedPromises_h
 
+#include "bindings/core/v8/SourceLocation.h"
 #include "core/fetch/AccessControlStatus.h"
 #include "wtf/Deque.h"
 #include "wtf/Forward.h"
@@ -17,7 +18,6 @@
 
 namespace blink {
 
-class ScriptCallStack;
 class ScriptState;
 
 class RejectedPromises final : public RefCounted<RejectedPromises> {
@@ -31,7 +31,7 @@
     ~RejectedPromises();
     void dispose();
 
-    void rejectedWithNoHandler(ScriptState*, v8::PromiseRejectMessage, const String& errorMessage, const String& resourceName, int scriptId, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>, AccessControlStatus);
+    void rejectedWithNoHandler(ScriptState*, v8::PromiseRejectMessage, const String& errorMessage, PassOwnPtr<SourceLocation>, AccessControlStatus);
     void handlerAdded(v8::PromiseRejectMessage);
 
     void processQueue();
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptCallStack.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptCallStack.cpp
index 6b954e3a..b7c5b08 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptCallStack.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptCallStack.cpp
@@ -40,15 +40,6 @@
 
 namespace blink {
 
-PassRefPtr<ScriptCallStack> ScriptCallStack::create(v8::Isolate* isolate, v8::Local<v8::StackTrace> stackTrace, size_t maxStackSize)
-{
-    V8PerIsolateData* data = V8PerIsolateData::from(isolate);
-    if (!data->threadDebugger())
-        return nullptr;
-    std::unique_ptr<V8StackTrace> stack = data->threadDebugger()->debugger()->createStackTrace(stackTrace, maxStackSize);
-    return stack ? adoptRef(new ScriptCallStack(std::move(stack))) : nullptr;
-}
-
 PassRefPtr<ScriptCallStack> ScriptCallStack::capture(size_t maxStackSize)
 {
     v8::Isolate* isolate = v8::Isolate::GetCurrent();
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptCallStack.h b/third_party/WebKit/Source/bindings/core/v8/ScriptCallStack.h
index 49b5f80..c4d57dba 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptCallStack.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptCallStack.h
@@ -43,7 +43,6 @@
 
 class CORE_EXPORT ScriptCallStack final : public RefCounted<ScriptCallStack> {
 public:
-    static PassRefPtr<ScriptCallStack> create(v8::Isolate*, v8::Local<v8::StackTrace>, size_t maxStackSize = V8StackTrace::maxCallStackSizeToCapture);
     static PassRefPtr<ScriptCallStack> capture(size_t maxStackSize = V8StackTrace::maxCallStackSizeToCapture);
     static PassRefPtr<ScriptCallStack> captureForConsole();
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp
index 21f16e35..4ec63860 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp
@@ -1249,15 +1249,15 @@
     return true;
 }
 
-bool SerializedScriptValueReader::read(v8::Local<v8::Value>* value, ScriptValueCompositeCreator& creator)
+bool SerializedScriptValueReader::read(v8::Local<v8::Value>* value, ScriptValueDeserializer& deserializer)
 {
     SerializationTag tag;
     if (!readTag(&tag))
         return false;
-    return readWithTag(tag, value, creator);
+    return readWithTag(tag, value, deserializer);
 }
 
-bool SerializedScriptValueReader::readWithTag(SerializationTag tag, v8::Local<v8::Value>* value, ScriptValueCompositeCreator& creator)
+bool SerializedScriptValueReader::readWithTag(SerializationTag tag, v8::Local<v8::Value>* value, ScriptValueDeserializer& deserializer)
 {
     switch (tag) {
     case ReferenceCountTag: {
@@ -1269,7 +1269,7 @@
         // If this test fails, then the serializer and deserializer disagree about the assignment
         // of object reference IDs. On the deserialization side, this means there are too many or too few
         // calls to pushObjectReference.
-        if (referenceTableSize != creator.objectReferenceCount())
+        if (referenceTableSize != deserializer.objectReferenceCount())
             return false;
         return true;
     }
@@ -1291,11 +1291,11 @@
         break;
     case TrueObjectTag:
         *value = v8::BooleanObject::New(isolate(), true);
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case FalseObjectTag:
         *value = v8::BooleanObject::New(isolate(), false);
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case StringTag:
         if (!readString(value))
@@ -1308,7 +1308,7 @@
     case StringObjectTag:
         if (!readStringObject(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case Int32Tag:
         if (!readInt32(value))
@@ -1321,7 +1321,7 @@
     case DateTag:
         if (!readDate(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case NumberTag:
         if (!readNumber(value))
@@ -1330,53 +1330,53 @@
     case NumberObjectTag:
         if (!readNumberObject(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case BlobTag:
     case BlobIndexTag:
         if (!readBlob(value, tag == BlobIndexTag))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case FileTag:
     case FileIndexTag:
         if (!readFile(value, tag == FileIndexTag))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case FileListTag:
     case FileListIndexTag:
         if (!readFileList(value, tag == FileListIndexTag))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case CompositorProxyTag:
         if (!readCompositorProxy(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
 
     case ImageDataTag:
         if (!readImageData(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case ImageBitmapTag:
         if (!readImageBitmap(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
 
     case RegExpTag:
         if (!readRegExp(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case ObjectTag: {
         uint32_t numProperties;
         if (!doReadUint32(&numProperties))
             return false;
-        if (!creator.completeObject(numProperties, value))
+        if (!deserializer.completeObject(numProperties, value))
             return false;
         break;
     }
@@ -1387,7 +1387,7 @@
             return false;
         if (!doReadUint32(&length))
             return false;
-        if (!creator.completeSparseArray(numProperties, length, value))
+        if (!deserializer.completeSparseArray(numProperties, length, value))
             return false;
         break;
     }
@@ -1398,7 +1398,7 @@
             return false;
         if (!doReadUint32(&length))
             return false;
-        if (!creator.completeDenseArray(numProperties, length, value))
+        if (!deserializer.completeDenseArray(numProperties, length, value))
             return false;
         break;
     }
@@ -1406,7 +1406,7 @@
         uint32_t length;
         if (!doReadUint32(&length))
             return false;
-        if (!creator.completeMap(length, value))
+        if (!deserializer.completeMap(length, value))
             return false;
         break;
     }
@@ -1414,16 +1414,16 @@
         uint32_t length;
         if (!doReadUint32(&length))
             return false;
-        if (!creator.completeSet(length, value))
+        if (!deserializer.completeSet(length, value))
             return false;
         break;
     }
     case ArrayBufferViewTag: {
         if (!m_version)
             return false;
-        if (!readArrayBufferView(value, creator))
+        if (!readArrayBufferView(value, deserializer))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     }
     case ArrayBufferTag: {
@@ -1431,13 +1431,13 @@
             return false;
         if (!readArrayBuffer(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     }
     case GenerateFreshObjectTag: {
         if (!m_version)
             return false;
-        if (!creator.newObject())
+        if (!deserializer.newObject())
             return false;
         return true;
     }
@@ -1447,7 +1447,7 @@
         uint32_t length;
         if (!doReadUint32(&length))
             return false;
-        if (!creator.newSparseArray(length))
+        if (!deserializer.newSparseArray(length))
             return false;
         return true;
     }
@@ -1457,21 +1457,21 @@
         uint32_t length;
         if (!doReadUint32(&length))
             return false;
-        if (!creator.newDenseArray(length))
+        if (!deserializer.newDenseArray(length))
             return false;
         return true;
     }
     case GenerateFreshMapTag: {
         if (!m_version)
             return false;
-        if (!creator.newMap())
+        if (!deserializer.newMap())
             return false;
         return true;
     }
     case GenerateFreshSetTag: {
         if (!m_version)
             return false;
-        if (!creator.newSet())
+        if (!deserializer.newSet())
             return false;
         return true;
     }
@@ -1481,7 +1481,7 @@
         uint32_t index;
         if (!doReadUint32(&index))
             return false;
-        if (!creator.tryGetTransferredMessagePort(index, value))
+        if (!deserializer.tryGetTransferredMessagePort(index, value))
             return false;
         break;
     }
@@ -1491,7 +1491,7 @@
         uint32_t index;
         if (!doReadUint32(&index))
             return false;
-        if (!creator.tryGetTransferredArrayBuffer(index, value))
+        if (!deserializer.tryGetTransferredArrayBuffer(index, value))
             return false;
         break;
     }
@@ -1501,7 +1501,7 @@
         uint32_t index;
         if (!doReadUint32(&index))
             return false;
-        if (!creator.tryGetTransferredImageBitmap(index, value))
+        if (!deserializer.tryGetTransferredImageBitmap(index, value))
             return false;
         break;
     }
@@ -1517,7 +1517,7 @@
             return false;
         if (!doReadUint32(&id))
             return false;
-        if (!creator.tryGetTransferredOffscreenCanvas(index, width, height, id, value))
+        if (!deserializer.tryGetTransferredOffscreenCanvas(index, width, height, id, value))
             return false;
         break;
     }
@@ -1527,7 +1527,7 @@
         uint32_t index;
         if (!doReadUint32(&index))
             return false;
-        if (!creator.tryGetTransferredSharedArrayBuffer(index, value))
+        if (!deserializer.tryGetTransferredSharedArrayBuffer(index, value))
             return false;
         break;
     }
@@ -1537,7 +1537,7 @@
         uint32_t reference;
         if (!doReadUint32(&reference))
             return false;
-        if (!creator.tryGetObjectFromObjectReference(reference, value))
+        if (!deserializer.tryGetObjectFromObjectReference(reference, value))
             return false;
         break;
     }
@@ -1770,7 +1770,7 @@
     return !value->IsEmpty();
 }
 
-bool SerializedScriptValueReader::readArrayBufferView(v8::Local<v8::Value>* value, ScriptValueCompositeCreator& creator)
+bool SerializedScriptValueReader::readArrayBufferView(v8::Local<v8::Value>* value, ScriptValueDeserializer& deserializer)
 {
     ArrayBufferViewSubTag subTag;
     uint32_t byteOffset;
@@ -1783,7 +1783,7 @@
         return false;
     if (!doReadUint32(&byteLength))
         return false;
-    if (!creator.consumeTopOfStack(&arrayBufferV8Value))
+    if (!deserializer.consumeTopOfStack(&arrayBufferV8Value))
         return false;
     if (arrayBufferV8Value.IsEmpty())
         return false;
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.h b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.h
index 3f436616..4eb6246 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.h
@@ -448,34 +448,7 @@
     BlobDataHandleMap& m_blobDataHandles;
 };
 
-// Interface used by SerializedScriptValueReader to create objects of composite types.
-class CORE_EXPORT ScriptValueCompositeCreator {
-    STACK_ALLOCATED();
-    WTF_MAKE_NONCOPYABLE(ScriptValueCompositeCreator);
-public:
-    ScriptValueCompositeCreator() { }
-    virtual ~ScriptValueCompositeCreator() { }
-
-    virtual bool consumeTopOfStack(v8::Local<v8::Value>*) = 0;
-    virtual uint32_t objectReferenceCount() = 0;
-    virtual void pushObjectReference(const v8::Local<v8::Value>&) = 0;
-    virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Local<v8::Value>*) = 0;
-    virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Local<v8::Value>*) = 0;
-    virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Local<v8::Value>*) = 0;
-    virtual bool tryGetTransferredImageBitmap(uint32_t index, v8::Local<v8::Value>*) = 0;
-    virtual bool tryGetTransferredOffscreenCanvas(uint32_t index, uint32_t width, uint32_t height, uint32_t id, v8::Local<v8::Value>*) = 0;
-    virtual bool tryGetTransferredSharedArrayBuffer(uint32_t index, v8::Local<v8::Value>*) = 0;
-    virtual bool newSparseArray(uint32_t length) = 0;
-    virtual bool newDenseArray(uint32_t length) = 0;
-    virtual bool newMap() = 0;
-    virtual bool newSet() = 0;
-    virtual bool newObject() = 0;
-    virtual bool completeObject(uint32_t numProperties, v8::Local<v8::Value>*) = 0;
-    virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Local<v8::Value>*) = 0;
-    virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Local<v8::Value>*) = 0;
-    virtual bool completeMap(uint32_t length, v8::Local<v8::Value>*) = 0;
-    virtual bool completeSet(uint32_t length, v8::Local<v8::Value>*) = 0;
-};
+class ScriptValueDeserializer;
 
 // SerializedScriptValueReader is responsible for deserializing primitive types and
 // restoring information about saved objects of composite types.
@@ -514,12 +487,12 @@
     }
 
 public:
-    virtual bool read(v8::Local<v8::Value>*, ScriptValueCompositeCreator&);
+    virtual bool read(v8::Local<v8::Value>*, ScriptValueDeserializer&);
     bool readVersion(uint32_t& version);
     void setVersion(uint32_t);
 
 protected:
-    bool readWithTag(SerializationTag, v8::Local<v8::Value>*, ScriptValueCompositeCreator&);
+    bool readWithTag(SerializationTag, v8::Local<v8::Value>*, ScriptValueDeserializer&);
 
     bool readTag(SerializationTag*);
     bool readWebCoreString(String*);
@@ -543,7 +516,7 @@
     bool readCompositorProxy(v8::Local<v8::Value>*);
     DOMArrayBuffer* doReadArrayBuffer();
     bool readArrayBuffer(v8::Local<v8::Value>*);
-    bool readArrayBufferView(v8::Local<v8::Value>*, ScriptValueCompositeCreator&);
+    bool readArrayBufferView(v8::Local<v8::Value>*, ScriptValueDeserializer&);
     bool readRegExp(v8::Local<v8::Value>*);
     bool readBlob(v8::Local<v8::Value>*, bool isIndexed);
     bool readFile(v8::Local<v8::Value>*, bool isIndexed);
@@ -581,7 +554,7 @@
     const BlobDataHandleMap& m_blobDataHandles;
 };
 
-class CORE_EXPORT ScriptValueDeserializer : public ScriptValueCompositeCreator {
+class CORE_EXPORT ScriptValueDeserializer {
     STACK_ALLOCATED();
     WTF_MAKE_NONCOPYABLE(ScriptValueDeserializer);
 public:
@@ -597,25 +570,25 @@
     }
 
     v8::Local<v8::Value> deserialize();
-    bool newSparseArray(uint32_t) override;
-    bool newDenseArray(uint32_t length) override;
-    bool newMap() override;
-    bool newSet() override;
-    bool consumeTopOfStack(v8::Local<v8::Value>*) override;
-    bool newObject() override;
-    bool completeObject(uint32_t numProperties, v8::Local<v8::Value>*) override;
-    bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Local<v8::Value>*) override;
-    bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Local<v8::Value>*) override;
-    bool completeMap(uint32_t length, v8::Local<v8::Value>*) override;
-    bool completeSet(uint32_t length, v8::Local<v8::Value>*) override;
-    void pushObjectReference(const v8::Local<v8::Value>&) override;
-    bool tryGetTransferredMessagePort(uint32_t index, v8::Local<v8::Value>*) override;
-    bool tryGetTransferredArrayBuffer(uint32_t index, v8::Local<v8::Value>*) override;
-    bool tryGetTransferredImageBitmap(uint32_t index, v8::Local<v8::Value>*) override;
-    bool tryGetTransferredOffscreenCanvas(uint32_t index, uint32_t width, uint32_t height, uint32_t id, v8::Local<v8::Value>*) override;
-    bool tryGetTransferredSharedArrayBuffer(uint32_t index, v8::Local<v8::Value>*) override;
-    bool tryGetObjectFromObjectReference(uint32_t reference, v8::Local<v8::Value>*) override;
-    uint32_t objectReferenceCount() override;
+    bool newSparseArray(uint32_t);
+    bool newDenseArray(uint32_t length);
+    bool newMap();
+    bool newSet();
+    bool consumeTopOfStack(v8::Local<v8::Value>*);
+    bool newObject();
+    bool completeObject(uint32_t numProperties, v8::Local<v8::Value>*);
+    bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Local<v8::Value>*);
+    bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Local<v8::Value>*);
+    bool completeMap(uint32_t length, v8::Local<v8::Value>*);
+    bool completeSet(uint32_t length, v8::Local<v8::Value>*);
+    void pushObjectReference(const v8::Local<v8::Value>&);
+    bool tryGetTransferredMessagePort(uint32_t index, v8::Local<v8::Value>*);
+    bool tryGetTransferredArrayBuffer(uint32_t index, v8::Local<v8::Value>*);
+    bool tryGetTransferredImageBitmap(uint32_t index, v8::Local<v8::Value>*);
+    bool tryGetTransferredOffscreenCanvas(uint32_t index, uint32_t width, uint32_t height, uint32_t id, v8::Local<v8::Value>*);
+    bool tryGetTransferredSharedArrayBuffer(uint32_t index, v8::Local<v8::Value>*);
+    bool tryGetObjectFromObjectReference(uint32_t reference, v8::Local<v8::Value>*);
+    uint32_t objectReferenceCount();
 
 protected:
     SerializedScriptValueReader& reader() { return m_reader; }
diff --git a/third_party/WebKit/Source/bindings/core/v8/SourceLocation.cpp b/third_party/WebKit/Source/bindings/core/v8/SourceLocation.cpp
index e821aa3..f7e4197 100644
--- a/third_party/WebKit/Source/bindings/core/v8/SourceLocation.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/SourceLocation.cpp
@@ -4,6 +4,7 @@
 
 #include "bindings/core/v8/SourceLocation.h"
 
+#include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
@@ -66,6 +67,37 @@
 }
 
 // static
+PassOwnPtr<SourceLocation> SourceLocation::fromMessage(v8::Isolate* isolate, v8::Local<v8::Message> message, ExecutionContext* executionContext)
+{
+    v8::Local<v8::StackTrace> stack = message->GetStackTrace();
+    std::unique_ptr<V8StackTrace> stackTrace = nullptr;
+    V8PerIsolateData* data = V8PerIsolateData::from(isolate);
+    if (data && data->threadDebugger())
+        stackTrace = data->threadDebugger()->debugger()->createStackTrace(stack);
+
+    int scriptId = message->GetScriptOrigin().ScriptID()->Value();
+    if (!stack.IsEmpty() && stack->GetFrameCount() > 0) {
+        int topScriptId = stack->GetFrame(0)->GetScriptId();
+        if (topScriptId == scriptId)
+            scriptId = 0;
+    }
+
+    int lineNumber = 0;
+    int columnNumber = 0;
+    if (v8Call(message->GetLineNumber(isolate->GetCurrentContext()), lineNumber)
+        && v8Call(message->GetStartColumn(isolate->GetCurrentContext()), columnNumber))
+        ++columnNumber;
+
+    if ((!scriptId || !lineNumber) && stackTrace && !stackTrace->isEmpty())
+        return adoptPtr(new SourceLocation(stackTrace->topSourceURL(), stackTrace->topLineNumber(), stackTrace->topColumnNumber(), std::move(stackTrace), 0));
+
+    String url = toCoreStringWithUndefinedOrNullCheck(message->GetScriptOrigin().ResourceName());
+    if (url.isNull())
+        url = executionContext->url();
+    return adoptPtr(new SourceLocation(url, lineNumber, columnNumber, std::move(stackTrace), scriptId));
+}
+
+// static
 PassOwnPtr<SourceLocation> SourceLocation::create(const String& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace> stackTrace, int scriptId)
 {
     return adoptPtr(new SourceLocation(url, lineNumber, columnNumber, std::move(stackTrace), scriptId));
diff --git a/third_party/WebKit/Source/bindings/core/v8/SourceLocation.h b/third_party/WebKit/Source/bindings/core/v8/SourceLocation.h
index d29eb1f..0890401f4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/SourceLocation.h
+++ b/third_party/WebKit/Source/bindings/core/v8/SourceLocation.h
@@ -25,6 +25,8 @@
     // Shortcut when location is unknown. Tries to capture call stack or parsing location if available.
     static PassOwnPtr<SourceLocation> capture(ExecutionContext* = nullptr);
 
+    static PassOwnPtr<SourceLocation> fromMessage(v8::Isolate*, v8::Local<v8::Message>, ExecutionContext*);
+
     static PassOwnPtr<SourceLocation> create(const String& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace>, int scriptId = 0);
     ~SourceLocation();
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
index 3b22250c..b3d61c8d 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
@@ -44,6 +44,7 @@
 #include "core/html/imports/HTMLImportsController.h"
 #include "core/inspector/InspectorTraceEvents.h"
 #include "platform/Histogram.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/TraceEvent.h"
 #include "public/platform/BlameContext.h"
 #include "public/platform/Platform.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
index 2ff20cc..cd6e616c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -28,9 +28,9 @@
 #include "bindings/core/v8/DOMWrapperWorld.h"
 #include "bindings/core/v8/RejectedPromises.h"
 #include "bindings/core/v8/RetainedDOMInfo.h"
-#include "bindings/core/v8/ScriptCallStack.h"
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/ScriptValue.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8Binding.h"
 #include "bindings/core/v8/V8DOMException.h"
 #include "bindings/core/v8/V8ErrorEvent.h"
@@ -95,26 +95,6 @@
     CRASH();
 }
 
-static PassRefPtr<ScriptCallStack> extractCallStack(v8::Isolate* isolate, v8::Local<v8::Message> message, int* const scriptId)
-{
-    v8::Local<v8::StackTrace> stackTrace = message->GetStackTrace();
-    RefPtr<ScriptCallStack> callStack = ScriptCallStack::create(isolate, stackTrace);
-    *scriptId = message->GetScriptOrigin().ScriptID()->Value();
-    if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) {
-        int topScriptId = stackTrace->GetFrame(0)->GetScriptId();
-        if (topScriptId == *scriptId)
-            *scriptId = 0;
-    }
-    return callStack.release();
-}
-
-static String extractResourceName(v8::Local<v8::Message> message, const ExecutionContext* context)
-{
-    v8::Local<v8::Value> resourceName = message->GetScriptOrigin().ResourceName();
-    bool shouldUseDocumentURL = context->isDocument() && (resourceName.IsEmpty() || !resourceName->IsString());
-    return shouldUseDocumentURL ? context->url() : toCoreString(resourceName.As<v8::String>());
-}
-
 static String extractMessageForConsole(v8::Isolate* isolate, v8::Local<v8::Value> data)
 {
     if (V8DOMWrapper::isWrapper(isolate, data)) {
@@ -129,17 +109,6 @@
     return emptyString();
 }
 
-static ErrorEvent* createErrorEventFromMesssage(ScriptState* scriptState, v8::Local<v8::Message> message, String resourceName)
-{
-    String errorMessage = toCoreStringWithNullCheck(message->Get());
-    int lineNumber = 0;
-    int columnNumber = 0;
-    if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber)
-        && v8Call(message->GetStartColumn(scriptState->context()), columnNumber))
-        ++columnNumber;
-    return ErrorEvent::create(errorMessage, resourceName, lineNumber, columnNumber, &scriptState->world());
-}
-
 static void messageHandlerInMainThread(v8::Local<v8::Message> message, v8::Local<v8::Value> data)
 {
     ASSERT(isMainThread());
@@ -150,8 +119,8 @@
     if (!scriptState->contextIsValid())
         return;
 
-    int scriptId = 0;
-    RefPtr<ScriptCallStack> callStack = extractCallStack(isolate, message, &scriptId);
+    ExecutionContext* context = scriptState->getExecutionContext();
+    OwnPtr<SourceLocation> location = SourceLocation::fromMessage(isolate, message, context);
 
     AccessControlStatus accessControlStatus = NotSharableCrossOrigin;
     if (message->IsOpaque())
@@ -159,9 +128,7 @@
     else if (message->IsSharedCrossOrigin())
         accessControlStatus = SharableCrossOrigin;
 
-    ExecutionContext* context = scriptState->getExecutionContext();
-    String resourceName = extractResourceName(message, context);
-    ErrorEvent* event = createErrorEventFromMesssage(scriptState, message, resourceName);
+    ErrorEvent* event = ErrorEvent::create(toCoreStringWithNullCheck(message->Get()), location->url(), location->lineNumber(), location->columnNumber(), &scriptState->world());
 
     String messageForConsole = extractMessageForConsole(isolate, data);
     if (!messageForConsole.isEmpty())
@@ -185,9 +152,9 @@
         // other isolated worlds (which means that the error events won't fire any event listeners
         // in user's scripts).
         EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents;
-        context->reportException(event, scriptId, callStack, accessControlStatus);
+        context->reportException(event, std::move(location), accessControlStatus);
     } else {
-        context->reportException(event, scriptId, callStack, accessControlStatus);
+        context->reportException(event, std::move(location), accessControlStatus);
     }
 }
 
@@ -207,7 +174,7 @@
     rejectedPromisesOnMainThread().processQueue();
 }
 
-static void promiseRejectHandler(v8::PromiseRejectMessage data, RejectedPromises& rejectedPromises, const String& fallbackResourceName)
+static void promiseRejectHandler(v8::PromiseRejectMessage data, RejectedPromises& rejectedPromises, ScriptState* scriptState)
 {
     if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) {
         rejectedPromises.handlerAdded(data);
@@ -218,7 +185,7 @@
 
     v8::Local<v8::Promise> promise = data.GetPromise();
     v8::Isolate* isolate = promise->GetIsolate();
-    ScriptState* scriptState = ScriptState::current(isolate);
+    ExecutionContext* context = scriptState->getExecutionContext();
 
     v8::Local<v8::Value> exception = data.GetValue();
     if (V8DOMWrapper::isWrapper(isolate, exception)) {
@@ -230,35 +197,26 @@
             exception = error;
     }
 
-    int scriptId = 0;
-    int lineNumber = 0;
-    int columnNumber = 0;
-    String resourceName = fallbackResourceName;
     String errorMessage;
     AccessControlStatus corsStatus = NotSharableCrossOrigin;
-    RefPtr<ScriptCallStack> callStack;
+    OwnPtr<SourceLocation> location;
 
     v8::Local<v8::Message> message = v8::Exception::CreateMessage(isolate, exception);
     if (!message.IsEmpty()) {
-        V8StringResource<> v8ResourceName(message->GetScriptOrigin().ResourceName());
-        if (v8ResourceName.prepare())
-            resourceName = v8ResourceName;
-        scriptId = message->GetScriptOrigin().ScriptID()->Value();
-        if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber)
-            && v8Call(message->GetStartColumn(scriptState->context()), columnNumber))
-            ++columnNumber;
         // message->Get() can be empty here. https://crbug.com/450330
         errorMessage = toCoreStringWithNullCheck(message->Get());
-        callStack = extractCallStack(isolate, message, &scriptId);
+        location = SourceLocation::fromMessage(isolate, message, context);
         if (message->IsSharedCrossOrigin())
             corsStatus = SharableCrossOrigin;
+    } else {
+        location = SourceLocation::create(context->url().getString(), 0, 0, nullptr);
     }
 
     String messageForConsole = extractMessageForConsole(isolate, data.GetValue());
     if (!messageForConsole.isEmpty())
         errorMessage = "Uncaught " + messageForConsole;
 
-    rejectedPromises.rejectedWithNoHandler(scriptState, data, errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack, corsStatus);
+    rejectedPromises.rejectedWithNoHandler(scriptState, data, errorMessage, std::move(location), corsStatus);
 }
 
 static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data)
@@ -280,7 +238,7 @@
     if (!scriptState->contextIsValid())
         return;
 
-    promiseRejectHandler(data, rejectedPromisesOnMainThread(), scriptState->getExecutionContext()->url());
+    promiseRejectHandler(data, rejectedPromisesOnMainThread(), scriptState);
 }
 
 static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
@@ -301,7 +259,7 @@
     WorkerOrWorkletScriptController* scriptController = toWorkerGlobalScope(executionContext)->scriptController();
     ASSERT(scriptController);
 
-    promiseRejectHandler(data, *scriptController->getRejectedPromises(), String());
+    promiseRejectHandler(data, *scriptController->getRejectedPromises(), scriptState);
 }
 
 static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data)
@@ -440,11 +398,9 @@
 
     perIsolateData->setReportingException(true);
 
-    TOSTRING_VOID(V8StringResource<>, resourceName, message->GetScriptOrigin().ResourceName());
-    ErrorEvent* event = createErrorEventFromMesssage(scriptState, message, resourceName);
-
-    int scriptId = 0;
-    RefPtr<ScriptCallStack> callStack = extractCallStack(isolate, message, &scriptId);
+    ExecutionContext* context = scriptState->getExecutionContext();
+    OwnPtr<SourceLocation> location = SourceLocation::fromMessage(isolate, message, context);
+    ErrorEvent* event = ErrorEvent::create(toCoreStringWithNullCheck(message->Get()), location->url(), location->lineNumber(), location->columnNumber(), &scriptState->world());
 
     AccessControlStatus corsStatus = message->IsSharedCrossOrigin() ? SharableCrossOrigin : NotSharableCrossOrigin;
 
@@ -452,7 +408,7 @@
     // the error event from the v8::Message, quietly leave.
     if (!isolate->IsExecutionTerminating()) {
         V8ErrorHandler::storeExceptionOnErrorEventWrapper(scriptState, event, data, scriptState->context()->Global());
-        scriptState->getExecutionContext()->reportException(event, scriptId, callStack, corsStatus);
+        scriptState->getExecutionContext()->reportException(event, std::move(location), corsStatus);
     }
 
     perIsolateData->setReportingException(false);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp
index 19c775d92..9a7c82293f 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp
@@ -30,9 +30,9 @@
 
 #include "bindings/core/v8/V8LazyEventListener.h"
 
-#include "bindings/core/v8/ScriptCallStack.h"
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/ScriptSourceCode.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8Binding.h"
 #include "bindings/core/v8/V8DOMWrapper.h"
 #include "bindings/core/v8/V8Document.h"
@@ -221,7 +221,7 @@
     else if (message->IsSharedCrossOrigin())
         accessControlStatus = SharableCrossOrigin;
 
-    executionContext->reportException(event, 0, nullptr, accessControlStatus);
+    executionContext->reportException(event, SourceLocation::create(m_sourceURL, lineNumber, columnNumber, nullptr), accessControlStatus);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PagePopupControllerBinding.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PagePopupControllerBinding.cpp
index 95716414..e8c989cc 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PagePopupControllerBinding.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PagePopupControllerBinding.cpp
@@ -9,6 +9,7 @@
 #include "core/dom/ContextFeatures.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
+#include "core/frame/LocalDOMWindow.h"
 #include "core/page/PagePopupController.h"
 #include "core/page/PagePopupSupplement.h"
 #include "platform/TraceEvent.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
index 1e3265b..f308e0c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
@@ -30,10 +30,10 @@
 
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 
-#include "bindings/core/v8/ScriptCallStack.h"
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/ScriptSourceCode.h"
 #include "bindings/core/v8/ScriptValue.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8DedicatedWorkerGlobalScope.h"
 #include "bindings/core/v8/V8ErrorHandler.h"
 #include "bindings/core/v8/V8Initializer.h"
@@ -283,7 +283,7 @@
                 event = state.m_errorEventFromImportedScript.release();
             else
                 event = ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get());
-            m_globalScope->reportException(event, 0, nullptr, NotSharableCrossOrigin);
+            m_globalScope->reportException(event, SourceLocation::create(event->filename(), event->lineno(), event->colno(), nullptr), NotSharableCrossOrigin);
         }
         return false;
     }
diff --git a/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.cpp b/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.cpp
index a0ee508f..d65e406 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.cpp
@@ -334,7 +334,7 @@
     return ScriptValueSerializer::doSerializeObject(jsObject, next);
 }
 
-bool SerializedScriptValueReaderForModules::read(v8::Local<v8::Value>* value, ScriptValueCompositeCreator& creator)
+bool SerializedScriptValueReaderForModules::read(v8::Local<v8::Value>* value, ScriptValueDeserializer& deserializer)
 {
     SerializationTag tag;
     if (!readTag(&tag))
@@ -343,20 +343,20 @@
     case DOMFileSystemTag:
         if (!readDOMFileSystem(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case CryptoKeyTag:
         if (!readCryptoKey(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     case RTCCertificateTag:
         if (!readRTCCertificate(value))
             return false;
-        creator.pushObjectReference(*value);
+        deserializer.pushObjectReference(*value);
         break;
     default:
-        return SerializedScriptValueReader::readWithTag(tag, value, creator);
+        return SerializedScriptValueReader::readWithTag(tag, value, deserializer);
     }
     return !value->IsEmpty();
 }
diff --git a/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.h b/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.h
index d083e12..d661459f9 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.h
+++ b/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.h
@@ -50,7 +50,7 @@
     {
     }
 
-    bool read(v8::Local<v8::Value>*, ScriptValueCompositeCreator&) override;
+    bool read(v8::Local<v8::Value>*, ScriptValueDeserializer&) override;
 
 private:
     bool readDOMFileSystem(v8::Local<v8::Value>*);
diff --git a/third_party/WebKit/Source/build/scripts/templates/ElementFactory.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/ElementFactory.cpp.tmpl
index d9c20ac..7b7e9def 100644
--- a/third_party/WebKit/Source/build/scripts/templates/ElementFactory.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/ElementFactory.cpp.tmpl
@@ -29,7 +29,7 @@
     {% if namespace == 'HTML' %}
     HTMLFormElement*,
     {% endif %}
-    bool createdByParser);
+    CreateElementFlags);
 
 typedef HashMap<AtomicString, ConstructorFunction> FunctionMap;
 
@@ -41,7 +41,7 @@
     {% if namespace == 'HTML' %}
     HTMLFormElement* formElement,
     {% endif %}
-    bool createdByParser)
+    CreateElementFlags flags)
 {
     {% if tag.runtimeEnabled %}
     if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled())
@@ -51,7 +51,7 @@
         {%- if tag.multipleTagNames %}{{tag|symbol}}Tag, {% endif -%}
         document
         {%- if namespace == 'HTML' and tag.constructorNeedsFormElement %}, formElement{% endif -%}
-        {%- if tag.constructorNeedsCreatedByParser %}, createdByParser{% endif -%}
+        {%- if tag.constructorNeedsCreatedByParser %}, flags & CreatedByParser{% endif -%}
     );
 }
 {% endfor %}
@@ -82,16 +82,16 @@
     {% if namespace == 'HTML' %}
     HTMLFormElement* formElement,
     {% endif %}
-    bool createdByParser)
+    CreateElementFlags flags)
 {
     if (!g_constructors)
         create{{namespace}}FunctionMap();
     if (ConstructorFunction function = g_constructors->get(localName))
-        return function(document, {% if namespace == 'HTML' %}formElement, {% endif %}createdByParser);
+        return function(document, {% if namespace == 'HTML' %}formElement, {% endif %}flags);
 
     {% if namespace == 'HTML' %}
     if (CustomElement::shouldCreateCustomElement(document, localName))
-        return CustomElement::createCustomElement(document, localName);
+        return CustomElement::createCustomElement(document, localName, flags);
     {% endif %}
 
     if (document.registrationContext() && V0CustomElement::isValidName(localName)) {
diff --git a/third_party/WebKit/Source/build/scripts/templates/ElementFactory.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/ElementFactory.h.tmpl
index 0d26c33..6b47f18e 100644
--- a/third_party/WebKit/Source/build/scripts/templates/ElementFactory.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/ElementFactory.h.tmpl
@@ -4,6 +4,7 @@
 #ifndef {{namespace}}ElementFactory_h
 #define {{namespace}}ElementFactory_h
 
+#include "core/dom/Document.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
@@ -24,7 +25,7 @@
         {% if namespace == 'HTML' %}
         HTMLFormElement* = 0,
         {% endif %}
-        bool createdByParser = true);
+        CreateElementFlags flags = CreatedByParser);
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/OWNERS b/third_party/WebKit/Source/core/OWNERS
index 004bd189..6b152611 100644
--- a/third_party/WebKit/Source/core/OWNERS
+++ b/third_party/WebKit/Source/core/OWNERS
@@ -34,7 +34,6 @@
 kenneth.r.christiansen@intel.com
 kinuko@chromium.org
 kouhei@chromium.org
-leviw@chromium.org
 mkwst@chromium.org
 morrita@chromium.org
 mstensho@opera.com
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
index 3a897e0..4dcad3f8 100644
--- a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
@@ -459,73 +459,36 @@
 
 namespace {
 
-void getCubicBezierTimingFunctionParameters(const TimingFunction& timingFunction, bool& outCustom,
-    CompositorAnimationCurve::TimingFunctionType& outEaseSubType,
-    double& outX1, double& outY1, double& outX2, double& outY2)
-{
-    const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(timingFunction);
-    outCustom = false;
-
-    switch (cubic.subType()) {
-    case CubicBezierTimingFunction::Ease:
-        outEaseSubType = CompositorAnimationCurve::TimingFunctionTypeEase;
-        break;
-    case CubicBezierTimingFunction::EaseIn:
-        outEaseSubType = CompositorAnimationCurve::TimingFunctionTypeEaseIn;
-        break;
-    case CubicBezierTimingFunction::EaseOut:
-        outEaseSubType = CompositorAnimationCurve::TimingFunctionTypeEaseOut;
-        break;
-    case CubicBezierTimingFunction::EaseInOut:
-        outEaseSubType = CompositorAnimationCurve::TimingFunctionTypeEaseInOut;
-        break;
-    case CubicBezierTimingFunction::Custom:
-        outCustom = true;
-        outX1 = cubic.x1();
-        outY1 = cubic.y1();
-        outX2 = cubic.x2();
-        outY2 = cubic.y2();
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-}
-
 template<typename PlatformAnimationCurveType, typename PlatformAnimationKeyframeType>
 void addCompositorKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const PlatformAnimationKeyframeType& keyframe, const TimingFunction* timingFunction)
 {
     if (!timingFunction) {
-        curve.add(keyframe);
+        curve.addCubicBezierKeyframe(keyframe, CubicBezierTimingFunction::EaseType::EASE);
         return;
     }
 
     switch (timingFunction->type()) {
     case TimingFunction::kLinearFunction:
-        curve.add(keyframe, CompositorAnimationCurve::TimingFunctionTypeLinear);
+        curve.addLinearKeyframe(keyframe);
         break;
 
     case TimingFunction::kCubicBezierFunction: {
-        bool custom;
-        CompositorAnimationCurve::TimingFunctionType easeSubType;
-        double x1, y1;
-        double x2, y2;
-        getCubicBezierTimingFunctionParameters(*timingFunction, custom, easeSubType, x1, y1, x2, y2);
-
-        if (custom)
-            curve.add(keyframe, x1, y1, x2, y2);
+        const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(*timingFunction);
+        if (cubic.getEaseType() == CubicBezierTimingFunction::EaseType::CUSTOM)
+            curve.addCubicBezierKeyframe(keyframe, cubic.x1(), cubic.y1(), cubic.x2(), cubic.y2());
         else
-            curve.add(keyframe, easeSubType);
+            curve.addCubicBezierKeyframe(keyframe, cubic.getEaseType());
         break;
     }
 
     case TimingFunction::kStepsFunction: {
         const StepsTimingFunction& steps = toStepsTimingFunction(*timingFunction);
-        curve.add(keyframe, steps.numberOfSteps(), steps.getStepPosition());
+        curve.addStepsKeyframe(keyframe, steps.numberOfSteps(), steps.getStepPosition());
         break;
     }
 
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
 }
 
@@ -543,16 +506,11 @@
         break;
 
     case TimingFunction::kCubicBezierFunction: {
-        bool custom;
-        CompositorAnimationCurve::TimingFunctionType easeSubType;
-        double x1, y1;
-        double x2, y2;
-        getCubicBezierTimingFunctionParameters(*timingFunction, custom, easeSubType, x1, y1, x2, y2);
-
-        if (custom)
-            curve.setCubicBezierTimingFunction(x1, y1, x2, y2);
+        const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(*timingFunction);
+        if (cubic.getEaseType() == CubicBezierTimingFunction::EaseType::CUSTOM)
+            curve.setCubicBezierTimingFunction(cubic.x1(), cubic.y1(), cubic.x2(), cubic.y2());
         else
-            curve.setCubicBezierTimingFunction(easeSubType);
+            curve.setCubicBezierTimingFunction(cubic.getEaseType());
         break;
     }
 
@@ -563,7 +521,7 @@
     }
 
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
 }
 
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
index 4610e8a..af2f65d 100644
--- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
@@ -94,7 +94,7 @@
         CompositorFactory::initializeForTesting(adoptPtr(m_mockCompositorFactory));
 
         m_linearTimingFunction = LinearTimingFunction::shared();
-        m_cubicEaseTimingFunction = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
+        m_cubicEaseTimingFunction = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE);
         m_cubicCustomTimingFunction = CubicBezierTimingFunction::create(1, 2, 3, 4);
         m_stepTimingFunction = StepsTimingFunction::create(1, StepsTimingFunction::StepPosition::END);
 
@@ -637,12 +637,12 @@
     AnimatableValueKeyframeEffectModel* basicFrames = AnimatableValueKeyframeEffectModel::create(basicFramesVector);
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames));
 
-    basicFramesVector[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+    basicFramesVector[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN));
     basicFrames = AnimatableValueKeyframeEffectModel::create(basicFramesVector);
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames));
 
     nonBasicFramesVector[0]->setEasing(m_linearTimingFunction.get());
-    nonBasicFramesVector[1]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+    nonBasicFramesVector[1]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN));
     AnimatableValueKeyframeEffectModel* nonBasicFrames = AnimatableValueKeyframeEffectModel::create(nonBasicFramesVector);
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *nonBasicFrames));
 }
@@ -664,8 +664,8 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // Create animation
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -709,8 +709,8 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(10.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(10.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // Create animation
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -759,10 +759,10 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.25, -1.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.5, 20.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.25, -1.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.5, 20.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // KeyframeEffect is created
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -808,8 +808,8 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.75, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.75, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // Create animation
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -863,10 +863,10 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeEase));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.5, -1.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.0, 20.0), 1.0, 2.0, 3.0, 4.0));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(2.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(0.0, 2.0), CubicBezierTimingFunction::EaseType::EASE));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.5, -1.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.0, 20.0), 1.0, 2.0, 3.0, 4.0));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(2.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // KeyframeEffect is created
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -904,7 +904,7 @@
     frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25));
     frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5));
     frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
-    frames[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+    frames[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN));
     frames[1]->setEasing(m_linearTimingFunction.get());
     frames[2]->setEasing(cubicEasyFlipTimingFunction.get());
     AnimatableValueKeyframeEffectModel* effect = AnimatableValueKeyframeEffectModel::create(frames);
@@ -921,10 +921,10 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeEaseIn));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.25, -1.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.5, 20.0), 0.0, 0.0, 0.0, 1.0));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(0.0, 2.0), CubicBezierTimingFunction::EaseType::EASE_IN));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.25, -1.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(0.5, 20.0), 0.0, 0.0, 0.0, 1.0));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // Create the animation
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -971,8 +971,8 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.5, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.5, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // Create animation
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -1016,8 +1016,8 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // Create animation
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -1061,8 +1061,8 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // Create animation
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -1106,8 +1106,8 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
 
     // Create animation
     WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(CompositorTargetProperty::OPACITY);
@@ -1151,8 +1151,8 @@
     EXPECT_CALL(*m_mockCompositorFactory, createFloatAnimationCurve())
         .WillOnce(Return(mockCurvePtr));
 
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(0.0, 2.0), CompositorAnimationCurve::TimingFunctionTypeLinear));
-    usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(CompositorFloatKeyframe(1.0, 5.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addLinearKeyframe(CompositorFloatKeyframe(0.0, 2.0)));
+    usesMockCurve += EXPECT_CALL(*mockCurvePtr, addCubicBezierKeyframe(CompositorFloatKeyframe(1.0, 5.0), CubicBezierTimingFunction::EaseType::EASE));
     usesMockCurve += EXPECT_CALL(*mockCurvePtr, setCubicBezierTimingFunction(1, 2, 3, 4));
 
     // Create animation
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h b/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
index 9f393a6..6a42e69 100644
--- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
@@ -96,14 +96,14 @@
 template<typename CurveType, typename KeyframeType>
 class WebCompositorAnimationCurveMock : public CurveType {
 public:
-    MOCK_METHOD1_T(add, void(const KeyframeType&));
-    MOCK_METHOD2_T(add, void(const KeyframeType&, CompositorAnimationCurve::TimingFunctionType));
-    MOCK_METHOD5_T(add, void(const KeyframeType&, double, double, double, double));
-    MOCK_METHOD3_T(add, void(const KeyframeType&, int steps, StepsTimingFunction::StepPosition));
+    MOCK_METHOD1_T(addLinearKeyframe, void(const KeyframeType&));
+    MOCK_METHOD2_T(addCubicBezierKeyframe, void(const KeyframeType&, CubicBezierTimingFunction::EaseType));
+    MOCK_METHOD5_T(addCubicBezierKeyframe, void(const KeyframeType&, double, double, double, double));
+    MOCK_METHOD3_T(addStepsKeyframe, void(const KeyframeType&, int steps, StepsTimingFunction::StepPosition));
 
     MOCK_METHOD0(setLinearTimingFunction, void());
     MOCK_METHOD4(setCubicBezierTimingFunction, void(double, double, double, double));
-    MOCK_METHOD1(setCubicBezierTimingFunction, void(CompositorAnimationCurve::TimingFunctionType));
+    MOCK_METHOD1(setCubicBezierTimingFunction, void(CubicBezierTimingFunction::EaseType));
     MOCK_METHOD2(setStepsTimingFunction, void(int, StepsTimingFunction::StepPosition));
 
     MOCK_CONST_METHOD1_T(getValue, float(double)); // Only on CompositorFloatAnimationCurve, but can't hurt to have here.
diff --git a/third_party/WebKit/Source/core/animation/InterpolationEffectTest.cpp b/third_party/WebKit/Source/core/animation/InterpolationEffectTest.cpp
index 488b2779..0c4e9c4 100644
--- a/third_party/WebKit/Source/core/animation/InterpolationEffectTest.cpp
+++ b/third_party/WebKit/Source/core/animation/InterpolationEffectTest.cpp
@@ -79,7 +79,7 @@
     interpolationEffect.addInterpolation(SampleInterpolation::create(InterpolableNumber::create(0), InterpolableNumber::create(1)),
         LinearTimingFunction::shared(), 0, 1, 0, 1);
     interpolationEffect.addInterpolation(SampleInterpolation::create(InterpolableNumber::create(1), InterpolableNumber::create(6)),
-        CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease), 0.5, 1.5, 0.5, 1.5);
+        CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE), 0.5, 1.5, 0.5, 1.5);
 
     Vector<RefPtr<Interpolation>> activeInterpolations;
     interpolationEffect.getActiveInterpolations(-0.5, duration, activeInterpolations);
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp b/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp
index 17c05b2..bbbb57e 100644
--- a/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp
+++ b/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp
@@ -144,7 +144,7 @@
 {
     AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
     keyframes[0]->setComposite(EffectModel::CompositeReplace);
-    keyframes[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+    keyframes[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN));
     keyframes[1]->setComposite(EffectModel::CompositeReplace);
     AnimatableValueKeyframeEffectModel* effect = AnimatableValueKeyframeEffectModel::create(keyframes);
     Vector<RefPtr<Interpolation>> values;
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp b/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp
index 1545e0f..887a169 100644
--- a/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp
+++ b/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp
@@ -106,7 +106,7 @@
     EXPECT_EQ("100px", keyframe1Width->cssText());
     EXPECT_EQ("0px", keyframe2Width->cssText());
 
-    EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut)), keyframes[0]->easing());
+    EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT)), keyframes[0]->easing());
     EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), keyframes[1]->easing());
 }
 
diff --git a/third_party/WebKit/Source/core/animation/TimingInputTest.cpp b/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
index ea312229..3a763fea 100644
--- a/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
+++ b/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
@@ -192,13 +192,13 @@
     const RefPtr<TimingFunction> defaultTimingFunction = LinearTimingFunction::shared();
     bool success;
 
-    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease), *applyTimingInputString("easing", "ease", success).timingFunction);
+    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE), *applyTimingInputString("easing", "ease", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn), *applyTimingInputString("easing", "ease-in", success).timingFunction);
+    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN), *applyTimingInputString("easing", "ease-in", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut), *applyTimingInputString("easing", "ease-out", success).timingFunction);
+    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT), *applyTimingInputString("easing", "ease-out", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut), *applyTimingInputString("easing", "ease-in-out", success).timingFunction);
+    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT), *applyTimingInputString("easing", "ease-in-out", success).timingFunction);
     EXPECT_TRUE(success);
     EXPECT_EQ(*LinearTimingFunction::shared(), *applyTimingInputString("easing", "linear", success).timingFunction);
     EXPECT_TRUE(success);
diff --git a/third_party/WebKit/Source/core/animation/css/CSSTimingData.h b/third_party/WebKit/Source/core/animation/css/CSSTimingData.h
index b4d48b9..d9cb074b 100644
--- a/third_party/WebKit/Source/core/animation/css/CSSTimingData.h
+++ b/third_party/WebKit/Source/core/animation/css/CSSTimingData.h
@@ -29,7 +29,7 @@
 
     static double initialDelay() { return 0; }
     static double initialDuration() { return 0; }
-    static PassRefPtr<TimingFunction> initialTimingFunction() { return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease); }
+    static PassRefPtr<TimingFunction> initialTimingFunction() { return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE); }
 
     template <class T> static const T& getRepeated(const Vector<T>& v, size_t index) { return v[index % v.size()]; }
 
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.cpp b/third_party/WebKit/Source/core/css/CSSSelector.cpp
index d6bc71a4..3965932 100644
--- a/third_party/WebKit/Source/core/css/CSSSelector.cpp
+++ b/third_party/WebKit/Source/core/css/CSSSelector.cpp
@@ -257,6 +257,7 @@
     case PseudoFutureCue:
     case PseudoPastCue:
     case PseudoUnresolved:
+    case PseudoDefined:
     case PseudoContent:
     case PseudoHost:
     case PseudoHostContext:
@@ -317,6 +318,7 @@
 {"cue",                           CSSSelector::PseudoWebKitCustomElement},
 {"decrement",                     CSSSelector::PseudoDecrement},
 {"default",                       CSSSelector::PseudoDefault},
+{"defined",                       CSSSelector::PseudoDefined},
 {"disabled",                      CSSSelector::PseudoDisabled},
 {"double-button",                 CSSSelector::PseudoDoubleButton},
 {"empty",                         CSSSelector::PseudoEmpty},
@@ -414,6 +416,9 @@
     if (match == pseudoTypeMapEnd || match->string != name.getString())
         return CSSSelector::PseudoUnknown;
 
+    if (match->type == CSSSelector::PseudoDefined && !RuntimeEnabledFeatures::customElementsV1Enabled())
+        return CSSSelector::PseudoUnknown;
+
     return static_cast<CSSSelector::PseudoType>(match->type);
 }
 
@@ -512,6 +517,7 @@
     case PseudoCornerPresent:
     case PseudoDecrement:
     case PseudoDefault:
+    case PseudoDefined:
     case PseudoDisabled:
     case PseudoDoubleButton:
     case PseudoDrag:
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.h b/third_party/WebKit/Source/core/css/CSSSelector.h
index d7a25a3..65dab52 100644
--- a/third_party/WebKit/Source/core/css/CSSSelector.h
+++ b/third_party/WebKit/Source/core/css/CSSSelector.h
@@ -201,6 +201,7 @@
         PseudoFutureCue,
         PseudoPastCue,
         PseudoUnresolved,
+        PseudoDefined,
         PseudoContent,
         PseudoHost,
         PseudoHostContext,
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 6fddfd1..5d2056d7 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -1054,19 +1054,19 @@
     case TimingFunction::kCubicBezierFunction:
         {
             const CubicBezierTimingFunction* bezierTimingFunction = toCubicBezierTimingFunction(timingFunction);
-            if (bezierTimingFunction->subType() != CubicBezierTimingFunction::Custom) {
+            if (bezierTimingFunction->getEaseType() != CubicBezierTimingFunction::EaseType::CUSTOM) {
                 CSSValueID valueId = CSSValueInvalid;
-                switch (bezierTimingFunction->subType()) {
-                case CubicBezierTimingFunction::Ease:
+                switch (bezierTimingFunction->getEaseType()) {
+                case CubicBezierTimingFunction::EaseType::EASE:
                     valueId = CSSValueEase;
                     break;
-                case CubicBezierTimingFunction::EaseIn:
+                case CubicBezierTimingFunction::EaseType::EASE_IN:
                     valueId = CSSValueEaseIn;
                     break;
-                case CubicBezierTimingFunction::EaseOut:
+                case CubicBezierTimingFunction::EaseType::EASE_OUT:
                     valueId = CSSValueEaseOut;
                     break;
-                case CubicBezierTimingFunction::EaseInOut:
+                case CubicBezierTimingFunction::EaseType::EASE_IN_OUT:
                     valueId = CSSValueEaseInOut;
                     break;
                 default:
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.cpp b/third_party/WebKit/Source/core/css/RuleFeature.cpp
index 24500d6..6284b303 100644
--- a/third_party/WebKit/Source/core/css/RuleFeature.cpp
+++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp
@@ -148,6 +148,7 @@
     case CSSSelector::PseudoFutureCue:
     case CSSSelector::PseudoPastCue:
     case CSSSelector::PseudoUnresolved:
+    case CSSSelector::PseudoDefined:
     case CSSSelector::PseudoContent:
     case CSSSelector::PseudoHost:
     case CSSSelector::PseudoShadow:
@@ -345,6 +346,7 @@
         case CSSSelector::PseudoInRange:
         case CSSSelector::PseudoOutOfRange:
         case CSSSelector::PseudoUnresolved:
+        case CSSSelector::PseudoDefined:
             return &ensurePseudoInvalidationSet(selector.getPseudoType(), type);
         default:
             break;
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
index c9c325e..5cb5611 100644
--- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp
+++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -916,6 +916,9 @@
         return context.scope == &element;
     case CSSSelector::PseudoUnresolved:
         return element.isUnresolvedV0CustomElement();
+    case CSSSelector::PseudoDefined:
+        DCHECK(RuntimeEnabledFeatures::customElementsV1Enabled());
+        return element.isDefined();
     case CSSSelector::PseudoHost:
     case CSSSelector::PseudoHostContext:
         return checkPseudoHost(context, result);
diff --git a/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp b/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
index bec29ee3..417393ebee 100644
--- a/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
@@ -388,13 +388,13 @@
         case CSSValueLinear:
             return LinearTimingFunction::shared();
         case CSSValueEase:
-            return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
+            return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE);
         case CSSValueEaseIn:
-            return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
+            return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN);
         case CSSValueEaseOut:
-            return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
+            return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT);
         case CSSValueEaseInOut:
-            return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
+            return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT);
         case CSSValueStepStart:
             return StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START);
         case CSSValueStepMiddle:
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
index a1793d86..20c504b 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -42,6 +42,7 @@
 #include "core/css/CSSURIValue.h"
 #include "core/css/CSSValuePair.h"
 #include "core/css/resolver/FilterOperationResolver.h"
+#include "core/frame/LocalFrame.h"
 #include "core/svg/SVGURIReference.h"
 #include "platform/transforms/RotateTransformOperation.h"
 #include "platform/transforms/ScaleTransformOperation.h"
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 36caca2f..f8e5af2 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -33,8 +33,8 @@
 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
 #include "bindings/core/v8/HTMLScriptElementOrSVGScriptElement.h"
 #include "bindings/core/v8/Microtask.h"
-#include "bindings/core/v8/ScriptCallStack.h"
 #include "bindings/core/v8/ScriptController.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V0CustomElementConstructorBuilder.h"
 #include "bindings/core/v8/V8DOMWrapper.h"
 #include "bindings/core/v8/V8PerIsolateData.h"
@@ -666,7 +666,7 @@
     }
 
     if (isXHTMLDocument() || isHTMLDocument())
-        return HTMLElementFactory::createHTMLElement(convertLocalName(name), *this, 0, false);
+        return HTMLElementFactory::createHTMLElement(convertLocalName(name), *this, 0, CreatedByCreateElement);
 
     return Element::create(QualifiedName(nullAtom, name, nullAtom), this);
 }
@@ -681,7 +681,7 @@
     Element* element;
 
     if (CustomElement::shouldCreateCustomElement(*this, localName)) {
-        element = CustomElement::createCustomElement(*this, localName);
+        element = CustomElement::createCustomElement(*this, localName, CreatedByCreateElement);
     } else if (V0CustomElement::isValidName(localName) && registrationContext()) {
         element = registrationContext()->createCustomTagElement(*this, QualifiedName(nullAtom, convertLocalName(localName), xhtmlNamespaceURI));
     } else {
@@ -717,7 +717,7 @@
     if (qName == QualifiedName::null())
         return nullptr;
 
-    return createElement(qName, false);
+    return createElement(qName, CreatedByCreateElement);
 }
 
 Element* Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState& exceptionState)
@@ -728,11 +728,11 @@
 
     Element* element;
     if (CustomElement::shouldCreateCustomElement(*this, qName))
-        element = CustomElement::createCustomElement(*this, qName);
+        element = CustomElement::createCustomElement(*this, qName, CreatedByCreateElement);
     else if (V0CustomElement::isValidName(qName.localName()) && registrationContext())
         element = registrationContext()->createCustomTagElement(*this, qName);
     else
-        element = createElement(qName, false);
+        element = createElement(qName, CreatedByCreateElement);
 
     if (!typeExtension.isEmpty())
         V0CustomElementRegistrationContext::setIsAttributeAndTypeExtension(element, typeExtension);
@@ -883,7 +883,7 @@
             exceptionState.throwDOMException(NamespaceError, "The imported node has an invalid namespace.");
             return nullptr;
         }
-        Element* newElement = createElement(oldElement->tagQName(), false);
+        Element* newElement = createElement(oldElement->tagQName(), CreatedByImportNode);
 
         newElement->cloneDataFromElement(*oldElement);
 
@@ -988,15 +988,15 @@
 }
 
 // FIXME: This should really be in a possible ElementFactory class
-Element* Document::createElement(const QualifiedName& qName, bool createdByParser)
+Element* Document::createElement(const QualifiedName& qName, CreateElementFlags flags)
 {
     Element* e = nullptr;
 
     // FIXME: Use registered namespaces and look up in a hash to find the right factory.
     if (qName.namespaceURI() == xhtmlNamespaceURI)
-        e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, 0, createdByParser);
+        e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, 0, flags);
     else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
-        e = SVGElementFactory::createSVGElement(qName.localName(), *this, createdByParser);
+        e = SVGElementFactory::createSVGElement(qName.localName(), *this, flags);
 
     if (e)
         m_sawElementsInKnownNamespaces = true;
@@ -2925,9 +2925,9 @@
     return domWindow();
 }
 
-void Document::logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+void Document::logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
-    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, columnNumber, callStack, scriptId);
+    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, std::move(location));
     addConsoleMessage(consoleMessage);
 }
 
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 2816210a..6460655 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -31,7 +31,6 @@
 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
 #include "bindings/core/v8/ScriptValue.h"
 #include "core/CoreExport.h"
-#include "core/animation/AnimationClock.h"
 #include "core/dom/ContainerNode.h"
 #include "core/dom/DocumentEncodingData.h"
 #include "core/dom/DocumentInit.h"
@@ -47,14 +46,10 @@
 #include "core/fetch/ClientHintsPreferences.h"
 #include "core/frame/DOMTimerCoordinator.h"
 #include "core/frame/HostsUsingFeatures.h"
-#include "core/frame/LocalDOMWindow.h"
-#include "core/frame/VisualViewport.h"
-#include "core/html/CollectionType.h"
 #include "core/html/parser/ParserSynchronizationPolicy.h"
 #include "core/page/PageVisibilityState.h"
 #include "platform/Length.h"
 #include "platform/Timer.h"
-#include "platform/heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/ReferrerPolicy.h"
 #include "public/platform/WebFocusType.h"
@@ -65,6 +60,7 @@
 
 namespace blink {
 
+class AnimationClock;
 class AnimationTimeline;
 class AXObjectCache;
 class Attr;
@@ -128,6 +124,7 @@
 class LayoutPoint;
 class LayoutViewItem;
 class LiveNodeListBase;
+class LocalDOMWindow;
 class Locale;
 class LocalFrame;
 class Location;
@@ -169,6 +166,7 @@
 class TransformSource;
 class TreeWalker;
 class VisitedLinkState;
+class VisualViewport;
 class WebGLRenderingContext;
 enum class SelectionBehaviorOnFocus;
 struct AnnotatedRegionValue;
@@ -214,6 +212,23 @@
     ShadowCascadeV1
 };
 
+enum CreateElementFlags {
+    CreatedByParser = 1 << 0,
+    // Synchronous custom elements flag:
+    // https://dom.spec.whatwg.org/#concept-create-element
+    SynchronousCustomElements = 0 << 1,
+    AsynchronousCustomElements = 1 << 1,
+
+    // Aliases by callers.
+    // Clone a node: https://dom.spec.whatwg.org/#concept-node-clone
+    CreatedByCloneNode = AsynchronousCustomElements,
+    CreatedByImportNode = CreatedByCloneNode,
+    // https://dom.spec.whatwg.org/#dom-document-createelement
+    CreatedByCreateElement = SynchronousCustomElements,
+    // https://html.spec.whatwg.org/#create-an-element-for-the-token
+    CreatedByFragmentParser = CreatedByParser | AsynchronousCustomElements,
+};
+
 using DocumentClassFlags = unsigned char;
 
 class CORE_EXPORT Document : public ContainerNode, public TreeScope, public SecurityContext, public ExecutionContext, public Supplementable<Document> {
@@ -292,7 +307,7 @@
     Attr* createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&, bool shouldIgnoreNamespaceChecks = false);
     Node* importNode(Node* importedNode, bool deep, ExceptionState&);
     Element* createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&);
-    Element* createElement(const QualifiedName&, bool createdByParser);
+    Element* createElement(const QualifiedName&, CreateElementFlags);
 
     Element* elementFromPoint(int x, int y) const;
     HeapVector<Member<Element>> elementsFromPoint(int x, int y) const;
@@ -933,7 +948,7 @@
     void cancelIdleCallback(int id);
 
     EventTarget* errorEventTarget() final;
-    void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) final;
+    void logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation>) final;
 
     void initDNSPrefetch();
 
diff --git a/third_party/WebKit/Source/core/dom/DocumentStatisticsCollector.cpp b/third_party/WebKit/Source/core/dom/DocumentStatisticsCollector.cpp
index 2a15a4e..62515ecb 100644
--- a/third_party/WebKit/Source/core/dom/DocumentStatisticsCollector.cpp
+++ b/third_party/WebKit/Source/core/dom/DocumentStatisticsCollector.cpp
@@ -10,6 +10,8 @@
 #include "core/dom/NodeComputedStyle.h"
 #include "core/dom/Text.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLHeadElement.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLMetaElement.h"
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index ec37d1c4..092cbd4 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -268,7 +268,7 @@
 
 Element* Element::cloneElementWithoutAttributesAndChildren()
 {
-    return document().createElement(tagQName(), false);
+    return document().createElement(tagQName(), CreatedByCloneNode);
 }
 
 Attr* Element::detachAttribute(size_t index)
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
index 98610a0f..0a5bebd 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
@@ -27,7 +27,7 @@
 
 #include "core/dom/ExecutionContext.h"
 
-#include "bindings/core/v8/ScriptCallStack.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "core/dom/ExecutionContextTask.h"
 #include "core/events/ErrorEvent.h"
 #include "core/events/EventTarget.h"
@@ -43,22 +43,14 @@
 class ExecutionContext::PendingException {
     WTF_MAKE_NONCOPYABLE(PendingException);
 public:
-    PendingException(const String& errorMessage, int lineNumber, int columnNumber, int scriptId, const String& sourceURL, PassRefPtr<ScriptCallStack> callStack)
+    PendingException(const String& errorMessage, PassOwnPtr<SourceLocation> location)
         : m_errorMessage(errorMessage)
-        , m_lineNumber(lineNumber)
-        , m_columnNumber(columnNumber)
-        , m_scriptId(scriptId)
-        , m_sourceURL(sourceURL)
-        , m_callStack(callStack)
+        , m_location(std::move(location))
     {
     }
 
     String m_errorMessage;
-    int m_lineNumber;
-    int m_columnNumber;
-    int m_scriptId;
-    String m_sourceURL;
-    RefPtr<ScriptCallStack> m_callStack;
+    OwnPtr<SourceLocation> m_location;
 };
 
 ExecutionContext::ExecutionContext()
@@ -146,25 +138,25 @@
     return !(getSecurityOrigin()->canRequestNoSuborigin(completeURL(sourceURL)) || corsStatus == SharableCrossOrigin);
 }
 
-void ExecutionContext::reportException(ErrorEvent* errorEvent, int scriptId, PassRefPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
+void ExecutionContext::reportException(ErrorEvent* errorEvent, PassOwnPtr<SourceLocation> location, AccessControlStatus corsStatus)
 {
     if (m_inDispatchErrorEvent) {
         if (!m_pendingExceptions)
             m_pendingExceptions = adoptPtr(new Vector<OwnPtr<PendingException>>());
-        m_pendingExceptions->append(adoptPtr(new PendingException(errorEvent->messageForConsole(), errorEvent->lineno(), errorEvent->colno(), scriptId, errorEvent->filename(), callStack)));
+        m_pendingExceptions->append(adoptPtr(new PendingException(errorEvent->messageForConsole(), std::move(location))));
         return;
     }
 
     // First report the original exception and only then all the nested ones.
     if (!dispatchErrorEvent(errorEvent, corsStatus))
-        logExceptionToConsole(errorEvent->messageForConsole(), scriptId, errorEvent->filename(), errorEvent->lineno(), errorEvent->colno(), callStack);
+        logExceptionToConsole(errorEvent->messageForConsole(), std::move(location));
 
     if (!m_pendingExceptions)
         return;
 
     for (size_t i = 0; i < m_pendingExceptions->size(); i++) {
         PendingException* e = m_pendingExceptions->at(i).get();
-        logExceptionToConsole(e->m_errorMessage, e->m_scriptId, e->m_sourceURL, e->m_lineNumber, e->m_columnNumber, e->m_callStack);
+        logExceptionToConsole(e->m_errorMessage, std::move(e->m_location));
     }
     m_pendingExceptions.reset();
 }
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.h b/third_party/WebKit/Source/core/dom/ExecutionContext.h
index 700055b..58baf89 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.h
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.h
@@ -55,7 +55,7 @@
 class LocalDOMWindow;
 class PublicURLManager;
 class SecurityOrigin;
-class ScriptCallStack;
+class SourceLocation;
 
 class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier, public Supplementable<ExecutionContext> {
     WTF_MAKE_NONCOPYABLE(ExecutionContext);
@@ -104,10 +104,10 @@
     KURL contextCompleteURL(const String& url) const { return virtualCompleteURL(url); }
 
     bool shouldSanitizeScriptError(const String& sourceURL, AccessControlStatus);
-    void reportException(ErrorEvent*, int scriptId, PassRefPtr<ScriptCallStack>, AccessControlStatus);
+    void reportException(ErrorEvent*, PassOwnPtr<SourceLocation>, AccessControlStatus);
 
     virtual void addConsoleMessage(ConsoleMessage*) = 0;
-    virtual void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) = 0;
+    virtual void logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation>) = 0;
 
     PublicURLManager& publicURLManager();
 
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
index 9ab6211..2abbbf9 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
@@ -7,6 +7,7 @@
 #include "core/dom/ElementRareData.h"
 #include "core/dom/IntersectionObserver.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/layout/LayoutBox.h"
 #include "core/layout/LayoutView.h"
 #include "core/paint/PaintLayer.h"
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
index 47d0bc3..f853921 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
@@ -16,6 +16,8 @@
 #include "core/dom/IntersectionObserverInit.h"
 #include "core/dom/NodeIntersectionObserverData.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/layout/LayoutView.h"
 #include "core/timing/DOMWindowPerformance.h"
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 9565e1f7..8927e6f 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -2342,15 +2342,21 @@
 
     DCHECK(isHTMLElement());
     DCHECK_NE(V0Upgraded, getV0CustomElementState());
+#if DCHECK_IS_ON()
+    bool wasDefined = toElement(this)->isDefined();
+#endif
 
     setFlag(CustomElementFlag);
     if (newState == CustomElementState::Custom)
         setFlag(CustomElementCustomFlag);
     DCHECK(newState == getCustomElementState());
 
-    // TODO(kojii): Should fire pseudoStateChanged() when :defined selector is
-    // ready.
-    // toElement(this)->pseudoStateChanged(CSSSelector::PseudoDefined);
+    // When the state goes from Uncustomized to Undefined, and then to Custom,
+    // isDefined is always flipped.
+#if DCHECK_IS_ON()
+    DCHECK_NE(wasDefined, toElement(this)->isDefined());
+#endif
+    toElement(this)->pseudoStateChanged(CSSSelector::PseudoDefined);
 }
 
 void Node::setV0CustomElementState(V0CustomElementState newState)
diff --git a/third_party/WebKit/Source/core/dom/ViewportDescription.cpp b/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
index 8fd6d241..1a7fb06 100644
--- a/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
+++ b/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
@@ -32,6 +32,7 @@
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "platform/Histogram.h"
 #include "platform/weborigin/KURL.h"
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
index 51fc350..4baaeb9 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
@@ -63,13 +63,14 @@
         && tagName.namespaceURI() == HTMLNames::xhtmlNamespaceURI;
 }
 
-HTMLElement* CustomElement::createCustomElement(Document& document, const AtomicString& localName)
+HTMLElement* CustomElement::createCustomElement(Document& document, const AtomicString& localName, CreateElementFlags flags)
 {
     return createCustomElement(document,
-        QualifiedName(nullAtom, document.convertLocalName(localName), HTMLNames::xhtmlNamespaceURI));
+        QualifiedName(nullAtom, document.convertLocalName(localName), HTMLNames::xhtmlNamespaceURI),
+        flags);
 }
 
-HTMLElement* CustomElement::createCustomElement(Document& document, const QualifiedName& tagName)
+HTMLElement* CustomElement::createCustomElement(Document& document, const QualifiedName& tagName, CreateElementFlags flags)
 {
     DCHECK(shouldCreateCustomElement(document, tagName));
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElement.h b/third_party/WebKit/Source/core/dom/custom/CustomElement.h
index b37b8d7..7b9dccc 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElement.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElement.h
@@ -6,6 +6,7 @@
 #define CustomElement_h
 
 #include "core/CoreExport.h"
+#include "core/dom/Document.h"
 #include "wtf/Allocator.h"
 #include "wtf/text/AtomicString.h"
 
@@ -23,8 +24,8 @@
     static bool shouldCreateCustomElement(Document&, const AtomicString& localName);
     static bool shouldCreateCustomElement(Document&, const QualifiedName&);
 
-    static HTMLElement* createCustomElement(Document&, const AtomicString& localName);
-    static HTMLElement* createCustomElement(Document&, const QualifiedName&);
+    static HTMLElement* createCustomElement(Document&, const AtomicString& localName, CreateElementFlags);
+    static HTMLElement* createCustomElement(Document&, const QualifiedName&, CreateElementFlags);
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/CaretBase.cpp b/third_party/WebKit/Source/core/editing/CaretBase.cpp
index dc32b36..8cbc6be2 100644
--- a/third_party/WebKit/Source/core/editing/CaretBase.cpp
+++ b/third_party/WebKit/Source/core/editing/CaretBase.cpp
@@ -214,4 +214,9 @@
     context.fillRect(FloatRect(drawingRect), caretColor);
 }
 
+void CaretBase::setCaretVisibility(CaretVisibility visibility)
+{
+    m_caretVisibility = visibility;
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/CaretBase.h b/third_party/WebKit/Source/core/editing/CaretBase.h
index d1c7736..a69b67a 100644
--- a/third_party/WebKit/Source/core/editing/CaretBase.h
+++ b/third_party/WebKit/Source/core/editing/CaretBase.h
@@ -62,7 +62,7 @@
 
     const LayoutRect& localCaretRectWithoutUpdate() const { return m_caretLocalRect; }
 
-    void setCaretVisibility(CaretVisibility visibility) { m_caretVisibility = visibility; }
+    virtual void setCaretVisibility(CaretVisibility);
     bool caretIsVisible() const { return m_caretVisibility == CaretVisibility::Visible; }
     CaretVisibility getCaretVisibility() const { return m_caretVisibility; }
 
diff --git a/third_party/WebKit/Source/core/editing/DOMSelection.cpp b/third_party/WebKit/Source/core/editing/DOMSelection.cpp
index 1c73094..241a657 100644
--- a/third_party/WebKit/Source/core/editing/DOMSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/DOMSelection.cpp
@@ -414,6 +414,9 @@
     if (!isAvailable())
         return;
 
+    if (newRange->ownerDocument() != m_frame->document())
+        return;
+
     if (!newRange->inShadowIncludingDocument()) {
         addConsoleError("The given range isn't in document.");
         return;
diff --git a/third_party/WebKit/Source/core/editing/EditingCommandTest.cpp b/third_party/WebKit/Source/core/editing/EditingCommandTest.cpp
index 864b825..cd38a87 100644
--- a/third_party/WebKit/Source/core/editing/EditingCommandTest.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingCommandTest.cpp
@@ -5,6 +5,7 @@
 #include "core/editing/EditingTestBase.h"
 #include "core/editing/Editor.h"
 #include "core/editing/commands/EditorCommandNames.h"
+#include "core/frame/LocalFrame.h"
 #include "public/platform/WebEditingCommandType.h"
 #include "wtf/StringExtras.h"
 
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
index 7417544f..0edfc24 100644
--- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -1326,7 +1326,7 @@
 
 HTMLElement* createHTMLElement(Document& document, const QualifiedName& name)
 {
-    return HTMLElementFactory::createHTMLElement(name.localName(), document, 0, false);
+    return HTMLElementFactory::createHTMLElement(name.localName(), document, 0, CreatedByCloneNode);
 }
 
 bool isTabHTMLSpanElement(const Node* node)
diff --git a/third_party/WebKit/Source/core/editing/FrameCaret.cpp b/third_party/WebKit/Source/core/editing/FrameCaret.cpp
index e171e9ee79..9b653ae8 100644
--- a/third_party/WebKit/Source/core/editing/FrameCaret.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameCaret.cpp
@@ -25,6 +25,8 @@
 
 #include "core/editing/FrameCaret.h"
 
+#include "core/frame/LocalFrame.h"
+
 namespace blink {
 
 FrameCaret::FrameCaret(LocalFrame* frame)
@@ -34,6 +36,7 @@
     , m_caretRectDirty(true)
     , m_shouldPaintCaret(true)
     , m_isCaretBlinkingSuspended(false)
+    , m_shouldShowBlockCursor(false)
 {
     DCHECK(frame);
 }
@@ -44,7 +47,20 @@
 {
     visitor->trace(m_frame);
     visitor->trace(m_previousCaretNode);
+    visitor->trace(m_caretPosition);
     CaretBase::trace(visitor);
 }
 
+void FrameCaret::setCaretPosition(const PositionWithAffinity& position)
+{
+    m_caretPosition = position;
+    setCaretRectNeedsUpdate();
+}
+
+void FrameCaret::clear()
+{
+    m_caretPosition = PositionWithAffinity();
+    setCaretRectNeedsUpdate();
+}
+
 } // nemaspace blink
diff --git a/third_party/WebKit/Source/core/editing/FrameCaret.h b/third_party/WebKit/Source/core/editing/FrameCaret.h
index 8c50d97..1c1a5386 100644
--- a/third_party/WebKit/Source/core/editing/FrameCaret.h
+++ b/third_party/WebKit/Source/core/editing/FrameCaret.h
@@ -28,6 +28,7 @@
 
 #include "core/editing/CaretBase.h"
 #include "core/editing/VisibleSelection.h"
+#include "platform/geometry/IntRect.h"
 
 namespace blink {
 
@@ -36,15 +37,26 @@
     FrameCaret(LocalFrame*);
     ~FrameCaret() override;
 
+    void setCaretPosition(const PositionWithAffinity&);
+    void clear();
+    bool isActive() const { return m_caretPosition.isNotNull(); }
+
+    void updateAppearance();
+
     // Used to suspend caret blinking while the mouse is down.
     void setCaretBlinkingSuspended(bool suspended) { m_isCaretBlinkingSuspended = suspended; }
     bool isCaretBlinkingSuspended() const { return m_isCaretBlinkingSuspended; }
     void stopCaretBlinkTimer();
     void startBlinkCaret();
 
+    void setCaretVisibility(CaretVisibility) override;
     bool isCaretBoundsDirty() const { return m_caretRectDirty; }
     void setCaretRectNeedsUpdate();
     void invalidateCaretRect(const VisibleSelection&);
+    IntRect absoluteCaretBounds();
+
+    bool shouldShowBlockCursor() const { return m_shouldShowBlockCursor; }
+    void setShouldShowBlockCursor(bool);
 
     void paintCaret(GraphicsContext&, const LayoutPoint&, const VisibleSelection&);
 
@@ -60,8 +72,10 @@
     DECLARE_VIRTUAL_TRACE();
 
 private:
+    bool shouldBlinkCaret() const;
     void caretBlinkTimerFired(Timer<FrameCaret>*);
 
+    PositionWithAffinity m_caretPosition;
     const Member<LocalFrame> m_frame;
     // The last node which painted the caret. Retained for clearing the old
     // caret when it moves.
@@ -72,6 +86,7 @@
     bool m_caretRectDirty : 1;
     bool m_shouldPaintCaret : 1;
     bool m_isCaretBlinkingSuspended : 1;
+    bool m_shouldShowBlockCursor : 1;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index b1c5826..5471661 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -100,7 +100,6 @@
     , m_granularity(CharacterGranularity)
     , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation())
     , m_focused(frame->page() && frame->page()->focusController().focusedFrame() == frame)
-    , m_shouldShowBlockCursor(false)
     , m_frameCaret(new FrameCaret(frame))
 {
     DCHECK(frame);
@@ -333,7 +332,10 @@
     const VisibleSelection oldSelectionInDOMTree = selection();
 
     m_selectionEditor->setVisibleSelection(s, options);
-    setCaretRectNeedsUpdate();
+    if (s.isCaret())
+        m_frameCaret->setCaretPosition(PositionWithAffinity(toPositionInDOMTree(s.start()), s.affinity()));
+    else
+        m_frameCaret->clear();
 
     if (!s.isNone() && !(options & DoNotSetFocus))
         setFocusedNodeIfNeeded();
@@ -485,8 +487,15 @@
     if (clearLayoutTreeSelection)
         selection().start().document()->layoutViewItem().clearSelection();
 
-    if (clearDOMTreeSelection)
+    if (clearDOMTreeSelection) {
         setSelection(VisibleSelection(), DoNotSetFocus);
+    } else {
+        const VisibleSelection& selection = m_selectionEditor->visibleSelection<EditingStrategy>();
+        if (selection.isCaret())
+            m_frameCaret->setCaretPosition(PositionWithAffinity(selection.start(), selection.affinity()));
+        else
+            m_frameCaret->clear();
+    }
 
     // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
     // |Editor| class.
@@ -676,6 +685,7 @@
 // TODO(yoiciho): We should move this function to FrameCaret.cpp
 void FrameCaret::prepareForDestruction()
 {
+    m_caretPosition = PositionWithAffinity();
     m_caretBlinkTimer.stop();
     m_previousCaretNode.clear();
 }
@@ -695,11 +705,6 @@
     m_frameCaret->prepareForDestruction();
 }
 
-static bool isTextFormControl(const VisibleSelection& selection)
-{
-    return enclosingTextFormControl(selection.start());
-}
-
 LayoutBlock* FrameSelection::caretLayoutObject() const
 {
     DCHECK(selection().isValidFor(*m_frame->document()));
@@ -708,23 +713,26 @@
     return CaretBase::caretLayoutObject(selection().start().anchorNode());
 }
 
-// TODO(yoichio): All of functionality should be in FrameCaret.
-// FrameCaret should have PositionWithAffnity and FrameSelection set in
-// setSelecitonAlgorithm.
+// TODO(yoiciho): We should move this function to FrameCaret.cpp
+IntRect FrameCaret::absoluteCaretBounds()
+{
+    DCHECK_NE(m_frame->document()->lifecycle().state(), DocumentLifecycle::InPaintInvalidation);
+    m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
+    if (!isActive()) {
+        clearCaretRect();
+    } else {
+        if (enclosingTextFormControl(m_caretPosition.position()))
+            updateCaretRect(PositionWithAffinity(isVisuallyEquivalentCandidate(m_caretPosition.position()) ? m_caretPosition.position() : Position(), m_caretPosition.affinity()));
+        else
+            updateCaretRect(createVisiblePosition(m_caretPosition));
+    }
+    return absoluteBoundsForLocalRect(m_caretPosition.position().anchorNode(), localCaretRectWithoutUpdate());
+}
+
 IntRect FrameSelection::absoluteCaretBounds()
 {
     DCHECK(selection().isValidFor(*m_frame->document()));
-    DCHECK_NE(m_frame->document()->lifecycle().state(), DocumentLifecycle::InPaintInvalidation);
-    m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
-    if (!isCaret()) {
-        m_frameCaret->clearCaretRect();
-    } else {
-        if (isTextFormControl(selection()))
-            m_frameCaret->updateCaretRect(PositionWithAffinity(isVisuallyEquivalentCandidate(selection().start()) ? selection().start() : Position(), selection().affinity()));
-        else
-            m_frameCaret->updateCaretRect(createVisiblePosition(selection().start(), selection().affinity()));
-    }
-    return m_frameCaret->absoluteBoundsForLocalRect(selection().start().anchorNode(), m_frameCaret->localCaretRectWithoutUpdate());
+    return m_frameCaret->absoluteCaretBounds();
 }
 
 // TODO(yoiciho): We should move this function to FrameCaret.cpp
@@ -1004,7 +1012,7 @@
         setSelectionFromNone();
     else
         m_frame->spellChecker().spellCheckAfterBlur();
-    setCaretVisibility(activeAndFocused ? CaretVisibility::Visible : CaretVisibility::Hidden);
+    m_frameCaret->setCaretVisibility(activeAndFocused ? CaretVisibility::Visible : CaretVisibility::Hidden);
 
     // Update for caps lock state
     m_frame->eventHandler().capsLockStateMayHaveChanged();
@@ -1078,54 +1086,56 @@
 
 }
 
-// TODO(yoichio): All of functionality should be in FrameCaret.
-// FrameCaret should have PositionWithAffnity and FrameSelection set in
-// setSelecitonAlgorithm.
-void FrameSelection::updateAppearance()
+// TODO(yoiciho): We should move this function to FrameCaret.cpp
+void FrameCaret::updateAppearance()
 {
     // Paint a block cursor instead of a caret in overtype mode unless the caret is at the end of a line (in this case
     // the FrameSelection will paint a blinking caret as usual).
-    bool paintBlockCursor = m_shouldShowBlockCursor && selection().isCaret() && !isLogicalEndOfLine(selection().visibleEnd());
+    bool paintBlockCursor = m_shouldShowBlockCursor && isActive() && !isLogicalEndOfLine(createVisiblePosition(m_caretPosition));
 
     bool shouldBlink = !paintBlockCursor && shouldBlinkCaret();
 
     // If the caret moved, stop the blink timer so we can restart with a
     // black caret in the new location.
     if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame))
-        m_frameCaret->stopCaretBlinkTimer();
+        stopCaretBlinkTimer();
 
     // Start blinking with a black caret. Be sure not to restart if we're
     // already blinking in the right location.
     if (shouldBlink)
-        m_frameCaret->startBlinkCaret();
+        startBlinkCaret();
+}
+
+void FrameSelection::updateAppearance()
+{
+    m_frameCaret->updateAppearance();
 
     if (m_frame->contentLayoutItem().isNull())
         return;
     m_pendingSelection->setHasPendingSelection();
 }
 
-// TODO(yoichio): All of functionality should be in FrameCaret.
-// FrameCaret should have PositionWithAffnity and FrameSelection set in
-// setSelecitonAlgorithm.
-void FrameSelection::setCaretVisibility(CaretVisibility visibility)
+// TODO(yoiciho): We should move this function to FrameCaret.cpp
+void FrameCaret::setCaretVisibility(CaretVisibility visibility)
 {
-    if (m_frameCaret->getCaretVisibility() == visibility)
+    if (getCaretVisibility() == visibility)
         return;
 
-    m_frameCaret->setCaretVisibility(visibility);
+    CaretBase::setCaretVisibility(visibility);
 
     updateAppearance();
 }
 
-bool FrameSelection::shouldBlinkCaret() const
+// TODO(yoiciho): We should move this function to FrameCaret.cpp
+bool FrameCaret::shouldBlinkCaret() const
 {
-    if (!m_frameCaret->caretIsVisible() || !isCaret())
+    if (!caretIsVisible() || !isActive())
         return false;
 
     if (m_frame->settings() && m_frame->settings()->caretBrowsingEnabled())
         return false;
 
-    Element* root = rootEditableElement();
+    Element* root = rootEditableElementOf(m_caretPosition.position());
     if (!root)
         return false;
 
@@ -1133,7 +1143,7 @@
     if (!focusedElement)
         return false;
 
-    return focusedElement->isShadowIncludingInclusiveAncestorOf(selection().start().anchorNode());
+    return focusedElement->isShadowIncludingInclusiveAncestorOf(m_caretPosition.position().anchorNode());
 }
 
 // TODO(yoiciho): We should move this function to FrameCaret.cpp
@@ -1345,7 +1355,16 @@
         setSelection(VisibleSelection(firstPositionInOrBeforeNode(body), TextAffinity::Downstream));
 }
 
-void FrameSelection::setShouldShowBlockCursor(bool shouldShowBlockCursor)
+// TODO(yoichio): We should have LocalFrame having FrameCaret,
+// Editor and PendingSelection using FrameCaret directly
+// and get rid of this.
+bool FrameSelection::shouldShowBlockCursor() const
+{
+    return m_frameCaret->shouldShowBlockCursor();
+}
+
+// TODO(yoiciho): We should move this function to FrameCaret.cpp
+void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor)
 {
     m_shouldShowBlockCursor = shouldShowBlockCursor;
 
@@ -1354,6 +1373,18 @@
     updateAppearance();
 }
 
+// TODO(yoichio): We should have LocalFrame having FrameCaret,
+// Editor and PendingSelection using FrameCaret directly
+// and get rid of this.
+// TODO(yoichio): We should use "caret-shape" in "CSS Basic User Interface
+// Module Level 4" https://drafts.csswg.org/css-ui-4/
+// To use "caret-shape", we need to expose inserting mode information to CSS;
+// https://github.com/w3c/csswg-drafts/issues/133
+void FrameSelection::setShouldShowBlockCursor(bool shouldShowBlockCursor)
+{
+    m_frameCaret->setShouldShowBlockCursor(shouldShowBlockCursor);
+}
+
 template <typename Strategy>
 VisibleSelectionTemplate<Strategy> FrameSelection::validateSelection(const VisibleSelectionTemplate<Strategy>& selection)
 {
@@ -1486,7 +1517,7 @@
 
 void FrameSelection::setCaretVisible(bool caretIsVisible)
 {
-    setCaretVisibility(caretIsVisible ? CaretVisibility::Visible : CaretVisibility::Hidden);
+    m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible : CaretVisibility::Hidden);
 }
 
 bool FrameSelection::shouldPaintCaretForTesting() const
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.h b/third_party/WebKit/Source/core/editing/FrameSelection.h
index b7ceabf..dd03f368 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.h
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.h
@@ -230,7 +230,7 @@
     void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
     void setSelectionFromNone();
 
-    bool shouldShowBlockCursor() const { return m_shouldShowBlockCursor; }
+    bool shouldShowBlockCursor() const;
     void setShouldShowBlockCursor(bool);
 
     // TODO(yosin): We should check DOM tree version and style version in
@@ -271,9 +271,6 @@
 
     void setUseSecureKeyboardEntry(bool);
 
-    void setCaretVisibility(CaretVisibility);
-    bool shouldBlinkCaret() const;
-
     void updateSelectionIfNeeded(const Position& base, const Position& extent, const Position& start, const Position& end);
 
     template <typename Strategy>
@@ -298,7 +295,6 @@
     Member<EditingStyle> m_typingStyle;
 
     bool m_focused : 1;
-    bool m_shouldShowBlockCursor : 1;
 
     // Controls text granularity used to adjust the selection's extent in moveRangeSelectionExtent.
     OwnPtr<GranularityStrategy> m_granularityStrategy;
diff --git a/third_party/WebKit/Source/core/editing/OWNERS b/third_party/WebKit/Source/core/editing/OWNERS
index bc2980ed..ec56b9e 100644
--- a/third_party/WebKit/Source/core/editing/OWNERS
+++ b/third_party/WebKit/Source/core/editing/OWNERS
@@ -1,4 +1,3 @@
-leviw@chrimium.org
 ojan@chromium.org
 yosin@chromium.org
 yutak@chromium.org
diff --git a/third_party/WebKit/Source/core/editing/SelectionModifier.cpp b/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
index 74078c1..9445d8f 100644
--- a/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
@@ -28,6 +28,7 @@
 #include "core/editing/EditingUtilities.h"
 #include "core/editing/Editor.h"
 #include "core/editing/VisibleUnits.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/layout/LayoutBlock.h"
 #include "core/layout/line/InlineTextBox.h"
diff --git a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp
index 95af147..aecd921 100644
--- a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp
@@ -88,7 +88,7 @@
     // We should calculate visible range in list item because inserting new
     // list element will change visibility of list item, e.g. :first-child
     // CSS selector.
-    HTMLElement* newList = toHTMLElement(document().createElement(listElement->tagQName(), false));
+    HTMLElement* newList = toHTMLElement(document().createElement(listElement->tagQName(), CreatedByCloneNode));
     insertNodeBefore(newList, selectedListItem, editingState);
     if (editingState->isAborted())
         return false;
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp
index 9aba281..7955351 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp
@@ -6,6 +6,7 @@
 
 #include "core/editing/EditingTestBase.h"
 #include "core/editing/Editor.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/events/CustomEvent.idl b/third_party/WebKit/Source/core/events/CustomEvent.idl
index ca1e27ff..d0c6ee9 100644
--- a/third_party/WebKit/Source/core/events/CustomEvent.idl
+++ b/third_party/WebKit/Source/core/events/CustomEvent.idl
@@ -28,7 +28,7 @@
 [
     // TODO(bashi): Don't use CustomConstructor. Constructor should be:
     // Constructor(DOMString type, optional CustomEventInit eventInitDict),
-    CustomConstructor,
+    CustomConstructor(DOMString type, optional CustomEventInit eventInitDict),
     Exposed=(Window,Worker),
 ] interface CustomEvent : Event {
     [Custom=Getter] readonly attribute any detail;
diff --git a/third_party/WebKit/Source/core/events/EventPathTest.cpp b/third_party/WebKit/Source/core/events/EventPathTest.cpp
index 40ef500..4351aab 100644
--- a/third_party/WebKit/Source/core/events/EventPathTest.cpp
+++ b/third_party/WebKit/Source/core/events/EventPathTest.cpp
@@ -30,7 +30,7 @@
 
 TEST_F(EventPathTest, ShouldBeEmptyForPseudoElementWithoutParentElement)
 {
-    Element* div = document().createElement(HTMLNames::divTag, false);
+    Element* div = document().createElement(HTMLNames::divTag, CreatedByCreateElement);
     PseudoElement* pseudo = PseudoElement::create(div, PseudoIdFirstLetter);
     pseudo->dispose();
     EventPath eventPath(*pseudo);
diff --git a/third_party/WebKit/Source/core/fetch/Resource.h b/third_party/WebKit/Source/core/fetch/Resource.h
index b5abc81f..290d8f16 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.h
+++ b/third_party/WebKit/Source/core/fetch/Resource.h
@@ -33,7 +33,7 @@
 #include "platform/network/ResourceResponse.h"
 #include "platform/scheduler/CancellableTaskFactory.h"
 #include "public/platform/WebDataConsumerHandle.h"
-#include "public/platform/WebMemoryDumpProvider.h"
+#include "public/platform/WebProcessMemoryDump.h"
 #include "wtf/Allocator.h"
 #include "wtf/HashCountedSet.h"
 #include "wtf/HashSet.h"
diff --git a/third_party/WebKit/Source/core/frame/FrameHost.cpp b/third_party/WebKit/Source/core/frame/FrameHost.cpp
index aa04f2c..7d30a33 100644
--- a/third_party/WebKit/Source/core/frame/FrameHost.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameHost.cpp
@@ -35,6 +35,7 @@
 #include "core/frame/PageScaleConstraints.h"
 #include "core/frame/PageScaleConstraintsSet.h"
 #include "core/frame/TopControls.h"
+#include "core/frame/VisualViewport.h"
 #include "core/inspector/ConsoleMessageStorage.h"
 #include "core/page/Page.h"
 #include "core/page/scrolling/OverscrollController.h"
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index cff7ed8..3b83f92 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -45,6 +45,7 @@
 #include "core/frame/PageScaleConstraintsSet.h"
 #include "core/frame/Settings.h"
 #include "core/frame/TopControls.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLFrameElement.h"
 #include "core/html/HTMLPlugInElement.h"
 #include "core/html/HTMLTextFormControlElement.h"
@@ -2897,8 +2898,10 @@
     for (Frame* frame = m_frame->tree().top(); frame; frame = frame->tree().traverseNext()) {
         if (!frame->isLocalFrame())
             continue;
-        if (LayoutViewItem layoutView = toLocalFrame(frame)->contentLayoutItem())
+        if (LayoutViewItem layoutView = toLocalFrame(frame)->contentLayoutItem()) {
+            layoutView.frameView()->m_isTrackingPaintInvalidations = trackPaintInvalidations;
             layoutView.compositor()->setTracksPaintInvalidations(trackPaintInvalidations);
+        }
     }
 
     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"),
diff --git a/third_party/WebKit/Source/core/frame/HostsUsingFeatures.cpp b/third_party/WebKit/Source/core/frame/HostsUsingFeatures.cpp
index 1af6f9d..8277ba8 100644
--- a/third_party/WebKit/Source/core/frame/HostsUsingFeatures.cpp
+++ b/third_party/WebKit/Source/core/frame/HostsUsingFeatures.cpp
@@ -6,6 +6,7 @@
 
 #include "bindings/core/v8/ScriptState.h"
 #include "core/dom/Document.h"
+#include "core/frame/LocalDOMWindow.h"
 #include "core/page/Page.h"
 #include "public/platform/Platform.h"
 
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index c5bf20c..a2fdaff 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -52,11 +52,13 @@
 #include "core/frame/FrameConsole.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/History.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Navigator.h"
 #include "core/frame/Screen.h"
 #include "core/frame/ScrollToOptions.h"
 #include "core/frame/Settings.h"
 #include "core/frame/SuspendableTimer.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/input/EventHandler.h"
 #include "core/inspector/ConsoleMessageStorage.h"
diff --git a/third_party/WebKit/Source/core/frame/TopControls.cpp b/third_party/WebKit/Source/core/frame/TopControls.cpp
index 387caf2c..4ebcb03 100644
--- a/third_party/WebKit/Source/core/frame/TopControls.cpp
+++ b/third_party/WebKit/Source/core/frame/TopControls.cpp
@@ -5,6 +5,7 @@
 #include "core/frame/TopControls.h"
 
 #include "core/frame/FrameHost.h"
+#include "core/frame/VisualViewport.h"
 #include "core/page/ChromeClient.h"
 #include "platform/geometry/FloatSize.h"
 #include <algorithm> // for std::min and std::max
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 85b58c48..34a8e1e 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -802,8 +802,6 @@
         ExternalIsSearchProviderInstalled = 982,
         V8Permissions_RequestAll_Method = 983,
         BluetoothDeviceInstanceId = 984,
-        HTMLLabelElementFormIDLAttribute = 985,
-        HTMLLabelElementFormContentAttribute = 986,
         DeviceOrientationAbsoluteInsecureOrigin = 987,
         DeviceOrientationAbsoluteSecureOrigin = 988,
         FontFaceConstructor = 989,
@@ -1073,8 +1071,6 @@
         DocumentAllLegacyCallIndexed = 1258,
         DocumentAllLegacyCallIndexedWithNonNumber = 1259,
         DocumentAllLegacyCallTwoArguments = 1260,
-        HTMLLabelElementFormIsDifferentFromControlForm = 1261,
-        HTMLLabelElementHasNoControlAndFormIsAncestor = 1262,
         HTMLLabelElementControlForNonFormAssociatedElement = 1263,
         PatternAttributeUnicodeFlagIsIncompatible = 1264,
         HTMLMediaElementLoadNetworkEmptyNotPaused = 1265,
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
index 21d5e07..0ba92459 100644
--- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -417,14 +417,20 @@
     return reportingStatus == ContentSecurityPolicy::SendReport ? checkAncestorsAndReportViolation(m_frameAncestors.get(), frame, url) : checkAncestors(m_frameAncestors.get(), frame);
 }
 
-bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
+CSPDirectiveList::NoncePolicyDisposition CSPDirectiveList::allowScriptNonce(const String& nonce) const
 {
-    return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
+    SourceListDirective* directive = operativeDirective(m_scriptSrc.get());
+    if (!directive)
+        return NoncePolicyDisposition::NoDirective;
+    return checkNonce(directive, nonce) ? NoncePolicyDisposition::Allowed : NoncePolicyDisposition::Denied;
 }
 
-bool CSPDirectiveList::allowStyleNonce(const String& nonce) const
+CSPDirectiveList::NoncePolicyDisposition CSPDirectiveList::allowStyleNonce(const String& nonce) const
 {
-    return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
+    SourceListDirective* directive = operativeDirective(m_styleSrc.get());
+    if (!directive)
+        return NoncePolicyDisposition::NoDirective;
+    return checkNonce(directive, nonce) ? NoncePolicyDisposition::Allowed : NoncePolicyDisposition::Denied;
 }
 
 bool CSPDirectiveList::allowScriptHash(const CSPHashValue& hashValue, ContentSecurityPolicy::InlineType type) const
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
index 0f1ded5..2d852660 100644
--- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
+++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
@@ -25,6 +25,12 @@
 class CORE_EXPORT CSPDirectiveList : public GarbageCollectedFinalized<CSPDirectiveList> {
     WTF_MAKE_NONCOPYABLE(CSPDirectiveList);
 public:
+    enum class NoncePolicyDisposition {
+        NoDirective = 0,
+        Allowed,
+        Denied
+    };
+
     static CSPDirectiveList* create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
 
     void parse(const UChar* begin, const UChar* end);
@@ -59,8 +65,8 @@
     // because a child frame can't manipulate the URL of a cross-origin
     // parent.
     bool allowAncestors(LocalFrame*, const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowScriptNonce(const String&) const;
-    bool allowStyleNonce(const String&) const;
+    NoncePolicyDisposition allowScriptNonce(const String&) const;
+    NoncePolicyDisposition allowStyleNonce(const String&) const;
     bool allowScriptHash(const CSPHashValue&, ContentSecurityPolicy::InlineType) const;
     bool allowStyleHash(const CSPHashValue&, ContentSecurityPolicy::InlineType) const;
     bool allowDynamic() const;
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
index 71b01c8..2fa82b78f 100644
--- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -391,7 +391,7 @@
     return isAllowed;
 }
 
-template<bool (CSPDirectiveList::*allowed)(const String&) const>
+template<CSPDirectiveList::NoncePolicyDisposition (CSPDirectiveList::*allowed)(const String&) const>
 bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce)
 {
     bool isExplicitlyAllowed = false;
@@ -402,9 +402,11 @@
         // better fix would be to delay the nonce processing until such time as the whitelist
         // processing fails. https://crbug.com/611652
         if (policy.get()->headerType() == ContentSecurityPolicyHeaderTypeEnforce) {
-            if (!(policy.get()->*allowed)(nonce))
+            CSPDirectiveList::NoncePolicyDisposition policyDisposition = (policy.get()->*allowed)(nonce);
+            if (policyDisposition == CSPDirectiveList::NoncePolicyDisposition::Denied)
                 return false;
-            isExplicitlyAllowed = true;
+            if (policyDisposition == CSPDirectiveList::NoncePolicyDisposition::Allowed)
+                isExplicitlyAllowed = true;
         }
     }
     return isExplicitlyAllowed;
diff --git a/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp b/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
index 27fd630..6a12459 100644
--- a/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
+++ b/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
@@ -29,7 +29,6 @@
 #include "core/dom/NodeTraversal.h"
 #include "core/html/HTMLFormControlElement.h"
 #include "core/html/HTMLFormElement.h"
-#include "core/html/HTMLLabelElement.h"
 #include "core/html/HTMLObjectElement.h"
 #include "core/html/ValidityState.h"
 
@@ -311,8 +310,6 @@
 {
     if (associatedElement.isFormControlElement())
         return toHTMLFormControlElement(associatedElement);
-    if (associatedElement.isLabelElement())
-        return toHTMLLabelElement(associatedElement);
     return toHTMLObjectElement(associatedElement);
 }
 
diff --git a/third_party/WebKit/Source/core/html/FormAssociatedElement.h b/third_party/WebKit/Source/core/html/FormAssociatedElement.h
index 6bb33ef4..efed2e0 100644
--- a/third_party/WebKit/Source/core/html/FormAssociatedElement.h
+++ b/third_party/WebKit/Source/core/html/FormAssociatedElement.h
@@ -50,7 +50,6 @@
     virtual bool isFormControlElement() const = 0;
     virtual bool isFormControlElementWithState() const;
     virtual bool isEnumeratable() const = 0;
-    virtual bool isLabelElement() const { return false; }
 
     // Returns the 'name' attribute value. If this element has no name
     // attribute, it returns an empty string instead of null string.
diff --git a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
index b99fd3e..a723dd1 100644
--- a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
@@ -373,7 +373,8 @@
 
 bool isLinkClick(Event* event)
 {
-    return event->type() == EventTypeNames::click && (!event->isMouseEvent() || toMouseEvent(event)->button() != RightButton);
+    // Allow detail <= 1 so that synthetic clicks work. They may have detail == 0.
+    return event->type() == EventTypeNames::click && (!event->isMouseEvent() || (toMouseEvent(event)->button() != RightButton && toMouseEvent(event)->detail() <= 1));
 }
 
 bool HTMLAnchorElement::willRespondToMouseClickEvents()
diff --git a/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp b/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
index b02addc..db1bbbf 100644
--- a/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
@@ -31,7 +31,7 @@
 #include "core/css/parser/CSSParser.h"
 #include "core/dom/Attribute.h"
 #include "core/dom/StyleChangeReason.h"
-#include "core/frame/UseCounter.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index 72bf3360..ceebfd50 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -612,6 +612,36 @@
         exceptionState.throwSecurityError("Tainted canvases may not be exported.");
         return String();
     }
+    Optional<ScopedUsHistogramTimer> timer;
+    String lowercaseMimeType = mimeType.lower();
+    if (mimeType.isNull())
+        lowercaseMimeType = DefaultMimeType;
+    if (lowercaseMimeType == "image/png") {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterPNG, new CustomCountHistogram("Blink.Canvas.ToDataURL.PNG", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterPNG);
+    } else if (lowercaseMimeType == "image/jpeg") {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterJPEG, new CustomCountHistogram("Blink.Canvas.ToDataURL.JPEG", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterJPEG);
+    } else if (lowercaseMimeType == "image/webp") {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterWEBP, new CustomCountHistogram("Blink.Canvas.ToDataURL.WEBP", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterWEBP);
+    } else if (lowercaseMimeType == "image/gif") {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterGIF, new CustomCountHistogram("Blink.Canvas.ToDataURL.GIF", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterGIF);
+    } else if (lowercaseMimeType == "image/bmp" || lowercaseMimeType == "image/x-windows-bmp") {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterBMP, new CustomCountHistogram("Blink.Canvas.ToDataURL.BMP", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterBMP);
+    } else if (lowercaseMimeType == "image/x-icon") {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterICON, new CustomCountHistogram("Blink.Canvas.ToDataURL.ICON", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterICON);
+    } else if (lowercaseMimeType == "image/tiff" || lowercaseMimeType == "image/x-tiff") {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterTIFF, new CustomCountHistogram("Blink.Canvas.ToDataURL.TIFF", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterTIFF);
+    } else {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterUnknown, new CustomCountHistogram("Blink.Canvas.ToDataURL.Unknown", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterUnknown);
+    }
+
     double quality = UndefinedQualityValue;
     if (!qualityArgument.isEmpty()) {
         v8::Local<v8::Value> v8Value = qualityArgument.v8Value();
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index d92d0d7..e072c43 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -35,6 +35,7 @@
 #include "core/fetch/ImageResource.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/ImageBitmap.h"
+#include "core/frame/LocalDOMWindow.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLFormElement.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp b/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
index c20f516..e958b1e2 100644
--- a/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
@@ -42,17 +42,15 @@
 
 using namespace HTMLNames;
 
-inline HTMLLabelElement::HTMLLabelElement(Document& document, HTMLFormElement* form)
+inline HTMLLabelElement::HTMLLabelElement(Document& document)
     : HTMLElement(labelTag, document)
     , m_processingClick(false)
 {
-    FormAssociatedElement::associateByParser(form);
 }
 
-HTMLLabelElement* HTMLLabelElement::create(Document& document, HTMLFormElement* form)
+HTMLLabelElement* HTMLLabelElement::create(Document& document)
 {
-    HTMLLabelElement* labelElement = new HTMLLabelElement(document, form);
-    return labelElement;
+    return new HTMLLabelElement(document);
 }
 
 LabelableElement* HTMLLabelElement::control() const
@@ -83,24 +81,11 @@
     return nullptr;
 }
 
-HTMLFormElement* HTMLLabelElement::formOwner() const
+HTMLFormElement* HTMLLabelElement::form() const
 {
-    return FormAssociatedElement::form();
-}
-
-HTMLFormElement* HTMLLabelElement::formForBinding() const
-{
-    HTMLFormElement* formOwner = FormAssociatedElement::form();
-    HTMLFormElement* controlForm = nullptr;
-    if (LabelableElement* control = this->control()) {
-        if (control->isFormControlElement())
-            controlForm = toHTMLFormControlElement(control)->form();
-    }
-    if (formOwner != controlForm)
-        UseCounter::count(document(), UseCounter::HTMLLabelElementFormIsDifferentFromControlForm);
-    if (!controlForm && formOwner && formOwner == findFormAncestor())
-        UseCounter::count(document(), UseCounter::HTMLLabelElementHasNoControlAndFormIsAncestor);
-    return formOwner;
+    if (LabelableElement* control = this->control())
+        return control->isFormControlElement() ? toHTMLFormControlElement(control)->form() : nullptr;
+    return nullptr;
 }
 
 void HTMLLabelElement::setActive(bool down)
@@ -260,7 +245,6 @@
 Node::InsertionNotificationRequest HTMLLabelElement::insertedInto(ContainerNode* insertionPoint)
 {
     InsertionNotificationRequest result = HTMLElement::insertedInto(insertionPoint);
-    FormAssociatedElement::insertedInto(insertionPoint);
     if (insertionPoint->isInTreeScope()) {
         TreeScope& scope = insertionPoint->treeScope();
         if (scope == treeScope() && scope.shouldCacheLabelsByForAttribute())
@@ -282,29 +266,17 @@
             updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
     }
     HTMLElement::removedFrom(insertionPoint);
-    FormAssociatedElement::removedFrom(insertionPoint);
     document().removeFormAssociation(this);
 }
 
-DEFINE_TRACE(HTMLLabelElement)
-{
-    HTMLElement::trace(visitor);
-    FormAssociatedElement::trace(visitor);
-}
-
 void HTMLLabelElement::parseAttribute(const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& attributeValue)
 {
-    if (attributeName == formAttr) {
-        formAttributeChanged();
-        UseCounter::count(document(), UseCounter::HTMLLabelElementFormContentAttribute);
-    } else {
-        if (attributeName == forAttr) {
-            TreeScope& scope = treeScope();
-            if (scope.shouldCacheLabelsByForAttribute())
-                updateLabel(scope, oldValue, attributeValue);
-        }
-        HTMLElement::parseAttribute(attributeName, oldValue, attributeValue);
+    if (attributeName == forAttr) {
+        TreeScope& scope = treeScope();
+        if (scope.shouldCacheLabelsByForAttribute())
+            updateLabel(scope, oldValue, attributeValue);
     }
+    HTMLElement::parseAttribute(attributeName, oldValue, attributeValue);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLLabelElement.h b/third_party/WebKit/Source/core/html/HTMLLabelElement.h
index 533fd1e..4eea330 100644
--- a/third_party/WebKit/Source/core/html/HTMLLabelElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLLabelElement.h
@@ -25,28 +25,23 @@
 #define HTMLLabelElement_h
 
 #include "core/CoreExport.h"
-#include "core/html/FormAssociatedElement.h"
 #include "core/html/HTMLElement.h"
-#include "core/html/LabelableElement.h"
 
 namespace blink {
 
-class CORE_EXPORT HTMLLabelElement final : public HTMLElement, public FormAssociatedElement {
+class LabelableElement;
+
+class CORE_EXPORT HTMLLabelElement final : public HTMLElement {
     DEFINE_WRAPPERTYPEINFO();
-    USING_GARBAGE_COLLECTED_MIXIN(HTMLLabelElement);
 public:
-    static HTMLLabelElement* create(Document&, HTMLFormElement*);
+    static HTMLLabelElement* create(Document&);
     LabelableElement* control() const;
+    HTMLFormElement* form() const;
 
     bool willRespondToMouseClickEvents() override;
 
-    DECLARE_VIRTUAL_TRACE();
-
-    HTMLFormElement* formOwner() const override;
-    HTMLFormElement* formForBinding() const;
-
 private:
-    explicit HTMLLabelElement(Document&, HTMLFormElement*);
+    explicit HTMLLabelElement(Document&);
     bool isInInteractiveContent(Node*) const;
 
     bool isInteractiveContent() const override;
@@ -64,11 +59,6 @@
 
     void focus(const FocusParams&) override;
 
-    // FormAssociatedElement methods
-    bool isFormControlElement() const override { return false; }
-    bool isEnumeratable() const override { return false; }
-    bool isLabelElement() const override { return true; }
-
     void parseAttribute(const QualifiedName&, const AtomicString&, const AtomicString&) override;
 
     void updateLabel(TreeScope&, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue);
@@ -76,26 +66,6 @@
     bool m_processingClick;
 };
 
-
-template<typename T> inline const T& toElement(const FormAssociatedElement&);
-template<typename T> inline const T* toElement(const FormAssociatedElement*);
-// Make toHTMLLabelElement() accept a FormAssociatedElement as input instead of a Node.
-template<> inline const HTMLLabelElement* toElement<HTMLLabelElement>(const FormAssociatedElement* element)
-{
-    const HTMLLabelElement* labelElement = static_cast<const HTMLLabelElement*>(element);
-    // FormAssociatedElement doesn't have hasTagName, hence check for assert.
-    ASSERT_WITH_SECURITY_IMPLICATION(!labelElement || labelElement->hasTagName(HTMLNames::labelTag));
-    return labelElement;
-}
-
-template<> inline const HTMLLabelElement& toElement<HTMLLabelElement>(const FormAssociatedElement& element)
-{
-    const HTMLLabelElement& labelElement = static_cast<const HTMLLabelElement&>(element);
-    // FormAssociatedElement doesn't have hasTagName, hence check for assert.
-    ASSERT_WITH_SECURITY_IMPLICATION(labelElement.hasTagName(HTMLNames::labelTag));
-    return labelElement;
-}
-
 } // namespace blink
 
 #endif // HTMLLabelElement_h
diff --git a/third_party/WebKit/Source/core/html/HTMLLabelElement.idl b/third_party/WebKit/Source/core/html/HTMLLabelElement.idl
index 4db6d184..7ec0641 100644
--- a/third_party/WebKit/Source/core/html/HTMLLabelElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLLabelElement.idl
@@ -21,7 +21,7 @@
 // https://html.spec.whatwg.org/#the-label-element
 
 interface HTMLLabelElement : HTMLElement {
-    [ImplementedAs=formForBinding, MeasureAs=HTMLLabelElementFormIDLAttribute] readonly attribute HTMLFormElement? form;
+    readonly attribute HTMLFormElement? form;
     [Reflect=for] attribute DOMString htmlFor;
     readonly attribute HTMLElement? control;
 };
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index a2136d9..7beecb9 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -1692,7 +1692,10 @@
     DVLOG(MEDIA_LOG_LEVEL) << "seek(" << (void*)this << ", " << time << ")";
 
     // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps.
-    if (m_readyState == HAVE_NOTHING)
+    // FIXME: remove m_webMediaPlayer check once we figure out how
+    // m_webMediaPlayer is going out of sync with readystate.
+    // m_webMediaPlayer is cleared but readystate is not set to HAVE_NOTHING.
+    if (!m_webMediaPlayer || m_readyState == HAVE_NOTHING)
         return;
 
     // Ignore preload none and start load if necessary.
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.h b/third_party/WebKit/Source/core/html/HTMLObjectElement.h
index bcac853..e1eedf6d 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.h
@@ -115,7 +115,6 @@
 template<> inline const HTMLObjectElement* toElement<HTMLObjectElement>(const FormAssociatedElement* element)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!element || !element->isFormControlElement());
-    ASSERT_WITH_SECURITY_IMPLICATION(!element || !element->isLabelElement());
     const HTMLObjectElement* objectElement = static_cast<const HTMLObjectElement*>(element);
     // We need to assert after the cast because FormAssociatedElement doesn't
     // have hasTagName.
@@ -126,7 +125,6 @@
 template<> inline const HTMLObjectElement& toElement<HTMLObjectElement>(const FormAssociatedElement& element)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!element.isFormControlElement());
-    ASSERT_WITH_SECURITY_IMPLICATION(!element.isLabelElement());
     const HTMLObjectElement& objectElement = static_cast<const HTMLObjectElement&>(element);
     // We need to assert after the cast because FormAssociatedElement doesn't
     // have hasTagName.
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
index 89a0a69..48f22041 100644
--- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -501,7 +501,7 @@
 
     if (diff < 0) { // Add dummy elements.
         do {
-            appendChild(document().createElement(optionTag, false), exceptionState);
+            appendChild(document().createElement(optionTag, CreatedByCreateElement), exceptionState);
             if (exceptionState.hadException())
                 break;
         } while (++diff);
diff --git a/third_party/WebKit/Source/core/html/HTMLTagNames.in b/third_party/WebKit/Source/core/html/HTMLTagNames.in
index 08cb1d32..807e319 100644
--- a/third_party/WebKit/Source/core/html/HTMLTagNames.in
+++ b/third_party/WebKit/Source/core/html/HTMLTagNames.in
@@ -72,7 +72,7 @@
 ins interfaceName=HTMLModElement
 kbd interfaceName=HTMLElement
 keygen constructorNeedsFormElement
-label constructorNeedsFormElement
+label
 layer interfaceName=HTMLElement
 legend
 li interfaceName=HTMLLIElement
diff --git a/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp b/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
index 48fe21d..a68cc16 100644
--- a/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
@@ -34,6 +34,7 @@
 #include "core/dom/Fullscreen.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/frame/ImageBitmap.h"
+#include "core/frame/LocalDOMWindow.h"
 #include "core/frame/Settings.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/imagebitmap/ImageBitmapOptions.h"
diff --git a/third_party/WebKit/Source/core/html/LabelsNodeList.cpp b/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
index 9764cdb..3cdc57e3 100644
--- a/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
+++ b/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
@@ -27,6 +27,7 @@
 #include "core/dom/Element.h"
 #include "core/dom/NodeRareData.h"
 #include "core/html/HTMLLabelElement.h"
+#include "core/html/LabelableElement.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
index e40177f6..48def60 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -738,10 +738,15 @@
     queueTask(task);
 }
 
+CreateElementFlags HTMLConstructionSite::getCreateElementFlags() const
+{
+    return m_isParsingFragment ? CreatedByFragmentParser : CreatedByParser;
+}
+
 Element* HTMLConstructionSite::createElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
 {
     QualifiedName tagName(nullAtom, token->name(), namespaceURI);
-    Element* element = ownerDocumentForCurrentNode().createElement(tagName, true);
+    Element* element = ownerDocumentForCurrentNode().createElement(tagName, getCreateElementFlags());
     setAttributes(element, token, m_parserContentPolicy);
     return element;
 }
@@ -762,7 +767,7 @@
     // FIXME: This can't use HTMLConstructionSite::createElement because we
     // have to pass the current form element.  We should rework form association
     // to occur after construction to allow better code sharing here.
-    HTMLElement* element = HTMLElementFactory::createHTMLElement(token->name(), document, form, true);
+    HTMLElement* element = HTMLElementFactory::createHTMLElement(token->name(), document, form, getCreateElementFlags());
     setAttributes(element, token, m_parserContentPolicy);
     return element;
 }
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
index 2be5879..ae383c4 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
+++ b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
@@ -234,6 +234,7 @@
 
     void findFosterSite(HTMLConstructionSiteTask&);
 
+    CreateElementFlags getCreateElementFlags() const;
     HTMLElement* createHTMLElement(AtomicHTMLToken*);
     Element* createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
 
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
index e3ffd2f..e20520e 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -35,6 +35,7 @@
 #include "core/css/parser/SizesAttributeParser.h"
 #include "core/dom/Document.h"
 #include "core/fetch/IntegrityMetadata.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/frame/SubresourceIntegrity.h"
 #include "core/html/CrossOriginAttribute.h"
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
index ce9656d..7328980 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
@@ -499,7 +499,7 @@
 Element* MediaControlTextTrackListElement::createTextTrackListItem(TextTrack* track)
 {
     int trackIndex = track ? track->trackIndex() : trackIndexOffValue;
-    HTMLLabelElement* trackItem = HTMLLabelElement::create(document(), nullptr);
+    HTMLLabelElement* trackItem = HTMLLabelElement::create(document());
     trackItem->setShadowPseudoId(AtomicString("-internal-media-controls-text-track-list-item"));
     HTMLInputElement* trackItemInput = HTMLInputElement::create(document(), nullptr, false);
     trackItemInput->setShadowPseudoId(AtomicString("-internal-media-controls-text-track-list-item-input"));
diff --git a/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp b/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp
index 16a475c..3e988c1 100644
--- a/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp
+++ b/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp
@@ -68,11 +68,11 @@
 }
 
 // static
-ConsoleMessage* ConsoleMessage::create(MessageSource source, MessageLevel level, const String& message, PassOwnPtr<SourceLocation> location)
+ConsoleMessage* ConsoleMessage::create(MessageSource source, MessageLevel level, const String& message, PassOwnPtr<SourceLocation> location, ScriptArguments* arguments)
 {
     if (!location)
-        return new ConsoleMessage(source, level, message, String(), 0, 0, nullptr, 0, nullptr);
-    return new ConsoleMessage(source, level, message, location->url(), location->lineNumber(), location->columnNumber(), location->takeStackTrace(), location->scriptId(), nullptr);
+        return new ConsoleMessage(source, level, message, String(), 0, 0, nullptr, 0, arguments);
+    return new ConsoleMessage(source, level, message, location->url(), location->lineNumber(), location->columnNumber(), location->takeStackTrace(), location->scriptId(), arguments);
 }
 
 // static
diff --git a/third_party/WebKit/Source/core/inspector/ConsoleMessage.h b/third_party/WebKit/Source/core/inspector/ConsoleMessage.h
index 7c777f6d..882326e7 100644
--- a/third_party/WebKit/Source/core/inspector/ConsoleMessage.h
+++ b/third_party/WebKit/Source/core/inspector/ConsoleMessage.h
@@ -43,7 +43,7 @@
     // This method captures callstack.
     static ConsoleMessage* createForConsoleAPI(MessageLevel, MessageType, const String& message, ScriptArguments*);
 
-    static ConsoleMessage* create(MessageSource, MessageLevel, const String& message, PassOwnPtr<SourceLocation>);
+    static ConsoleMessage* create(MessageSource, MessageLevel, const String& message, PassOwnPtr<SourceLocation>, ScriptArguments* = nullptr);
     static ConsoleMessage* create(MessageSource, MessageLevel, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace>, int scriptId, ScriptArguments*);
 
     ~ConsoleMessage();
diff --git a/third_party/WebKit/Source/core/inspector/IdentifiersFactory.cpp b/third_party/WebKit/Source/core/inspector/IdentifiersFactory.cpp
index dc752ebd..5482e92 100644
--- a/third_party/WebKit/Source/core/inspector/IdentifiersFactory.cpp
+++ b/third_party/WebKit/Source/core/inspector/IdentifiersFactory.cpp
@@ -29,6 +29,7 @@
 #include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectedFrames.h"
 #include "core/loader/DocumentLoader.h"
+#include "public/platform/Platform.h"
 #include "wtf/Assertions.h"
 #include "wtf/text/StringBuilder.h"
 
@@ -49,10 +50,11 @@
 
 
 // static
-void IdentifiersFactory::setProcessId(long processId)
+void IdentifiersFactory::initialize()
 {
     StringBuilder builder;
-    builder.appendNumber(processId);
+
+    builder.appendNumber(Platform::current()->getUniqueIdForProcess());
     builder.append('.');
     ASSERT(processIdPrefix().isEmpty() || processIdPrefix() == builder.toString());
     processIdPrefix() = builder.toString();
@@ -108,7 +110,8 @@
 // static
 String IdentifiersFactory::addProcessIdPrefixTo(int id)
 {
-    ASSERT(!processIdPrefix().isEmpty());
+    if (processIdPrefix().isEmpty())
+        initialize();
     return processIdPrefix() + String::number(id);
 }
 
diff --git a/third_party/WebKit/Source/core/inspector/IdentifiersFactory.h b/third_party/WebKit/Source/core/inspector/IdentifiersFactory.h
index 30b06598..aafb533 100644
--- a/third_party/WebKit/Source/core/inspector/IdentifiersFactory.h
+++ b/third_party/WebKit/Source/core/inspector/IdentifiersFactory.h
@@ -39,7 +39,6 @@
 class CORE_EXPORT IdentifiersFactory {
     STATIC_ONLY(IdentifiersFactory);
 public:
-    static void setProcessId(long);
     static String createIdentifier();
 
     static String requestId(unsigned long identifier);
@@ -51,6 +50,7 @@
     static DocumentLoader* loaderById(InspectedFrames*, const String&);
 
 private:
+    static void initialize();
     static String addProcessIdPrefixTo(int id);
     static int removeProcessIdPrefixFrom(const String&, bool* ok);
 };
diff --git a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
index ee6126b..cd1cca18 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
@@ -20,6 +20,7 @@
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/DOMNodeIds.h"
 #include "core/dom/NodeComputedStyle.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectedFrames.h"
 #include "core/inspector/InspectorCSSAgent.h"
 #include "core/inspector/InspectorDOMAgent.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
index 1d8a0e5..aad900e 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
@@ -570,7 +570,7 @@
     didRemoveBreakpoint();
 }
 
-void InspectorDOMDebuggerAgent::willSendXMLHttpRequest(const String& url)
+void InspectorDOMDebuggerAgent::willSendXMLHttpOrFetchNetworkRequest(const String& url)
 {
     String breakpointURL;
     if (m_state->booleanProperty(DOMDebuggerAgentState::pauseOnAllXHRs, false))
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
index a528d2a..fbab05d 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
@@ -81,7 +81,7 @@
     void willRemoveDOMNode(Node*);
     void didRemoveDOMNode(Node*);
     void willModifyDOMAttr(Element*, const AtomicString&, const AtomicString&);
-    void willSendXMLHttpRequest(const String& url);
+    void willSendXMLHttpOrFetchNetworkRequest(const String& url);
     void didFireWebGLError(const String& errorName);
     void didFireWebGLWarning();
     void didFireWebGLErrorOrWarning(const String& message);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
index 38f7e24..cd24cf7 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
@@ -32,6 +32,7 @@
 
 #include "bindings/core/v8/ScriptCallStack.h"
 #include "core/InstrumentingAgents.h"
+#include "core/events/Event.h"
 #include "core/events/EventTarget.h"
 #include "core/fetch/FetchInitiatorInfo.h"
 #include "core/frame/FrameHost.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
index e6cebb9a..7703ffb 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
+++ b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
@@ -116,7 +116,7 @@
     void willPopShadowRoot([Keep] Element* host, ShadowRoot*);
 
     [DOMDebugger]
-    void willSendXMLHttpRequest(ExecutionContext*, const String& url);
+    void willSendXMLHttpOrFetchNetworkRequest(ExecutionContext*, const String& url);
 
     [DOMDebugger]
     void didFireWebGLError(Element*, const String& errorName);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
index 422566d..1907afb 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -36,7 +36,7 @@
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
-#include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/inspector/IdentifiersFactory.h"
 #include "core/inspector/InspectedFrames.h"
 #include "core/layout/LayoutPart.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
index ab128da2..61a07532 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -148,6 +148,7 @@
         DEFINE_STRING_MAPPING(PseudoFutureCue)
         DEFINE_STRING_MAPPING(PseudoPastCue)
         DEFINE_STRING_MAPPING(PseudoUnresolved)
+        DEFINE_STRING_MAPPING(PseudoDefined)
         DEFINE_STRING_MAPPING(PseudoContent)
         DEFINE_STRING_MAPPING(PseudoHost)
         DEFINE_STRING_MAPPING(PseudoHostContext)
diff --git a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
index ed7a8a39..90d6a13 100644
--- a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
+++ b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
@@ -53,7 +53,6 @@
 #include "core/xml/XPathResult.h"
 #include "platform/UserGestureIndicator.h"
 #include "platform/v8_inspector/public/V8Debugger.h"
-#include "public/platform/Platform.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/ThreadingPrimitives.h"
@@ -87,7 +86,6 @@
     MutexLocker locker(creationMutex());
     ASSERT(!s_instance);
     s_instance = this;
-    IdentifiersFactory::setProcessId(Platform::current()->getUniqueIdForProcess());
 }
 
 MainThreadDebugger::~MainThreadDebugger()
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
index 5fb474b..9081857 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -26,6 +26,7 @@
 #include "core/layout/LayoutBoxModelObject.h"
 
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLBodyElement.h"
 #include "core/layout/ImageQualityController.h"
 #include "core/layout/LayoutBlock.h"
@@ -200,7 +201,7 @@
         if (!layer() && layerCreationAllowedForSubtree()) {
             if (wasFloatingBeforeStyleChanged && isFloating())
                 setChildNeedsLayout();
-            createLayer(type);
+            createLayer();
             if (parent() && !needsLayout()) {
                 // FIXME: We should call a specialized version of this function.
                 layer()->updateLayerPositionsAfterLayout();
@@ -222,10 +223,6 @@
     }
 
     if (layer()) {
-        // FIXME: Ideally we shouldn't need this setter but we can't easily infer an overflow-only layer
-        // from the style.
-        layer()->setLayerType(type);
-
         layer()->styleDidChange(diff, oldStyle);
         if (hadLayer && layer()->isSelfPaintingLayer() != layerWasSelfPainting)
             setChildNeedsLayout();
@@ -325,10 +322,10 @@
         ancestorOverflowLayer->getScrollableArea()->invalidateAllStickyConstraints();
 }
 
-void LayoutBoxModelObject::createLayer(PaintLayerType type)
+void LayoutBoxModelObject::createLayer()
 {
     ASSERT(!m_layer);
-    m_layer = adoptPtr(new PaintLayer(this, type));
+    m_layer = adoptPtr(new PaintLayer(this));
     setHasLayer(true);
     m_layer->insertOnlyThisLayerAfterStyleChange();
 }
@@ -438,11 +435,20 @@
 
 void LayoutBoxModelObject::invalidateDisplayItemClientOnBacking(const DisplayItemClient& displayItemClient, PaintInvalidationReason invalidationReason) const
 {
+    displayItemClient.setDisplayItemsUncached();
+
+    // We need to inform the GraphicsLayer about this paint invalidation only when we are tracking
+    // paint invalidation or ENABLE(ASSERT).
+#if !ENABLE(ASSERT)
+    if (!frameView()->isTrackingPaintInvalidations())
+        return;
+#endif
+
     if (layer()->groupedMapping()) {
         if (GraphicsLayer* squashingLayer = layer()->groupedMapping()->squashingLayer())
-            squashingLayer->invalidateDisplayItemClient(displayItemClient, invalidationReason);
+            squashingLayer->displayItemClientWasInvalidated(displayItemClient, invalidationReason);
     } else if (CompositedLayerMapping* compositedLayerMapping = layer()->compositedLayerMapping()) {
-        compositedLayerMapping->invalidateDisplayItemClient(displayItemClient, invalidationReason);
+        compositedLayerMapping->displayItemClientWasInvalidated(displayItemClient, invalidationReason);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
index 87f386e..cffef09 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
@@ -364,7 +364,7 @@
     virtual void moveChildrenTo(LayoutBoxModelObject* toBoxModelObject, LayoutObject* startChild, LayoutObject* endChild, LayoutObject* beforeChild, bool fullRemoveInsert = false);
 
 private:
-    void createLayer(PaintLayerType);
+    void createLayer();
 
     LayoutUnit computedCSSPadding(const Length&) const;
     bool isBoxModelObject() const final { return true; }
diff --git a/third_party/WebKit/Source/core/layout/LayoutFullScreen.cpp b/third_party/WebKit/Source/core/layout/LayoutFullScreen.cpp
index 53acce1..760c11e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFullScreen.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFullScreen.cpp
@@ -26,7 +26,7 @@
 
 #include "core/dom/Fullscreen.h"
 #include "core/frame/FrameHost.h"
-#include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/layout/LayoutBlockFlow.h"
 #include "core/page/Page.h"
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index 8f801933..c7baa7c9 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -336,7 +336,6 @@
 
 void LayoutGrid::computeTrackSizesForDirection(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit freeSpace)
 {
-    ASSERT(freeSpace >= 0);
     sizingData.freeSpaceForDirection(direction) = freeSpace - guttersSize(direction, direction == ForRows ? gridRowCount() : gridColumnCount());
     sizingData.sizingOperation = GridSizingData::TrackSizing;
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 6c0677a..3bcf0bf 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -1230,11 +1230,20 @@
 void LayoutObject::invalidateDisplayItemClient(const DisplayItemClient& displayItemClient) const
 {
     if (PaintLayer* paintingLayer = this->paintingLayer()) {
+        paintingLayer->setNeedsRepaint();
+
+#if !ENABLE(ASSERT)
+        // This is a fast path when we don't need to inform the GraphicsLayer about this paint invalidation.
+        FrameView* frameView = this->frameView();
+        if (!frameView || !frameView->isTrackingPaintInvalidations()) {
+            displayItemClient.setDisplayItemsUncached();
+            return;
+        }
+#endif
         // This is valid because we want to invalidate the client in the display item list of the current backing.
         DisableCompositingQueryAsserts disabler;
         if (const PaintLayer* paintInvalidationLayer = paintingLayer->enclosingLayerForPaintInvalidationCrossingFrameBoundaries())
             paintInvalidationLayer->layoutObject()->invalidateDisplayItemClientOnBacking(displayItemClient, PaintInvalidationFull);
-        paintingLayer->setNeedsRepaint();
     }
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h
index 868a1386..b4f44f69 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -38,6 +38,7 @@
 #include "core/layout/api/HitTestAction.h"
 #include "core/layout/api/SelectionState.h"
 #include "core/layout/compositing/CompositingState.h"
+#include "core/paint/PaintPhase.h"
 #include "core/style/ComputedStyle.h"
 #include "platform/geometry/FloatQuad.h"
 #include "platform/geometry/LayoutRect.h"
diff --git a/third_party/WebKit/Source/core/layout/OWNERS b/third_party/WebKit/Source/core/layout/OWNERS
index 1c1d76b..f092ae9 100644
--- a/third_party/WebKit/Source/core/layout/OWNERS
+++ b/third_party/WebKit/Source/core/layout/OWNERS
@@ -7,7 +7,6 @@
 fmalita@chromium.org
 fs@opera.com
 kouhei@chromium.org
-leviw@chromium.org
 mstensho@opera.com
 ojan@chromium.org
 pdr@chromium.org
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
index 4a038a1..07b5e36 100644
--- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
+++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
@@ -5,6 +5,7 @@
 #include "core/layout/PaintInvalidationState.h"
 
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/layout/LayoutInline.h"
 #include "core/layout/LayoutPart.h"
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index d1e048b..94dc9dc1 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -32,6 +32,7 @@
 #include "core/frame/FrameView.h"
 #include "core/frame/RemoteFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/html/HTMLMediaElement.h"
@@ -2108,10 +2109,10 @@
     ApplyToGraphicsLayers(this, functor, ApplyToContentLayers);
 }
 
-void CompositedLayerMapping::invalidateDisplayItemClient(const DisplayItemClient& displayItemClient, PaintInvalidationReason paintInvalidationReason)
+void CompositedLayerMapping::displayItemClientWasInvalidated(const DisplayItemClient& displayItemClient, PaintInvalidationReason paintInvalidationReason)
 {
     ApplyToGraphicsLayers(this, [&displayItemClient, paintInvalidationReason](GraphicsLayer* layer) {
-        layer->invalidateDisplayItemClient(displayItemClient, paintInvalidationReason);
+        layer->displayItemClientWasInvalidated(displayItemClient, paintInvalidationReason);
     }, ApplyToContentLayers);
 }
 
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
index 591eb627..7a9e6e5 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -129,7 +129,9 @@
     // LayoutRect is in the coordinate space of the layer's layout object.
     void setContentsNeedDisplayInRect(const LayoutRect&, PaintInvalidationReason, const DisplayItemClient&);
 
-    void invalidateDisplayItemClient(const DisplayItemClient&, PaintInvalidationReason);
+    // This is called only if we are tracking paint invalidation for testing, or ENABLE(ASSERT)
+    // for error checking and debugging.
+    void displayItemClientWasInvalidated(const DisplayItemClient&, PaintInvalidationReason);
 
     // Notification from the layoutObject that its content changed.
     void contentChanged(ContentChangeType);
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
index 8a5e5b8a..3f2989f 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -34,6 +34,7 @@
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/html/HTMLVideoElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 6b54a3f2..808d273 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -38,6 +38,7 @@
 #include "core/frame/FrameConsole.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameOwnerElement.h"
diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
index 3be68c3..9eae2d2 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
+++ b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
@@ -36,6 +36,7 @@
 #include "core/fetch/ResourceLoaderOptions.h"
 #include "core/frame/FrameClient.h"
 #include "core/html/LinkResource.h"
+#include "core/loader/FrameLoadRequest.h"
 #include "core/loader/FrameLoaderTypes.h"
 #include "core/loader/NavigationPolicy.h"
 #include "platform/heap/Handle.h"
@@ -53,6 +54,7 @@
 class Document;
 class DocumentLoader;
 class FetchRequest;
+struct FrameLoadRequest;
 class HTMLFormElement;
 class HTMLFrameElementBase;
 class HTMLFrameOwnerElement;
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp
index 0b430f6..82058af 100644
--- a/third_party/WebKit/Source/core/page/Page.cpp
+++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -36,6 +36,7 @@
 #include "core/frame/RemoteFrame.h"
 #include "core/frame/RemoteFrameView.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLMediaElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/layout/TextAutosizer.h"
diff --git a/third_party/WebKit/Source/core/page/PagePopupClient.cpp b/third_party/WebKit/Source/core/page/PagePopupClient.cpp
index fa5553e..1d940799 100644
--- a/third_party/WebKit/Source/core/page/PagePopupClient.cpp
+++ b/third_party/WebKit/Source/core/page/PagePopupClient.cpp
@@ -31,6 +31,7 @@
 #include "core/page/PagePopupClient.h"
 
 #include "core/dom/NodeComputedStyle.h"
+#include "core/frame/LocalFrame.h"
 #include "wtf/text/CharacterNames.h"
 #include "wtf/text/StringBuilder.h"
 
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index efc8861..6c487e3 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -32,6 +32,7 @@
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLElement.h"
 #include "core/layout/LayoutGeometryMap.h"
 #include "core/layout/LayoutPart.h"
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp
index 5175913..b87fd5e 100644
--- a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp
@@ -58,7 +58,7 @@
         newPaintInvalidationRect = scrollControlPaintInvalidationRect(scrollbar->frameRect(), box, paintInvalidationState);
 
     bool needsPaintInvalidation = needsPaintInvalidationArg;
-    if (graphicsLayer) {
+    if (needsPaintInvalidation && graphicsLayer) {
         // If the scrollbar needs paint invalidation but didn't change location/size or the scrollbar is an
         // overlay scrollbar (paint invalidation rect is empty), invalidating the graphics layer is enough
         // (which has been done in ScrollableArea::setScrollbarNeedsPaintInvalidation()).
@@ -66,8 +66,7 @@
         // of the scrollbar on the box's paint invalidation container to ensure newly expanded/shrunk areas
         // of the box to be invalidated.
         needsPaintInvalidation = false;
-
-        graphicsLayer->invalidateDisplayItemClient(*graphicsLayer, PaintInvalidationScroll);
+        DCHECK(!graphicsLayer->drawsContent() || graphicsLayer->getPaintController().cacheIsEmpty());
     }
 
     // Invalidate the box's display item client if the box's padding box size is affected by change of the
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index a19a2d21..1775ac30 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -132,9 +132,8 @@
 {
 }
 
-PaintLayer::PaintLayer(LayoutBoxModelObject* layoutObject, PaintLayerType type)
-    : m_layerType(type)
-    , m_hasSelfPaintingLayerDescendant(false)
+PaintLayer::PaintLayer(LayoutBoxModelObject* layoutObject)
+    : m_hasSelfPaintingLayerDescendant(false)
     , m_hasSelfPaintingLayerDescendantDirty(false)
     , m_isRootLayer(layoutObject->isLayoutView())
     , m_visibleContentStatusDirty(true)
@@ -2444,7 +2443,7 @@
 {
     if (layoutObject()->isLayoutPart() && toLayoutPart(layoutObject())->requiresAcceleratedCompositing())
         return true;
-    return m_layerType == NormalPaintLayer
+    return layoutObject()->layerTypeRequired() == NormalPaintLayer
         || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars())
         || needsCompositedScrolling();
 }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h
index 0d627d0..7df19e2 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -209,7 +209,7 @@
 class CORE_EXPORT PaintLayer : public DisplayItemClient {
     WTF_MAKE_NONCOPYABLE(PaintLayer);
 public:
-    PaintLayer(LayoutBoxModelObject*, PaintLayerType);
+    PaintLayer(LayoutBoxModelObject*);
     ~PaintLayer() override;
 
     // DisplayItemClient methods
@@ -239,8 +239,6 @@
     // FIXME: Many people call this function while it has out-of-date information.
     bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
 
-    void setLayerType(PaintLayerType layerType) { m_layerType = layerType; ASSERT(static_cast<PaintLayerType>(m_layerType) == layerType); }
-
     bool isTransparent() const { return layoutObject()->isTransparent() || layoutObject()->style()->hasBlendMode() || layoutObject()->hasMask(); }
 
     bool isReflection() const { return layoutObject()->isReplica(); }
@@ -786,8 +784,6 @@
         m_needsPaintPhaseDescendantBlockBackgrounds |= layer.m_needsPaintPhaseDescendantBlockBackgrounds;
     }
 
-    unsigned m_layerType : 2; // PaintLayerType
-
     // Self-painting layer is an optimization where we avoid the heavy Layer painting
     // machinery for a Layer allocated only to handle the overflow clip case.
     // FIXME(crbug.com/332791): Self-painting layer should be merged into the overflow-only concept.
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index 122d51d..a175d75 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -5,6 +5,7 @@
 #include "core/paint/PaintPropertyTreeBuilder.h"
 
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/layout/LayoutPart.h"
 #include "core/paint/ObjectPaintProperties.h"
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.cpp
index 8340737..796c69a 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.cpp
@@ -5,6 +5,7 @@
 #include "core/paint/PaintPropertyTreePrinter.h"
 
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/layout/LayoutView.h"
 #include "core/paint/ObjectPaintProperties.h"
 
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamController.h b/third_party/WebKit/Source/core/streams/ReadableStreamController.h
index 647f6c3..21edc0c 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamController.h
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamController.h
@@ -9,7 +9,9 @@
 #include "bindings/core/v8/ScriptValue.h"
 #include "bindings/core/v8/ToV8.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
+#include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/CoreExport.h"
+#include "core/workers/WorkerGlobalScope.h"
 #include "platform/heap/Handle.h"
 #include "wtf/RefPtr.h"
 #include <v8.h>
@@ -43,6 +45,10 @@
 
     void close()
     {
+        if (isTerminating(m_scriptState.get())) {
+            m_jsController.clear();
+            return;
+        }
         ScriptState* scriptState = m_scriptState.get();
         ScriptState::Scope scope(scriptState); // will assert context is valid; do not call this method when the context is invalidated
         v8::Isolate* isolate = scriptState->isolate();
@@ -52,13 +58,17 @@
             return;
 
         v8::Local<v8::Value> args[] = { controller };
-        V8ScriptRunner::callExtraOrCrash(scriptState, "ReadableStreamDefaultControllerClose", args);
-
+        v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "ReadableStreamDefaultControllerClose", args);
         m_jsController.clear();
+        if (isTerminating(m_scriptState.get()))
+            return;
+        v8CallOrCrash(result);
     }
 
     double desiredSize() const
     {
+        if (isTerminating(m_scriptState.get()))
+            return 0;
         ScriptState* scriptState = m_scriptState.get();
         ScriptState::Scope scope(scriptState); // will assert context is valid; do not call this method when the context is invalidated
         v8::Isolate* isolate = scriptState->isolate();
@@ -68,14 +78,18 @@
             return 0;
 
         v8::Local<v8::Value> args[] = { controller };
-        v8::Local<v8::Value> result = V8ScriptRunner::callExtraOrCrash(scriptState, "ReadableStreamDefaultControllerGetDesiredSize", args);
+        v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "ReadableStreamDefaultControllerGetDesiredSize", args);
+        if (isTerminating(m_scriptState.get()))
+            return 0;
 
-        return result.As<v8::Number>()->Value();
+        return v8CallOrCrash(result).As<v8::Number>()->Value();
     }
 
     template <typename ChunkType>
     void enqueue(ChunkType chunk) const
     {
+        if (isTerminating(m_scriptState.get()))
+            return;
         ScriptState* scriptState = m_scriptState.get();
         ScriptState::Scope scope(scriptState); // will assert context is valid; do not call this method when the context is invalidated
         v8::Isolate* isolate = scriptState->isolate();
@@ -86,12 +100,19 @@
 
         v8::Local<v8::Value> jsChunk = toV8(chunk, scriptState);
         v8::Local<v8::Value> args[] = { controller, jsChunk };
-        V8ScriptRunner::callExtraOrCrash(scriptState, "ReadableStreamDefaultControllerEnqueue", args);
+        v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "ReadableStreamDefaultControllerEnqueue", args);
+        if (isTerminating(m_scriptState.get()))
+            return;
+        v8CallOrCrash(result);
     }
 
     template <typename ErrorType>
     void error(ErrorType error)
     {
+        if (isTerminating(m_scriptState.get())) {
+            m_jsController.clear();
+            return;
+        }
         ScriptState* scriptState = m_scriptState.get();
         ScriptState::Scope scope(scriptState); // will assert context is valid; do not call this method when the context is invalidated
         v8::Isolate* isolate = scriptState->isolate();
@@ -102,9 +123,11 @@
 
         v8::Local<v8::Value> jsError = toV8(error, scriptState);
         v8::Local<v8::Value> args[] = { controller, jsError };
-        V8ScriptRunner::callExtraOrCrash(scriptState, "ReadableStreamDefaultControllerError", args);
-
+        v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "ReadableStreamDefaultControllerError", args);
         m_jsController.clear();
+        if (isTerminating(m_scriptState.get()))
+            return;
+        v8CallOrCrash(result);
     }
 
 private:
@@ -113,6 +136,16 @@
         weakInfo.GetParameter()->clear();
     }
 
+    static bool isTerminating(ScriptState* scriptState)
+    {
+        ExecutionContext* executionContext = scriptState->getExecutionContext();
+        if (!executionContext)
+            return true;
+        if (!executionContext->isWorkerGlobalScope())
+            return false;
+        return toWorkerGlobalScope(executionContext)->scriptController()->isExecutionTerminating();
+    }
+
     RefPtr<ScriptState> m_scriptState;
     ScopedPersistent<v8::Value> m_jsController;
 };
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamOperations.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamOperations.cpp
index fa0f282..2a3adfc5 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamOperations.cpp
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamOperations.cpp
@@ -8,34 +8,59 @@
 #include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/ToV8.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
+#include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/streams/UnderlyingSourceBase.h"
+#include "core/workers/WorkerGlobalScope.h"
 
 namespace blink {
 
+namespace {
+
+bool isTerminating(ScriptState* scriptState)
+{
+    ExecutionContext* executionContext = scriptState->getExecutionContext();
+    if (!executionContext)
+        return true;
+    if (!executionContext->isWorkerGlobalScope())
+        return false;
+    return toWorkerGlobalScope(executionContext)->scriptController()->isExecutionTerminating();
+}
+
+} // namespace
+
 ScriptValue ReadableStreamOperations::createReadableStream(ScriptState* scriptState, UnderlyingSourceBase* underlyingSource, ScriptValue strategy)
 {
+    if (isTerminating(scriptState))
+        return ScriptValue();
     ScriptState::Scope scope(scriptState);
 
     v8::Local<v8::Value> jsUnderlyingSource = toV8(underlyingSource, scriptState);
     v8::Local<v8::Value> jsStrategy = strategy.v8Value();
     v8::Local<v8::Value> args[] = { jsUnderlyingSource, jsStrategy };
-    v8::Local<v8::Value> jsStream = V8ScriptRunner::callExtraOrCrash(scriptState, "createReadableStreamWithExternalController", args);
-
-    return ScriptValue(scriptState, jsStream);
+    v8::MaybeLocal<v8::Value> jsStream = V8ScriptRunner::callExtra(scriptState, "createReadableStreamWithExternalController", args);
+    if (isTerminating(scriptState))
+        return ScriptValue();
+    return ScriptValue(scriptState, v8CallOrCrash(jsStream));
 }
 
 ScriptValue ReadableStreamOperations::createCountQueuingStrategy(ScriptState* scriptState, size_t highWaterMark)
 {
+    if (isTerminating(scriptState))
+        return ScriptValue();
     ScriptState::Scope scope(scriptState);
 
     v8::Local<v8::Value> args[] = { v8::Number::New(scriptState->isolate(), highWaterMark) };
-    v8::Local<v8::Value> jsStrategy = V8ScriptRunner::callExtraOrCrash(scriptState, "createBuiltInCountQueuingStrategy", args);
+    v8::MaybeLocal<v8::Value> jsStrategy = V8ScriptRunner::callExtra(scriptState, "createBuiltInCountQueuingStrategy", args);
+    if (isTerminating(scriptState))
+        return ScriptValue();
 
-    return ScriptValue(scriptState, jsStrategy);
+    return ScriptValue(scriptState, v8CallOrCrash(jsStrategy));
 }
 
 ScriptValue ReadableStreamOperations::getReader(ScriptState* scriptState, ScriptValue stream, ExceptionState& es)
 {
+    if (isTerminating(scriptState))
+        return ScriptValue();
     ASSERT(isReadableStream(scriptState, stream));
 
     v8::TryCatch block(scriptState->isolate());
@@ -48,86 +73,140 @@
 
 bool ReadableStreamOperations::isReadableStream(ScriptState* scriptState, ScriptValue value)
 {
+    if (isTerminating(scriptState))
+        return true;
     ASSERT(!value.isEmpty());
 
     if (!value.isObject())
         return false;
 
     v8::Local<v8::Value> args[] = { value.v8Value() };
-    return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStream", args)->ToBoolean()->Value();
+    v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "IsReadableStream", args);
+    if (isTerminating(scriptState))
+        return true;
+    return v8CallOrCrash(result)->ToBoolean()->Value();
 }
 
 bool ReadableStreamOperations::isDisturbed(ScriptState* scriptState, ScriptValue stream)
 {
+    if (isTerminating(scriptState))
+        return true;
     ASSERT(isReadableStream(scriptState, stream));
 
     v8::Local<v8::Value> args[] = { stream.v8Value() };
-    return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamDisturbed", args)->ToBoolean()->Value();
+    v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "IsReadableStreamDisturbed", args);
+    if (isTerminating(scriptState))
+        return true;
+    return v8CallOrCrash(result)->ToBoolean()->Value();
 }
 
 bool ReadableStreamOperations::isLocked(ScriptState* scriptState, ScriptValue stream)
 {
+    if (isTerminating(scriptState))
+        return true;
     ASSERT(isReadableStream(scriptState, stream));
 
     v8::Local<v8::Value> args[] = { stream.v8Value() };
-    return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamLocked", args)->ToBoolean()->Value();
+    v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "IsReadableStreamLocked", args);
+    if (isTerminating(scriptState))
+        return true;
+    return v8CallOrCrash(result)->ToBoolean()->Value();
 }
 
 bool ReadableStreamOperations::isReadable(ScriptState* scriptState, ScriptValue stream)
 {
+    if (isTerminating(scriptState))
+        return false;
     ASSERT(isReadableStream(scriptState, stream));
 
     v8::Local<v8::Value> args[] = { stream.v8Value() };
-    return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamReadable", args)->ToBoolean()->Value();
+    v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamReadable", args);
+    if (isTerminating(scriptState))
+        return false;
+    return v8CallOrCrash(result)->ToBoolean()->Value();
 }
 
 bool ReadableStreamOperations::isClosed(ScriptState* scriptState, ScriptValue stream)
 {
+    if (isTerminating(scriptState))
+        return false;
     ASSERT(isReadableStream(scriptState, stream));
 
     v8::Local<v8::Value> args[] = { stream.v8Value() };
-    return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamClosed", args)->ToBoolean()->Value();
+    v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "IsReadableStreamClosed", args);
+    if (isTerminating(scriptState))
+        return false;
+    return v8CallOrCrash(result)->ToBoolean()->Value();
 }
 
 bool ReadableStreamOperations::isErrored(ScriptState* scriptState, ScriptValue stream)
 {
+    if (isTerminating(scriptState))
+        return true;
     ASSERT(isReadableStream(scriptState, stream));
 
     v8::Local<v8::Value> args[] = { stream.v8Value() };
-    return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamErrored", args)->ToBoolean()->Value();
+    v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "IsReadableStreamErrored", args);
+    if (isTerminating(scriptState))
+        return true;
+    return v8CallOrCrash(result)->ToBoolean()->Value();
 }
 
 bool ReadableStreamOperations::isReadableStreamDefaultReader(ScriptState* scriptState, ScriptValue value)
 {
+    if (isTerminating(scriptState))
+        return true;
     ASSERT(!value.isEmpty());
 
     if (!value.isObject())
         return false;
 
     v8::Local<v8::Value> args[] = { value.v8Value() };
-    return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamDefaultReader", args)->ToBoolean()->Value();
+    v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "IsReadableStreamDefaultReader", args);
+    if (isTerminating(scriptState))
+        return true;
+    return v8CallOrCrash(result)->ToBoolean()->Value();
 }
 
 ScriptPromise ReadableStreamOperations::defaultReaderRead(ScriptState* scriptState, ScriptValue reader)
 {
+    if (isTerminating(scriptState))
+        return ScriptPromise();
     ASSERT(isReadableStreamDefaultReader(scriptState, reader));
 
     v8::Local<v8::Value> args[] = { reader.v8Value() };
-    return ScriptPromise::cast(scriptState, V8ScriptRunner::callExtraOrCrash(scriptState, "ReadableStreamDefaultReaderRead", args));
+    v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callExtra(scriptState, "ReadableStreamDefaultReaderRead", args);
+    if (isTerminating(scriptState))
+        return ScriptPromise();
+    return ScriptPromise::cast(scriptState, v8CallOrCrash(result));
 }
 
 void ReadableStreamOperations::tee(ScriptState* scriptState, ScriptValue stream, ScriptValue* newStream1, ScriptValue* newStream2)
 {
+    if (isTerminating(scriptState))
+        return;
     DCHECK(isReadableStream(scriptState, stream));
     DCHECK(!isLocked(scriptState, stream));
 
     v8::Local<v8::Value> args[] = { stream.v8Value() };
-    ScriptValue result(scriptState, V8ScriptRunner::callExtraOrCrash(scriptState, "ReadableStreamTee", args));
+
+    v8::MaybeLocal<v8::Value> maybeResult = V8ScriptRunner::callExtra(scriptState, "ReadableStreamTee", args);
+    if (isTerminating(scriptState))
+        return;
+    ScriptValue result(scriptState, v8CallOrCrash(maybeResult));
     DCHECK(result.v8Value()->IsArray());
     v8::Local<v8::Array> branches = result.v8Value().As<v8::Array>();
     DCHECK_EQ(2u, branches->Length());
-    *newStream1 = ScriptValue(scriptState, v8CallOrCrash(branches->Get(scriptState->context(), 0)));
-    *newStream2 = ScriptValue(scriptState, v8CallOrCrash(branches->Get(scriptState->context(), 1)));
+
+    v8::MaybeLocal<v8::Value> maybeStream1 = branches->Get(scriptState->context(), 0);
+    if (isTerminating(scriptState))
+        return;
+    v8::MaybeLocal<v8::Value> maybeStream2 = branches->Get(scriptState->context(), 1);
+    if (isTerminating(scriptState))
+        return;
+
+    *newStream1 = ScriptValue(scriptState, v8CallOrCrash(maybeStream1));
+    *newStream2 = ScriptValue(scriptState, v8CallOrCrash(maybeStream2));
 
     DCHECK(isReadableStream(scriptState, *newStream1));
     DCHECK(isReadableStream(scriptState, *newStream2));
diff --git a/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp b/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp
index 07019259..6747c7ee 100644
--- a/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp
+++ b/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp
@@ -35,6 +35,7 @@
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/loader/EmptyClients.h"
 #include "wtf/Assertions.h"
 
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index be3ddf5..b4efe36 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -80,6 +80,7 @@
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLContentElement.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/html/HTMLImageElement.h"
diff --git a/third_party/WebKit/Source/core/testing/NullExecutionContext.h b/third_party/WebKit/Source/core/testing/NullExecutionContext.h
index 3435f05d..10a4500f 100644
--- a/third_party/WebKit/Source/core/testing/NullExecutionContext.h
+++ b/third_party/WebKit/Source/core/testing/NullExecutionContext.h
@@ -5,7 +5,7 @@
 #ifndef NullExecutionContext_h
 #define NullExecutionContext_h
 
-#include "bindings/core/v8/ScriptCallStack.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/SecurityContext.h"
 #include "core/events/EventQueue.h"
@@ -37,7 +37,7 @@
     DOMTimerCoordinator* timers() override { return nullptr; }
 
     void addConsoleMessage(ConsoleMessage*) override { }
-    void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) override { }
+    void logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation>) override { }
 
     void setIsSecureContext(bool);
     bool isSecureContext(String& errorMessage, const SecureContextCheck = StandardSecureContextCheck) const override;
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
index 5204c70..85d1803 100644
--- a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
+++ b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
@@ -52,10 +52,10 @@
 
 namespace {
 
-void processExceptionOnWorkerGlobalScope(int exceptionId, bool handled, ExecutionContext* scriptContext)
+void processUnhandledExceptionOnWorkerGlobalScope(const String& errorMessage, PassOwnPtr<SourceLocation> location, ExecutionContext* scriptContext)
 {
     WorkerGlobalScope* globalScope = toWorkerGlobalScope(scriptContext);
-    globalScope->exceptionHandled(exceptionId, handled);
+    globalScope->exceptionUnhandled(errorMessage, std::move(location));
 }
 
 void processMessageOnWorkerGlobalScope(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels, InProcessWorkerObjectProxy* workerObjectProxy, ExecutionContext* scriptContext)
@@ -158,7 +158,7 @@
     getExecutionContext()->postTask(BLINK_FROM_HERE, std::move(task));
 }
 
-void InProcessWorkerMessagingProxy::reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId)
+void InProcessWorkerMessagingProxy::reportException(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
     DCHECK(isParentContextThread());
     if (!m_workerObject)
@@ -170,9 +170,9 @@
     // because terminated workers no longer deliver messages (section 4.6 of the
     // WebWorker spec), but they do report exceptions.
 
-    ErrorEvent* event = ErrorEvent::create(errorMessage, sourceURL, lineNumber, columnNumber, nullptr);
-    DispatchEventResult dispatchResult = m_workerObject->dispatchEvent(event);
-    postTaskToWorkerGlobalScope(createCrossThreadTask(&processExceptionOnWorkerGlobalScope, exceptionId, dispatchResult != DispatchEventResult::NotCanceled));
+    ErrorEvent* event = ErrorEvent::create(errorMessage, location->url(), location->lineNumber(), location->columnNumber(), nullptr);
+    if (m_workerObject->dispatchEvent(event) == DispatchEventResult::NotCanceled)
+        postTaskToWorkerGlobalScope(createCrossThreadTask(&processUnhandledExceptionOnWorkerGlobalScope, errorMessage, passed(std::move(location))));
 }
 
 void InProcessWorkerMessagingProxy::reportConsoleMessage(MessageSource source, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.h b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.h
index 421f624..d1e0fc0 100644
--- a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.h
+++ b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.h
@@ -67,7 +67,7 @@
     // These methods come from worker context thread via
     // InProcessWorkerObjectProxy and are called on the parent context thread.
     void postMessageToWorkerObject(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>);
-    void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId);
+    void reportException(const String& errorMessage, PassOwnPtr<SourceLocation>);
     void reportConsoleMessage(MessageSource, MessageLevel, const String& message, int lineNumber, const String& sourceURL);
     void postMessageToPageInspector(const String&);
     void postWorkerConsoleAgentEnabled();
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.cpp b/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.cpp
index a2676615b..737024e 100644
--- a/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.cpp
+++ b/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.cpp
@@ -66,9 +66,9 @@
     getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::reportPendingActivity, AllowCrossThreadAccess(m_messagingProxy), hasPendingActivity));
 }
 
-void InProcessWorkerObjectProxy::reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId)
+void InProcessWorkerObjectProxy::reportException(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
-    getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::reportException, AllowCrossThreadAccess(m_messagingProxy), errorMessage, lineNumber, columnNumber, sourceURL, exceptionId));
+    getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::reportException, AllowCrossThreadAccess(m_messagingProxy), errorMessage, passed(std::move(location))));
 }
 
 void InProcessWorkerObjectProxy::reportConsoleMessage(ConsoleMessage* consoleMessage)
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.h b/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.h
index 6265aea3..111f10e 100644
--- a/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.h
+++ b/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.h
@@ -64,7 +64,7 @@
     void reportPendingActivity(bool hasPendingActivity);
 
     // WorkerReportingProxy overrides.
-    void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId) override;
+    void reportException(const String& errorMessage, PassOwnPtr<SourceLocation>) override;
     void reportConsoleMessage(ConsoleMessage*) override;
     void postMessageToPageInspector(const String&) override;
     void postWorkerConsoleAgentEnabled() override;
diff --git a/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp
index ca96bec..b299a80 100644
--- a/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp
@@ -30,7 +30,7 @@
 
 #include "core/workers/SharedWorkerGlobalScope.h"
 
-#include "bindings/core/v8/ScriptCallStack.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "core/events/MessageEvent.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/frame/LocalDOMWindow.h"
@@ -80,10 +80,10 @@
     return static_cast<SharedWorkerThread*>(Base::thread());
 }
 
-void SharedWorkerGlobalScope::logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+void SharedWorkerGlobalScope::logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
-    WorkerGlobalScope::logExceptionToConsole(errorMessage, scriptId, sourceURL, lineNumber, columnNumber, callStack);
-    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, columnNumber, callStack, scriptId);
+    WorkerGlobalScope::logExceptionToConsole(errorMessage, location->clone());
+    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, std::move(location));
     addMessageToWorkerConsole(consoleMessage);
 }
 
diff --git a/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h
index 852ad2a..22bcfb0 100644
--- a/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h
@@ -64,7 +64,7 @@
 
 private:
     SharedWorkerGlobalScope(const String& name, const KURL&, const String& userAgent, SharedWorkerThread*, PassOwnPtr<SecurityOrigin::PrivilegeData>, WorkerClients*);
-    void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) override;
+    void logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation>) override;
 
     String m_name;
 };
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
index 5ec02f10..e1aff2ae 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -29,9 +29,9 @@
 
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/ScheduledAction.h"
-#include "bindings/core/v8/ScriptCallStack.h"
 #include "bindings/core/v8/ScriptSourceCode.h"
 #include "bindings/core/v8/ScriptValue.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8AbstractEventListener.h"
 #include "bindings/core/v8/V8CacheOptions.h"
 #include "core/dom/ActiveDOMObject.h"
@@ -83,7 +83,6 @@
     , m_timers(Platform::current()->currentThread()->scheduler()->timerTaskRunner()->adoptClone())
     , m_timeOrigin(timeOrigin)
     , m_messageStorage(ConsoleMessageStorage::create())
-    , m_workerExceptionUniqueIdentifier(0)
 {
     setSecurityOrigin(SecurityOrigin::create(url));
     if (starterOriginPrivilageData)
@@ -278,13 +277,9 @@
     return this;
 }
 
-void WorkerGlobalScope::logExceptionToConsole(const String& errorMessage, int, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+void WorkerGlobalScope::logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
-    unsigned long exceptionId = ++m_workerExceptionUniqueIdentifier;
-    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, columnNumber, callStack);
-    m_pendingMessages.set(exceptionId, consoleMessage);
-
-    thread()->workerReportingProxy().reportException(errorMessage, lineNumber, columnNumber, sourceURL, exceptionId);
+    thread()->workerReportingProxy().reportException(errorMessage, std::move(location));
 }
 
 void WorkerGlobalScope::reportBlockedScriptExecutionToInspector(const String& directiveText)
@@ -360,11 +355,9 @@
     return m_messageStorage.get();
 }
 
-void WorkerGlobalScope::exceptionHandled(int exceptionId, bool isHandled)
+void WorkerGlobalScope::exceptionUnhandled(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
-    ConsoleMessage* consoleMessage = m_pendingMessages.take(exceptionId);
-    if (!isHandled)
-        addConsoleMessage(consoleMessage);
+    addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, std::move(location)));
 }
 
 bool WorkerGlobalScope::isSecureContext(String& errorMessage, const SecureContextCheck privilegeContextCheck) const
@@ -415,7 +408,6 @@
     visitor->trace(m_workerClients);
     visitor->trace(m_timers);
     visitor->trace(m_messageStorage);
-    visitor->trace(m_pendingMessages);
     visitor->trace(m_eventListeners);
     ExecutionContext::trace(visitor);
     EventTargetWithInlineData::trace(visitor);
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
index 6dd5e43..ff21f438 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -141,7 +141,7 @@
     void addConsoleMessage(ConsoleMessage*) final;
     ConsoleMessageStorage* messageStorage();
 
-    void exceptionHandled(int exceptionId, bool isHandled);
+    void exceptionUnhandled(const String& errorMessage, PassOwnPtr<SourceLocation>);
 
     virtual void scriptLoaded(size_t scriptSize, size_t cachedMetadataSize) { }
 
@@ -156,7 +156,7 @@
     WorkerGlobalScope(const KURL&, const String& userAgent, WorkerThread*, double timeOrigin, PassOwnPtr<SecurityOrigin::PrivilegeData>, WorkerClients*);
     void applyContentSecurityPolicyFromVector(const Vector<CSPHeaderAndType>& headers);
 
-    void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) override;
+    void logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation>) override;
     void addMessageToWorkerConsole(ConsoleMessage*);
     void setV8CacheOptions(V8CacheOptions v8CacheOptions) { m_v8CacheOptions = v8CacheOptions; }
 
@@ -201,8 +201,6 @@
 
     Member<ConsoleMessageStorage> m_messageStorage;
 
-    unsigned long m_workerExceptionUniqueIdentifier;
-    HeapHashMap<unsigned long, Member<ConsoleMessage>> m_pendingMessages;
     HeapListHashSet<Member<V8AbstractEventListener>> m_eventListeners;
 };
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h b/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
index eba4ea3c..ea14f923 100644
--- a/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
+++ b/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
@@ -34,10 +34,12 @@
 #include "core/CoreExport.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Forward.h"
+#include "wtf/PassOwnPtr.h"
 
 namespace blink {
 
 class ConsoleMessage;
+class SourceLocation;
 class WorkerGlobalScope;
 
 // APIs used by workers to report console and worker activity.
@@ -45,7 +47,7 @@
 public:
     virtual ~WorkerReportingProxy() { }
 
-    virtual void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId) = 0;
+    virtual void reportException(const String& errorMessage, PassOwnPtr<SourceLocation>) = 0;
     virtual void reportConsoleMessage(ConsoleMessage*) = 0;
     virtual void postMessageToPageInspector(const String&) = 0;
     virtual void postWorkerConsoleAgentEnabled() = 0;
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index f78e15e..09d432d27 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -76,7 +76,7 @@
 
                 // Dispose WorkerGlobalScope to stop associated ActiveDOMObjects
                 // and close the event queue.
-                m_workerThread->prepareForShutdown();
+                m_workerThread->prepareForShutdownOnWorkerThread();
             }
         }
     }
@@ -99,42 +99,184 @@
     return threads;
 }
 
+WorkerThread::~WorkerThread()
+{
+    MutexLocker lock(threadSetMutex());
+    DCHECK(workerThreads().contains(this));
+    workerThreads().remove(this);
+}
+
+void WorkerThread::start(PassOwnPtr<WorkerThreadStartupData> startupData)
+{
+    DCHECK(isMainThread());
+
+    if (m_started)
+        return;
+
+    m_started = true;
+    workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::initializeOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(startupData))));
+}
+
+void WorkerThread::terminate()
+{
+    DCHECK(isMainThread());
+
+    // Prevent the deadlock between GC and an attempt to terminate a thread.
+    SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
+
+    // Protect against this method, initializeOnWorkerThread() or termination
+    // via the global scope racing each other.
+    MutexLocker lock(m_threadStateMutex);
+
+    // If terminate has already been called, just return.
+    if (m_terminated)
+        return;
+    m_terminated = true;
+
+    // Signal the thread to notify that the thread's stopping.
+    if (m_terminationEvent)
+        m_terminationEvent->signal();
+
+    // If the worker thread was never initialized, don't start another
+    // shutdown, but still wait for the thread to signal when shutdown has
+    // completed on initializeOnWorkerThread().
+    if (!m_workerGlobalScope)
+        return;
+
+    if (!m_readyToShutdown) {
+        // Ensure that tasks are being handled by thread event loop. If script
+        // execution weren't forbidden, a while(1) loop in JS could keep the
+        // thread alive forever.
+        // If |m_readyToShutdown| is set, the worker thread has already noticed
+        // that the thread is about to be terminated and the worker global scope
+        // is already disposed, so we don't have to explicitly terminate the
+        // execution.
+        m_workerGlobalScope->scriptController()->willScheduleExecutionTermination();
+
+        // This condition is not entirely correct because other scripts can
+        // be being initialized or terminated simuletaneously. Though this
+        // function itself is protected by a mutex, it is possible that
+        // |workerScriptCount()| here is not consistent with that in
+        // |initialize| and |shutdown|.
+        if (workerBackingThread().workerScriptCount() == 1) {
+            if (m_runningDebuggerTask) {
+                // Terminating during debugger task may lead to crash due to
+                // heavy use of v8 api in debugger. Any debugger task is
+                // guaranteed to finish, so we can postpone termination after
+                // task has finished.
+                // Note: m_runningDebuggerTask and m_shouldTerminateV8Execution
+                // access must be guarded by the lock.
+                m_shouldTerminateV8Execution = true;
+            } else {
+                // TODO(yhirano): TerminateExecution should be called more
+                // carefully (https://crbug.com/413518).
+                isolate()->TerminateExecution();
+            }
+        }
+    }
+
+    m_inspectorTaskRunner->kill();
+    workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::prepareForShutdownOnWorkerThread, AllowCrossThreadAccess(this)));
+    workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::performShutdownOnWorkerThread, AllowCrossThreadAccess(this)));
+}
+
+void WorkerThread::terminateAndWait()
+{
+    DCHECK(isMainThread());
+    terminate();
+    m_shutdownEvent->wait();
+}
+
+void WorkerThread::terminateAndWaitForAllWorkers()
+{
+    DCHECK(isMainThread());
+
+    // Keep this lock to prevent WorkerThread instances from being destroyed.
+    MutexLocker lock(threadSetMutex());
+    HashSet<WorkerThread*> threads = workerThreads();
+    for (WorkerThread* thread : threads)
+        thread->terminate();
+
+    for (WorkerThread* thread : threads)
+        thread->m_shutdownEvent->wait();
+}
+
+v8::Isolate* WorkerThread::isolate()
+{
+    return workerBackingThread().isolate();
+}
+
+bool WorkerThread::isCurrentThread()
+{
+    return m_started && workerBackingThread().backingThread().isCurrentThread();
+}
+
+void WorkerThread::postTask(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
+{
+    workerBackingThread().backingThread().postTask(location, createWorkerThreadTask(std::move(task), true));
+}
+
+void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task)
+{
+    {
+        MutexLocker lock(m_threadStateMutex);
+        if (m_readyToShutdown)
+            return;
+    }
+    m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task))));
+    {
+        MutexLocker lock(m_threadStateMutex);
+        if (isolate())
+            m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate());
+    }
+    workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::runDebuggerTaskDontWaitOnWorkerThread, AllowCrossThreadAccess(this)));
+}
+
+void WorkerThread::startRunningDebuggerTasksOnPause()
+{
+    m_pausedInDebugger = true;
+    ThreadDebugger::idleStarted(isolate());
+    std::unique_ptr<CrossThreadClosure> task;
+    do {
+        {
+            SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
+            task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::WaitForTask);
+        }
+        if (task)
+            (*task)();
+    // Keep waiting until execution is resumed.
+    } while (task && m_pausedInDebugger);
+    ThreadDebugger::idleFinished(isolate());
+}
+
+void WorkerThread::stopRunningDebuggerTasksOnPause()
+{
+    m_pausedInDebugger = false;
+}
+
+WorkerGlobalScope* WorkerThread::workerGlobalScope()
+{
+    DCHECK(isCurrentThread());
+    return m_workerGlobalScope.get();
+}
+
+bool WorkerThread::terminated()
+{
+    MutexLocker lock(m_threadStateMutex);
+    return m_terminated;
+}
+
 unsigned WorkerThread::workerThreadCount()
 {
     MutexLocker lock(threadSetMutex());
     return workerThreads().size();
 }
 
-void WorkerThread::performTask(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented)
+PlatformThreadId WorkerThread::platformThreadId()
 {
-    DCHECK(isCurrentThread());
-    {
-        MutexLocker lock(m_threadStateMutex);
-        if (m_readyToShutdown)
-            return;
-    }
-
-    WorkerGlobalScope* globalScope = workerGlobalScope();
-    // If the thread is terminated before it had a chance initialize (see
-    // WorkerThread::Initialize()), we mustn't run any of the posted tasks.
-    if (!globalScope) {
-        DCHECK(terminated());
-        return;
-    }
-
-    InspectorInstrumentation::AsyncTask asyncTask(globalScope, task.get(), isInstrumented);
-    task->performTask(globalScope);
-}
-
-std::unique_ptr<CrossThreadClosure> WorkerThread::createWorkerThreadTask(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented)
-{
-    if (isInstrumented)
-        isInstrumented = !task->taskNameForInstrumentation().isEmpty();
-    if (isInstrumented) {
-        DCHECK(isCurrentThread());
-        InspectorInstrumentation::asyncTaskScheduled(workerGlobalScope(), "Worker task", task.get());
-    }
-    return threadSafeBind(&WorkerThread::performTask, AllowCrossThreadAccess(this), passed(std::move(task)), isInstrumented);
+    if (!m_started)
+        return 0;
+    return workerBackingThread().backingThread().platformThread().threadId();
 }
 
 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, WorkerReportingProxy& workerReportingProxy)
@@ -152,32 +294,18 @@
     workerThreads().add(this);
 }
 
-WorkerThread::~WorkerThread()
+std::unique_ptr<CrossThreadClosure> WorkerThread::createWorkerThreadTask(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented)
 {
-    MutexLocker lock(threadSetMutex());
-    DCHECK(workerThreads().contains(this));
-    workerThreads().remove(this);
+    if (isInstrumented)
+        isInstrumented = !task->taskNameForInstrumentation().isEmpty();
+    if (isInstrumented) {
+        DCHECK(isCurrentThread());
+        InspectorInstrumentation::asyncTaskScheduled(workerGlobalScope(), "Worker task", task.get());
+    }
+    return threadSafeBind(&WorkerThread::performTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task)), isInstrumented);
 }
 
-void WorkerThread::start(PassOwnPtr<WorkerThreadStartupData> startupData)
-{
-    DCHECK(isMainThread());
-
-    if (m_started)
-        return;
-
-    m_started = true;
-    workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::initialize, AllowCrossThreadAccess(this), passed(std::move(startupData))));
-}
-
-PlatformThreadId WorkerThread::platformThreadId()
-{
-    if (!m_started)
-        return 0;
-    return workerBackingThread().backingThread().platformThread().threadId();
-}
-
-void WorkerThread::initialize(PassOwnPtr<WorkerThreadStartupData> startupData)
+void WorkerThread::initializeOnWorkerThread(PassOwnPtr<WorkerThreadStartupData> startupData)
 {
     KURL scriptURL = startupData->m_scriptURL;
     String sourceCode = startupData->m_sourceCode;
@@ -238,7 +366,7 @@
     postInitialize();
 }
 
-void WorkerThread::prepareForShutdown()
+void WorkerThread::prepareForShutdownOnWorkerThread()
 {
     DCHECK(isCurrentThread());
     {
@@ -254,7 +382,7 @@
     workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.get());
 }
 
-void WorkerThread::performShutdown()
+void WorkerThread::performShutdownOnWorkerThread()
 {
     DCHECK(isCurrentThread());
 #if DCHECK_IS_ON
@@ -285,142 +413,28 @@
     m_shutdownEvent->signal();
 }
 
-void WorkerThread::terminate()
-{
-    DCHECK(isMainThread());
-
-    // Prevent the deadlock between GC and an attempt to terminate a thread.
-    SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
-
-    // Protect against this method, initialize() or termination via the global
-    // scope racing each other.
-    MutexLocker lock(m_threadStateMutex);
-
-    // If terminate has already been called, just return.
-    if (m_terminated)
-        return;
-    m_terminated = true;
-
-    // Signal the thread to notify that the thread's stopping.
-    if (m_terminationEvent)
-        m_terminationEvent->signal();
-
-    // If the worker thread was never initialized, don't start another
-    // shutdown, but still wait for the thread to signal when shutdown has
-    // completed on initialize().
-    if (!m_workerGlobalScope)
-        return;
-
-    if (!m_readyToShutdown) {
-        // Ensure that tasks are being handled by thread event loop. If script
-        // execution weren't forbidden, a while(1) loop in JS could keep the
-        // thread alive forever.
-        // If |m_readyToShutdown| is set, the worker thread has already noticed
-        // that the thread is about to be terminated and the worker global scope
-        // is already disposed, so we don't have to explicitly terminate the
-        // execution.
-        m_workerGlobalScope->scriptController()->willScheduleExecutionTermination();
-
-        // This condition is not entirely correct because other scripts can
-        // be being initialized or terminated simuletaneously. Though this
-        // function itself is protected by a mutex, it is possible that
-        // |workerScriptCount()| here is not consistent with that in
-        // |initialize| and |shutdown|.
-        if (workerBackingThread().workerScriptCount() == 1) {
-            if (m_runningDebuggerTask) {
-                // Terminating during debugger task may lead to crash due to
-                // heavy use of v8 api in debugger. Any debugger task is
-                // guaranteed to finish, so we can postpone termination after
-                // task has finished.
-                // Note: m_runningDebuggerTask and m_shouldTerminateV8Execution
-                // access must be guarded by the lock.
-                m_shouldTerminateV8Execution = true;
-            } else {
-                // TODO(yhirano): TerminateExecution should be called more
-                // carefully (https://crbug.com/413518).
-                isolate()->TerminateExecution();
-            }
-        }
-    }
-
-    m_inspectorTaskRunner->kill();
-    workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::prepareForShutdown, AllowCrossThreadAccess(this)));
-    workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::performShutdown, AllowCrossThreadAccess(this)));
-}
-
-void WorkerThread::terminateAndWait()
-{
-    DCHECK(isMainThread());
-    terminate();
-    m_shutdownEvent->wait();
-}
-
-void WorkerThread::terminateAndWaitForAllWorkers()
-{
-    DCHECK(isMainThread());
-
-    // Keep this lock to prevent WorkerThread instances from being destroyed.
-    MutexLocker lock(threadSetMutex());
-    HashSet<WorkerThread*> threads = workerThreads();
-    for (WorkerThread* thread : threads)
-        thread->terminate();
-
-    for (WorkerThread* thread : threads)
-        thread->m_shutdownEvent->wait();
-}
-
-WorkerGlobalScope* WorkerThread::workerGlobalScope()
+void WorkerThread::performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented)
 {
     DCHECK(isCurrentThread());
-    return m_workerGlobalScope.get();
-}
-
-bool WorkerThread::terminated()
-{
-    MutexLocker lock(m_threadStateMutex);
-    return m_terminated;
-}
-
-v8::Isolate* WorkerThread::isolate()
-{
-    return workerBackingThread().isolate();
-}
-
-bool WorkerThread::isCurrentThread()
-{
-    return m_started && workerBackingThread().backingThread().isCurrentThread();
-}
-
-void WorkerThread::postTask(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
-{
-    workerBackingThread().backingThread().postTask(location, createWorkerThreadTask(std::move(task), true));
-}
-
-void WorkerThread::runDebuggerTaskDontWait()
-{
-    DCHECK(isCurrentThread());
-    std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::DontWaitForTask);
-    if (task)
-        (*task)();
-}
-
-void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task)
-{
     {
         MutexLocker lock(m_threadStateMutex);
         if (m_readyToShutdown)
             return;
     }
-    m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerTask, AllowCrossThreadAccess(this), passed(std::move(task))));
-    {
-        MutexLocker lock(m_threadStateMutex);
-        if (isolate())
-            m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate());
+
+    WorkerGlobalScope* globalScope = workerGlobalScope();
+    // If the thread is terminated before it had a chance initialize (see
+    // WorkerThread::Initialize()), we mustn't run any of the posted tasks.
+    if (!globalScope) {
+        DCHECK(terminated());
+        return;
     }
-    workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::runDebuggerTaskDontWait, AllowCrossThreadAccess(this)));
+
+    InspectorInstrumentation::AsyncTask asyncTask(globalScope, task.get(), isInstrumented);
+    task->performTask(globalScope);
 }
 
-void WorkerThread::runDebuggerTask(std::unique_ptr<CrossThreadClosure> task)
+void WorkerThread::runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure> task)
 {
     DCHECK(isCurrentThread());
     InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get());
@@ -441,26 +455,12 @@
     }
 }
 
-void WorkerThread::startRunningDebuggerTasksOnPause()
+void WorkerThread::runDebuggerTaskDontWaitOnWorkerThread()
 {
-    m_pausedInDebugger = true;
-    ThreadDebugger::idleStarted(isolate());
-    std::unique_ptr<CrossThreadClosure> task;
-    do {
-        {
-            SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
-            task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::WaitForTask);
-        }
-        if (task)
-            (*task)();
-    // Keep waiting until execution is resumed.
-    } while (task && m_pausedInDebugger);
-    ThreadDebugger::idleFinished(isolate());
-}
-
-void WorkerThread::stopRunningDebuggerTasksOnPause()
-{
-    m_pausedInDebugger = false;
+    DCHECK(isCurrentThread());
+    std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::DontWaitForTask);
+    if (task)
+        (*task)();
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.h b/third_party/WebKit/Source/core/workers/WorkerThread.h
index a8b118f2..f6ac76aa 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.h
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.h
@@ -84,6 +84,7 @@
     WaitableEvent* terminationEvent() { return m_terminationEvent.get(); }
 
     bool isCurrentThread();
+
     WorkerLoaderProxy* workerLoaderProxy() const
     {
         RELEASE_ASSERT(m_workerLoaderProxy);
@@ -128,13 +129,12 @@
 
     std::unique_ptr<CrossThreadClosure> createWorkerThreadTask(std::unique_ptr<ExecutionContextTask>, bool isInstrumented);
 
-    // Called on the worker thread.
-    void initialize(PassOwnPtr<WorkerThreadStartupData>);
-    void performTask(std::unique_ptr<ExecutionContextTask>, bool isInstrumented);
-    void prepareForShutdown();
-    void performShutdown();
-    void runDebuggerTask(std::unique_ptr<CrossThreadClosure>);
-    void runDebuggerTaskDontWait();
+    void initializeOnWorkerThread(PassOwnPtr<WorkerThreadStartupData>);
+    void prepareForShutdownOnWorkerThread();
+    void performShutdownOnWorkerThread();
+    void performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTask>, bool isInstrumented);
+    void runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure>);
+    void runDebuggerTaskDontWaitOnWorkerThread();
 
     bool m_started = false;
     bool m_terminated = false;
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h b/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
index d223537..b64dc471 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
+++ b/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "bindings/core/v8/ScriptCallStack.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8CacheOptions.h"
 #include "bindings/core/v8/V8GCController.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
@@ -53,7 +53,11 @@
     MockWorkerReportingProxy() { }
     ~MockWorkerReportingProxy() override { }
 
-    MOCK_METHOD5(reportException, void(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId));
+    MOCK_METHOD2(reportExceptionMock, void(const String& errorMessage, SourceLocation*));
+    void reportException(const String& errorMessage, PassOwnPtr<SourceLocation> location)
+    {
+        reportExceptionMock(errorMessage, location.get());
+    }
     MOCK_METHOD1(reportConsoleMessage, void(ConsoleMessage*));
     MOCK_METHOD1(postMessageToPageInspector, void(const String&));
     MOCK_METHOD0(postWorkerConsoleAgentEnabled, void());
@@ -148,7 +152,7 @@
         return EventTargetNames::DedicatedWorkerGlobalScope;
     }
 
-    void logExceptionToConsole(const String&, int, const String&, int, int, PassRefPtr<ScriptCallStack>) override
+    void logExceptionToConsole(const String&, PassOwnPtr<SourceLocation>) override
     {
     }
 
diff --git a/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp b/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp
index 839f09e6..f120f51 100644
--- a/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp
+++ b/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp
@@ -979,7 +979,7 @@
     m_sawFirstElement = true;
 
     QualifiedName qName(prefix, localName, adjustedURI);
-    Element* newElement = m_currentNode->document().createElement(qName, true);
+    Element* newElement = m_currentNode->document().createElement(qName, CreatedByParser);
     if (!newElement) {
         stopParsing();
         return;
diff --git a/third_party/WebKit/Source/core/xml/parser/XMLErrors.cpp b/third_party/WebKit/Source/core/xml/parser/XMLErrors.cpp
index 1c3c9c80..36c1b224 100644
--- a/third_party/WebKit/Source/core/xml/parser/XMLErrors.cpp
+++ b/third_party/WebKit/Source/core/xml/parser/XMLErrors.cpp
@@ -90,17 +90,17 @@
 
 static inline Element* createXHTMLParserErrorHeader(Document* doc, const String& errorMessages)
 {
-    Element* reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), true);
+    Element* reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), CreatedByParser);
 
     Vector<Attribute> reportAttributes;
     reportAttributes.append(Attribute(styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black"));
     reportElement->parserSetAttributes(reportAttributes);
 
-    Element* h3 = doc->createElement(h3Tag, true);
+    Element* h3 = doc->createElement(h3Tag, CreatedByParser);
     reportElement->parserAppendChild(h3);
     h3->parserAppendChild(doc->createTextNode("This page contains the following errors:"));
 
-    Element* fixed = doc->createElement(divTag, true);
+    Element* fixed = doc->createElement(divTag, CreatedByParser);
     Vector<Attribute> fixedAttributes;
     fixedAttributes.append(Attribute(styleAttr, "font-family:monospace;font-size:12px"));
     fixed->parserSetAttributes(fixedAttributes);
@@ -108,7 +108,7 @@
 
     fixed->parserAppendChild(doc->createTextNode(errorMessages));
 
-    h3 = doc->createElement(h3Tag, true);
+    h3 = doc->createElement(h3Tag, CreatedByParser);
     reportElement->parserAppendChild(h3);
     h3->parserAppendChild(doc->createTextNode("Below is a rendering of the page up to the first error."));
 
@@ -124,20 +124,20 @@
     // Create elements for display
     Element* documentElement = m_document->documentElement();
     if (!documentElement) {
-        Element* rootElement = m_document->createElement(htmlTag, true);
-        Element* body = m_document->createElement(bodyTag, true);
+        Element* rootElement = m_document->createElement(htmlTag, CreatedByParser);
+        Element* body = m_document->createElement(bodyTag, CreatedByParser);
         rootElement->parserAppendChild(body);
         m_document->parserAppendChild(rootElement);
         documentElement = body;
     } else if (documentElement->namespaceURI() == SVGNames::svgNamespaceURI) {
-        Element* rootElement = m_document->createElement(htmlTag, true);
-        Element* head = m_document->createElement(headTag, true);
-        Element* style = m_document->createElement(styleTag, true);
+        Element* rootElement = m_document->createElement(htmlTag, CreatedByParser);
+        Element* head = m_document->createElement(headTag, CreatedByParser);
+        Element* style = m_document->createElement(styleTag, CreatedByParser);
         head->parserAppendChild(style);
         style->parserAppendChild(m_document->createTextNode("html, body { height: 100% } parsererror + svg { width: 100%; height: 100% }"));
         style->finishParsingChildren();
         rootElement->parserAppendChild(head);
-        Element* body = m_document->createElement(bodyTag, true);
+        Element* body = m_document->createElement(bodyTag, CreatedByParser);
         rootElement->parserAppendChild(body);
 
         m_document->parserRemoveChild(*documentElement);
@@ -154,7 +154,7 @@
     if (DocumentXSLT::hasTransformSourceDocument(*m_document)) {
         Vector<Attribute> attributes;
         attributes.append(Attribute(styleAttr, "white-space: normal"));
-        Element* paragraph = m_document->createElement(pTag, true);
+        Element* paragraph = m_document->createElement(pTag, CreatedByParser);
         paragraph->parserSetAttributes(attributes);
         paragraph->parserAppendChild(m_document->createTextNode("This document was created as the result of an XSL transformation. The line and column numbers given are from the transformed result."));
         reportElement->parserAppendChild(paragraph);
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
index b0112b2..ebc7cf9 100644
--- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
+++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -650,7 +650,7 @@
 
 void XMLHttpRequest::send(const ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormData& body, ExceptionState& exceptionState)
 {
-    InspectorInstrumentation::willSendXMLHttpRequest(getExecutionContext(), url());
+    InspectorInstrumentation::willSendXMLHttpOrFetchNetworkRequest(getExecutionContext(), url());
 
     if (body.isNull()) {
         send(String(), exceptionState);
diff --git a/third_party/WebKit/Source/devtools/front_end/.eslintrc.js b/third_party/WebKit/Source/devtools/front_end/.eslintrc.js
index 8ea48893..13becdf 100644
--- a/third_party/WebKit/Source/devtools/front_end/.eslintrc.js
+++ b/third_party/WebKit/Source/devtools/front_end/.eslintrc.js
@@ -30,6 +30,7 @@
         "spaced-comment": [2, "always", {
             "markers": ["*"]
         }],
+        "eqeqeq": [2],
         "arrow-body-style": [2, "as-needed"],
         "accessor-pairs": [2, {
             "getWithoutSet": false,
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
index 1d6e2d9..a5619277 100644
--- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
+++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
@@ -258,7 +258,7 @@
 
         var propertiesArray = /** @type {!Array.<!AccessibilityAgent.AXProperty> } */ (axNode.properties);
         for (var property of propertiesArray) {
-            if (property.name == AccessibilityAgent.AXWidgetAttributes.Valuetext) {
+            if (property.name === AccessibilityAgent.AXWidgetAttributes.Valuetext) {
                 addProperty(property);
                 break;
             }
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js
index 7f8dc91..972463000 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js
@@ -385,9 +385,9 @@
     _updateNodeStyle: function(duration, delay, node)
     {
         var animationPrefix;
-        if (this.type() == WebInspector.AnimationModel.Animation.Type.CSSTransition)
+        if (this.type() === WebInspector.AnimationModel.Animation.Type.CSSTransition)
             animationPrefix = "transition-";
-        else if (this.type() == WebInspector.AnimationModel.Animation.Type.CSSAnimation)
+        else if (this.type() === WebInspector.AnimationModel.Animation.Type.CSSAnimation)
             animationPrefix = "animation-";
         else
             return;
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
index 2cb854c..cdaaf902 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
@@ -305,7 +305,7 @@
      */
     _mouseDown: function(mouseEventType, keyframeIndex, event)
     {
-        if (event.buttons == 2)
+        if (event.buttons === 2)
             return false;
         if (this._svg.enclosingNodeOrSelfWithClass("animation-node-removed"))
             return false;
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Geometry.js b/third_party/WebKit/Source/devtools/front_end/common/Geometry.js
index 20a0525..720c687f 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/Geometry.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/Geometry.js
@@ -125,7 +125,7 @@
 {
     var keywordValues = WebInspector.Geometry.CubicBezier.KeywordValues;
     var value = text.toLowerCase().replace(/\s+/g, "");
-    if (Object.keys(keywordValues).indexOf(value) != -1)
+    if (Object.keys(keywordValues).indexOf(value) !== -1)
         return WebInspector.Geometry.CubicBezier.parse(keywordValues[value]);
     var bezierRegex = /^cubic-bezier\(([^,]+),([^,]+),([^,]+),([^,]+)\)$/;
     var match = value.match(bezierRegex);
@@ -406,7 +406,7 @@
      */
     isEqual: function(insets)
     {
-        return !!insets && this.left === insets.left && this.top === insets.top && this.right == insets.right && this.bottom == insets.bottom;
+        return !!insets && this.left === insets.left && this.top === insets.top && this.right === insets.right && this.bottom === insets.bottom;
     }
 }
 
@@ -433,7 +433,7 @@
      */
     isEqual: function(rect)
     {
-        return !!rect && this.left === rect.left && this.top === rect.top && this.width == rect.width && this.height == rect.height;
+        return !!rect && this.left === rect.left && this.top === rect.top && this.width === rect.width && this.height === rect.height;
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/common/TextRange.js b/third_party/WebKit/Source/devtools/front_end/common/TextRange.js
index e411b615..3be2be8 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/TextRange.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/TextRange.js
@@ -219,9 +219,9 @@
     {
         var relative = this.clone();
 
-        if (this.startLine == line)
+        if (this.startLine === line)
             relative.startColumn -= column;
-        if (this.endLine == line)
+        if (this.endLine === line)
             relative.endColumn -= column;
 
         relative.startLine -= line;
diff --git a/third_party/WebKit/Source/devtools/front_end/components/CustomPreviewSection.js b/third_party/WebKit/Source/devtools/front_end/components/CustomPreviewSection.js
index 0a6649c2..43cd3d1 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/CustomPreviewSection.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/CustomPreviewSection.js
@@ -116,7 +116,7 @@
             return createElement("span");
         }
         var element = createElement(/** @type {string} */ (tagName));
-        if ((typeof object[0] == "object") && !Array.isArray(object[0])) {
+        if ((typeof object[0] === "object") && !Array.isArray(object[0])) {
             var attributes = object.shift();
             for (var key in attributes) {
                 var value = attributes[key];
diff --git a/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js
index 59acb277..6c1fa04 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js
@@ -438,7 +438,7 @@
 
     onContentReady: function()
     {
-        for (var i = 0; i != this._proxies.length; i++)
+        for (var i = 0; i < this._proxies.length; i++)
             this._proxies[i].onContentReady();
     },
 
diff --git a/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js b/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js
index def99d1..2b1cc22 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js
@@ -586,7 +586,7 @@
 
         if (internalProperties) {
             for (var i = 0; i < internalProperties.length; i++) {
-                if (internalProperties[i].name == "[[TargetFunction]]") {
+                if (internalProperties[i].name === "[[TargetFunction]]") {
                     hasTargetFunction = true;
                     break;
                 }
@@ -936,14 +936,14 @@
         if (!result)
             return;
         var ranges = /** @type {!Array.<!Array.<number>>} */ (result.ranges);
-        if (ranges.length == 1) {
+        if (ranges.length === 1) {
             WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeNode, object, ranges[0][0], ranges[0][1]);
         } else {
             for (var i = 0; i < ranges.length; ++i) {
                 var fromIndex = ranges[i][0];
                 var toIndex = ranges[i][1];
                 var count = ranges[i][2];
-                if (fromIndex == toIndex)
+                if (fromIndex === toIndex)
                     WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeNode, object, fromIndex, toIndex);
                 else
                     treeNode.appendChild(new WebInspector.ArrayGroupingTreeElement(object, fromIndex, toIndex, count));
diff --git a/third_party/WebKit/Source/devtools/front_end/components/RemoteObjectPreviewFormatter.js b/third_party/WebKit/Source/devtools/front_end/components/RemoteObjectPreviewFormatter.js
index da9ea14..8121eac3 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/RemoteObjectPreviewFormatter.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/RemoteObjectPreviewFormatter.js
@@ -87,7 +87,7 @@
 
             var property = properties[i];
             var name = property.name;
-            if (!isArray || name != i || i >= arrayLength) {
+            if (!isArray || name !== String(i) || i >= arrayLength) {
                 if (/^\s|\s$|^$|\n/.test(name))
                     parentElement.createChild("span", "name").createTextChildren("\"", name.replace(/\n/g, "\u21B5"), "\"");
                 else
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
index a94f6bf7..a3ac3f8 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
+++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
@@ -555,7 +555,7 @@
             const maxColumnsToRender = 20;
             for (var j = 0; j < rowPreview.properties.length; ++j) {
                 var cellProperty = rowPreview.properties[j];
-                var columnRendered = columnNames.indexOf(cellProperty.name) != -1;
+                var columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
                 if (!columnRendered) {
                     if (columnNames.length === maxColumnsToRender)
                         continue;
@@ -1284,7 +1284,7 @@
             start = links[i].positionRight;
         }
 
-        if (start != string.length)
+        if (start !== string.length)
             formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start)));
 
         return formattedResult;
diff --git a/third_party/WebKit/Source/devtools/front_end/devtools.js b/third_party/WebKit/Source/devtools/front_end/devtools.js
index f9c05b2c..63bc72f2 100644
--- a/third_party/WebKit/Source/devtools/front_end/devtools.js
+++ b/third_party/WebKit/Source/devtools/front_end/devtools.js
@@ -998,6 +998,7 @@
     function getValue(property)
     {
         // Note that |property| comes from another context, so we can't use === here.
+        // eslint-disable-next-line eqeqeq
         if (property == "padding-left") {
             return {
                 /**
@@ -1011,7 +1012,7 @@
         throw new Error("getPropertyCSSValue is undefined");
     }
 
-    // Support for legacy (<M41) frontends. Remove in M45.
+    // Support for legacy (<M41) frontends.
     window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue;
 
     function CSSPrimitiveValue()
@@ -1020,7 +1021,7 @@
     CSSPrimitiveValue.CSS_PX = 5;
     window.CSSPrimitiveValue = CSSPrimitiveValue;
 
-    // Support for legacy (<M44) frontends. Remove in M48.
+    // Support for legacy (<M44) frontends.
     var styleElement = window.document.createElement("style");
     styleElement.type = "text/css";
     styleElement.textContent = "html /deep/ * { min-width: 0; min-height: 0; }";
@@ -1031,7 +1032,7 @@
     styleElement.textContent += "\nhtml /deep/ .cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber { border-style: solid !important; }";
     window.document.head.appendChild(styleElement);
 
-    // Support for legacy (<M49) frontends. Remove in M52.
+    // Support for legacy (<M49) frontends.
     Event.prototype.deepPath = undefined;
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js
index 18f351b2..c088cd2 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js
@@ -307,7 +307,7 @@
                 // with a tie going to child crumbs.
                 var startIndex = 0;
                 var endIndex = crumbs.childNodes.length - 1;
-                while (startIndex != significantIndex || endIndex != significantIndex) {
+                while (startIndex !== significantIndex || endIndex !== significantIndex) {
                     var startDistance = significantIndex - startIndex;
                     var endDistance = endIndex - significantIndex;
                     if (startDistance >= endDistance)
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
index 2d18fb15..8dd2da6 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -389,7 +389,7 @@
             var executionContexts = selectedNode.target().runtimeModel.executionContexts();
             var nodeFrameId = selectedNode.frameId();
             for (var context of executionContexts) {
-                if (context.frameId == nodeFrameId) {
+                if (context.frameId === nodeFrameId) {
                     WebInspector.context.setFlavor(WebInspector.ExecutionContext, context);
                     break;
                 }
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js
index 5c27d6a1..15a6a60 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js
@@ -46,7 +46,7 @@
 
     this._elementCloseTag = elementCloseTag;
 
-    if (this._node.nodeType() == Node.ELEMENT_NODE && !elementCloseTag)
+    if (this._node.nodeType() === Node.ELEMENT_NODE && !elementCloseTag)
         this._canAddAttributes = true;
     this._searchQuery = null;
     this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit;
@@ -464,10 +464,10 @@
      */
     _startEditingTarget: function(eventTarget)
     {
-        if (this.treeOutline.selectedDOMNode() != this._node)
+        if (this.treeOutline.selectedDOMNode() !== this._node)
             return false;
 
-        if (this._node.nodeType() != Node.ELEMENT_NODE && this._node.nodeType() != Node.TEXT_NODE)
+        if (this._node.nodeType() !== Node.ELEMENT_NODE && this._node.nodeType() !== Node.TEXT_NODE)
             return false;
 
         var textNode = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-text-node");
@@ -1085,7 +1085,7 @@
     {
         var treeElement = this.parent;
         var depth = 0;
-        while (treeElement != null) {
+        while (treeElement !== null) {
             depth++;
             treeElement = treeElement.parent;
         }
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js b/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js
index 0ae03f13..8252f02b 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js
@@ -134,8 +134,8 @@
     _showFrameworkListenersChanged: function()
     {
         var dispatchFilter = this._dispatchFilterBySetting.get();
-        var showPassive = dispatchFilter == WebInspector.EventListenersWidget.DispatchFilterBy.All || dispatchFilter == WebInspector.EventListenersWidget.DispatchFilterBy.Passive;
-        var showBlocking = dispatchFilter == WebInspector.EventListenersWidget.DispatchFilterBy.All || dispatchFilter == WebInspector.EventListenersWidget.DispatchFilterBy.Blocking;
+        var showPassive = dispatchFilter === WebInspector.EventListenersWidget.DispatchFilterBy.All || dispatchFilter === WebInspector.EventListenersWidget.DispatchFilterBy.Passive;
+        var showBlocking = dispatchFilter === WebInspector.EventListenersWidget.DispatchFilterBy.All || dispatchFilter === WebInspector.EventListenersWidget.DispatchFilterBy.Blocking;
         this._eventListenersView.showFrameworkListeners(this._showFrameworkListenersSetting.get(), showPassive, showBlocking);
     },
 
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js b/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js
index ad2adce..fd43e8c 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js
@@ -773,7 +773,7 @@
             var v = lastV;
             v = lastV + currentSlope * dS;
 
-            v = approach(V, v, s == 0);
+            v = approach(V, v, s === 0);
             if (v === null)
                 break;
 
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
index a23780a9..f8c11cf8 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
@@ -453,7 +453,7 @@
                 this._appliedUserAgentType = this._device.touch() ? WebInspector.DeviceModeModel.UA.Mobile : WebInspector.DeviceModeModel.UA.MobileNoTouch;
             else
                 this._appliedUserAgentType = this._device.touch() ? WebInspector.DeviceModeModel.UA.DesktopTouch : WebInspector.DeviceModeModel.UA.Desktop;
-            this._applyDeviceMetrics(new Size(orientation.width, orientation.height), this._mode.insets, outline, this._scaleSetting.get(), this._device.deviceScaleFactor, this._device.mobile(), this._mode.orientation == WebInspector.EmulatedDevice.Horizontal ? "landscapePrimary" : "portraitPrimary", resetPageScaleFactor);
+            this._applyDeviceMetrics(new Size(orientation.width, orientation.height), this._mode.insets, outline, this._scaleSetting.get(), this._device.deviceScaleFactor, this._device.mobile(), this._mode.orientation === WebInspector.EmulatedDevice.Horizontal ? "landscapePrimary" : "portraitPrimary", resetPageScaleFactor);
             this._applyUserAgent(this._device.userAgent);
             this._applyTouch(this._device.touch(), this._device.mobile());
         } else if (this._type === WebInspector.DeviceModeModel.Type.None) {
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/MediaQueryInspector.js b/third_party/WebKit/Source/devtools/front_end/emulation/MediaQueryInspector.js
index 9ee96a8d..9dd1fa97 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/MediaQueryInspector.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/MediaQueryInspector.js
@@ -196,7 +196,7 @@
         queryModels.sort(compareModels);
         queryModels = this._squashAdjacentEqual(queryModels);
 
-        var allEqual = this._cachedQueryModels && this._cachedQueryModels.length == queryModels.length;
+        var allEqual = this._cachedQueryModels && this._cachedQueryModels.length === queryModels.length;
         for (var i = 0; allEqual && i < queryModels.length; ++i)
             allEqual = allEqual && this._cachedQueryModels[i].equals(queryModels[i]);
         if (allEqual)
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/SensorsView.js b/third_party/WebKit/Source/devtools/front_end/emulation/SensorsView.js
index 1ed0f00..2228ea13 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/SensorsView.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/SensorsView.js
@@ -256,7 +256,7 @@
             return Math.round(angle * 10000) / 10000;
         }
 
-        if (modificationSource != WebInspector.SensorsView.DeviceOrientationModificationSource.UserInput) {
+        if (modificationSource !== WebInspector.SensorsView.DeviceOrientationModificationSource.UserInput) {
             this._alphaSetter(roundAngle(deviceOrientation.alpha));
             this._betaSetter(roundAngle(deviceOrientation.beta));
             this._gammaSetter(roundAngle(deviceOrientation.gamma));
diff --git a/third_party/WebKit/Source/devtools/front_end/formatter_worker/JavaScriptFormatter.js b/third_party/WebKit/Source/devtools/front_end/formatter_worker/JavaScriptFormatter.js
index 6a61ddc..ae9a5de 100644
--- a/third_party/WebKit/Source/devtools/front_end/formatter_worker/JavaScriptFormatter.js
+++ b/third_party/WebKit/Source/devtools/front_end/formatter_worker/JavaScriptFormatter.js
@@ -281,7 +281,7 @@
                 return "";
             if (node.parent && node.parent.type === "DoWhileStatement")
                 return "";
-            if (node.parent && node.parent.type === "TryStatement" && node.parent.block == node)
+            if (node.parent && node.parent.type === "TryStatement" && node.parent.block === node)
                 return "s";
             if (node.parent && node.parent.type === "CatchClause" && node.parent.parent.finalizer)
                 return "s";
diff --git a/third_party/WebKit/Source/devtools/front_end/heap_snapshot_worker/AllocationProfile.js b/third_party/WebKit/Source/devtools/front_end/heap_snapshot_worker/AllocationProfile.js
index 19b9e076..0dfc4e7 100644
--- a/third_party/WebKit/Source/devtools/front_end/heap_snapshot_worker/AllocationProfile.js
+++ b/third_party/WebKit/Source/devtools/front_end/heap_snapshot_worker/AllocationProfile.js
@@ -131,7 +131,7 @@
             if (info.totalCount === 0)
                 continue;
             var nodeId = this._nextNodeId++;
-            var isRoot = i == 0;
+            var isRoot = i === 0;
             result.push(this._serializeNode(
                 nodeId,
                 info,
diff --git a/third_party/WebKit/Source/devtools/front_end/network/FilterSuggestionBuilder.js b/third_party/WebKit/Source/devtools/front_end/network/FilterSuggestionBuilder.js
index 700b0ca1..d80ad3a 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/FilterSuggestionBuilder.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/FilterSuggestionBuilder.js
@@ -53,7 +53,7 @@
     {
         var text = input.value;
         var end = input.selectionEnd;
-        if (end != text.length)
+        if (end !== text.length)
             return null;
 
         var start = input.selectionStart;
@@ -189,7 +189,7 @@
             var negative = key.startsWith("-");
             if (negative)
                 key = key.substring(1);
-            if (this._keys.indexOf(key) == -1) {
+            if (this._keys.indexOf(key) === -1) {
                 text.push(part);
                 continue;
             }
diff --git a/third_party/WebKit/Source/devtools/front_end/network/JSONView.js b/third_party/WebKit/Source/devtools/front_end/network/JSONView.js
index 8c7c396d..32b2e82 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/JSONView.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/JSONView.js
@@ -133,7 +133,7 @@
     var start = text.indexOf(open);
     var end = text.lastIndexOf(close);
     var length = end - start - 1;
-    if (start == -1 || end == -1 || end < start)
+    if (start === -1 || end === -1 || end < start)
         length = -1;
     return {start: start, end: end, length: length};
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
index 1eadb6e..fe5f0dcd 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
@@ -56,7 +56,7 @@
         var resourceType = this._request.resourceType();
         var simpleType = resourceType.name();
 
-        if (resourceType == WebInspector.resourceTypes.Other || resourceType == WebInspector.resourceTypes.Image)
+        if (resourceType === WebInspector.resourceTypes.Other || resourceType === WebInspector.resourceTypes.Image)
             simpleType = mimeType.replace(/^(application|image)\//, "");
 
         return simpleType;
@@ -528,7 +528,7 @@
         if (labelAfter && (graphElementOffsetWidth * ((100 - this._percentages.end) / 100)) < (labelRightElementOffsetWidth + 10))
             var rightHidden = true;
 
-        if (barLeftElementOffsetWidth == barRightElementOffsetWidth) {
+        if (barLeftElementOffsetWidth === barRightElementOffsetWidth) {
             // The left/right label data are the same, so a before/after label can be replaced by an on-bar label.
             if (labelBefore && !labelAfter)
                 leftHidden = true;
@@ -718,7 +718,7 @@
 {
     var aValue = a._request[propertyName];
     var bValue = b._request[propertyName];
-    if (aValue == bValue)
+    if (aValue === bValue)
         return a._request.indentityCompare(b._request);
     return aValue > bValue ? 1 : -1;
 }
@@ -746,7 +746,7 @@
 {
     var aValue = (a._request.responseHeaderValue(propertyName) !== undefined) ? parseFloat(a._request.responseHeaderValue(propertyName)) : -Infinity;
     var bValue = (b._request.responseHeaderValue(propertyName) !== undefined) ? parseFloat(b._request.responseHeaderValue(propertyName)) : -Infinity;
-    if (aValue == bValue)
+    if (aValue === bValue)
         return a._request.indentityCompare(b._request);
     return aValue > bValue ? 1 : -1;
 }
@@ -763,7 +763,7 @@
     var bHeader = b._request.responseHeaderValue(propertyName);
     var aValue = aHeader ? new Date(aHeader).getTime() : -Infinity;
     var bValue = bHeader ? new Date(bHeader).getTime() : -Infinity;
-    if (aValue == bValue)
+    if (aValue === bValue)
         return a._request.indentityCompare(b._request);
     return aValue > bValue ? 1 : -1;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/platform/utilities.js b/third_party/WebKit/Source/devtools/front_end/platform/utilities.js
index 7099804..6e28f97 100644
--- a/third_party/WebKit/Source/devtools/front_end/platform/utilities.js
+++ b/third_party/WebKit/Source/devtools/front_end/platform/utilities.js
@@ -257,7 +257,7 @@
 String.prototype.removeURLFragment = function()
 {
     var fragmentIndex = this.indexOf("#");
-    if (fragmentIndex == -1)
+    if (fragmentIndex === -1)
         fragmentIndex = this.length;
     return this.substring(0, fragmentIndex);
 }
@@ -1174,7 +1174,7 @@
     var regex = "";
     for (var i = 0; i < query.length; ++i) {
         var c = query.charAt(i);
-        if (regexSpecialCharacters.indexOf(c) != -1)
+        if (regexSpecialCharacters.indexOf(c) !== -1)
             regex += "\\";
         regex += c;
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileDataGrid.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileDataGrid.js
index 51ba6d8..69ac9c8f 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileDataGrid.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileDataGrid.js
@@ -446,9 +446,9 @@
                 }
 
                 if (equalTo) {
-                    if (profileDataGridNode.selfPercent == queryNumber)
+                    if (profileDataGridNode.selfPercent === queryNumber)
                         profileDataGridNode._searchMatchedSelfColumn = true;
-                    if (profileDataGridNode.totalPercent == queryNumber)
+                    if (profileDataGridNode.totalPercent === queryNumber)
                         profileDataGridNode._searchMatchedTotalColumn = true;
                 }
             } else if (millisecondsUnits || secondsUnits) {
@@ -465,9 +465,9 @@
                 }
 
                 if (equalTo) {
-                    if (profileDataGridNode.self == queryNumberMilliseconds)
+                    if (profileDataGridNode.self === queryNumberMilliseconds)
                         profileDataGridNode._searchMatchedSelfColumn = true;
-                    if (profileDataGridNode.total == queryNumberMilliseconds)
+                    if (profileDataGridNode.total === queryNumberMilliseconds)
                         profileDataGridNode._searchMatchedTotalColumn = true;
                 }
             }
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js b/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
index 980e14a8..9ee0058 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
@@ -125,7 +125,7 @@
         function populateResourcesForDocuments(resource)
         {
             var url = resource.documentURL.asParsedURL();
-            if (url && url.securityOrigin() == this._cookieDomain)
+            if (url && url.securityOrigin() === this._cookieDomain)
                 resourceURLsForDocumentURL.push(resource.url);
         }
         WebInspector.forAllResources(populateResourcesForDocuments.bind(this));
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseModel.js b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseModel.js
index 157e995..11ca511a 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseModel.js
@@ -119,7 +119,7 @@
                 var message;
                 if (errorObj.message)
                     message = errorObj.message;
-                else if (errorObj.code == 2)
+                else if (errorObj.code === 2)
                     message = WebInspector.UIString("Database no longer has expected version.");
                 else
                     message = WebInspector.UIString("An unexpected error %s occurred.", errorObj.code);
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
index 7ae1cc8..f8ac937 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
@@ -172,7 +172,7 @@
         if (Array.isArray(keyPath)) {
             keyColumnHeaderFragment.createTextChild("[");
             for (var i = 0; i < keyPath.length; ++i) {
-                if (i != 0)
+                if (i !== 0)
                     keyColumnHeaderFragment.createTextChild(", ");
                 keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPath[i]));
             }
diff --git a/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js b/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js
index 7ed90c3..94a3f23 100644
--- a/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js
+++ b/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js
@@ -746,7 +746,7 @@
 
     _navigationUrlKeyUp: function(event)
     {
-        if (event.keyIdentifier != "Enter")
+        if (event.keyIdentifier !== "Enter")
             return;
         var url = this._navigationUrl.value;
         if (!url)
@@ -770,8 +770,8 @@
         this._historyIndex = currentIndex;
         this._historyEntries = entries;
 
-        this._navigationBack.disabled = currentIndex == 0;
-        this._navigationForward.disabled = currentIndex == (entries.length - 1);
+        this._navigationBack.disabled = currentIndex === 0;
+        this._navigationForward.disabled = currentIndex === (entries.length - 1);
 
         var url = entries[currentIndex].url;
         var match = url.match(WebInspector.ScreencastView._HttpRegex);
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
index 1068dde90..3e8ad8b 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
@@ -121,7 +121,7 @@
      */
     _isBlacklisted: function(msg)
     {
-        if (msg.source != WebInspector.ConsoleMessage.MessageSource.Network || msg.level != WebInspector.ConsoleMessage.MessageLevel.Error || !msg.url || !msg.url.startsWith("chrome-extension"))
+        if (msg.source !== WebInspector.ConsoleMessage.MessageSource.Network || msg.level !== WebInspector.ConsoleMessage.MessageLevel.Error || !msg.url || !msg.url.startsWith("chrome-extension"))
             return false;
 
         // ignore Chromecast's cast_sender spam
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CookieParser.js b/third_party/WebKit/Source/devtools/front_end/sdk/CookieParser.js
index 33b64dcb..f33cd97 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/CookieParser.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/CookieParser.js
@@ -445,7 +445,7 @@
     if (!url || !WebInspector.Cookies.cookieDomainMatchesResourceDomain(cookie.domain(), url.host))
         return false;
     return (url.path.startsWith(cookie.path())
-        && (!cookie.port() || url.port == cookie.port())
+        && (!cookie.port() || url.port === cookie.port())
         && (!cookie.secure() || url.scheme === "https"));
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
index 919c1d9..53053ded 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
@@ -705,7 +705,7 @@
     _renumber: function()
     {
         this._childNodeCount = this._children.length;
-        if (this._childNodeCount == 0) {
+        if (this._childNodeCount === 0) {
             this.firstChild = null;
             this.lastChild = null;
             return;
@@ -1694,7 +1694,7 @@
                 callback(null);
                 return;
             }
-            if (nodeIds.length != 1)
+            if (nodeIds.length !== 1)
                 return;
 
             callback(this.nodeForId(nodeIds[0]));
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
index 9b3bd43..61f5f58 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -815,7 +815,7 @@
     _targetDisposed: function(event)
     {
         var target = /** @type {!WebInspector.Target} */ (event.data);
-        if (target != this.target())
+        if (target !== this.target())
             return;
         WebInspector.moduleSetting("pauseOnExceptionEnabled").removeChangeListener(this._pauseOnExceptionStateChanged, this);
         WebInspector.moduleSetting("pauseOnCaughtException").removeChangeListener(this._pauseOnExceptionStateChanged, this);
@@ -1192,7 +1192,7 @@
         {
             for (var i = 0; properties && i < properties.length; ++i)
                 result[properties[i].name] = true;
-            if (--pendingRequests == 0)
+            if (--pendingRequests === 0)
                 callback(result);
         }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
index 78a9934..c6d38c3 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
@@ -395,7 +395,7 @@
             return;
 
         networkRequest.resourceSize += dataLength;
-        if (encodedDataLength != -1)
+        if (encodedDataLength !== -1)
             networkRequest.increaseTransferSize(encodedDataLength);
         networkRequest.endTime = time;
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js
index 1effc86..30316e25 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js
@@ -97,7 +97,7 @@
     _executionContextCreated: function(context)
     {
         // The private script context should be hidden behind an experiment.
-        if (context.name == WebInspector.RuntimeModel._privateScript && !context.origin && !Runtime.experiments.isEnabled("privateScriptInspection")) {
+        if (context.name === WebInspector.RuntimeModel._privateScript && !context.origin && !Runtime.experiments.isEnabled("privateScriptInspection")) {
             return;
         }
         var executionContext = new WebInspector.ExecutionContext(this.target(), context.id, context.name, context.origin, context.isDefault, context.frameId);
@@ -499,7 +499,7 @@
         if (dotNotation || bracketNotation)
             expressionString = expressionString.substr(0, lastIndex);
 
-        if (expressionString && parseInt(expressionString, 10) == expressionString) {
+        if (expressionString && !isNaN(expressionString)) {
             // User is entering float value, do not suggest anything.
             completionsReadyCallback([]);
             return;
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerCacheModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerCacheModel.js
index 722cc8a..98c5529 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerCacheModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerCacheModel.js
@@ -146,7 +146,7 @@
     {
         for (var opaqueId of this._caches.keys()) {
             var cache = this._caches.get(opaqueId);
-            if (cache.securityOrigin == securityOrigin) {
+            if (cache.securityOrigin === securityOrigin) {
                 this._caches.delete(opaqueId);
                 this._cacheRemoved(cache);
             }
@@ -186,7 +186,7 @@
          */
         function deleteAndSaveOldCaches(cache)
         {
-            if (cache.securityOrigin == securityOrigin && !updatingCachesIds.has(cache.cacheId)) {
+            if (cache.securityOrigin === securityOrigin && !updatingCachesIds.has(cache.cacheId)) {
                 oldCaches.set(cache.cacheId, cache);
                 this._caches.delete(cache.cacheId);
             }
@@ -308,7 +308,7 @@
      */
     equals: function(cache)
     {
-        return this.cacheId == cache.cacheId;
+        return this.cacheId === cache.cacheId;
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerManager.js
index 10dfcb62..c28a30c5 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerManager.js
@@ -638,14 +638,14 @@
      */
     isWebContents: function()
     {
-        return this.type == "web_contents";
+        return this.type === "web_contents";
     },
     /**
      * @return {boolean}
      */
     isFrame: function()
     {
-        return this.type == "frame";
+        return this.type === "frame";
     },
 }
 
@@ -701,7 +701,7 @@
      */
     isStoppedAndRedundant: function()
     {
-        return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopped && this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Redundant;
+        return this.runningStatus === ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopped && this.status === ServiceWorkerAgent.ServiceWorkerVersionStatus.Redundant;
     },
 
     /**
@@ -709,7 +709,7 @@
      */
     isStopped: function()
     {
-        return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopped;
+        return this.runningStatus === ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopped;
     },
 
     /**
@@ -717,7 +717,7 @@
      */
     isStarting: function()
     {
-        return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Starting;
+        return this.runningStatus === ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Starting;
     },
 
     /**
@@ -725,7 +725,7 @@
      */
     isRunning: function()
     {
-        return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Running;
+        return this.runningStatus === ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Running;
     },
 
     /**
@@ -733,7 +733,7 @@
      */
     isStopping: function()
     {
-        return this.runningStatus == ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopping;
+        return this.runningStatus === ServiceWorkerAgent.ServiceWorkerVersionRunningStatus.Stopping;
     },
 
     /**
@@ -741,7 +741,7 @@
      */
     isNew: function()
     {
-        return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.New;
+        return this.status === ServiceWorkerAgent.ServiceWorkerVersionStatus.New;
     },
 
     /**
@@ -749,7 +749,7 @@
      */
     isInstalling: function()
     {
-        return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Installing;
+        return this.status === ServiceWorkerAgent.ServiceWorkerVersionStatus.Installing;
     },
 
     /**
@@ -757,7 +757,7 @@
      */
     isInstalled: function()
     {
-        return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Installed;
+        return this.status === ServiceWorkerAgent.ServiceWorkerVersionStatus.Installed;
     },
 
     /**
@@ -765,7 +765,7 @@
      */
     isActivating: function()
     {
-        return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Activating;
+        return this.status === ServiceWorkerAgent.ServiceWorkerVersionStatus.Activating;
     },
 
     /**
@@ -773,7 +773,7 @@
      */
     isActivated: function()
     {
-        return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Activated;
+        return this.status === ServiceWorkerAgent.ServiceWorkerVersionStatus.Activated;
     },
 
     /**
@@ -781,7 +781,7 @@
      */
     isRedundant: function()
     {
-        return this.status == ServiceWorkerAgent.ServiceWorkerVersionStatus.Redundant;
+        return this.status === ServiceWorkerAgent.ServiceWorkerVersionStatus.Redundant;
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js
index 641f4d4..1e50f8d 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js
@@ -555,7 +555,7 @@
  */
 WebInspector.TracingModel.Event.compareStartAndEndTime = function(a, b)
 {
-    return a.startTime - b.startTime || (b.endTime != undefined && a.endTime !== undefined && b.endTime - a.endTime) || 0;
+    return a.startTime - b.startTime || (b.endTime !== undefined && a.endTime !== undefined && b.endTime - a.endTime) || 0;
 }
 
 /**
diff --git a/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js b/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
index 8dab64ea..472e776 100644
--- a/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
@@ -132,7 +132,7 @@
     _onResponseReceived: function(event)
     {
         var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
-        if (request.resourceType() == WebInspector.resourceTypes.Document)
+        if (request.resourceType() === WebInspector.resourceTypes.Document)
             this._lastResponseReceivedForLoaderId.set(request.loaderId, request);
     },
 
@@ -159,7 +159,7 @@
             var originState = this._origins.get(origin);
             var oldSecurityState = originState.securityState;
             originState.securityState = this._securityStateMin(oldSecurityState, securityState);
-            if (oldSecurityState != originState.securityState) {
+            if (oldSecurityState !== originState.securityState) {
                 this._sidebarTree.updateOrigin(origin, securityState);
                 if (originState.originView)
                     originState.originView.setSecurityState(securityState);
diff --git a/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js b/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
index 42ea06e7..38aa0d4 100644
--- a/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
+++ b/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
@@ -558,6 +558,7 @@
             if (!WebInspector.GenericSettingsTab.isSettingVisible(extension))
                 return;
             if (extension.descriptor()["settingName"] === setting.name) {
+                InspectorFrontendHost.bringToFront();
                 WebInspector._settingsController.showSettingsScreen("preferences");
                 success = true;
             }
@@ -570,6 +571,7 @@
         {
             var settings = extension.descriptor()["settings"];
             if (settings && settings.indexOf(setting.name) !== -1) {
+                InspectorFrontendHost.bringToFront();
                 WebInspector._settingsController.showSettingsScreen("preferences");
                 success = true;
             }
@@ -582,6 +584,7 @@
         {
             var settings = extension.descriptor()["settings"];
             if (settings && settings.indexOf(setting.name) !== -1) {
+                InspectorFrontendHost.bringToFront();
                 WebInspector._settingsController.showSettingsScreen(extension.descriptor()["name"]);
                 success = true;
             }
diff --git a/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorTextEditor.js b/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorTextEditor.js
index 8348f4e..6baa1b6 100644
--- a/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorTextEditor.js
+++ b/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorTextEditor.js
@@ -1697,7 +1697,7 @@
      */
     equal: function(positionHandle)
     {
-        return positionHandle._lineHandle === this._lineHandle && positionHandle._columnNumber == this._columnNumber && positionHandle._codeMirror === this._codeMirror;
+        return positionHandle._lineHandle === this._lineHandle && positionHandle._columnNumber === this._columnNumber && positionHandle._codeMirror === this._codeMirror;
     }
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/FilePathScoreFunction.js b/third_party/WebKit/Source/devtools/front_end/sources/FilePathScoreFunction.js
index 0d33a56..a85408d7 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/FilePathScoreFunction.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/FilePathScoreFunction.js
@@ -130,7 +130,7 @@
         var isWordStart = this._testWordStart(data, j);
         var isFileName = j > this._fileNameIndex;
         var isPathTokenStart = j === 0 || data[j - 1] === "/";
-        var isCapsMatch = query[i] === data[j] && query[i] == this._queryUpperCase[i];
+        var isCapsMatch = query[i] === data[j] && query[i] === this._queryUpperCase[i];
         var score = 10;
         if (isPathTokenStart)
             score += 4;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
index c4049b8..2a109a7 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
@@ -205,7 +205,7 @@
 
             contextMenu.appendSeparator();
 
-            contextMenu.appendItem(enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true), !(enableBreakpointCount != breakpoints.length));
+            contextMenu.appendItem(enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true), !(enableBreakpointCount !== breakpoints.length));
             contextMenu.appendItem(disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, false), !(enableBreakpointCount > 1));
         }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
index fee1c77b..00cef5c 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -491,7 +491,7 @@
      */
     _isIdentifier: function(tokenType)
     {
-        return tokenType.startsWith("js-variable") || tokenType.startsWith("js-property") || tokenType == "js-def";
+        return tokenType.startsWith("js-variable") || tokenType.startsWith("js-property") || tokenType === "js-def";
     },
 
     _getPopoverAnchor: function(element, event)
@@ -591,7 +591,7 @@
         function showObjectPopover(result, wasThrown)
         {
             var target = WebInspector.context.flavor(WebInspector.Target);
-            if (selectedCallFrame.target() != target || !debuggerModel.isPaused() || !result) {
+            if (selectedCallFrame.target() !== target || !debuggerModel.isPaused() || !result) {
                 this._popoverHelper.hidePopover();
                 return;
             }
@@ -1064,7 +1064,7 @@
         var lineNumber = eventData.lineNumber;
         var eventObject = eventData.event;
 
-        if (eventObject.button != 0 || eventObject.altKey || eventObject.ctrlKey || eventObject.metaKey)
+        if (eventObject.button !== 0 || eventObject.altKey || eventObject.ctrlKey || eventObject.metaKey)
             return;
 
         this._toggleBreakpoint(lineNumber, eventObject.shiftKey);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
index e08456b8..6b0dc58 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
@@ -77,7 +77,7 @@
                 emptyPlaceholder = WebInspector.UIString("No Variables");
                 if (thisObject)
                     extraProperties.push(new WebInspector.RemoteObjectProperty("this", thisObject));
-                if (i == 0) {
+                if (i === 0) {
                     var details = callFrame.debuggerModel.debuggerPausedDetails();
                     var exception = details.exception();
                     if (exception)
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
index 2c033c8..eb53ef2 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
@@ -383,7 +383,7 @@
     _onSectionClick: function(event)
     {
         event.consume(true);
-        if (event.detail == 1) {
+        if (event.detail === 1) {
             this._preventClickTimeout = setTimeout(handleClick.bind(this), 333);
         } else {
             clearTimeout(this._preventClickTimeout);
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js b/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js
index c1682d46..09642566 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js
@@ -792,7 +792,7 @@
     {
         var selection = this._selectionFromEventPoint(event);
         if (selection) {
-            if (selection.type() == WebInspector.LayerView.Selection.Type.Tile)
+            if (selection.type() === WebInspector.LayerView.Selection.Type.Tile)
                 this.dispatchEventToListeners(WebInspector.Layers3DView.Events.PaintProfilerRequested, selection.traceEvent());
             else if (selection.layer())
                 this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSnapshotRequested, selection.layer());
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/PaintProfilerView.js b/third_party/WebKit/Source/devtools/front_end/timeline/PaintProfilerView.js
index 991fd7d0..b686e3e 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/PaintProfilerView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/PaintProfilerView.js
@@ -129,7 +129,7 @@
                 heightByCategory[categoryName] = (heightByCategory[categoryName] || 0) + sample;
             }
             ++i;
-            if (i - lastBarIndex == this._samplesPerBar || i == sampleCount) {
+            if (i - lastBarIndex === this._samplesPerBar || i === sampleCount) {
                 // Normalize by total number of samples accumulated.
                 var factor = this._profiles.length * (i - lastBarIndex);
                 lastBarTime /= factor;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineProfileTree.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineProfileTree.js
index 6eeb31c..97cd608 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineProfileTree.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineProfileTree.js
@@ -207,7 +207,7 @@
  */
 WebInspector.TimelineProfileTree.eventStackFrame = function(event)
 {
-    if (event.name == WebInspector.TimelineModel.RecordType.JSFrame)
+    if (event.name === WebInspector.TimelineModel.RecordType.JSFrame)
         return event.args["data"];
     var topFrame = event.stackTrace && event.stackTrace[0];
     if (topFrame)
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
index 3ba7d96b..0e252132 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
@@ -721,7 +721,7 @@
         contentHelper.appendWarningRow(event);
     if (event.name === recordTypes.JSFrame) {
         var deoptReason = eventData["deoptReason"];
-        if (deoptReason && deoptReason != "no reason")
+        if (deoptReason && deoptReason !== "no reason")
             contentHelper.appendWarningRow(event, WebInspector.TimelineModel.WarningType.V8Deopt);
     }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SidebarPane.js b/third_party/WebKit/Source/devtools/front_end/ui/SidebarPane.js
index 216b626..b5b7764 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SidebarPane.js
@@ -132,7 +132,7 @@
     _collapse: function()
     {
         this.element.classList.remove("expanded");
-        if (this._pane.element.parentNode == this.element.parentNode)
+        if (this._pane.element.parentNode === this.element.parentNode)
             this._pane.detach();
     },
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
index 530a41b1..6a52c0c 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
@@ -772,7 +772,7 @@
     hasCustomResizer: function()
     {
         var elements = this._resizerWidget.elements();
-        return elements.length > 1 || (elements.length == 1 && elements[0] !== this._resizerElement);
+        return elements.length > 1 || (elements.length === 1 && elements[0] !== this._resizerElement);
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/DataGrid.js b/third_party/WebKit/Source/devtools/front_end/ui_lazy/DataGrid.js
index f655300d..ebbfc16 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/DataGrid.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/DataGrid.js
@@ -395,7 +395,7 @@
             }
         }
 
-        if (textBeforeEditing == newText) {
+        if (textBeforeEditing === newText) {
             this._editingCancelled(element);
             moveToNextIfNeeded.call(this, false);
             return;
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
index 29c48be..d54204e 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -17,6 +17,7 @@
 #include "modules/canvas2d/CanvasPattern.h"
 #include "modules/canvas2d/CanvasStyle.h"
 #include "modules/canvas2d/Path2D.h"
+#include "platform/Histogram.h"
 #include "platform/geometry/FloatQuad.h"
 #include "platform/graphics/Color.h"
 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h"
@@ -988,6 +989,62 @@
     if (!drawingCanvas())
         return;
 
+    // TODO(xidachen): After collecting some data, come back and prune off
+    // the ones that is not needed.
+    Optional<ScopedUsHistogramTimer> timer;
+    if (imageBuffer() && imageBuffer()->isAccelerated()) {
+        if (imageSource->isVideoElement()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterVideoGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Video.GPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterVideoGPU);
+        } else if (imageSource->isCanvasElement()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCanvasGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Canvas.GPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterCanvasGPU);
+        } else if (imageSource->isSVGSource()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterSVGGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.SVG.GPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterSVGGPU);
+        } else if (imageSource->isImageBitmap()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterImageBitmapGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.ImageBitmap.GPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterImageBitmapGPU);
+        } else {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterOthersGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Others.GPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterOthersGPU);
+        }
+    } else if (imageBuffer() && imageBuffer()->isRecording()) {
+        if (imageSource->isVideoElement()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterVideoDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.Video.DisplayList", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterVideoDisplayList);
+        } else if (imageSource->isCanvasElement()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCanvasDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.Canvas.DisplayList", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterCanvasDisplayList);
+        } else if (imageSource->isSVGSource()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterSVGDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.SVG.DisplayList", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterSVGDisplayList);
+        } else if (imageSource->isImageBitmap()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterImageBitmapDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.ImageBitmap.DisplayList", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterImageBitmapDisplayList);
+        } else {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterOthersDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.Others.DisplayList", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterOthersDisplayList);
+        }
+    } else {
+        if (imageSource->isVideoElement()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterVideoCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Video.CPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterVideoCPU);
+        } else if (imageSource->isCanvasElement()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCanvasCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Canvas.CPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterCanvasCPU);
+        } else if (imageSource->isSVGSource()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterSVGCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.SVG.CPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterSVGCPU);
+        } else if (imageSource->isImageBitmap()) {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterImageBitmapCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.ImageBitmap.CPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterImageBitmapCPU);
+        } else {
+            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterOthersCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Others.CPU", 0, 10000000, 50));
+            timer.emplace(scopedUsCounterOthersCPU);
+        }
+    }
+
     RefPtr<Image> image;
     FloatSize defaultObjectSize(width(), height());
     SourceImageStatus sourceImageStatus = InvalidSourceImageStatus;
@@ -1190,6 +1247,18 @@
 
 ImageData* BaseRenderingContext2D::getImageData(double sx, double sy, double sw, double sh, ExceptionState& exceptionState) const
 {
+    Optional<ScopedUsHistogramTimer> timer;
+    if (imageBuffer() && imageBuffer()->isAccelerated()) {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterGPU, new CustomCountHistogram("Blink.Canvas.GetImageData.GPU", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterGPU);
+    } else if (imageBuffer() && imageBuffer()->isRecording()) {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterDisplayList, new CustomCountHistogram("Blink.Canvas.GetImageData.DisplayList", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterDisplayList);
+    } else {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCPU, new CustomCountHistogram("Blink.Canvas.GetImageData.CPU", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterCPU);
+    }
+
     if (!originClean())
         exceptionState.throwSecurityError("The canvas has been tainted by cross-origin data.");
     else if (!sw || !sh)
@@ -1243,6 +1312,18 @@
 
 void BaseRenderingContext2D::putImageData(ImageData* data, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight, ExceptionState& exceptionState)
 {
+    Optional<ScopedUsHistogramTimer> timer;
+    if (imageBuffer() && imageBuffer()->isAccelerated()) {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterGPU, new CustomCountHistogram("Blink.Canvas.PutImageData.GPU", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterGPU);
+    } else if (imageBuffer() && imageBuffer()->isRecording()) {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterDisplayList, new CustomCountHistogram("Blink.Canvas.PutImageData.DisplayList", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterDisplayList);
+    } else {
+        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCPU, new CustomCountHistogram("Blink.Canvas.PutImageData.CPU", 0, 10000000, 50));
+        timer.emplace(scopedUsCounterCPU);
+    }
+
     if (data->data()->bufferBase()->isNeutered()) {
         exceptionState.throwDOMException(InvalidStateError, "The source data has been neutered.");
         return;
diff --git a/third_party/WebKit/Source/modules/compositorworker/CompositorWorker.cpp b/third_party/WebKit/Source/modules/compositorworker/CompositorWorker.cpp
index 3e5b4c48..20c79e4 100644
--- a/third_party/WebKit/Source/modules/compositorworker/CompositorWorker.cpp
+++ b/third_party/WebKit/Source/modules/compositorworker/CompositorWorker.cpp
@@ -8,6 +8,7 @@
 #include "core/dom/CompositorProxyClient.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/ChromeClient.h"
 #include "core/workers/WorkerClients.h"
 #include "modules/EventTargetModules.h"
diff --git a/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp b/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp
index fec8983..3b58e35 100644
--- a/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp
+++ b/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp
@@ -5,6 +5,7 @@
 #include "modules/compositorworker/CompositorWorkerThread.h"
 
 #include "bindings/core/v8/ScriptSourceCode.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8GCController.h"
 #include "core/dom/CompositorProxyClient.h"
 #include "core/inspector/ConsoleMessage.h"
@@ -35,7 +36,7 @@
     }
 
     // (Empty) WorkerReportingProxy implementation:
-    virtual void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId) {}
+    virtual void reportException(const String& errorMessage, PassOwnPtr<SourceLocation>) {}
     void reportConsoleMessage(ConsoleMessage*) override {}
     void postMessageToPageInspector(const String&) override {}
     void postWorkerConsoleAgentEnabled() override {}
diff --git a/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp b/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
index d402f596..107f4e3 100644
--- a/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
+++ b/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
@@ -6,11 +6,13 @@
 
 #include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/V8HiddenValue.h"
+#include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMTypedArray.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/streams/ReadableStreamController.h"
 #include "core/streams/ReadableStreamOperations.h"
+#include "core/workers/WorkerGlobalScope.h"
 #include "modules/fetch/Body.h"
 #include "modules/fetch/DataConsumerHandleUtil.h"
 #include "modules/fetch/DataConsumerTee.h"
@@ -21,6 +23,20 @@
 
 namespace blink {
 
+namespace {
+
+bool isTerminating(ScriptState* scriptState)
+{
+    ExecutionContext* executionContext = scriptState->getExecutionContext();
+    if (!executionContext)
+        return true;
+    if (!executionContext->isWorkerGlobalScope())
+        return false;
+    return toWorkerGlobalScope(executionContext)->scriptController()->isExecutionTerminating();
+}
+
+} // namespace
+
 class BodyStreamBuffer::LoaderClient final : public GarbageCollectedFinalized<LoaderClient>, public ActiveDOMObject, public FetchDataLoader::Client {
     WTF_MAKE_NONCOPYABLE(LoaderClient);
     USING_GARBAGE_COLLECTED_MIXIN(LoaderClient);
@@ -90,8 +106,13 @@
 {
     if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
         ScriptState::Scope scope(scriptState);
+        if (isTerminating(scriptState))
+            return;
         v8::Local<v8::Value> bodyValue = toV8(this, scriptState);
-        ASSERT(!bodyValue.IsEmpty());
+        if (bodyValue.IsEmpty()) {
+            DCHECK(isTerminating(scriptState));
+            return;
+        }
         ASSERT(bodyValue->IsObject());
         v8::Local<v8::Object> body = bodyValue.As<v8::Object>();
 
@@ -112,8 +133,13 @@
     ScriptState::Scope scope(scriptState);
     DCHECK(RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled());
     DCHECK(ReadableStreamOperations::isReadableStream(scriptState, stream));
+    if (isTerminating(scriptState))
+        return;
     v8::Local<v8::Value> bodyValue = toV8(this, scriptState);
-    DCHECK(!bodyValue.IsEmpty());
+    if (bodyValue.IsEmpty()) {
+        DCHECK(isTerminating(scriptState));
+        return;
+    }
     DCHECK(bodyValue->IsObject());
     v8::Local<v8::Object> body = bodyValue.As<v8::Object>();
 
@@ -124,8 +150,13 @@
 {
     ScriptState::Scope scope(m_scriptState.get());
     if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
+        if (isTerminating(m_scriptState.get()))
+            return ScriptValue();
         v8::Local<v8::Value> bodyValue = toV8(this, m_scriptState.get());
-        ASSERT(!bodyValue.IsEmpty());
+        if (bodyValue.IsEmpty()) {
+            DCHECK(isTerminating(m_scriptState.get()));
+            return ScriptValue();
+        }
         ASSERT(bodyValue->IsObject());
         v8::Local<v8::Object> body = bodyValue.As<v8::Object>();
         return ScriptValue(m_scriptState.get(), V8HiddenValue::getHiddenValue(m_scriptState.get(), body, V8HiddenValue::internalBodyStream(m_scriptState->isolate())));
diff --git a/third_party/WebKit/Source/modules/fetch/GlobalFetch.cpp b/third_party/WebKit/Source/modules/fetch/GlobalFetch.cpp
index a4bdd71..872a327 100644
--- a/third_party/WebKit/Source/modules/fetch/GlobalFetch.cpp
+++ b/third_party/WebKit/Source/modules/fetch/GlobalFetch.cpp
@@ -6,6 +6,7 @@
 
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/UseCounter.h"
+#include "core/inspector/InspectorInstrumentation.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "modules/fetch/FetchManager.h"
 #include "modules/fetch/Request.h"
@@ -49,6 +50,9 @@
         Request* r = Request::create(scriptState, input, init, exceptionState);
         if (exceptionState.hadException())
             return ScriptPromise();
+
+        if (ExecutionContext* executionContext = m_fetchManager->getExecutionContext())
+            InspectorInstrumentation::willSendXMLHttpOrFetchNetworkRequest(executionContext, r->url());
         return m_fetchManager->fetch(scriptState, r->passRequestData(scriptState));
     }
 
diff --git a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandle.cpp b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandle.cpp
index 639665e..40be088a 100644
--- a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandle.cpp
+++ b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandle.cpp
@@ -12,8 +12,10 @@
 #include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/core/v8/V8IteratorResultValue.h"
 #include "bindings/core/v8/V8Uint8Array.h"
+#include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/dom/DOMTypedArray.h"
 #include "core/streams/ReadableStreamOperations.h"
+#include "core/workers/WorkerGlobalScope.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebTaskRunner.h"
 #include "public/platform/WebThread.h"
@@ -27,6 +29,20 @@
 
 namespace blink {
 
+namespace {
+
+bool isTerminating(ScriptState* scriptState)
+{
+    ExecutionContext* executionContext = scriptState->getExecutionContext();
+    if (!executionContext)
+        return true;
+    if (!executionContext->isWorkerGlobalScope())
+        return false;
+    return toWorkerGlobalScope(executionContext)->scriptController()->isExecutionTerminating();
+}
+
+} // namespace
+
 using Result = WebDataConsumerHandle::Result;
 using Flags = WebDataConsumerHandle::Flags;
 
@@ -49,7 +65,12 @@
             bool done;
             v8::Local<v8::Value> item = v.v8Value();
             ASSERT(item->IsObject());
-            v8::Local<v8::Value> value = v8CallOrCrash(v8UnpackIteratorResult(v.getScriptState(), item.As<v8::Object>(), &done));
+            if (isTerminating(v.getScriptState()))
+                return ScriptValue();
+            v8::MaybeLocal<v8::Value> maybeValue = v8UnpackIteratorResult(v.getScriptState(), item.As<v8::Object>(), &done);
+            if (isTerminating(v.getScriptState()))
+                return ScriptValue();
+            v8::Local<v8::Value> value = v8CallOrCrash(maybeValue);
             if (done) {
                 readingContext->onReadDone();
                 return v;
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp
index b648340..f7b4cba 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp
@@ -8,6 +8,7 @@
 #include "core/dom/DOMException.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
+#include "core/frame/LocalFrame.h"
 #include "modules/EventTargetModules.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
index 3fe542f..de78c5e 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
@@ -31,10 +31,10 @@
 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h"
 
 #include "bindings/core/v8/CallbackPromiseAdapter.h"
-#include "bindings/core/v8/ScriptCallStack.h"
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/ScriptState.h"
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/events/Event.h"
@@ -208,10 +208,10 @@
     return ServiceWorkerScriptCachedMetadataHandler::create(this, scriptURL, metaData);
 }
 
-void ServiceWorkerGlobalScope::logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+void ServiceWorkerGlobalScope::logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
-    WorkerGlobalScope::logExceptionToConsole(errorMessage, scriptId, sourceURL, lineNumber, columnNumber, callStack);
-    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, columnNumber, callStack, scriptId);
+    WorkerGlobalScope::logExceptionToConsole(errorMessage, location->clone());
+    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, std::move(location));
     addMessageToWorkerConsole(consoleMessage);
 }
 
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.h
index ac72d691..330860b 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.h
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.h
@@ -95,7 +95,7 @@
     ServiceWorkerGlobalScope(const KURL&, const String& userAgent, ServiceWorkerThread*, double timeOrigin, PassOwnPtr<SecurityOrigin::PrivilegeData>, WorkerClients*);
     void importScripts(const Vector<String>& urls, ExceptionState&) override;
     CachedMetadataHandler* createWorkerScriptCachedMetadataHandler(const KURL& scriptURL, const Vector<char>* metaData) override;
-    void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) override;
+    void logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation>) override;
     void scriptLoaded(size_t scriptSize, size_t cachedMetadataSize) override;
 
     Member<ServiceWorkerClients> m_clients;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerLinkResource.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerLinkResource.cpp
index b7883a1..255f515d 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerLinkResource.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerLinkResource.cpp
@@ -5,6 +5,7 @@
 #include "modules/serviceworkers/ServiceWorkerLinkResource.h"
 
 #include "core/dom/Document.h"
+#include "core/frame/DOMWindow.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLLinkElement.h"
 #include "core/loader/FrameLoaderClient.h"
diff --git a/third_party/WebKit/Source/modules/speech/testing/InternalsSpeechSynthesis.cpp b/third_party/WebKit/Source/modules/speech/testing/InternalsSpeechSynthesis.cpp
index e5654d5..594b59f 100644
--- a/third_party/WebKit/Source/modules/speech/testing/InternalsSpeechSynthesis.cpp
+++ b/third_party/WebKit/Source/modules/speech/testing/InternalsSpeechSynthesis.cpp
@@ -31,6 +31,7 @@
 #include "InternalsSpeechSynthesis.h"
 
 #include "core/dom/Document.h"
+#include "core/frame/LocalDOMWindow.h"
 #include "core/testing/Internals.h"
 #include "modules/speech/DOMWindowSpeechSynthesis.h"
 #include "modules/speech/SpeechSynthesis.h"
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
index c89d97b..92696e0 100644
--- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
@@ -49,6 +49,11 @@
 {
     m_renderBus = AudioBus::create(renderTarget->numberOfChannels(), renderQuantumSize);
     m_framesToProcess = m_renderTarget->length();
+
+    // Node-specific defaults.
+    m_channelCount = m_renderTarget->numberOfChannels();
+    m_channelCountMode = Explicit;
+    m_channelInterpretation = AudioBus::Speakers;
 }
 
 PassRefPtr<OfflineAudioDestinationHandler> OfflineAudioDestinationHandler::create(AudioNode& node, AudioBuffer* renderTarget)
@@ -91,6 +96,11 @@
     return static_cast<OfflineAudioContext*>(AudioDestinationHandler::context());
 }
 
+unsigned long OfflineAudioDestinationHandler::maxChannelCount() const
+{
+    return m_channelCount;
+}
+
 void OfflineAudioDestinationHandler::startRendering()
 {
     ASSERT(isMainThread());
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.h b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.h
index 47f23e3..69a700b 100644
--- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.h
@@ -53,6 +53,7 @@
     // AudioDestinationHandler
     void startRendering() override;
     void stopRendering() override;
+    unsigned long maxChannelCount() const override;
 
     float sampleRate()  const override { return m_renderTarget->sampleRate(); }
 
diff --git a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.cpp b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.cpp
index a24656a..69a2d50 100644
--- a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.cpp
@@ -4,6 +4,7 @@
 
 #include "modules/worklet/WorkletGlobalScope.h"
 
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/frame/FrameConsole.h"
 #include "core/inspector/InspectorInstrumentation.h"
@@ -74,9 +75,9 @@
     frame()->console().addMessage(consoleMessage);
 }
 
-void WorkletGlobalScope::logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+void WorkletGlobalScope::logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
-    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, columnNumber, callStack, scriptId);
+    ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, std::move(location));
     addConsoleMessage(consoleMessage);
 }
 
diff --git a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.h b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.h
index 365abc8..52f83af8 100644
--- a/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.h
+++ b/third_party/WebKit/Source/modules/worklet/WorkletGlobalScope.h
@@ -5,7 +5,6 @@
 #ifndef WorkletGlobalScope_h
 #define WorkletGlobalScope_h
 
-#include "bindings/core/v8/ScriptCallStack.h"
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/ExecutionContextTask.h"
@@ -58,7 +57,7 @@
 
     void reportBlockedScriptExecutionToInspector(const String& directiveText) final;
     void addConsoleMessage(ConsoleMessage*) final;
-    void logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) final;
+    void logExceptionToConsole(const String& errorMessage, PassOwnPtr<SourceLocation>) final;
 
     DECLARE_VIRTUAL_TRACE();
 
diff --git a/third_party/WebKit/Source/platform/MemoryCacheDumpProvider.cpp b/third_party/WebKit/Source/platform/MemoryCacheDumpProvider.cpp
index 21c3f1e..025f84a 100644
--- a/third_party/WebKit/Source/platform/MemoryCacheDumpProvider.cpp
+++ b/third_party/WebKit/Source/platform/MemoryCacheDumpProvider.cpp
@@ -5,7 +5,6 @@
 #include "platform/MemoryCacheDumpProvider.h"
 
 #include "platform/web_process_memory_dump_impl.h"
-#include "public/platform/WebMemoryDumpProvider.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/OWNERS b/third_party/WebKit/Source/platform/OWNERS
index 89e0448a..92cb8559 100644
--- a/third_party/WebKit/Source/platform/OWNERS
+++ b/third_party/WebKit/Source/platform/OWNERS
@@ -9,7 +9,6 @@
 junov@chromium.org
 kbr@chromium.org
 kinuko@chromium.org
-leviw@chromium.org
 mkwst@chromium.org
 noel@chromium.org
 pdr@chromium.org
diff --git a/third_party/WebKit/Source/platform/animation/CompositorAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorAnimationCurve.cpp
deleted file mode 100644
index 59d64b1f..0000000
--- a/third_party/WebKit/Source/platform/animation/CompositorAnimationCurve.cpp
+++ /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.
-
-#include "platform/animation/CompositorAnimationCurve.h"
-
-#include "cc/animation/timing_function.h"
-
-namespace blink {
-
-std::unique_ptr<cc::TimingFunction> CompositorAnimationCurve::createTimingFunction(TimingFunctionType type)
-{
-    switch (type) {
-    case blink::CompositorAnimationCurve::TimingFunctionTypeEase:
-        return cc::EaseTimingFunction::Create();
-    case blink::CompositorAnimationCurve::TimingFunctionTypeEaseIn:
-        return cc::EaseInTimingFunction::Create();
-    case blink::CompositorAnimationCurve::TimingFunctionTypeEaseOut:
-        return cc::EaseOutTimingFunction::Create();
-    case blink::CompositorAnimationCurve::TimingFunctionTypeEaseInOut:
-        return cc::EaseInOutTimingFunction::Create();
-    case blink::CompositorAnimationCurve::TimingFunctionTypeLinear:
-        return nullptr;
-    }
-    return nullptr;
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorAnimationCurve.h
index 4b85868..f0b3181b 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorAnimationCurve.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorAnimationCurve.h
@@ -11,26 +11,14 @@
 
 namespace cc {
 class AnimationCurve;
-class TimingFunction;
 }
 
 namespace blink {
 
 class PLATFORM_EXPORT CompositorAnimationCurve {
 public:
-    enum TimingFunctionType {
-        TimingFunctionTypeEase,
-        TimingFunctionTypeEaseIn,
-        TimingFunctionTypeEaseOut,
-        TimingFunctionTypeEaseInOut,
-        TimingFunctionTypeLinear
-    };
-
     virtual ~CompositorAnimationCurve() {}
     virtual std::unique_ptr<cc::AnimationCurve> cloneToAnimationCurve() const = 0;
-
-protected:
-    static std::unique_ptr<cc::TimingFunction> createTimingFunction(TimingFunctionType);
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp
index 1608638..a6d8bab6 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp
@@ -22,15 +22,23 @@
 {
 }
 
-void CompositorFilterAnimationCurve::add(const CompositorFilterKeyframe& keyframe, TimingFunctionType type)
+void CompositorFilterAnimationCurve::addLinearKeyframe(const CompositorFilterKeyframe& keyframe)
+{
+    const cc::FilterOperations& filterOperations = keyframe.value().asFilterOperations();
+    m_curve->AddKeyframe(cc::FilterKeyframe::Create(
+        base::TimeDelta::FromSecondsD(keyframe.time()), filterOperations, nullptr));
+
+}
+
+void CompositorFilterAnimationCurve::addCubicBezierKeyframe(const CompositorFilterKeyframe& keyframe, CubicBezierTimingFunction::EaseType easeType)
 {
     const cc::FilterOperations& filterOperations = keyframe.value().asFilterOperations();
     m_curve->AddKeyframe(cc::FilterKeyframe::Create(
         base::TimeDelta::FromSecondsD(keyframe.time()), filterOperations,
-        createTimingFunction(type)));
+        cc::CubicBezierTimingFunction::CreatePreset(easeType)));
 }
 
-void CompositorFilterAnimationCurve::add(const CompositorFilterKeyframe& keyframe, double x1, double y1, double x2, double y2)
+void CompositorFilterAnimationCurve::addCubicBezierKeyframe(const CompositorFilterKeyframe& keyframe, double x1, double y1, double x2, double y2)
 {
     const cc::FilterOperations& filterOperations = keyframe.value().asFilterOperations();
     m_curve->AddKeyframe(cc::FilterKeyframe::Create(
@@ -38,7 +46,7 @@
         cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
 }
 
-void CompositorFilterAnimationCurve::add(const CompositorFilterKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
+void CompositorFilterAnimationCurve::addStepsKeyframe(const CompositorFilterKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
 {
     const cc::FilterOperations& filterOperations = keyframe.value().asFilterOperations();
     m_curve->AddKeyframe(cc::FilterKeyframe::Create(
@@ -51,9 +59,9 @@
     m_curve->SetTimingFunction(nullptr);
 }
 
-void CompositorFilterAnimationCurve::setCubicBezierTimingFunction(TimingFunctionType type)
+void CompositorFilterAnimationCurve::setCubicBezierTimingFunction(CubicBezierTimingFunction::EaseType easeType)
 {
-    m_curve->SetTimingFunction(createTimingFunction(type));
+    m_curve->SetTimingFunction(cc::CubicBezierTimingFunction::CreatePreset(easeType));
 }
 
 void CompositorFilterAnimationCurve::setCubicBezierTimingFunction(double x1, double y1, double x2, double y2)
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h
index 5463a409..ff9a71ae 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h
@@ -11,8 +11,6 @@
 #include "platform/animation/TimingFunction.h"
 #include "wtf/Noncopyable.h"
 
-#include <memory>
-
 namespace cc {
 class KeyframedFilterAnimationCurve;
 }
@@ -30,15 +28,15 @@
     CompositorFilterAnimationCurve();
     ~CompositorFilterAnimationCurve() override;
 
-    virtual void add(const CompositorFilterKeyframe&, TimingFunctionType = TimingFunctionTypeEase);
+    virtual void addLinearKeyframe(const CompositorFilterKeyframe&);
+    virtual void addCubicBezierKeyframe(const CompositorFilterKeyframe&, CubicBezierTimingFunction::EaseType);
     // Adds the keyframe with a custom, bezier timing function. Note, it is
     // assumed that x0 = y0, and x3 = y3 = 1.
-    virtual void add(const CompositorFilterKeyframe&, double x1, double y1, double x2, double y2);
-    // Adds the keyframe with a steps timing function.
-    virtual void add(const CompositorFilterKeyframe&, int steps, StepsTimingFunction::StepPosition);
+    virtual void addCubicBezierKeyframe(const CompositorFilterKeyframe&, double x1, double y1, double x2, double y2);
+    virtual void addStepsKeyframe(const CompositorFilterKeyframe&, int steps, StepsTimingFunction::StepPosition);
 
     virtual void setLinearTimingFunction();
-    virtual void setCubicBezierTimingFunction(TimingFunctionType);
+    virtual void setCubicBezierTimingFunction(CubicBezierTimingFunction::EaseType);
     virtual void setCubicBezierTimingFunction(double x1, double y1, double x2, double y2);
     virtual void setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition);
 
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp
index e325d3b..3bba534 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp
@@ -21,27 +21,29 @@
 {
 }
 
-void CompositorFloatAnimationCurve::add(const CompositorFloatKeyframe& keyframe)
-{
-    add(keyframe, TimingFunctionTypeEase);
-}
-
-void CompositorFloatAnimationCurve::add(const CompositorFloatKeyframe& keyframe,
-    TimingFunctionType type)
+void CompositorFloatAnimationCurve::addLinearKeyframe(const CompositorFloatKeyframe& keyframe)
 {
     m_curve->AddKeyframe(
         cc::FloatKeyframe::Create(base::TimeDelta::FromSecondsD(keyframe.time),
-            keyframe.value, createTimingFunction(type)));
+            keyframe.value, nullptr));
 }
 
-void CompositorFloatAnimationCurve::add(const CompositorFloatKeyframe& keyframe, double x1, double y1, double x2, double y2)
+void CompositorFloatAnimationCurve::addCubicBezierKeyframe(const CompositorFloatKeyframe& keyframe,
+    CubicBezierTimingFunction::EaseType easeType)
+{
+    m_curve->AddKeyframe(
+        cc::FloatKeyframe::Create(base::TimeDelta::FromSecondsD(keyframe.time),
+            keyframe.value, cc::CubicBezierTimingFunction::CreatePreset(easeType)));
+}
+
+void CompositorFloatAnimationCurve::addCubicBezierKeyframe(const CompositorFloatKeyframe& keyframe, double x1, double y1, double x2, double y2)
 {
     m_curve->AddKeyframe(cc::FloatKeyframe::Create(
         base::TimeDelta::FromSecondsD(keyframe.time), keyframe.value,
         cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
 }
 
-void CompositorFloatAnimationCurve::add(const CompositorFloatKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
+void CompositorFloatAnimationCurve::addStepsKeyframe(const CompositorFloatKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
 {
     m_curve->AddKeyframe(cc::FloatKeyframe::Create(
         base::TimeDelta::FromSecondsD(keyframe.time), keyframe.value,
@@ -53,9 +55,9 @@
     m_curve->SetTimingFunction(nullptr);
 }
 
-void CompositorFloatAnimationCurve::setCubicBezierTimingFunction(TimingFunctionType type)
+void CompositorFloatAnimationCurve::setCubicBezierTimingFunction(CubicBezierTimingFunction::EaseType easeType)
 {
-    m_curve->SetTimingFunction(createTimingFunction(type));
+    m_curve->SetTimingFunction(cc::CubicBezierTimingFunction::CreatePreset(easeType));
 }
 
 void CompositorFloatAnimationCurve::setCubicBezierTimingFunction(double x1, double y1, double x2, double y2)
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h
index 26060f27..1598fe57f 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h
@@ -11,8 +11,6 @@
 #include "platform/animation/TimingFunction.h"
 #include "wtf/Noncopyable.h"
 
-#include <memory>
-
 namespace cc {
 class KeyframedFloatAnimationCurve;
 }
@@ -30,17 +28,15 @@
     CompositorFloatAnimationCurve();
     ~CompositorFloatAnimationCurve() override;
 
-    // Adds the keyframe with the default timing function (ease).
-    virtual void add(const CompositorFloatKeyframe&);
-    virtual void add(const CompositorFloatKeyframe&, TimingFunctionType);
+    virtual void addLinearKeyframe(const CompositorFloatKeyframe&);
+    virtual void addCubicBezierKeyframe(const CompositorFloatKeyframe&, CubicBezierTimingFunction::EaseType);
     // Adds the keyframe with a custom, bezier timing function. Note, it is
     // assumed that x0 = y0 , and x3 = y3 = 1.
-    virtual void add(const CompositorFloatKeyframe&, double x1, double y1, double x2, double y2);
-    // Adds the keyframe with a steps timing function.
-    virtual void add(const CompositorFloatKeyframe&, int steps, StepsTimingFunction::StepPosition);
+    virtual void addCubicBezierKeyframe(const CompositorFloatKeyframe&, double x1, double y1, double x2, double y2);
+    virtual void addStepsKeyframe(const CompositorFloatKeyframe&, int steps, StepsTimingFunction::StepPosition);
 
     virtual void setLinearTimingFunction();
-    virtual void setCubicBezierTimingFunction(TimingFunctionType);
+    virtual void setCubicBezierTimingFunction(CubicBezierTimingFunction::EaseType);
     virtual void setCubicBezierTimingFunction(double x1, double y1, double x2, double y2);
     virtual void setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition);
 
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurveTest.cpp b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurveTest.cpp
index 3046711..8059c29 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurveTest.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurveTest.cpp
@@ -19,8 +19,7 @@
 TEST(WebFloatAnimationCurveTest, OneFloatKeyframe)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 2),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(0, 2));
     EXPECT_FLOAT_EQ(2, curve->getValue(-1));
     EXPECT_FLOAT_EQ(2, curve->getValue(0));
     EXPECT_FLOAT_EQ(2, curve->getValue(0.5));
@@ -32,10 +31,8 @@
 TEST(WebFloatAnimationCurveTest, TwoFloatKeyframe)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 2),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(1, 4),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(0, 2));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 4));
     EXPECT_FLOAT_EQ(2, curve->getValue(-1));
     EXPECT_FLOAT_EQ(2, curve->getValue(0));
     EXPECT_FLOAT_EQ(3, curve->getValue(0.5));
@@ -47,12 +44,9 @@
 TEST(WebFloatAnimationCurveTest, ThreeFloatKeyframe)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 2),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(1, 4),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(2, 8),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(0, 2));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 4));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(2, 8));
     EXPECT_FLOAT_EQ(2, curve->getValue(-1));
     EXPECT_FLOAT_EQ(2, curve->getValue(0));
     EXPECT_FLOAT_EQ(3, curve->getValue(0.5));
@@ -66,14 +60,10 @@
 TEST(WebFloatAnimationCurveTest, RepeatedFloatKeyTimes)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 4),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(1, 4),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(1, 6),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(2, 6),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(0, 4));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 4));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 6));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(2, 6));
 
     EXPECT_FLOAT_EQ(4, curve->getValue(-1));
     EXPECT_FLOAT_EQ(4, curve->getValue(0));
@@ -92,12 +82,9 @@
 TEST(WebFloatAnimationCurveTest, UnsortedKeyframes)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(2, 8),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(0, 2),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(1, 4),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(2, 8));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(0, 2));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 4));
 
     EXPECT_FLOAT_EQ(2, curve->getValue(-1));
     EXPECT_FLOAT_EQ(2, curve->getValue(0));
@@ -112,9 +99,8 @@
 TEST(WebFloatAnimationCurveTest, CubicBezierTimingFunction)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 0), 0.25, 0, 0.75, 1);
-    curve->add(CompositorFloatKeyframe(1, 1),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0, 0), 0.25, 0, 0.75, 1);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 1));
 
     EXPECT_FLOAT_EQ(0, curve->getValue(0));
     EXPECT_LT(0, curve->getValue(0.25));
@@ -129,10 +115,8 @@
 TEST(WebFloatAnimationCurveTest, EaseTimingFunction)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 0),
-        CompositorAnimationCurve::TimingFunctionTypeEase);
-    curve->add(CompositorFloatKeyframe(1, 1),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0, 0), CubicBezierTimingFunction::EaseType::EASE);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 1));
 
     std::unique_ptr<cc::TimingFunction> timingFunction(
         cc::EaseTimingFunction::Create());
@@ -146,10 +130,8 @@
 TEST(WebFloatAnimationCurveTest, LinearTimingFunction)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 0),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
-    curve->add(CompositorFloatKeyframe(1, 1),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(0, 0));
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 1));
 
     for (int i = 0; i <= 4; ++i) {
         const double time = i * 0.25;
@@ -161,10 +143,8 @@
 TEST(WebFloatAnimationCurveTest, EaseInTimingFunction)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 0),
-        CompositorAnimationCurve::TimingFunctionTypeEaseIn);
-    curve->add(CompositorFloatKeyframe(1, 1),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0, 0), CubicBezierTimingFunction::EaseType::EASE_IN);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 1));
 
     std::unique_ptr<cc::TimingFunction> timingFunction(
         cc::EaseInTimingFunction::Create());
@@ -178,10 +158,8 @@
 TEST(WebFloatAnimationCurveTest, EaseOutTimingFunction)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 0),
-        CompositorAnimationCurve::TimingFunctionTypeEaseOut);
-    curve->add(CompositorFloatKeyframe(1, 1),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0, 0), CubicBezierTimingFunction::EaseType::EASE_OUT);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 1));
 
     std::unique_ptr<cc::TimingFunction> timingFunction(
         cc::EaseOutTimingFunction::Create());
@@ -195,10 +173,8 @@
 TEST(WebFloatAnimationCurveTest, EaseInOutTimingFunction)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 0),
-        CompositorAnimationCurve::TimingFunctionTypeEaseInOut);
-    curve->add(CompositorFloatKeyframe(1, 1),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0, 0), CubicBezierTimingFunction::EaseType::EASE_IN_OUT);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 1));
 
     std::unique_ptr<cc::TimingFunction> timingFunction(
         cc::EaseInOutTimingFunction::Create());
@@ -216,9 +192,8 @@
     double y1 = 0.2;
     double x2 = 0.8;
     double y2 = 0.7;
-    curve->add(CompositorFloatKeyframe(0, 0), x1, y1, x2, y2);
-    curve->add(CompositorFloatKeyframe(1, 1),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0, 0), x1, y1, x2, y2);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 1));
 
     std::unique_ptr<cc::TimingFunction> timingFunction(
         cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2));
@@ -232,9 +207,8 @@
 TEST(WebFloatAnimationCurveTest, DefaultTimingFunction)
 {
     std::unique_ptr<CompositorFloatAnimationCurve> curve(new CompositorFloatAnimationCurve);
-    curve->add(CompositorFloatKeyframe(0, 0));
-    curve->add(CompositorFloatKeyframe(1, 1),
-        CompositorAnimationCurve::TimingFunctionTypeLinear);
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0, 0), CubicBezierTimingFunction::EaseType::EASE);
+    curve->addLinearKeyframe(CompositorFloatKeyframe(1, 1));
 
     std::unique_ptr<cc::TimingFunction> timingFunction(
         cc::EaseTimingFunction::Create());
diff --git a/third_party/WebKit/Source/platform/animation/CompositorScrollOffsetAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorScrollOffsetAnimationCurve.cpp
index 6c9ba0c..2383fe94 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorScrollOffsetAnimationCurve.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorScrollOffsetAnimationCurve.cpp
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "platform/animation/CompositorScrollOffsetAnimationCurve.h"
+#include "platform/animation/TimingFunction.h"
 
 #include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/animation/timing_function.h"
@@ -30,11 +31,10 @@
 
 CompositorScrollOffsetAnimationCurve::CompositorScrollOffsetAnimationCurve(
     FloatPoint targetValue,
-    TimingFunctionType timingFunction,
     ScrollDurationBehavior durationBehavior)
     : m_curve(cc::ScrollOffsetAnimationCurve::Create(
         gfx::ScrollOffset(targetValue.x(), targetValue.y()),
-        createTimingFunction(timingFunction),
+        cc::CubicBezierTimingFunction::CreatePreset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
         GetDurationBehavior(durationBehavior)))
 {
 }
diff --git a/third_party/WebKit/Source/platform/animation/CompositorScrollOffsetAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorScrollOffsetAnimationCurve.h
index ebf9e7a..f7baac0 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorScrollOffsetAnimationCurve.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorScrollOffsetAnimationCurve.h
@@ -25,7 +25,7 @@
         ScrollDurationInverseDelta
     };
 
-    CompositorScrollOffsetAnimationCurve(FloatPoint, TimingFunctionType, ScrollDurationBehavior);
+    CompositorScrollOffsetAnimationCurve(FloatPoint, ScrollDurationBehavior);
     CompositorScrollOffsetAnimationCurve(cc::ScrollOffsetAnimationCurve*);
     ~CompositorScrollOffsetAnimationCurve() override;
 
diff --git a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp
index 7f320a06..d2b24f0 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp
@@ -22,20 +22,22 @@
 {
 }
 
-void CompositorTransformAnimationCurve::add(const CompositorTransformKeyframe& keyframe)
+void CompositorTransformAnimationCurve::addLinearKeyframe(const CompositorTransformKeyframe& keyframe)
 {
-    add(keyframe, TimingFunctionTypeEase);
+    const cc::TransformOperations& transformOperations = keyframe.value().asTransformOperations();
+    m_curve->AddKeyframe(cc::TransformKeyframe::Create(
+        base::TimeDelta::FromSecondsD(keyframe.time()), transformOperations, nullptr));
 }
 
-void CompositorTransformAnimationCurve::add(const CompositorTransformKeyframe& keyframe, TimingFunctionType type)
+void CompositorTransformAnimationCurve::addCubicBezierKeyframe(const CompositorTransformKeyframe& keyframe, CubicBezierTimingFunction::EaseType easeType)
 {
     const cc::TransformOperations& transformOperations = keyframe.value().asTransformOperations();
     m_curve->AddKeyframe(cc::TransformKeyframe::Create(
         base::TimeDelta::FromSecondsD(keyframe.time()), transformOperations,
-        createTimingFunction(type)));
+        cc::CubicBezierTimingFunction::CreatePreset(easeType)));
 }
 
-void CompositorTransformAnimationCurve::add(const CompositorTransformKeyframe& keyframe,  double x1, double y1, double x2, double y2)
+void CompositorTransformAnimationCurve::addCubicBezierKeyframe(const CompositorTransformKeyframe& keyframe,  double x1, double y1, double x2, double y2)
 {
     const cc::TransformOperations& transformOperations = keyframe.value().asTransformOperations();
     m_curve->AddKeyframe(cc::TransformKeyframe::Create(
@@ -43,7 +45,7 @@
         cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
 }
 
-void CompositorTransformAnimationCurve::add(const CompositorTransformKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
+void CompositorTransformAnimationCurve::addStepsKeyframe(const CompositorTransformKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
 {
     const cc::TransformOperations& transformOperations = keyframe.value().asTransformOperations();
     m_curve->AddKeyframe(cc::TransformKeyframe::Create(
@@ -56,9 +58,9 @@
     m_curve->SetTimingFunction(nullptr);
 }
 
-void CompositorTransformAnimationCurve::setCubicBezierTimingFunction(TimingFunctionType type)
+void CompositorTransformAnimationCurve::setCubicBezierTimingFunction(CubicBezierTimingFunction::EaseType easeType)
 {
-    m_curve->SetTimingFunction(createTimingFunction(type));
+    m_curve->SetTimingFunction(cc::CubicBezierTimingFunction::CreatePreset(easeType));
 }
 
 void CompositorTransformAnimationCurve::setCubicBezierTimingFunction(double x1, double y1, double x2, double y2)
diff --git a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h
index 25ae686..724fe1b1 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h
@@ -11,8 +11,6 @@
 #include "platform/animation/TimingFunction.h"
 #include "wtf/Noncopyable.h"
 
-#include <memory>
-
 namespace cc {
 class KeyframedTransformAnimationCurve;
 }
@@ -30,17 +28,15 @@
     CompositorTransformAnimationCurve();
     ~CompositorTransformAnimationCurve() override;
 
-    // Adds the keyframe with the default timing function (ease).
-    virtual void add(const CompositorTransformKeyframe&);
-    virtual void add(const CompositorTransformKeyframe&, TimingFunctionType);
+    virtual void addLinearKeyframe(const CompositorTransformKeyframe&);
+    virtual void addCubicBezierKeyframe(const CompositorTransformKeyframe&, CubicBezierTimingFunction::EaseType);
     // Adds the keyframe with a custom, bezier timing function. Note, it is
     // assumed that x0 = y0, and x3 = y3 = 1.
-    virtual void add(const CompositorTransformKeyframe&, double x1, double y1, double x2, double y2);
-    // Adds the keyframe with a steps timing function.
-    virtual void add(const CompositorTransformKeyframe&, int steps, StepsTimingFunction::StepPosition);
+    virtual void addCubicBezierKeyframe(const CompositorTransformKeyframe&, double x1, double y1, double x2, double y2);
+    virtual void addStepsKeyframe(const CompositorTransformKeyframe&, int steps, StepsTimingFunction::StepPosition);
 
     virtual void setLinearTimingFunction();
-    virtual void setCubicBezierTimingFunction(TimingFunctionType);
+    virtual void setCubicBezierTimingFunction(CubicBezierTimingFunction::EaseType);
     virtual void setCubicBezierTimingFunction(double x1, double y1, double x2, double y2);
     virtual void setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition);
 
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunction.cpp b/third_party/WebKit/Source/platform/animation/TimingFunction.cpp
index 905fbf04..52c16dd 100644
--- a/third_party/WebKit/Source/platform/animation/TimingFunction.cpp
+++ b/third_party/WebKit/Source/platform/animation/TimingFunction.cpp
@@ -25,23 +25,23 @@
 
 String CubicBezierTimingFunction::toString() const
 {
-    switch (this->subType()) {
-    case CubicBezierTimingFunction::Ease:
+    switch (this->getEaseType()) {
+    case CubicBezierTimingFunction::EaseType::EASE:
         return "ease";
-    case CubicBezierTimingFunction::EaseIn:
+    case CubicBezierTimingFunction::EaseType::EASE_IN:
         return "ease-in";
-    case CubicBezierTimingFunction::EaseOut:
+    case CubicBezierTimingFunction::EaseType::EASE_OUT:
         return "ease-out";
-    case CubicBezierTimingFunction::EaseInOut:
+    case CubicBezierTimingFunction::EaseType::EASE_IN_OUT:
         return "ease-in-out";
-    case CubicBezierTimingFunction::Custom:
+    case CubicBezierTimingFunction::EaseType::CUSTOM:
         return "cubic-bezier(" + String::numberToStringECMAScript(this->x1()) + ", " +
             String::numberToStringECMAScript(this->y1()) + ", " + String::numberToStringECMAScript(this->x2()) +
             ", " + String::numberToStringECMAScript(this->y2()) + ")";
     default:
-        ASSERT_NOT_REACHED();
+        NOTREACHED();
+        return "";
     }
-    return "";
 }
 
 double CubicBezierTimingFunction::evaluate(double fraction, double accuracy) const
@@ -169,10 +169,10 @@
         return false;
 
     const CubicBezierTimingFunction& ctf = toCubicBezierTimingFunction(rhs);
-    if ((lhs.subType() == CubicBezierTimingFunction::Custom) && (ctf.subType() == CubicBezierTimingFunction::Custom))
+    if ((lhs.getEaseType() == CubicBezierTimingFunction::EaseType::CUSTOM) && (ctf.getEaseType() == CubicBezierTimingFunction::EaseType::CUSTOM))
         return (lhs.x1() == ctf.x1()) && (lhs.y1() == ctf.y1()) && (lhs.x2() == ctf.x2()) && (lhs.y2() == ctf.y2());
 
-    return lhs.subType() == ctf.subType();
+    return lhs.getEaseType() == ctf.getEaseType();
 }
 
 bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs)
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunction.h b/third_party/WebKit/Source/platform/animation/TimingFunction.h
index 325e67d..caab057 100644
--- a/third_party/WebKit/Source/platform/animation/TimingFunction.h
+++ b/third_party/WebKit/Source/platform/animation/TimingFunction.h
@@ -94,45 +94,32 @@
 
 class PLATFORM_EXPORT CubicBezierTimingFunction final : public TimingFunction {
 public:
-    enum FunctionSubType {
-        Ease,
-        EaseIn,
-        EaseOut,
-        EaseInOut,
-        Custom
-    };
+    using EaseType = cc::CubicBezierTimingFunction::EaseType;
 
     static PassRefPtr<CubicBezierTimingFunction> create(double x1, double y1, double x2, double y2)
     {
-        return adoptRef(new CubicBezierTimingFunction(Custom, x1, y1, x2, y2));
+        return adoptRef(new CubicBezierTimingFunction(EaseType::CUSTOM, x1, y1, x2, y2));
     }
 
-    static CubicBezierTimingFunction* preset(FunctionSubType subType)
+    static CubicBezierTimingFunction* preset(EaseType easeType)
     {
-        switch (subType) {
-        case Ease:
-            {
-                DEFINE_STATIC_REF(CubicBezierTimingFunction, ease, (adoptRef(new CubicBezierTimingFunction(Ease, 0.25, 0.1, 0.25, 1.0))));
-                return ease;
-            }
-        case EaseIn:
-            {
-                DEFINE_STATIC_REF(CubicBezierTimingFunction, easeIn, (adoptRef(new CubicBezierTimingFunction(EaseIn, 0.42, 0.0, 1.0, 1.0))));
-                return easeIn;
-            }
-        case EaseOut:
-            {
-                DEFINE_STATIC_REF(CubicBezierTimingFunction, easeOut, (adoptRef(new CubicBezierTimingFunction(EaseOut, 0.0, 0.0, 0.58, 1.0))));
-                return easeOut;
-            }
-        case EaseInOut:
-            {
-                DEFINE_STATIC_REF(CubicBezierTimingFunction, easeInOut, (adoptRef(new CubicBezierTimingFunction(EaseInOut, 0.42, 0.0, 0.58, 1.0))));
-                return easeInOut;
-            }
+        DEFINE_STATIC_REF(CubicBezierTimingFunction, ease, (adoptRef(new CubicBezierTimingFunction(EaseType::EASE, 0.25, 0.1, 0.25, 1.0))));
+        DEFINE_STATIC_REF(CubicBezierTimingFunction, easeIn, (adoptRef(new CubicBezierTimingFunction(EaseType::EASE_IN, 0.42, 0.0, 1.0, 1.0))));
+        DEFINE_STATIC_REF(CubicBezierTimingFunction, easeOut, (adoptRef(new CubicBezierTimingFunction(EaseType::EASE_OUT, 0.0, 0.0, 0.58, 1.0))));
+        DEFINE_STATIC_REF(CubicBezierTimingFunction, easeInOut, (adoptRef(new CubicBezierTimingFunction(EaseType::EASE_IN_OUT, 0.42, 0.0, 0.58, 1.0))));
+
+        switch (easeType) {
+        case EaseType::EASE:
+            return ease;
+        case EaseType::EASE_IN:
+            return easeIn;
+        case EaseType::EASE_OUT:
+            return easeOut;
+        case EaseType::EASE_IN_OUT:
+            return easeInOut;
         default:
-            ASSERT_NOT_REACHED();
-            return 0;
+            NOTREACHED();
+            return nullptr;
         }
     }
 
@@ -148,17 +135,17 @@
     double x2() const { return m_x2; }
     double y2() const { return m_y2; }
 
-    FunctionSubType subType() const { return m_subType; }
+    EaseType getEaseType() const { return m_easeType; }
 
 private:
-    explicit CubicBezierTimingFunction(FunctionSubType subType, double x1, double y1, double x2, double y2)
+    explicit CubicBezierTimingFunction(EaseType easeType, double x1, double y1, double x2, double y2)
         : TimingFunction(kCubicBezierFunction)
         , m_bezier(x1, y1, x2, y2)
         , m_x1(x1)
         , m_y1(y1)
         , m_x2(x2)
         , m_y2(y2)
-        , m_subType(subType)
+        , m_easeType(easeType)
     {
     }
 
@@ -172,7 +159,7 @@
     const double m_y1;
     const double m_x2;
     const double m_y2;
-    FunctionSubType m_subType;
+    const EaseType m_easeType;
 };
 
 class PLATFORM_EXPORT StepsTimingFunction final : public TimingFunction {
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunctionTest.cpp b/third_party/WebKit/Source/platform/animation/TimingFunctionTest.cpp
index 67b0a39..8867d139 100644
--- a/third_party/WebKit/Source/platform/animation/TimingFunctionTest.cpp
+++ b/third_party/WebKit/Source/platform/animation/TimingFunctionTest.cpp
@@ -73,13 +73,13 @@
 
 TEST_F(TimingFunctionTest, CubicToString)
 {
-    RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
+    RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE);
     EXPECT_EQ("ease", cubicEaseTiming->toString());
-    RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
+    RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN);
     EXPECT_EQ("ease-in", cubicEaseInTiming->toString());
-    RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
+    RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT);
     EXPECT_EQ("ease-out", cubicEaseOutTiming->toString());
-    RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
+    RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT);
     EXPECT_EQ("ease-in-out", cubicEaseInOutTiming->toString());
 
     RefPtr<TimingFunction> cubicCustomTiming = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
@@ -110,7 +110,7 @@
 TEST_F(TimingFunctionTest, BaseOperatorEq)
 {
     RefPtr<TimingFunction> linearTiming = LinearTimingFunction::shared();
-    RefPtr<TimingFunction> cubicTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
+    RefPtr<TimingFunction> cubicTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN);
     RefPtr<TimingFunction> cubicTiming2 = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
     RefPtr<TimingFunction> stepsTiming1 = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END);
     RefPtr<TimingFunction> stepsTiming2 = StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::START);
@@ -134,18 +134,18 @@
 
 TEST_F(TimingFunctionTest, CubicOperatorEq)
 {
-    RefPtr<TimingFunction> cubicEaseInTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
-    RefPtr<TimingFunction> cubicEaseInTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
+    RefPtr<TimingFunction> cubicEaseInTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN);
+    RefPtr<TimingFunction> cubicEaseInTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN);
     EXPECT_EQ(*cubicEaseInTiming1, *cubicEaseInTiming1);
     EXPECT_EQ(*cubicEaseInTiming1, *cubicEaseInTiming2);
 
-    RefPtr<TimingFunction> cubicEaseOutTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
-    RefPtr<TimingFunction> cubicEaseOutTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
+    RefPtr<TimingFunction> cubicEaseOutTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT);
+    RefPtr<TimingFunction> cubicEaseOutTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT);
     EXPECT_EQ(*cubicEaseOutTiming1, *cubicEaseOutTiming1);
     EXPECT_EQ(*cubicEaseOutTiming1, *cubicEaseOutTiming2);
 
-    RefPtr<TimingFunction> cubicEaseInOutTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
-    RefPtr<TimingFunction> cubicEaseInOutTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
+    RefPtr<TimingFunction> cubicEaseInOutTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT);
+    RefPtr<TimingFunction> cubicEaseInOutTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT);
     EXPECT_EQ(*cubicEaseInOutTiming1, *cubicEaseInOutTiming1);
     EXPECT_EQ(*cubicEaseInOutTiming1, *cubicEaseInOutTiming2);
 
@@ -164,7 +164,7 @@
 
 TEST_F(TimingFunctionTest, CubicOperatorEqReflectivity)
 {
-    RefPtr<TimingFunction> cubicA = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
+    RefPtr<TimingFunction> cubicA = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN);
     RefPtr<TimingFunction> cubicB = CubicBezierTimingFunction::create(0.42, 0.0, 1.0, 1.0);
     EXPECT_NE(*cubicA, *cubicB);
     EXPECT_NE(*cubicB, *cubicA);
@@ -255,7 +255,7 @@
     double start = 0;
     double end = 1;
 
-    RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
+    RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE);
     start = 0;
     end = 1;
     cubicEaseTiming->range(&start, &end);
@@ -267,7 +267,7 @@
     EXPECT_NEAR(-0.4, start, 0.01);
     EXPECT_NEAR(1, end, 0.01);
 
-    RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
+    RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN);
     start = 0;
     end = 1;
     cubicEaseInTiming->range(&start, &end);
@@ -279,7 +279,7 @@
     EXPECT_NEAR(0.0, start, 0.01);
     EXPECT_NEAR(16.51, end, 0.01);
 
-    RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
+    RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT);
     start = 0;
     end = 1;
     cubicEaseOutTiming->range(&start, &end);
@@ -291,7 +291,7 @@
     EXPECT_NEAR(-1.72, start, 0.01);
     EXPECT_NEAR(1.0, end, 0.01);
 
-    RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
+    RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT);
     start = 0;
     end = 1;
     cubicEaseInOutTiming->range(&start, &end);
@@ -320,22 +320,22 @@
 TEST_F(TimingFunctionTest, CubicEvaluate)
 {
     double tolerance = 0.01;
-    RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
+    RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE);
     EXPECT_NEAR(0.418, cubicEaseTiming->evaluate(0.25, tolerance), tolerance);
     EXPECT_NEAR(0.805, cubicEaseTiming->evaluate(0.50, tolerance), tolerance);
     EXPECT_NEAR(0.960, cubicEaseTiming->evaluate(0.75, tolerance), tolerance);
 
-    RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
+    RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN);
     EXPECT_NEAR(0.093, cubicEaseInTiming->evaluate(0.25, tolerance), tolerance);
     EXPECT_NEAR(0.305, cubicEaseInTiming->evaluate(0.50, tolerance), tolerance);
     EXPECT_NEAR(0.620, cubicEaseInTiming->evaluate(0.75, tolerance), tolerance);
 
-    RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
+    RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT);
     EXPECT_NEAR(0.379, cubicEaseOutTiming->evaluate(0.25, tolerance), tolerance);
     EXPECT_NEAR(0.694, cubicEaseOutTiming->evaluate(0.50, tolerance), tolerance);
     EXPECT_NEAR(0.906, cubicEaseOutTiming->evaluate(0.75, tolerance), tolerance);
 
-    RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
+    RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT);
     EXPECT_NEAR(0.128, cubicEaseInOutTiming->evaluate(0.25, tolerance), tolerance);
     EXPECT_NEAR(0.500, cubicEaseInOutTiming->evaluate(0.50, tolerance), tolerance);
     EXPECT_NEAR(0.871, cubicEaseInOutTiming->evaluate(0.75, tolerance), tolerance);
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi
index fcd85e1..a43ef09 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gypi
+++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -145,7 +145,6 @@
       'animation/AnimationUtilities.h',
       'animation/CompositorAnimation.cpp',
       'animation/CompositorAnimation.h',
-      'animation/CompositorAnimationCurve.cpp',
       'animation/CompositorAnimationCurve.h',
       'animation/CompositorAnimationDelegate.h',
       'animation/CompositorAnimationHost.cpp',
@@ -334,7 +333,6 @@
       'exported/WebMediaStreamTrack.cpp',
       'exported/WebMediaStreamTrackSourcesRequest.cpp',
       'exported/WebMemoryAllocatorDump.cpp',
-      'exported/WebMemoryDumpProvider.cpp',
       'exported/WebMessagePortChannelClient.cpp',
       'exported/WebPasswordCredential.cpp',
       'exported/WebPrerender.cpp',
@@ -1111,8 +1109,6 @@
       'v8_inspector/public/V8ToProtocolValue.h',
       'web_memory_allocator_dump_impl.cc',
       'web_memory_allocator_dump_impl.h',
-      'web_memory_dump_provider_adapter.cc',
-      'web_memory_dump_provider_adapter.h',
       'web_process_memory_dump_impl.cc',
       'web_process_memory_dump_impl.h',
       'weborigin/KURL.cpp',
diff --git a/third_party/WebKit/Source/platform/exported/Platform.cpp b/third_party/WebKit/Source/platform/exported/Platform.cpp
index 0a1b610..171c4a8 100644
--- a/third_party/WebKit/Source/platform/exported/Platform.cpp
+++ b/third_party/WebKit/Source/platform/exported/Platform.cpp
@@ -37,7 +37,6 @@
 #include "platform/graphics/CompositorFactory.h"
 #include "platform/heap/BlinkGCMemoryDumpProvider.h"
 #include "platform/heap/GCTaskRunner.h"
-#include "platform/web_memory_dump_provider_adapter.h"
 #include "public/platform/Platform.h"
 #include "public/platform/ServiceRegistry.h"
 #include "public/platform/WebPrerenderingSupport.h"
@@ -47,20 +46,9 @@
 namespace blink {
 
 static Platform* s_platform = nullptr;
-using ProviderToAdapterMap = HashMap<WebMemoryDumpProvider*, OwnPtr<WebMemoryDumpProviderAdapter>>;
 
 static GCTaskRunner* s_gcTaskRunner = nullptr;
 
-namespace {
-
-ProviderToAdapterMap& memoryDumpProviders()
-{
-    DEFINE_STATIC_LOCAL(ProviderToAdapterMap, providerToAdapterMap, ());
-    return providerToAdapterMap;
-}
-
-} // namespace
-
 Platform::Platform()
     : m_mainThread(0)
 {
@@ -157,35 +145,6 @@
     return m_mainThread;
 }
 
-void Platform::registerMemoryDumpProvider(WebMemoryDumpProvider* provider, const char* name)
-{
-    // MemoryDumpProvider needs a message loop.
-    if (!Platform::current()->currentThread())
-        return;
-
-    WebMemoryDumpProviderAdapter* adapter = new WebMemoryDumpProviderAdapter(provider);
-    ProviderToAdapterMap::AddResult result = memoryDumpProviders().add(provider, adoptPtr(adapter));
-    if (!result.isNewEntry)
-        return;
-    adapter->set_is_registered(true);
-    base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(adapter, name, base::ThreadTaskRunnerHandle::Get());
-}
-
-void Platform::unregisterMemoryDumpProvider(WebMemoryDumpProvider* provider)
-{
-    // MemoryDumpProvider needs a message loop.
-    if (!Platform::current()->currentThread())
-        return;
-
-    ProviderToAdapterMap::iterator it = memoryDumpProviders().find(provider);
-    if (it == memoryDumpProviders().end())
-        return;
-    WebMemoryDumpProviderAdapter* adapter = it->value.get();
-    base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(adapter);
-    adapter->set_is_registered(false);
-    memoryDumpProviders().remove(it);
-}
-
 ServiceRegistry* Platform::serviceRegistry()
 {
     return ServiceRegistry::getEmptyServiceRegistry();
diff --git a/third_party/WebKit/Source/platform/exported/WebMemoryDumpProvider.cpp b/third_party/WebKit/Source/platform/exported/WebMemoryDumpProvider.cpp
deleted file mode 100644
index 9bdf38d4..0000000
--- a/third_party/WebKit/Source/platform/exported/WebMemoryDumpProvider.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2015 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 "public/platform/WebMemoryDumpProvider.h"
-
-namespace blink {
-
-WebMemoryDumpProvider::~WebMemoryDumpProvider()
-{
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorFactory.cpp b/third_party/WebKit/Source/platform/graphics/CompositorFactory.cpp
index b086028..4f2e881 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorFactory.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CompositorFactory.cpp
@@ -29,11 +29,9 @@
 
     CompositorScrollOffsetAnimationCurve* createScrollOffsetAnimationCurve(
         FloatPoint targetValue,
-        CompositorAnimationCurve::TimingFunctionType timingFunctionType,
         CompositorScrollOffsetAnimationCurve::ScrollDurationBehavior durationBehavior)
     {
-        return new CompositorScrollOffsetAnimationCurve(targetValue, timingFunctionType,
-            durationBehavior);
+        return new CompositorScrollOffsetAnimationCurve(targetValue, durationBehavior);
     }
 
     CompositorScrollOffsetAnimationCurve* createScrollOffsetAnimationCurve(
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorFactory.h b/third_party/WebKit/Source/platform/graphics/CompositorFactory.h
index 098e3e03..a13cf409 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorFactory.h
+++ b/third_party/WebKit/Source/platform/graphics/CompositorFactory.h
@@ -37,7 +37,6 @@
 
     virtual CompositorScrollOffsetAnimationCurve* createScrollOffsetAnimationCurve(
         FloatPoint targetValue,
-        CompositorAnimationCurve::TimingFunctionType,
         CompositorScrollOffsetAnimationCurve::ScrollDurationBehavior) { return nullptr; }
 
     virtual CompositorScrollOffsetAnimationCurve* createScrollOffsetAnimationCurve(
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index 5dec2fd..c1b7be8 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -343,7 +343,6 @@
         && !m_client->needsRepaint(*this)
         && !getPaintController().cacheIsEmpty()
         && m_previousInterestRect == *interestRect) {
-        ASSERT(!getPaintController().hasInvalidations());
         return false;
     }
 
@@ -554,8 +553,8 @@
     ASSERT(isTrackingPaintInvalidations());
 
     Vector<PaintInvalidationInfo>& infos = paintInvalidationTrackingMap().add(this, Vector<PaintInvalidationInfo>()).storedValue->value;
-    // Omit the entry for invalidateDisplayItemClient() if the last entry is for the same client.
-    // This is to avoid duplicated entries for setNeedsDisplayInRect() and invalidateDisplayItemClient().
+    // Omit the entry for trackObjectPaintInvalidation() if the last entry is for the same client.
+    // This is to avoid duplicated entries for setNeedsDisplayInRect() and trackObjectPaintInvalidation().
     if (rect.isEmpty() && !infos.isEmpty() && infos.last().client == &client)
         return;
 
@@ -878,9 +877,8 @@
     // Note that we don't resize m_contentsLayer. It's up the caller to do that.
 
 #ifndef NDEBUG
-    // The red debug fill needs to be invalidated if the layer resizes.
-    if (m_paintController)
-        m_paintController->invalidateUntracked(*this);
+    // The red debug fill and needs to be invalidated if the layer resizes.
+    setDisplayItemsUncached();
 #endif
 }
 
@@ -1072,12 +1070,12 @@
         trackPaintInvalidation(client, rect, invalidationReason);
 }
 
-void GraphicsLayer::invalidateDisplayItemClient(const DisplayItemClient& displayItemClient, PaintInvalidationReason invalidationReason)
+void GraphicsLayer::displayItemClientWasInvalidated(const DisplayItemClient& displayItemClient, PaintInvalidationReason invalidationReason)
 {
     if (!drawsContent())
         return;
 
-    getPaintController().invalidate(displayItemClient);
+    getPaintController().displayItemClientWasInvalidated(displayItemClient);
 
     if (isTrackingPaintInvalidations())
         trackPaintInvalidation(displayItemClient, FloatRect(), invalidationReason);
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index 11983f3..d1d72af 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -186,7 +186,9 @@
 
     void setContentsNeedsDisplay();
 
-    void invalidateDisplayItemClient(const DisplayItemClient&, PaintInvalidationReason);
+    // This is called only if we are tracking paint invalidation for testing, or ENABLE(ASSERT)
+    // for error checking and debugging.
+    void displayItemClientWasInvalidated(const DisplayItemClient&, PaintInvalidationReason);
 
     // Set that the position/size of the contents (image or video).
     void setContentsRect(const IntRect&);
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
index 68ecef10..67b15bf 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -105,7 +105,7 @@
     ASSERT_FALSE(m_platformLayer->hasActiveAnimationForTesting());
 
     OwnPtr<CompositorFloatAnimationCurve> curve = adoptPtr(CompositorFactory::current().createFloatAnimationCurve());
-    curve->add(CompositorFloatKeyframe(0.0, 0.0));
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0.0, 0.0), CubicBezierTimingFunction::EaseType::EASE);
     OwnPtr<CompositorAnimation> floatAnimation(adoptPtr(CompositorFactory::current().createAnimation(*curve, CompositorTargetProperty::OPACITY)));
     int animationId = floatAnimation->id();
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index 6b6db13..a35ff2191 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -128,26 +128,19 @@
     endSkippingCache();
 }
 
-void PaintController::invalidate(const DisplayItemClient& client)
+void PaintController::displayItemClientWasInvalidated(const DisplayItemClient& client)
 {
 #if DCHECK_IS_ON()
     // Slimming paint v1 CompositedLayerMapping may invalidate client on extra layers.
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() || clientCacheIsValid(client))
         m_invalidations.append(client.debugName());
-#endif
 
-    invalidateUntracked(client);
-    if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvalidationObjects)
-        m_trackedPaintInvalidationObjects->append(client.debugName());
-}
-
-void PaintController::invalidateUntracked(const DisplayItemClient& client)
-{
-    // This can be called during painting, but we can't invalidate already painted clients.
-    client.setDisplayItemsUncached();
-#if DCHECK_IS_ON()
+    // Should not invalidate already painted clients.
     DCHECK(!m_newDisplayItemIndicesByClient.contains(&client));
 #endif
+
+    if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvalidationObjects)
+        m_trackedPaintInvalidationObjects->append(client.debugName());
 }
 
 void PaintController::invalidateAll()
@@ -174,7 +167,8 @@
 void PaintController::invalidatePaintOffset(const DisplayItemClient& client)
 {
     DCHECK(RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled());
-    invalidate(client);
+    displayItemClientWasInvalidated(client);
+    client.setDisplayItemsUncached();
 
 #if DCHECK_IS_ON()
     DCHECK(!paintOffsetWasInvalidated(client));
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
index dfa343e..95c1428 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
@@ -42,10 +42,6 @@
         return adoptPtr(new PaintController());
     }
 
-    // These methods are called during paint invalidation (or paint if SlimmingPaintV2 is on).
-
-    void invalidate(const DisplayItemClient&);
-    void invalidateUntracked(const DisplayItemClient&);
     void invalidateAll();
 
     // Record when paint offsets change during paint.
@@ -144,6 +140,10 @@
     void showDebugData() const;
 #endif
 
+    // This is called only if we are tracking paint invalidation for testing, or DCHECK_IS_ON()
+    // for error checking and debugging.
+    void displayItemClientWasInvalidated(const DisplayItemClient&);
+
 #if DCHECK_IS_ON()
     bool hasInvalidations() { return !m_invalidations.isEmpty(); }
 #endif
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
index 8692c119..4bdf5c10 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -120,7 +120,7 @@
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(first, foregroundDrawingType));
 
-    getPaintController().invalidate(second);
+    second.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 300, 300));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 300, 300));
     getPaintController().commitNewDisplayItems();
@@ -147,7 +147,7 @@
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(unaffected, backgroundDrawingType));
 
-    getPaintController().invalidate(second);
+    second.setDisplayItemsUncached();
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, unaffected, backgroundDrawingType, FloatRect(300, 300, 10, 10));
@@ -208,7 +208,7 @@
         TestDisplayItem(second, foregroundDrawingType),
         TestDisplayItem(third, foregroundDrawingType));
 
-    getPaintController().invalidate(second);
+    second.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, third, backgroundDrawingType, FloatRect(300, 100, 50, 50));
@@ -240,8 +240,8 @@
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(second, foregroundDrawingType));
 
-    getPaintController().invalidate(first);
-    getPaintController().invalidate(second);
+    first.setDisplayItemsUncached();
+    second.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50));
@@ -254,7 +254,7 @@
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(second, foregroundDrawingType));
 
-    getPaintController().invalidate(first);
+    first.setDisplayItemsUncached();
     drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50));
     drawRect(context, second, foregroundDrawingType, FloatRect(200, 200, 50, 50));
     getPaintController().commitNewDisplayItems();
@@ -278,8 +278,8 @@
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(first, foregroundDrawingType));
 
-    getPaintController().invalidate(first);
-    getPaintController().invalidate(second);
+    first.setDisplayItemsUncached();
+    second.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50));
@@ -292,8 +292,8 @@
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(second, foregroundDrawingType));
 
-    getPaintController().invalidate(first);
-    getPaintController().invalidate(second);
+    first.setDisplayItemsUncached();
+    second.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 150, 150));
     getPaintController().commitNewDisplayItems();
@@ -322,7 +322,7 @@
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(first, DisplayItem::clipTypeToEndClipType(clipType)));
 
-    getPaintController().invalidate(first);
+    first.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     getPaintController().commitNewDisplayItems();
@@ -331,7 +331,7 @@
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType));
 
-    getPaintController().invalidate(second);
+    second.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     {
         ClipRecorder clipRecorder(context, second, clipType, LayoutRect(1, 1, 2, 2));
@@ -364,7 +364,7 @@
     const SkPicture* firstPicture = static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[0]).picture();
     const SkPicture* secondPicture = static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[1]).picture();
 
-    getPaintController().invalidate(first);
+    first.setDisplayItemsUncached();
     EXPECT_FALSE(getPaintController().clientCacheIsValid(first));
     EXPECT_TRUE(getPaintController().clientCacheIsValid(second));
 
@@ -416,7 +416,7 @@
         TestDisplayItem(container2, foregroundDrawingType));
 
     // Simulate the situation when container1 e.g. gets a z-index that is now greater than container2.
-    getPaintController().invalidate(container1);
+    container1.setDisplayItemsUncached();
     drawRect(context, container2, backgroundDrawingType, FloatRect(100, 200, 100, 100));
     drawRect(context, content2, backgroundDrawingType, FloatRect(100, 200, 50, 200));
     drawRect(context, content2, foregroundDrawingType, FloatRect(100, 200, 50, 200));
@@ -574,13 +574,13 @@
         TestDisplayItem(container2, DisplayItem::EndSubsequence));
 
     // Invalidate container1 but not content1.
-    getPaintController().invalidate(container1);
+    container1.setDisplayItemsUncached();
 
     // Container2 itself now becomes empty (but still has the 'content2' child),
     // and chooses not to output subsequence info.
 
-    getPaintController().invalidate(container2);
-    getPaintController().invalidate(content2);
+    container2.setDisplayItemsUncached();
+    content2.setDisplayItemsUncached();
     EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container2));
     EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, content2));
     // Content2 now outputs foreground only.
@@ -676,7 +676,7 @@
     EXPECT_NE(picture2, static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[2]).picture());
 
     // Now the multicol becomes 3 columns and repaints.
-    getPaintController().invalidate(multicol);
+    multicol.setDisplayItemsUncached();
     drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 100, 100, 100));
 
     getPaintController().beginScope();
@@ -725,7 +725,7 @@
         TestDisplayItem(second, DisplayItem::EndClipPath),
         TestDisplayItem(third, backgroundDrawingType));
 
-    getPaintController().invalidate(second);
+    second.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(0, 0, 100, 100));
     {
         ClipRecorder clipRecorder(context, second, clipType, LayoutRect(1, 1, 2, 2));
@@ -739,7 +739,7 @@
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(third, backgroundDrawingType));
 
-    getPaintController().invalidate(second);
+    second.setDisplayItemsUncached();
     drawRect(context, first, backgroundDrawingType, FloatRect(0, 0, 100, 100));
     {
         ClipRecorder clipRecorder(context, second, clipType, LayoutRect(1, 1, 2, 2));
@@ -858,7 +858,7 @@
         EXPECT_FALSE(getPaintController().paintArtifact().isSuitableForGpuRasterization());
     }
 
-    getPaintController().invalidate(client);
+    client.setDisplayItemsUncached();
 
     {
         GraphicsContext context(getPaintController());
diff --git a/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.h b/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.h
index b829c59..5d056d30 100644
--- a/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.h
+++ b/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.h
@@ -8,7 +8,6 @@
 #include "base/trace_event/memory_dump_provider.h"
 #include "platform/PlatformExport.h"
 #include "platform/heap/BlinkGC.h"
-#include "public/platform/WebMemoryDumpProvider.h"
 #include "wtf/Allocator.h"
 #include "wtf/ThreadingPrimitives.h"
 #include "wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
index dba7b51..85c5c6d 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
@@ -304,7 +304,7 @@
         , m_startTime(0.0)
         , m_duration(duration)
         , m_animation(animation)
-        , m_timingFunction(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut))
+        , m_timingFunction(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT))
     {
     }
 
diff --git a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
index 59bac45..101a0e0 100644
--- a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
@@ -52,7 +52,6 @@
     m_targetOffset = offset;
     m_animationCurve = adoptPtr(CompositorFactory::current().createScrollOffsetAnimationCurve(
         compositorOffsetFromBlinkOffset(m_targetOffset),
-        CompositorAnimationCurve::TimingFunctionTypeEaseInOut,
         CompositorScrollOffsetAnimationCurve::ScrollDurationDeltaBased));
 
     m_scrollableArea->registerForAnimation();
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
index 324ce87..804f154 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
@@ -323,7 +323,6 @@
         if (!m_animationCurve) {
             m_animationCurve = adoptPtr(CompositorFactory::current().createScrollOffsetAnimationCurve(
                 compositorOffsetFromBlinkOffset(m_targetOffset),
-                CompositorAnimationCurve::TimingFunctionTypeEaseInOut,
                 m_lastGranularity == ScrollByPixel ?
                     CompositorScrollOffsetAnimationCurve::ScrollDurationInverseDelta :
                     CompositorScrollOffsetAnimationCurve::ScrollDurationConstant));
diff --git a/third_party/WebKit/Source/platform/testing/FakeDisplayItemClient.h b/third_party/WebKit/Source/platform/testing/FakeDisplayItemClient.h
index e43997df..f18aae6 100644
--- a/third_party/WebKit/Source/platform/testing/FakeDisplayItemClient.h
+++ b/third_party/WebKit/Source/platform/testing/FakeDisplayItemClient.h
@@ -20,9 +20,9 @@
     String debugName() const final { return m_name; }
     LayoutRect visualRect() const override { return m_visualRect; }
 
-private:
     DISPLAY_ITEM_CACHE_STATUS_IMPLEMENTATION
 
+private:
     String m_name;
     LayoutRect m_visualRect;
 };
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
index 14d31c0..9cc309c 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
@@ -94,8 +94,6 @@
     WebString defaultLocale() override;
     WebCompositorSupport* compositorSupport() override;
     WebThread* currentThread() override;
-    void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*, const char* name) override {}
-    void unregisterMemoryDumpProvider(blink::WebMemoryDumpProvider*) override {}
 
 protected:
     const Config m_config;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
index 0dfb7a95..ec1828a 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
@@ -335,7 +335,7 @@
 
     v8::Local<v8::StackTrace> stackTrace = message->GetStackTrace();
     if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0)
-        exceptionDetailsObject->setStack(m_context->debugger()->createStackTrace(stackTrace, stackTrace->GetFrameCount())->buildInspectorObject());
+        exceptionDetailsObject->setStack(m_context->debugger()->createStackTrace(stackTrace)->buildInspectorObject());
     return exceptionDetailsObject;
 }
 
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.cpp
index d0c71ce..7a91b92 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.cpp
@@ -725,10 +725,10 @@
     return script;
 }
 
-std::unique_ptr<V8StackTrace> V8DebuggerImpl::createStackTrace(v8::Local<v8::StackTrace> stackTrace, size_t maxStackSize)
+std::unique_ptr<V8StackTrace> V8DebuggerImpl::createStackTrace(v8::Local<v8::StackTrace> stackTrace)
 {
     V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(m_isolate->GetCurrentContext());
-    return V8StackTraceImpl::create(agent, stackTrace, maxStackSize);
+    return V8StackTraceImpl::create(agent, stackTrace, V8StackTrace::maxCallStackSizeToCapture);
 }
 
 std::unique_ptr<V8InspectorSession> V8DebuggerImpl::connect(int contextGroupId, V8InspectorSessionClient* client, const String16* state)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.h
index ffbe00a..bedb75de 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.h
@@ -114,7 +114,7 @@
     void didExecuteScript(v8::Local<v8::Context>) override;
     void idleStarted() override;
     void idleFinished() override;
-    std::unique_ptr<V8StackTrace> createStackTrace(v8::Local<v8::StackTrace>, size_t maxStackSize) override;
+    std::unique_ptr<V8StackTrace> createStackTrace(v8::Local<v8::StackTrace>) override;
     std::unique_ptr<V8StackTrace> captureStackTrace(size_t maxStackSize) override;
 
     using ContextByIdMap = protocol::HashMap<int, std::unique_ptr<InspectedContext>>;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp
index d43b48d..f821fa61 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp
@@ -72,7 +72,7 @@
 {
 }
 
-// buildInspectorObject() and ScriptCallStack's toTracedValue() should set the same fields.
+// buildInspectorObject() and SourceLocation's toTracedValue() should set the same fields.
 // If either of them is modified, the other should be also modified.
 std::unique_ptr<protocol::Runtime::CallFrame> V8StackTraceImpl::Frame::buildInspectorObject() const
 {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/public/V8Debugger.h b/third_party/WebKit/Source/platform/v8_inspector/public/V8Debugger.h
index 49a9ed8..1972697 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/public/V8Debugger.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/public/V8Debugger.h
@@ -47,7 +47,7 @@
     static bool isCommandLineAPIMethod(const String16& name);
     static bool isCommandLineAPIGetter(const String16& name);
 
-    virtual std::unique_ptr<V8StackTrace> createStackTrace(v8::Local<v8::StackTrace>, size_t maxStackSize) = 0;
+    virtual std::unique_ptr<V8StackTrace> createStackTrace(v8::Local<v8::StackTrace>) = 0;
     virtual std::unique_ptr<V8StackTrace> captureStackTrace(size_t maxStackSize) = 0;
 };
 
diff --git a/third_party/WebKit/Source/platform/web_memory_dump_provider_adapter.cc b/third_party/WebKit/Source/platform/web_memory_dump_provider_adapter.cc
deleted file mode 100644
index 0a57107..0000000
--- a/third_party/WebKit/Source/platform/web_memory_dump_provider_adapter.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015 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 "platform/web_memory_dump_provider_adapter.h"
-
-#include <stddef.h>
-
-#include "base/trace_event/trace_event_argument.h"
-#include "platform/web_process_memory_dump_impl.h"
-#include "public/platform/WebMemoryDumpProvider.h"
-
-namespace blink {
-
-WebMemoryDumpProviderAdapter::WebMemoryDumpProviderAdapter(
-    blink::WebMemoryDumpProvider* wmdp)
-    : web_memory_dump_provider_(wmdp), is_registered_(false) {
-}
-
-WebMemoryDumpProviderAdapter::~WebMemoryDumpProviderAdapter() {
-  DCHECK(!is_registered_);
-}
-
-bool WebMemoryDumpProviderAdapter::OnMemoryDump(
-    const base::trace_event::MemoryDumpArgs& args,
-    base::trace_event::ProcessMemoryDump* pmd) {
-  blink::WebMemoryDumpLevelOfDetail level;
-  switch (args.level_of_detail) {
-    case base::trace_event::MemoryDumpLevelOfDetail::LIGHT:
-      level = blink::WebMemoryDumpLevelOfDetail::Light;
-      break;
-    case base::trace_event::MemoryDumpLevelOfDetail::DETAILED:
-      level = blink::WebMemoryDumpLevelOfDetail::Detailed;
-      break;
-    default:
-      NOTREACHED();
-      return false;
-  }
-  WebProcessMemoryDumpImpl web_pmd_impl(args.level_of_detail, pmd);
-  return web_memory_dump_provider_->onMemoryDump(level, &web_pmd_impl);
-}
-
-void WebMemoryDumpProviderAdapter::OnHeapProfilingEnabled(bool enabled) {
-  if (!web_memory_dump_provider_->supportsHeapProfiling())
-    return;
-  web_memory_dump_provider_->onHeapProfilingEnabled(enabled);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/web_memory_dump_provider_adapter.h b/third_party/WebKit/Source/platform/web_memory_dump_provider_adapter.h
deleted file mode 100644
index 6cb0d3c0..0000000
--- a/third_party/WebKit/Source/platform/web_memory_dump_provider_adapter.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 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 WebMemoryDumpProviderAdapter_h
-#define WebMemoryDumpProviderAdapter_h
-
-#include "base/macros.h"
-#include "base/trace_event/memory_dump_provider.h"
-
-namespace blink {
-
-class WebMemoryDumpProvider;
-
-// Adapter class which makes it possible to register a WebMemoryDumpProvider (
-// from blink) to base::trace_event::MemoryDumpManager, which expects a
-// MemoryDumpProvider instead.
-// This is essentially proxying the OnMemoryDump from chromium base to blink.
-class WebMemoryDumpProviderAdapter
-    : public base::trace_event::MemoryDumpProvider {
- public:
-  explicit WebMemoryDumpProviderAdapter(blink::WebMemoryDumpProvider* wmdp);
-  ~WebMemoryDumpProviderAdapter() override;
-
-  // base::trace_event::MemoryDumpProvider implementation.
-  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
-                    base::trace_event::ProcessMemoryDump* pmd) override;
-
-  void OnHeapProfilingEnabled(bool enabled) override;
-
-  bool is_registered() const { return is_registered_; }
-  void set_is_registered(bool is_registered) { is_registered_ = is_registered; }
-
- private:
-  // The underlying WebMemoryDumpProvider instance to which the OnMemoryDump()
-  // calls will be proxied to.
-  blink::WebMemoryDumpProvider* web_memory_dump_provider_;  // Not owned.
-
-  // True iff this has been registered with the MDM (and not unregistered yet).
-  bool is_registered_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebMemoryDumpProviderAdapter);
-};
-
-}  // namespace blink
-
-#endif  // WebMemoryDumpProviderAdapter_h
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
index b6b0a58..d415d339 100644
--- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -41,6 +41,7 @@
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/forms/ColorChooser.h"
 #include "core/html/forms/ColorChooserClient.h"
diff --git a/third_party/WebKit/Source/web/DevToolsEmulator.cpp b/third_party/WebKit/Source/web/DevToolsEmulator.cpp
index f87f2e7..3b8be5b 100644
--- a/third_party/WebKit/Source/web/DevToolsEmulator.cpp
+++ b/third_party/WebKit/Source/web/DevToolsEmulator.cpp
@@ -7,6 +7,7 @@
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/page/Page.h"
 #include "core/style/ComputedStyle.h"
 #include "platform/RuntimeEnabledFeatures.h"
diff --git a/third_party/WebKit/Source/web/ExternalDateTimeChooser.cpp b/third_party/WebKit/Source/web/ExternalDateTimeChooser.cpp
index aa84f5db..c58e06b 100644
--- a/third_party/WebKit/Source/web/ExternalDateTimeChooser.cpp
+++ b/third_party/WebKit/Source/web/ExternalDateTimeChooser.cpp
@@ -27,6 +27,7 @@
 
 #include "core/InputTypeNames.h"
 #include "core/html/forms/DateTimeChooserClient.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "public/web/WebDateTimeChooserCompletion.h"
 #include "public/web/WebDateTimeChooserParams.h"
 #include "public/web/WebViewClient.h"
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp
index b6fa2c7..f88ab50d 100644
--- a/third_party/WebKit/Source/web/InspectorOverlay.cpp
+++ b/third_party/WebKit/Source/web/InspectorOverlay.cpp
@@ -37,6 +37,7 @@
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/input/EventHandler.h"
 #include "core/inspector/InspectorCSSAgent.h"
 #include "core/inspector/InspectorOverlayHost.h"
diff --git a/third_party/WebKit/Source/web/LinkHighlightImpl.cpp b/third_party/WebKit/Source/web/LinkHighlightImpl.cpp
index bd87ec48..6143627 100644
--- a/third_party/WebKit/Source/web/LinkHighlightImpl.cpp
+++ b/third_party/WebKit/Source/web/LinkHighlightImpl.cpp
@@ -37,6 +37,7 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/animation/CompositorAnimationCurve.h"
 #include "platform/animation/CompositorFloatAnimationCurve.h"
+#include "platform/animation/TimingFunction.h"
 #include "platform/graphics/Color.h"
 #include "platform/graphics/CompositorFactory.h"
 #include "platform/graphics/GraphicsLayer.h"
@@ -292,13 +293,15 @@
 
     OwnPtr<CompositorFloatAnimationCurve> curve = adoptPtr(CompositorFactory::current().createFloatAnimationCurve());
 
-    curve->add(CompositorFloatKeyframe(0, startOpacity));
+    const auto easeType = CubicBezierTimingFunction::EaseType::EASE;
+
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(0, startOpacity), easeType);
     // Make sure we have displayed for at least minPreFadeDuration before starting to fade out.
     float extraDurationRequired = std::max(0.f, minPreFadeDuration - static_cast<float>(monotonicallyIncreasingTime() - m_startTime));
     if (extraDurationRequired)
-        curve->add(CompositorFloatKeyframe(extraDurationRequired, startOpacity));
+        curve->addCubicBezierKeyframe(CompositorFloatKeyframe(extraDurationRequired, startOpacity), easeType);
     // For layout tests we don't fade out.
-    curve->add(CompositorFloatKeyframe(fadeDuration + extraDurationRequired, layoutTestMode() ? startOpacity : 0));
+    curve->addCubicBezierKeyframe(CompositorFloatKeyframe(fadeDuration + extraDurationRequired, layoutTestMode() ? startOpacity : 0), easeType);
 
     OwnPtr<CompositorAnimation> animation = adoptPtr(CompositorFactory::current().createAnimation(*curve, CompositorTargetProperty::OPACITY));
 
diff --git a/third_party/WebKit/Source/web/PageOverlay.cpp b/third_party/WebKit/Source/web/PageOverlay.cpp
index 34ebc84..cfb2d80e 100644
--- a/third_party/WebKit/Source/web/PageOverlay.cpp
+++ b/third_party/WebKit/Source/web/PageOverlay.cpp
@@ -29,7 +29,7 @@
 #include "web/PageOverlay.h"
 
 #include "core/frame/FrameHost.h"
-#include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/page/Page.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
 #include "platform/graphics/GraphicsContext.h"
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
index 557dd06..03466c1 100644
--- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
@@ -30,6 +30,7 @@
 
 #include "web/ServiceWorkerGlobalScopeProxy.h"
 
+#include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/dom/CrossThreadTask.h"
 #include "core/dom/Document.h"
@@ -210,9 +211,9 @@
     workerGlobalScope()->dispatchExtendableEvent(event, observer);
 }
 
-void ServiceWorkerGlobalScopeProxy::reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int)
+void ServiceWorkerGlobalScopeProxy::reportException(const String& errorMessage, PassOwnPtr<SourceLocation> location)
 {
-    client().reportException(errorMessage, lineNumber, columnNumber, sourceURL);
+    client().reportException(errorMessage, location->lineNumber(), location->columnNumber(), location->url());
 }
 
 void ServiceWorkerGlobalScopeProxy::reportConsoleMessage(ConsoleMessage* consoleMessage)
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h
index c87e4bc..60e56fa 100644
--- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h
+++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h
@@ -83,7 +83,7 @@
     void dispatchSyncEvent(int, const WebString& tag, LastChanceOption) override;
 
     // WorkerReportingProxy overrides:
-    void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId) override;
+    void reportException(const String& errorMessage, PassOwnPtr<SourceLocation>) override;
     void reportConsoleMessage(ConsoleMessage*) override;
     void postMessageToPageInspector(const String&) override;
     void postWorkerConsoleAgentEnabled() override { }
diff --git a/third_party/WebKit/Source/web/WebFormControlElement.cpp b/third_party/WebKit/Source/web/WebFormControlElement.cpp
index 64f0c9d..df17acd 100644
--- a/third_party/WebKit/Source/web/WebFormControlElement.cpp
+++ b/third_party/WebKit/Source/web/WebFormControlElement.cpp
@@ -31,6 +31,7 @@
 #include "public/web/WebFormControlElement.h"
 
 #include "core/dom/NodeComputedStyle.h"
+#include "core/events/Event.h"
 #include "core/html/HTMLFormControlElement.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLInputElement.h"
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
index e8a5c90..5365c9a 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -39,6 +39,7 @@
 #include "core/frame/FrameView.h"
 #include "core/frame/RemoteFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
 #include "core/input/EventHandler.h"
 #include "core/layout/LayoutView.h"
 #include "core/layout/api/LayoutViewItem.h"
diff --git a/third_party/WebKit/Source/web/WebLabelElement.cpp b/third_party/WebKit/Source/web/WebLabelElement.cpp
index 8737c0b8..937ac14 100644
--- a/third_party/WebKit/Source/web/WebLabelElement.cpp
+++ b/third_party/WebKit/Source/web/WebLabelElement.cpp
@@ -32,6 +32,7 @@
 
 #include "core/HTMLNames.h"
 #include "core/html/HTMLLabelElement.h"
+#include "core/html/LabelableElement.h"
 #include "public/platform/WebString.h"
 #include "wtf/PassRefPtr.h"
 
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
index 3651d91..bda498f 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -52,6 +52,7 @@
 class IntSize;
 class KURL;
 class Range;
+class ScrollableArea;
 class SharedWorkerRepositoryClientImpl;
 class TextFinder;
 class WebAutofillClient;
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
index 972d7208..393851f68 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
@@ -212,7 +212,7 @@
 
 // WorkerReportingProxy --------------------------------------------------------
 
-void WebSharedWorkerImpl::reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId)
+void WebSharedWorkerImpl::reportException(const String& errorMessage, PassOwnPtr<SourceLocation>)
 {
     // Not suppported in SharedWorker.
 }
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
index a4bf0d88..7c7031d 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
@@ -75,8 +75,7 @@
     explicit WebSharedWorkerImpl(WebSharedWorkerClient*);
 
     // WorkerReportingProxy methods:
-    void reportException(
-        const WTF::String&, int, int, const WTF::String&, int) override;
+    void reportException(const WTF::String&, PassOwnPtr<SourceLocation>) override;
     void reportConsoleMessage(ConsoleMessage*) override;
     void postMessageToPageInspector(const WTF::String&) override;
     void postWorkerConsoleAgentEnabled() override { }
diff --git a/third_party/WebKit/Source/web/tests/TextFinderTest.cpp b/third_party/WebKit/Source/web/tests/TextFinderTest.cpp
index fccd7d6..bfa8a86f 100644
--- a/third_party/WebKit/Source/web/tests/TextFinderTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TextFinderTest.cpp
@@ -10,6 +10,7 @@
 #include "core/dom/Range.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/VisualViewport.h"
 #include "core/html/HTMLElement.h"
 #include "core/layout/TextAutosizer.h"
 #include "core/page/Page.h"
diff --git a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
index 6fd0027..15e361b9 100644
--- a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
@@ -33,6 +33,7 @@
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
+#include "core/frame/VisualViewport.h"
 #include "core/layout/LayoutView.h"
 #include "core/page/Page.h"
 #include "platform/testing/URLTestHelpers.h"
diff --git a/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp b/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp
index 243ea13..ea2b8047 100644
--- a/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp
@@ -40,6 +40,7 @@
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
+#include "core/frame/VisualViewport.h"
 #include "core/layout/api/LayoutViewItem.h"
 #include "core/page/Page.h"
 #include "platform/testing/URLTestHelpers.h"
diff --git a/third_party/WebKit/public/blink_headers.gypi b/third_party/WebKit/public/blink_headers.gypi
index 13a5af1..a07c69aa 100644
--- a/third_party/WebKit/public/blink_headers.gypi
+++ b/third_party/WebKit/public/blink_headers.gypi
@@ -132,7 +132,6 @@
       "platform/WebMediaStreamTrack.h",
       "platform/WebMediaStreamTrackSourcesRequest.h",
       "platform/WebMemoryAllocatorDump.h",
-      "platform/WebMemoryDumpProvider.h",
       "platform/WebMemoryPressureLevel.h",
       "platform/WebMessagePortChannel.h",
       "platform/WebMessagePortChannelClient.h",
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index fab786c2..6d994cb 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -91,7 +91,6 @@
 class WebMediaStreamCenter;
 class WebMediaStreamCenterClient;
 class WebMediaStreamTrack;
-class WebMemoryDumpProvider;
 class WebMessagePortChannel;
 class WebMimeRegistry;
 class WebNotificationManager;
@@ -418,16 +417,6 @@
     // recordAction(UserMetricsAction("MyAction"))
     virtual void recordAction(const UserMetricsAction&) { }
 
-    // Registers a memory dump provider. The WebMemoryDumpProvider::onMemoryDump
-    // method will be called on the same thread that called the
-    // registerMemoryDumpProvider() method. |name| is used for debugging
-    // (duplicates are allowed) and must be a long-lived C string.
-    // See crbug.com/458295 for design docs.
-    virtual void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*, const char* name);
-
-    // Must be called on the thread that called registerMemoryDumpProvider().
-    virtual void unregisterMemoryDumpProvider(blink::WebMemoryDumpProvider*);
-
     class TraceLogEnabledStateObserver {
     public:
         virtual ~TraceLogEnabledStateObserver() = default;
diff --git a/third_party/WebKit/public/platform/WebMemoryDumpProvider.h b/third_party/WebKit/public/platform/WebMemoryDumpProvider.h
deleted file mode 100644
index 725c92ad..0000000
--- a/third_party/WebKit/public/platform/WebMemoryDumpProvider.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 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 WebMemoryDumpProvider_h
-#define WebMemoryDumpProvider_h
-
-#include "WebCommon.h"
-
-namespace blink {
-
-class WebProcessMemoryDump;
-
-// Used to specify the type of memory dump the WebMemoryDumpProvider should
-// generate on dump requests.
-// TODO(hajimehoshi): Remove this and use base::trace_event::
-// MemoryDumpLevelOfDetail instead.
-enum class WebMemoryDumpLevelOfDetail {
-    Light,
-    Detailed
-};
-
-// Base interface to be part of the memory tracing infrastructure. Blink classes
-// can implement this interface and register themselves (see
-// Platform::registerMemoryDumpProvider()) to dump stats for their allocators.
-class BLINK_PLATFORM_EXPORT WebMemoryDumpProvider {
-public:
-    // Function types for functions that can be called on alloc and free to do
-    // heap profiling.
-    typedef void AllocationHook(void* address, size_t, const char*);
-    typedef void FreeHook(void* address);
-
-    virtual ~WebMemoryDumpProvider();
-
-    // Called by the MemoryDumpManager when generating memory dumps.
-    // WebMemoryDumpLevelOfDetail specifies the size of dump the embedders
-    // should generate on dump requests. Embedders are expected to populate
-    // the WebProcessMemoryDump* argument depending on the level and return true
-    // on success or false if anything went wrong and the dump should be
-    // considered invalid.
-    virtual bool onMemoryDump(WebMemoryDumpLevelOfDetail, WebProcessMemoryDump*) = 0;
-
-    // Because Blink cannot depend on base, heap profiling bookkeeping has to
-    // be done in the glue layer for now. This method allows the glue layer to
-    // detect whether the current dump provider supports heap profiling.
-    // TODO(ruuda): Remove once wtf can depend on base and do bookkeeping in the
-    // provider itself.
-    virtual bool supportsHeapProfiling() { return false; }
-
-    // Called by the memory dump manager to enable heap profiling (with true) or
-    // called to disable heap profiling (with false).
-    virtual void onHeapProfilingEnabled(bool enabled) {}
-};
-
-} // namespace blink
-
-#endif // WebMemoryDumpProvider_h
diff --git a/third_party/WebKit/public/platform/WebProcessMemoryDump.h b/third_party/WebKit/public/platform/WebProcessMemoryDump.h
index c3cf99f..0d97baa 100644
--- a/third_party/WebKit/public/platform/WebProcessMemoryDump.h
+++ b/third_party/WebKit/public/platform/WebProcessMemoryDump.h
@@ -7,7 +7,6 @@
 
 #include "WebCommon.h"
 #include "WebMemoryAllocatorDump.h"
-#include "WebMemoryDumpProvider.h"
 #include "WebString.h"
 #include "base/trace_event/heap_profiler_allocation_context.h"
 
@@ -27,6 +26,15 @@
 
 namespace blink {
 
+// Used to specify the type of memory dump the WebProcessMemoryDump should
+// generate on dump requests.
+// TODO(hajimehoshi): Remove this and use base::trace_event::
+// MemoryDumpLevelOfDetail instead.
+enum class WebMemoryDumpLevelOfDetail {
+    Light,
+    Detailed
+};
+
 // A container which holds all the dumps for the various allocators for a given
 // process. Embedders of WebMemoryDumpProvider are expected to populate a
 // WebProcessMemoryDump instance with the stats of their allocators.
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium
index 76b0c19..c128f51 100644
--- a/third_party/libxml/README.chromium
+++ b/third_party/libxml/README.chromium
@@ -1,6 +1,6 @@
 Name: libxml
 URL: http://xmlsoft.org
-Version: 8effcb578e0590cc01bbcab0f9dccefc6bdbcdbd
+Version: bdec2183f34b37ee89ae1d330c6ad2bb4d76605f
 License: MIT
 License File: src/Copyright
 Security Critical: yes
@@ -14,11 +14,8 @@
   chromium/include/libxml/libxml_utils.h.
 - Fix printf format specifiers, https://chromium.googlesource.com/chromium/src/+/d31995076e55f1aac2f935c53b585a90ece27a11
 - Add second workaround for VS 2015 Update 2 code-gen bug - crbug.com/599427
-- Add patch from https://bugzilla.gnome.org/show_bug.cgi?id=758588 for
-  https://crbug.com/595262#c16
-- Fix integer overflow https://crbug.com/602280
 
-This import was generated by this script: https://goo.gl/Y75Cpf
+This import was generated by this script: https://goo.gl/72CTWf
 
 To import a new snapshot:
 
diff --git a/third_party/libxml/src/HTMLparser.c b/third_party/libxml/src/HTMLparser.c
index 69eed2b..d1395fa50 100644
--- a/third_party/libxml/src/HTMLparser.c
+++ b/third_party/libxml/src/HTMLparser.c
@@ -105,7 +105,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 htmlParseErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
              const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -132,7 +132,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 htmlParseErrInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
              const char *msg, int val)
 {
@@ -303,6 +303,7 @@
 #define UPP(val) (toupper(ctxt->input->cur[(val)]))
 
 #define CUR_PTR ctxt->input->cur
+#define BASE_PTR ctxt->input->base
 
 #define SHRINK if ((ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
 		   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
@@ -2471,6 +2472,10 @@
 	       (*in == '_') || (*in == '-') ||
 	       (*in == ':') || (*in == '.'))
 	    in++;
+
+	if (in == ctxt->input->end)
+	    return(NULL);
+
 	if ((*in > 0) && (*in < 0x80)) {
 	    count = in - ctxt->input->cur;
 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
@@ -2488,6 +2493,7 @@
     int len = 0, l;
     int c;
     int count = 0;
+    const xmlChar *base = ctxt->input->base;
 
     /*
      * Handler for more complex cases
@@ -2513,7 +2519,18 @@
 	len += l;
 	NEXTL(l);
 	c = CUR_CHAR(l);
+	if (ctxt->input->base != base) {
+	    /*
+	     * We changed encoding from an unknown encoding
+	     * Input buffer changed location, so we better start again
+	     */
+	    return(htmlParseNameComplex(ctxt));
+	}
     }
+
+    if (ctxt->input->base > ctxt->input->cur - len)
+	return(NULL);
+
     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
 }
 
@@ -2765,31 +2782,43 @@
 
 static xmlChar *
 htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
-    const xmlChar *q;
+    size_t len = 0, startPosition = 0;
     xmlChar *ret = NULL;
 
     if (CUR == '"') {
         NEXT;
-	q = CUR_PTR;
-	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
+
+        if (CUR_PTR < BASE_PTR)
+            return(ret);
+        startPosition = CUR_PTR - BASE_PTR;
+
+	while ((IS_CHAR_CH(CUR)) && (CUR != '"')) {
 	    NEXT;
+	    len++;
+	}
 	if (!IS_CHAR_CH(CUR)) {
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
 			 "Unfinished SystemLiteral\n", NULL, NULL);
 	} else {
-	    ret = xmlStrndup(q, CUR_PTR - q);
+	    ret = xmlStrndup((BASE_PTR+startPosition), len);
 	    NEXT;
         }
     } else if (CUR == '\'') {
         NEXT;
-	q = CUR_PTR;
-	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
+
+        if (CUR_PTR < BASE_PTR)
+            return(ret);
+        startPosition = CUR_PTR - BASE_PTR;
+
+	while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) {
 	    NEXT;
+	    len++;
+	}
 	if (!IS_CHAR_CH(CUR)) {
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
 			 "Unfinished SystemLiteral\n", NULL, NULL);
 	} else {
-	    ret = xmlStrndup(q, CUR_PTR - q);
+	    ret = xmlStrndup((BASE_PTR+startPosition), len);
 	    NEXT;
         }
     } else {
@@ -2813,32 +2842,47 @@
 
 static xmlChar *
 htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
-    const xmlChar *q;
+    size_t len = 0, startPosition = 0;
     xmlChar *ret = NULL;
     /*
      * Name ::= (Letter | '_') (NameChar)*
      */
     if (CUR == '"') {
         NEXT;
-	q = CUR_PTR;
-	while (IS_PUBIDCHAR_CH(CUR)) NEXT;
+
+        if (CUR_PTR < BASE_PTR)
+            return(ret);
+        startPosition = CUR_PTR - BASE_PTR;
+
+        while (IS_PUBIDCHAR_CH(CUR)) {
+            len++;
+            NEXT;
+        }
+
 	if (CUR != '"') {
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
 	                 "Unfinished PubidLiteral\n", NULL, NULL);
 	} else {
-	    ret = xmlStrndup(q, CUR_PTR - q);
+	    ret = xmlStrndup((BASE_PTR + startPosition), len);
 	    NEXT;
 	}
     } else if (CUR == '\'') {
         NEXT;
-	q = CUR_PTR;
-	while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\''))
-	    NEXT;
+
+        if (CUR_PTR < BASE_PTR)
+            return(ret);
+        startPosition = CUR_PTR - BASE_PTR;
+
+        while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\'')){
+            len++;
+            NEXT;
+        }
+
 	if (CUR != '\'') {
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
 	                 "Unfinished PubidLiteral\n", NULL, NULL);
 	} else {
-	    ret = xmlStrndup(q, CUR_PTR - q);
+	    ret = xmlStrndup((BASE_PTR + startPosition), len);
 	    NEXT;
 	}
     } else {
diff --git a/third_party/libxml/src/SAX2.c b/third_party/libxml/src/SAX2.c
index ffef3e1..5cbb700 100644
--- a/third_party/libxml/src/SAX2.c
+++ b/third_party/libxml/src/SAX2.c
@@ -55,7 +55,7 @@
  * @ctxt:  an XML validation parser context
  * @msg:   a string to accompany the error message
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
     xmlStructuredErrorFunc schannel = NULL;
     const char *str1 = "out of memory\n";
@@ -93,7 +93,7 @@
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const char *str1, const char *str2)
 {
@@ -133,7 +133,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -164,7 +164,7 @@
  *
  * Handle a parser warning
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                const char *msg, const xmlChar *str1)
 {
@@ -189,7 +189,7 @@
  *
  * Handle a namespace error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -213,7 +213,7 @@
  *
  * Handle a namespace warning
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
              const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
diff --git a/third_party/libxml/src/catalog.c b/third_party/libxml/src/catalog.c
index ac6e9815..6dfdfbb 100644
--- a/third_party/libxml/src/catalog.c
+++ b/third_party/libxml/src/catalog.c
@@ -238,7 +238,7 @@
  *
  * Handle a catalog error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error,
                const char *msg, const xmlChar *str1, const xmlChar *str2,
 	       const xmlChar *str3)
diff --git a/third_party/libxml/src/configure b/third_party/libxml/src/configure
index a785268..7ec31c4 100755
--- a/third_party/libxml/src/configure
+++ b/third_party/libxml/src/configure
@@ -12875,7 +12875,7 @@
   if test "$withval" != "no" -a "$withval" != "yes"; then
     RDL_DIR=$withval
     CPPFLAGS="${CPPFLAGS} -I$withval/include"
-    LIBS="${LIBS} -L$withval/lib"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
   fi
 
 fi
@@ -12971,7 +12971,7 @@
   if test "$withval" != "no" -a "$withval" != "yes"; then
     Z_DIR=$withval
     CPPFLAGS="${CPPFLAGS} -I$withval/include"
-    LIBS="${LIBS} -L$withval/lib"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
   fi
 
 fi
@@ -12983,7 +12983,7 @@
   if test "$withval" != "no" -a "$withval" != "yes"; then
     LZMA_DIR=$withval
     CPPFLAGS="${CPPFLAGS} -I$withval/include"
-    LIBS="${LIBS} -L$withval/lib"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
   fi
 
 fi
@@ -13262,9 +13262,7 @@
   cat >>confdefs.h <<_ACEOF
 #define HAVE_ZLIB_H 1
 _ACEOF
- SAVE_LDFLAGS="${LDFLAGS}"
-             LDFLAGS="-L${Z_DIR}/lib"
-            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5
 $as_echo_n "checking for gzread in -lz... " >&6; }
 if ${ac_cv_lib_z_gzread+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -13318,7 +13316,7 @@
   have_libz=no
 fi
 
-             LDFLAGS="${SAVE_LDFLAGS}"
+
 fi
 
 done
@@ -13444,9 +13442,7 @@
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LZMA_H 1
 _ACEOF
- SAVE_LDFLAGS="${LDFLAGS}"
-	     LDFLAGS="-L${LZMA_DIR}/lib"
-            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_code in -llzma" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_code in -llzma" >&5
 $as_echo_n "checking for lzma_code in -llzma... " >&6; }
 if ${ac_cv_lib_lzma_lzma_code+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -13495,7 +13491,7 @@
   have_liblzma=no
 fi
 
-	     LDFLAGS="${SAVE_LDFLAGS}"
+
 fi
 
 done
@@ -14454,7 +14450,7 @@
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether va_list is an array type" >&5
 $as_echo_n "checking whether va_list is an array type... " >&6; }
 cat > conftest.$ac_ext <<EOF
-#line 14457 "configure"
+#line 14453 "configure"
 #include "confdefs.h"
 
 #include <stdarg.h>
@@ -14464,7 +14460,7 @@
 va_list ap1, ap2; a(&ap1); ap2 = (va_list) ap1
 ; return 0; }
 EOF
-if { (eval echo configure:14467: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
+if { (eval echo configure:14463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
   rm -rf conftest*
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
@@ -14654,7 +14650,7 @@
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type of socket length (socklen_t)" >&5
 $as_echo_n "checking for type of socket length (socklen_t)... " >&6; }
 cat > conftest.$ac_ext <<EOF
-#line 14657 "configure"
+#line 14653 "configure"
 #include "confdefs.h"
 
 #include <stddef.h>
@@ -14665,7 +14661,7 @@
 (void)getsockopt (1, 1, 1, NULL, (socklen_t *)NULL)
 ; return 0; }
 EOF
-if { (eval echo configure:14668: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
+if { (eval echo configure:14664: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
   rm -rf conftest*
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: socklen_t *" >&5
@@ -14677,7 +14673,7 @@
   rm -rf conftest*
 
   cat > conftest.$ac_ext <<EOF
-#line 14680 "configure"
+#line 14676 "configure"
 #include "confdefs.h"
 
 #include <stddef.h>
@@ -14688,7 +14684,7 @@
 (void)getsockopt (1, 1, 1, NULL, (size_t *)NULL)
 ; return 0; }
 EOF
-if { (eval echo configure:14691: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
+if { (eval echo configure:14687: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
   rm -rf conftest*
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: size_t *" >&5
@@ -14700,7 +14696,7 @@
   rm -rf conftest*
 
     cat > conftest.$ac_ext <<EOF
-#line 14703 "configure"
+#line 14699 "configure"
 #include "confdefs.h"
 
 #include <stddef.h>
@@ -14711,7 +14707,7 @@
 (void)getsockopt (1, 1, 1, NULL, (int *)NULL)
 ; return 0; }
 EOF
-if { (eval echo configure:14714: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
+if { (eval echo configure:14710: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
   rm -rf conftest*
 
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: int *" >&5
@@ -15114,7 +15110,7 @@
     fi
 
     # warnings we'd like to see
-    CFLAGS="${CFLAGS} -pedantic -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls"
+    CFLAGS="${CFLAGS} -pedantic -W -Wformat -Wno-format-extra-args -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls"
     # warnings we'd like to supress
     CFLAGS="${CFLAGS} -Wno-long-long"
     case "${host}" in
@@ -15505,7 +15501,7 @@
 	fi
     fi
     if test "${GCC}" = "yes" ; then
-    CFLAGS="-g -O -pedantic -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls -Wall"
+    CFLAGS="-g -O -pedantic -W -Wformat -Wno-format-extra-args -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls -Wall"
     fi
     STATIC_BINARIES="-static"
 else
diff --git a/third_party/libxml/src/configure.ac b/third_party/libxml/src/configure.ac
index 6f012c9..911984e 100644
--- a/third_party/libxml/src/configure.ac
+++ b/third_party/libxml/src/configure.ac
@@ -159,7 +159,7 @@
   if test "$withval" != "no" -a "$withval" != "yes"; then
     RDL_DIR=$withval
     CPPFLAGS="${CPPFLAGS} -I$withval/include"
-    LIBS="${LIBS} -L$withval/lib"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
   fi
 ])
 AC_ARG_WITH(regexps,
@@ -195,7 +195,7 @@
   if test "$withval" != "no" -a "$withval" != "yes"; then
     Z_DIR=$withval
     CPPFLAGS="${CPPFLAGS} -I$withval/include"
-    LIBS="${LIBS} -L$withval/lib"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
   fi
 ])
 AC_ARG_WITH(lzma,
@@ -203,7 +203,7 @@
   if test "$withval" != "no" -a "$withval" != "yes"; then
     LZMA_DIR=$withval
     CPPFLAGS="${CPPFLAGS} -I$withval/include"
-    LIBS="${LIBS} -L$withval/lib"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
   fi
 ])
 AC_ARG_WITH(coverage,
@@ -399,8 +399,6 @@
 
      if test "x$have_libz" = "xno"; then
         AC_CHECK_HEADERS(zlib.h,
-            [SAVE_LDFLAGS="${LDFLAGS}"
-             LDFLAGS="-L${Z_DIR}/lib"
             AC_CHECK_LIB(z, gzread,[
                 have_libz=yes
                 if test "x${Z_DIR}" != "x"; then
@@ -415,7 +413,7 @@
                     Z_LIBS="-lz"
                 fi],
                 [have_libz=no])
-             LDFLAGS="${SAVE_LDFLAGS}"])
+             )
     else
 	# we still need to check for zlib.h header
 	AC_CHECK_HEADERS([zlib.h])
@@ -451,8 +449,6 @@
      # private dependencies, though, so static linking may fail.
      if test "x$have_liblzma" = "xno"; then
          AC_CHECK_HEADERS(lzma.h,
-	    [SAVE_LDFLAGS="${LDFLAGS}"
-	     LDFLAGS="-L${LZMA_DIR}/lib"
             AC_CHECK_LIB(lzma, lzma_code,[
                 have_liblzma=yes
                 if test "x${LZMA_DIR}" != "x"; then
@@ -462,7 +458,7 @@
                     LZMA_LIBS="-llzma"
                 fi],
                 [have_liblzma=no])
-	     LDFLAGS="${SAVE_LDFLAGS}"])
+	     )
     else
 	# we still need to check for lzma,h header
 	AC_CHECK_HEADERS([lzma.h])
@@ -795,7 +791,7 @@
     fi
 
     # warnings we'd like to see
-    CFLAGS="${CFLAGS} -pedantic -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls"
+    CFLAGS="${CFLAGS} -pedantic -W -Wformat -Wno-format-extra-args -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls"
     # warnings we'd like to supress
     CFLAGS="${CFLAGS} -Wno-long-long"
     case "${host}" in
@@ -1014,7 +1010,7 @@
 	fi
     fi
     if test "${GCC}" = "yes" ; then
-    CFLAGS="-g -O -pedantic -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls -Wall"
+    CFLAGS="-g -O -pedantic -W -Wformat -Wno-format-extra-args -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls -Wall"
     fi
     STATIC_BINARIES="-static"
 dnl -Wcast-qual -ansi
diff --git a/third_party/libxml/src/debugXML.c b/third_party/libxml/src/debugXML.c
index e34b140..a1b550a 100644
--- a/third_party/libxml/src/debugXML.c
+++ b/third_party/libxml/src/debugXML.c
@@ -164,7 +164,7 @@
 		    NULL, NULL, NULL, 0, 0,
 		    "%s", msg);
 }
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra)
 {
     ctxt->errors++;
@@ -174,7 +174,7 @@
 		    NULL, NULL, NULL, 0, 0,
 		    msg, extra);
 }
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra)
 {
     ctxt->errors++;
diff --git a/third_party/libxml/src/encoding.c b/third_party/libxml/src/encoding.c
index 574e1ae..e49c7f898 100644
--- a/third_party/libxml/src/encoding.c
+++ b/third_party/libxml/src/encoding.c
@@ -93,7 +93,7 @@
  *
  * n encoding error
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlEncodingErr(xmlParserErrors error, const char *msg, const char *val)
 {
     __xmlRaiseError(NULL, NULL, NULL, NULL, NULL,
diff --git a/third_party/libxml/src/entities.c b/third_party/libxml/src/entities.c
index a72afb3..64808ff6 100644
--- a/third_party/libxml/src/entities.c
+++ b/third_party/libxml/src/entities.c
@@ -83,7 +83,7 @@
  *
  * Handle an out of memory condition
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlEntitiesErr(xmlParserErrors code, const char *msg)
 {
     __xmlSimpleError(XML_FROM_TREE, code, NULL, msg, NULL);
diff --git a/third_party/libxml/src/error.c b/third_party/libxml/src/error.c
index 4ca6838..9606f13 100644
--- a/third_party/libxml/src/error.c
+++ b/third_party/libxml/src/error.c
@@ -18,7 +18,7 @@
 
 void XMLCDECL xmlGenericErrorDefaultFunc	(void *ctx ATTRIBUTE_UNUSED,
 				 const char *msg,
-				 ...);
+				 ...) LIBXML_ATTR_FORMAT(2,3);
 
 #define XML_GET_VAR_STR(msg, str) {				\
     int       size, prev_size = -1;				\
diff --git a/third_party/libxml/src/include/libxml/parserInternals.h b/third_party/libxml/src/include/libxml/parserInternals.h
index 6065320e..f30fc68 100644
--- a/third_party/libxml/src/include/libxml/parserInternals.h
+++ b/third_party/libxml/src/include/libxml/parserInternals.h
@@ -351,7 +351,7 @@
 						 xmlParserErrors xmlerr,
 						 const char *msg,
 						 const xmlChar * str1,
-						 const xmlChar * str2);
+						 const xmlChar * str2) LIBXML_ATTR_FORMAT(3,0);
 #endif
 
 /**
diff --git a/third_party/libxml/src/include/libxml/xmlerror.h b/third_party/libxml/src/include/libxml/xmlerror.h
index 43e68ca5..037c16d5 100644
--- a/third_party/libxml/src/include/libxml/xmlerror.h
+++ b/third_party/libxml/src/include/libxml/xmlerror.h
@@ -937,7 +937,7 @@
 				 int code,
 				 xmlNodePtr node,
 				 const char *msg,
-				 const char *extra);
+				 const char *extra) LIBXML_ATTR_FORMAT(4,0);
 #endif
 #ifdef __cplusplus
 }
diff --git a/third_party/libxml/src/include/libxml/xmlstring.h b/third_party/libxml/src/include/libxml/xmlstring.h
index 2036236..2d0b2d16 100644
--- a/third_party/libxml/src/include/libxml/xmlstring.h
+++ b/third_party/libxml/src/include/libxml/xmlstring.h
@@ -97,13 +97,13 @@
 XMLPUBFUN int XMLCALL
                 xmlStrPrintf             (xmlChar *buf,
                                          int len,
-                                         const xmlChar *msg,
-                                         ...);
+                                         const char *msg,
+                                         ...) LIBXML_ATTR_FORMAT(3,4);
 XMLPUBFUN int XMLCALL
                 xmlStrVPrintf                (xmlChar *buf,
                                          int len,
-                                         const xmlChar *msg,
-                                         va_list ap);
+                                         const char *msg,
+                                         va_list ap) LIBXML_ATTR_FORMAT(3,0);
 
 XMLPUBFUN int XMLCALL
         xmlGetUTF8Char                   (const unsigned char *utf,
diff --git a/third_party/libxml/src/libxml.h b/third_party/libxml/src/libxml.h
index 2da9044..88e515f 100644
--- a/third_party/libxml/src/libxml.h
+++ b/third_party/libxml/src/libxml.h
@@ -9,6 +9,8 @@
 #ifndef __XML_LIBXML_H__
 #define __XML_LIBXML_H__
 
+#include <libxml/xmlstring.h>
+
 #ifndef NO_LARGEFILE_SOURCE
 #ifndef _LARGEFILE_SOURCE
 #define _LARGEFILE_SOURCE
@@ -68,7 +70,7 @@
  * internal error reporting routines, shared but not partof the API.
  */
 void __xmlIOErr(int domain, int code, const char *extra);
-void __xmlLoaderErr(void *ctx, const char *msg, const char *filename);
+void __xmlLoaderErr(void *ctx, const char *msg, const char *filename) LIBXML_ATTR_FORMAT(2,0);
 #ifdef LIBXML_HTML_ENABLED
 /*
  * internal function of HTML parser needed for xmlParseInNodeContext
@@ -93,6 +95,7 @@
 int __xmlRandom(void);
 #endif
 
+XMLPUBFUN xmlChar * XMLCALL xmlEscapeFormatString(xmlChar **msg);
 int xmlNop(void);
 
 #ifdef IN_LIBXML
diff --git a/third_party/libxml/src/libxml.spec.in b/third_party/libxml/src/libxml.spec.in
index 6fe3c69a..9029a180 100644
--- a/third_party/libxml/src/libxml.spec.in
+++ b/third_party/libxml/src/libxml.spec.in
@@ -3,10 +3,10 @@
 Summary: Library providing XML and HTML support
 Name: libxml2
 Version: @VERSION@
-Release: 0rc2%{?dist}%{?extra_release}
+Release: 1%{?dist}%{?extra_release}
 License: MIT
 Group: Development/Libraries
-Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}-rc2.tar.gz
+Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
 BuildRoot: %{_tmppath}/%{name}-%{version}-root
 BuildRequires: python-devel
 %if 0%{?with_python3}
diff --git a/third_party/libxml/src/libxml2.spec b/third_party/libxml/src/libxml2.spec
index 9065955c..256ac618f 100644
--- a/third_party/libxml/src/libxml2.spec
+++ b/third_party/libxml/src/libxml2.spec
@@ -3,10 +3,10 @@
 Summary: Library providing XML and HTML support
 Name: libxml2
 Version: 2.9.4
-Release: 0rc2%{?dist}%{?extra_release}
+Release: 1%{?dist}%{?extra_release}
 License: MIT
 Group: Development/Libraries
-Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}-rc2.tar.gz
+Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
 BuildRoot: %{_tmppath}/%{name}-%{version}-root
 BuildRequires: python-devel
 %if 0%{?with_python3}
@@ -194,6 +194,6 @@
 %endif # with_python3
 
 %changelog
-* Thu May 19 2016 Daniel Veillard <veillard@redhat.com>
+* Thu May 26 2016 Daniel Veillard <veillard@redhat.com>
 - upstream release 2.9.4 see http://xmlsoft.org/news.html
 
diff --git a/third_party/libxml/src/parser.c b/third_party/libxml/src/parser.c
index 978a585..53a6b7f 100644
--- a/third_party/libxml/src/parser.c
+++ b/third_party/libxml/src/parser.c
@@ -138,14 +138,20 @@
      * entities problems
      */
     if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
-	(ent->content != NULL) && (ent->checked == 0)) {
+	(ent->content != NULL) && (ent->checked == 0) &&
+	(ctxt->errNo != XML_ERR_ENTITY_LOOP)) {
 	unsigned long oldnbent = ctxt->nbentities;
 	xmlChar *rep;
 
 	ent->checked = 1;
 
+        ++ctxt->depth;
 	rep = xmlStringDecodeEntities(ctxt, ent->content,
 				  XML_SUBSTITUTE_REF, 0, 0, 0);
+        --ctxt->depth;
+	if (ctxt->errNo == XML_ERR_ENTITY_LOOP) {
+	    ent->content[0] = 0;
+	}
 
 	ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
 	if (rep != NULL) {
@@ -344,7 +350,6 @@
 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
 {
     const char *errmsg;
-    char errstr[129] = "";
 
     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
         (ctxt->instate == XML_PARSER_EOF))
@@ -531,15 +536,17 @@
         default:
             errmsg = "Unregistered error message";
     }
-    if (info == NULL)
-        snprintf(errstr, 128, "%s\n", errmsg);
-    else
-        snprintf(errstr, 128, "%s: %%s\n", errmsg);
     if (ctxt != NULL)
 	ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
-                    XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, &errstr[0],
-                    info);
+    if (info == NULL) {
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
+                        errmsg);
+    } else {
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
+                        errmsg, info);
+    }
     if (ctxt != NULL) {
 	ctxt->wellFormed = 0;
 	if (ctxt->recovery == 0)
@@ -555,7 +562,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                const char *msg)
 {
@@ -583,7 +590,7 @@
  *
  * Handle a warning.
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
               const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -621,7 +628,7 @@
  *
  * Handle a validity error.
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
               const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -661,7 +668,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, int val)
 {
@@ -691,7 +698,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, const xmlChar *str1, int val,
 		  const xmlChar *str2)
@@ -721,7 +728,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, const xmlChar * val)
 {
@@ -750,7 +757,7 @@
  *
  * Handle a non fatal parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, const xmlChar * val)
 {
@@ -775,7 +782,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
          const char *msg,
          const xmlChar * info1, const xmlChar * info2,
@@ -804,7 +811,7 @@
  *
  * Handle a namespace warning error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
          const char *msg,
          const xmlChar * info1, const xmlChar * info2,
@@ -2008,6 +2015,7 @@
 #define CUR (*ctxt->input->cur)
 #define NXT(val) ctxt->input->cur[(val)]
 #define CUR_PTR ctxt->input->cur
+#define BASE_PTR ctxt->input->base
 
 #define CMP4( s, c1, c2, c3, c4 ) \
   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
@@ -2858,7 +2866,21 @@
 	        ctxt->nbentities += ent->checked / 2;
 	    if (ent != NULL) {
                 if (ent->content == NULL) {
-		    xmlLoadEntityContent(ctxt, ent);
+		    /*
+		     * Note: external parsed entities will not be loaded,
+		     * it is not required for a non-validating parser to
+		     * complete external PEreferences coming from the
+		     * internal subset
+		     */
+		    if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
+			((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
+			(ctxt->validate != 0)) {
+			xmlLoadEntityContent(ctxt, ent);
+		    } else {
+			xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
+		  "not validating will not read content for PE entity %s\n",
+		                      ent->name, NULL);
+		    }
 		}
 		ctxt->depth++;
 		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
@@ -3470,7 +3492,7 @@
     int len = 0, l;
     int c;
     int count = 0;
-    const xmlChar *end; /* needed because CUR_CHAR() can move cur on \r\n */
+    size_t startPosition = 0;
 
 #ifdef DEBUG
     nbParseNCNameComplex++;
@@ -3480,7 +3502,7 @@
      * Handler for more complex cases
      */
     GROW;
-    end = ctxt->input->cur;
+    startPosition = CUR_PTR - BASE_PTR;
     c = CUR_CHAR(l);
     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
 	(!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
@@ -3502,7 +3524,6 @@
 	}
 	len += l;
 	NEXTL(l);
-	end = ctxt->input->cur;
 	c = CUR_CHAR(l);
 	if (c == 0) {
 	    count = 0;
@@ -3516,7 +3537,6 @@
 	    ctxt->input->cur += l;
             if (ctxt->instate == XML_PARSER_EOF)
                 return(NULL);
-	    end = ctxt->input->cur;
 	    c = CUR_CHAR(l);
 	}
     }
@@ -3525,7 +3545,7 @@
         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
         return(NULL);
     }
-    return(xmlDictLookup(ctxt->dict, end - len, len));
+    return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len));
 }
 
 /**
@@ -3966,8 +3986,10 @@
 	 * an entity declaration, it is bypassed and left as is.
 	 * so XML_SUBSTITUTE_REF is not set here.
 	 */
+        ++ctxt->depth;
 	ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
 				      0, 0, 0);
+        --ctxt->depth;
 	if (orig != NULL)
 	    *orig = buf;
 	else
@@ -4092,9 +4114,11 @@
 		} else if ((ent != NULL) &&
 		           (ctxt->replaceEntities != 0)) {
 		    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
+			++ctxt->depth;
 			rep = xmlStringDecodeEntities(ctxt, ent->content,
 						      XML_SUBSTITUTE_REF,
 						      0, 0, 0);
+			--ctxt->depth;
 			if (rep != NULL) {
 			    current = rep;
 			    while (*current != 0) { /* non input consuming */
@@ -4130,8 +4154,10 @@
 			(ent->content != NULL) && (ent->checked == 0)) {
 			unsigned long oldnbent = ctxt->nbentities;
 
+			++ctxt->depth;
 			rep = xmlStringDecodeEntities(ctxt, ent->content,
 						  XML_SUBSTITUTE_REF, 0, 0, 0);
+			--ctxt->depth;
 
 			ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
 			if (rep != NULL) {
@@ -5501,7 +5527,7 @@
 	    skipped = SKIP_BLANKS;
 	    if (skipped == 0) {
 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
-			       "Space required after '%'\n");
+			       "Space required after '%%'\n");
 	    }
 	    isParameter = 1;
 	}
@@ -6686,6 +6712,7 @@
 	if (!IS_BLANK_CH(CUR)) {
 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 		           "Space required after 'ELEMENT'\n");
+	    return(-1);
 	}
         SKIP_BLANKS;
         name = xmlParseName(ctxt);
@@ -6837,6 +6864,7 @@
 
 	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
 		xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
+		xmlHaltParser(ctxt);
 		break;
 	    }
 	}
@@ -9466,7 +9494,10 @@
 		else
 		    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
 skip_default_ns:
-		if (alloc != 0) xmlFree(attvalue);
+		if ((attvalue != NULL) && (alloc != 0)) {
+		    xmlFree(attvalue);
+		    attvalue = NULL;
+		}
 		if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
 		    break;
 		if (!IS_BLANK_CH(RAW)) {
@@ -9475,6 +9506,8 @@
 		    break;
 		}
 		SKIP_BLANKS;
+		if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+		    goto base_changed;
 		continue;
 	    }
             if (aprefix == ctxt->str_xmlns) {
@@ -9546,7 +9579,10 @@
 		else
 		    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
 skip_ns:
-		if (alloc != 0) xmlFree(attvalue);
+		if ((attvalue != NULL) && (alloc != 0)) {
+		    xmlFree(attvalue);
+		    attvalue = NULL;
+		}
 		if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
 		    break;
 		if (!IS_BLANK_CH(RAW)) {
@@ -9817,6 +9853,7 @@
 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
                 const xmlChar *URI, int line, int nsNr, int tlen) {
     const xmlChar *name;
+    size_t curLength;
 
     GROW;
     if ((RAW != '<') || (NXT(1) != '/')) {
@@ -9825,9 +9862,11 @@
     }
     SKIP(2);
 
-    size_t curLength = ctxt->input->end - ctxt->input->cur;
-    if ((tlen > 0) && (curLength >= (size_t)tlen) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
-      if ((curLength >= (size_t)(tlen + 1)) && (ctxt->input->cur[tlen] == '>')) {
+    curLength = ctxt->input->end - ctxt->input->cur;
+    if ((tlen > 0) && (curLength >= (size_t)tlen) &&
+        (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
+        if ((curLength >= (size_t)(tlen + 1)) &&
+	    (ctxt->input->cur[tlen] == '>')) {
 	    ctxt->input->cur += tlen + 1;
 	    ctxt->input->col += tlen + 1;
 	    goto done;
diff --git a/third_party/libxml/src/parserInternals.c b/third_party/libxml/src/parserInternals.c
index 2b8646c21..bfc778ac 100644
--- a/third_party/libxml/src/parserInternals.c
+++ b/third_party/libxml/src/parserInternals.c
@@ -55,6 +55,10 @@
 #include <libxml/globals.h>
 #include <libxml/chvalid.h>
 
+#define CUR(ctxt) ctxt->input->cur
+#define END(ctxt) ctxt->input->end
+#define VALID_CTXT(ctxt) (CUR(ctxt) <= END(ctxt))
+
 #include "buf.h"
 #include "enc.h"
 
@@ -165,7 +169,7 @@
  *
  * Handle an internal error
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
 {
     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
@@ -193,7 +197,7 @@
  *
  * n encoding error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, int val)
 {
@@ -294,7 +298,7 @@
  */
 int
 xmlParserInputGrow(xmlParserInputPtr in, int len) {
-    size_t ret;
+    int ret;
     size_t indx;
     const xmlChar *content;
 
@@ -422,103 +426,105 @@
         (ctxt->input == NULL))
         return;
 
-    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-        if ((*ctxt->input->cur == 0) &&
-            (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
-            (ctxt->instate != XML_PARSER_COMMENT)) {
-            /*
-             * If we are at the end of the current entity and
-             * the context allows it, we pop consumed entities
-             * automatically.
-             * the auto closing should be blocked in other cases
-             */
+    if (!(VALID_CTXT(ctxt))) {
+        xmlErrInternal(ctxt, "Parser input data memory error\n", NULL);
+	ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+        xmlStopParser(ctxt);
+	return;
+    }
+
+    if ((*ctxt->input->cur == 0) &&
+        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
+        if ((ctxt->instate != XML_PARSER_COMMENT))
             xmlPopInput(ctxt);
-        } else {
-            const unsigned char *cur;
-            unsigned char c;
+        return;
+    }
 
-            /*
-             *   2.11 End-of-Line Handling
-             *   the literal two-character sequence "#xD#xA" or a standalone
-             *   literal #xD, an XML processor must pass to the application
-             *   the single character #xA.
-             */
-            if (*(ctxt->input->cur) == '\n') {
-                ctxt->input->line++; ctxt->input->col = 1;
-            } else
-                ctxt->input->col++;
+    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
+        const unsigned char *cur;
+        unsigned char c;
 
-            /*
-             * We are supposed to handle UTF8, check it's valid
-             * From rfc2044: encoding of the Unicode values on UTF-8:
-             *
-             * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
-             * 0000 0000-0000 007F   0xxxxxxx
-             * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
-             * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
-             *
-             * Check for the 0x110000 limit too
-             */
-            cur = ctxt->input->cur;
+        /*
+         *   2.11 End-of-Line Handling
+         *   the literal two-character sequence "#xD#xA" or a standalone
+         *   literal #xD, an XML processor must pass to the application
+         *   the single character #xA.
+         */
+        if (*(ctxt->input->cur) == '\n') {
+            ctxt->input->line++; ctxt->input->col = 1;
+        } else
+            ctxt->input->col++;
 
-            c = *cur;
-            if (c & 0x80) {
-	        if (c == 0xC0)
-		    goto encoding_error;
-                if (cur[1] == 0) {
+        /*
+         * We are supposed to handle UTF8, check it's valid
+         * From rfc2044: encoding of the Unicode values on UTF-8:
+         *
+         * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
+         * 0000 0000-0000 007F   0xxxxxxx
+         * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
+         * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
+         *
+         * Check for the 0x110000 limit too
+         */
+        cur = ctxt->input->cur;
+
+        c = *cur;
+        if (c & 0x80) {
+        if (c == 0xC0)
+	    goto encoding_error;
+            if (cur[1] == 0) {
+                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                cur = ctxt->input->cur;
+            }
+            if ((cur[1] & 0xc0) != 0x80)
+                goto encoding_error;
+            if ((c & 0xe0) == 0xe0) {
+                unsigned int val;
+
+                if (cur[2] == 0) {
                     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                     cur = ctxt->input->cur;
                 }
-                if ((cur[1] & 0xc0) != 0x80)
+                if ((cur[2] & 0xc0) != 0x80)
                     goto encoding_error;
-                if ((c & 0xe0) == 0xe0) {
-                    unsigned int val;
-
-                    if (cur[2] == 0) {
+                if ((c & 0xf0) == 0xf0) {
+                    if (cur[3] == 0) {
                         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                         cur = ctxt->input->cur;
                     }
-                    if ((cur[2] & 0xc0) != 0x80)
+                    if (((c & 0xf8) != 0xf0) ||
+                        ((cur[3] & 0xc0) != 0x80))
                         goto encoding_error;
-                    if ((c & 0xf0) == 0xf0) {
-                        if (cur[3] == 0) {
-                            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-                            cur = ctxt->input->cur;
-                        }
-                        if (((c & 0xf8) != 0xf0) ||
-                            ((cur[3] & 0xc0) != 0x80))
-                            goto encoding_error;
-                        /* 4-byte code */
-                        ctxt->input->cur += 4;
-                        val = (cur[0] & 0x7) << 18;
-                        val |= (cur[1] & 0x3f) << 12;
-                        val |= (cur[2] & 0x3f) << 6;
-                        val |= cur[3] & 0x3f;
-                    } else {
-                        /* 3-byte code */
-                        ctxt->input->cur += 3;
-                        val = (cur[0] & 0xf) << 12;
-                        val |= (cur[1] & 0x3f) << 6;
-                        val |= cur[2] & 0x3f;
-                    }
-                    if (((val > 0xd7ff) && (val < 0xe000)) ||
-                        ((val > 0xfffd) && (val < 0x10000)) ||
-                        (val >= 0x110000)) {
-			xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
-					  "Char 0x%X out of allowed range\n",
-					  val);
-                    }
-                } else
-                    /* 2-byte code */
-                    ctxt->input->cur += 2;
+                    /* 4-byte code */
+                    ctxt->input->cur += 4;
+                    val = (cur[0] & 0x7) << 18;
+                    val |= (cur[1] & 0x3f) << 12;
+                    val |= (cur[2] & 0x3f) << 6;
+                    val |= cur[3] & 0x3f;
+                } else {
+                    /* 3-byte code */
+                    ctxt->input->cur += 3;
+                    val = (cur[0] & 0xf) << 12;
+                    val |= (cur[1] & 0x3f) << 6;
+                    val |= cur[2] & 0x3f;
+                }
+                if (((val > 0xd7ff) && (val < 0xe000)) ||
+                    ((val > 0xfffd) && (val < 0x10000)) ||
+                    (val >= 0x110000)) {
+		xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+				  "Char 0x%X out of allowed range\n",
+				  val);
+                }
             } else
-                /* 1-byte code */
-                ctxt->input->cur++;
+                /* 2-byte code */
+                ctxt->input->cur += 2;
+        } else
+            /* 1-byte code */
+            ctxt->input->cur++;
 
-            ctxt->nbChars++;
-            if (*ctxt->input->cur == 0)
-                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-        }
+        ctxt->nbChars++;
+        if (*ctxt->input->cur == 0)
+            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
     } else {
         /*
          * Assume it's a fixed length encoding (1) with
diff --git a/third_party/libxml/src/relaxng.c b/third_party/libxml/src/relaxng.c
index 5779e7f..56a3344 100644
--- a/third_party/libxml/src/relaxng.c
+++ b/third_party/libxml/src/relaxng.c
@@ -507,7 +507,7 @@
  *
  * Handle a Relax NG Parsing error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
            const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
@@ -541,7 +541,7 @@
  *
  * Handle a Relax NG Validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
            const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
@@ -2215,7 +2215,8 @@
         snprintf(msg, 1000, "Unknown error code %d\n", err);
     }
     msg[1000 - 1] = 0;
-    return (xmlStrdup((xmlChar *) msg));
+    xmlChar *result = xmlCharStrdup(msg);
+    return (xmlEscapeFormatString(&result));
 }
 
 /**
diff --git a/third_party/libxml/src/runtest.c b/third_party/libxml/src/runtest.c
index 02fe09a..bb74d2a8 100644
--- a/third_party/libxml/src/runtest.c
+++ b/third_party/libxml/src/runtest.c
@@ -81,8 +81,10 @@
  */
 #ifdef	O_BINARY
 #define RD_FLAGS	O_RDONLY | O_BINARY
+#define WR_FLAGS	O_WRONLY | O_CREAT | O_TRUNC | O_BINARY
 #else
-#define	RD_FLAGS	O_RDONLY
+#define RD_FLAGS	O_RDONLY
+#define WR_FLAGS	O_WRONLY | O_CREAT | O_TRUNC
 #endif
 
 typedef int (*functest) (const char *filename, const char *result,
@@ -100,6 +102,7 @@
     int     options;  /* parser options for the test */
 };
 
+static int update_results = 0;
 static int checkTestFile(const char *filename);
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -604,12 +607,34 @@
     return(1);
 }
 
-static int compareFiles(const char *r1, const char *r2) {
+static int compareFiles(const char *r1 /* temp */, const char *r2 /* result */) {
     int res1, res2;
     int fd1, fd2;
     char bytes1[4096];
     char bytes2[4096];
 
+    if (update_results) {
+        fd1 = open(r1, RD_FLAGS);
+        if (fd1 < 0)
+            return(-1);
+        fd2 = open(r2, WR_FLAGS, 0644);
+        if (fd2 < 0) {
+            close(fd1);
+            return(-1);
+        }
+        do {
+            res1 = read(fd1, bytes1, 4096);
+            if (res1 <= 0)
+                break;
+            res2 = write(fd2, bytes1, res1);
+            if (res2 <= 0 || res2 != res1)
+                break;
+        } while (1);
+        close(fd2);
+        close(fd1);
+        return(res1 != 0);
+    }
+
     fd1 = open(r1, RD_FLAGS);
     if (fd1 < 0)
         return(-1);
@@ -646,13 +671,31 @@
     int idx = 0;
     struct stat info;
 
-    if (stat(filename, &info) < 0)
+    if (update_results) {
+        fd = open(filename, WR_FLAGS, 0644);
+        if (fd < 0) {
+	    fprintf(stderr, "failed to open %s for writing", filename);
+            return(-1);
+	}
+        res = write(fd, mem, size);
+        close(fd);
+        return(res != size);
+    }
+
+    if (stat(filename, &info) < 0) {
+        fprintf(stderr, "failed to stat %s\n", filename);
 	return(-1);
-    if (info.st_size != size)
+    }
+    if (info.st_size != size) {
+        fprintf(stderr, "file %s is %ld bytes, result is %d bytes\n",
+	        filename, info.st_size, size);
         return(-1);
+    }
     fd = open(filename, RD_FLAGS);
-    if (fd < 0)
+    if (fd < 0) {
+	fprintf(stderr, "failed to open %s for reading", filename);
         return(-1);
+    }
     while (idx < size) {
         res = read(fd, bytes, 4096);
 	if (res <= 0)
@@ -671,6 +714,9 @@
 	idx += res;
     }
     close(fd);
+    if (idx != size) {
+	fprintf(stderr,"Compare error index %d, size %d\n", idx, size);
+    }
     return(idx != size);
 }
 
@@ -1827,7 +1873,7 @@
     ctxt = xmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename);
     xmlCtxtUseOptions(ctxt, options);
     cur += 4;
-    while (cur < size) {
+    do {
         if (cur + 1024 >= size) {
 #ifdef LIBXML_HTML_ENABLED
 	    if (options & XML_PARSE_HTML)
@@ -1845,7 +1891,7 @@
 	    xmlParseChunk(ctxt, base + cur, 1024, 0);
 	    cur += 1024;
 	}
-    }
+    } while (cur < size);
     doc = ctxt->myDoc;
 #ifdef LIBXML_HTML_ENABLED
     if (options & XML_PARSE_HTML)
@@ -1871,7 +1917,7 @@
     if ((base == NULL) || (res != 0)) {
 	if (base != NULL)
 	    xmlFree((char *)base);
-        fprintf(stderr, "Result for %s failed\n", filename);
+        fprintf(stderr, "Result for %s failed in %s\n", filename, result);
 	return(-1);
     }
     xmlFree((char *)base);
@@ -1926,7 +1972,7 @@
     if ((base == NULL) || (res != 0)) {
 	if (base != NULL)
 	    xmlFree((char *)base);
-        fprintf(stderr, "Result for %s failed\n", filename);
+        fprintf(stderr, "Result for %s failed in %s\n", filename, result);
 	return(-1);
     }
     xmlFree((char *)base);
@@ -2037,16 +2083,16 @@
 	    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);
 	}
 	res = compareFileMem(result, base, size);
+	if (res != 0) {
+	    fprintf(stderr, "Result for %s failed in %s\n", filename, result);
+	    return(-1);
+	}
     }
     if (doc != NULL) {
 	if (base != NULL)
 	    xmlFree((char *)base);
 	xmlFreeDoc(doc);
     }
-    if (res != 0) {
-        fprintf(stderr, "Result for %s failed\n", filename);
-	return(-1);
-    }
     if (err != NULL) {
 	res = compareFileMem(err, testErrors, testErrorsSize);
 	if (res != 0) {
@@ -2159,7 +2205,7 @@
             free(temp);
         }
 	if (ret) {
-	    fprintf(stderr, "Result for %s failed\n", filename);
+	    fprintf(stderr, "Result for %s failed in %s\n", filename, result);
 	    return(-1);
 	}
     }
@@ -2362,7 +2408,7 @@
     if (result != NULL) {
 	ret = compareFiles(temp, result);
 	if (ret) {
-	    fprintf(stderr, "Result for %s failed\n", filename);
+	    fprintf(stderr, "Result for %s failed in %s\n", filename, result);
 	}
     }
 
@@ -2533,7 +2579,7 @@
     if (result != NULL) {
 	ret = compareFiles(temp, result);
 	if (ret) {
-	    fprintf(stderr, "Result for %s failed\n", filename);
+	    fprintf(stderr, "Result for %s failed in %s\n", filename, result);
 	    res = 1;
 	}
     }
@@ -2661,7 +2707,7 @@
     if (result != NULL) {
 	ret = compareFiles(temp, result);
 	if (ret) {
-	    fprintf(stderr, "Result for %s failed\n", filename);
+	    fprintf(stderr, "Result for %s failed in %s\n", filename, result);
 	    res = 1;
 	}
     }
@@ -3430,11 +3476,11 @@
     result[499] = 0;
     memcpy(xml + len, ".xml", 5);
 
-    if (!checkTestFile(xml)) {
+    if (!checkTestFile(xml) && !update_results) {
 	fprintf(stderr, "Missing xml file %s\n", xml);
 	return(-1);
     }
-    if (!checkTestFile(result)) {
+    if (!checkTestFile(result) && !update_results) {
 	fprintf(stderr, "Missing result file %s\n", result);
 	return(-1);
     }
@@ -3533,7 +3579,7 @@
 
     ret = compareFiles(temp, result);
     if (ret) {
-	fprintf(stderr, "Result for %s failed\n", filename);
+	fprintf(stderr, "Result for %s failed in %s\n", filename, result);
 	ret = 1;
     }
     if (temp != NULL) {
@@ -3805,7 +3851,7 @@
     prefix[len] = 0;
 
     snprintf(buf, 499, "result/c14n/%s/%s", subdir,prefix);
-    if (!checkTestFile(buf)) {
+    if (!checkTestFile(buf) && !update_results) {
         fprintf(stderr, "Missing result file %s", buf);
 	return(-1);
     }
@@ -4354,9 +4400,9 @@
 	    } else {
 	        error = NULL;
 	    }
-	    if ((result) &&(!checkTestFile(result))) {
+	    if ((result) &&(!checkTestFile(result)) && !update_results) {
 	        fprintf(stderr, "Missing result file %s\n", result);
-	    } else if ((error) &&(!checkTestFile(error))) {
+	    } else if ((error) &&(!checkTestFile(error)) && !update_results) {
 	        fprintf(stderr, "Missing error file %s\n", error);
 	    } else {
 		mem = xmlMemUsed();
@@ -4440,6 +4486,8 @@
     for (a = 1; a < argc;a++) {
         if (!strcmp(argv[a], "-v"))
 	    verbose = 1;
+        else if (!strcmp(argv[a], "-u"))
+	    update_results = 1;
         else if (!strcmp(argv[a], "-quiet"))
 	    tests_quiet = 1;
 	else {
diff --git a/third_party/libxml/src/schematron.c b/third_party/libxml/src/schematron.c
index 458984f..6200f2d4 100644
--- a/third_party/libxml/src/schematron.c
+++ b/third_party/libxml/src/schematron.c
@@ -245,7 +245,7 @@
  *
  * Handle a parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
               const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
diff --git a/third_party/libxml/src/testModule.c b/third_party/libxml/src/testModule.c
index e399f5c..77b7ba1 100644
--- a/third_party/libxml/src/testModule.c
+++ b/third_party/libxml/src/testModule.c
@@ -47,7 +47,7 @@
 
     /* build the module filename, and confirm the module exists */
     xmlStrPrintf(filename, sizeof(filename),
-                 (const xmlChar*) "%s/testdso%s",
+                 "%s/testdso%s",
                  (const xmlChar*)MODULE_PATH,
 		 (const xmlChar*)LIBXML_MODULE_EXTENSION);
 
diff --git a/third_party/libxml/src/tree.c b/third_party/libxml/src/tree.c
index 7fbca6e0..9d330b8 100644
--- a/third_party/libxml/src/tree.c
+++ b/third_party/libxml/src/tree.c
@@ -1593,6 +1593,7 @@
 			else if ((ent != NULL) && (ent->children == NULL)) {
 			    xmlNodePtr temp;
 
+			    ent->children = (xmlNodePtr) -1;
 			    ent->children = xmlStringGetNodeList(doc,
 				    (const xmlChar*)node->content);
 			    ent->owner = 1;
diff --git a/third_party/libxml/src/uri.c b/third_party/libxml/src/uri.c
index 3e51255..2bd5720d 100644
--- a/third_party/libxml/src/uri.c
+++ b/third_party/libxml/src/uri.c
@@ -325,11 +325,12 @@
 xmlParse3986Port(xmlURIPtr uri, const char **str)
 {
     const char *cur = *str;
+    unsigned port = 0; /* unsigned for defined overflow behavior */
 
     if (ISA_DIGIT(cur)) {
-	unsigned port = 0; /* unsigned for defined overflow behavior */
 	while (ISA_DIGIT(cur)) {
 	    port = port * 10 + (*cur - '0');
+
 	    cur++;
 	}
 	if (uri != NULL)
diff --git a/third_party/libxml/src/valid.c b/third_party/libxml/src/valid.c
index 6567f15..19f84b8 100644
--- a/third_party/libxml/src/valid.c
+++ b/third_party/libxml/src/valid.c
@@ -93,7 +93,7 @@
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const char *extra)
 {
@@ -137,7 +137,7 @@
  *
  * Handle a validation error, provide contextual informations
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlErrValidNode(xmlValidCtxtPtr ctxt,
                 xmlNodePtr node, xmlParserErrors error,
                 const char *msg, const xmlChar * str1,
@@ -180,7 +180,7 @@
  *
  * Handle a validation error, provide contextual informations
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlErrValidNodeNr(xmlValidCtxtPtr ctxt,
                 xmlNodePtr node, xmlParserErrors error,
                 const char *msg, const xmlChar * str1,
@@ -221,7 +221,7 @@
  *
  * Handle a validation error, provide contextual information
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlErrValidWarning(xmlValidCtxtPtr ctxt,
                 xmlNodePtr node, xmlParserErrors error,
                 const char *msg, const xmlChar * str1,
diff --git a/third_party/libxml/src/xinclude.c b/third_party/libxml/src/xinclude.c
index ff3dafb..e3bb43e 100644
--- a/third_party/libxml/src/xinclude.c
+++ b/third_party/libxml/src/xinclude.c
@@ -125,7 +125,7 @@
  *
  * Handle an XInclude error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
                const char *msg, const xmlChar *extra)
 {
@@ -147,7 +147,7 @@
  *
  * Emit an XInclude warning.
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlXIncludeWarn(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
                const char *msg, const xmlChar *extra)
 {
diff --git a/third_party/libxml/src/xmlIO.c b/third_party/libxml/src/xmlIO.c
index 8b13184..1a79c09 100644
--- a/third_party/libxml/src/xmlIO.c
+++ b/third_party/libxml/src/xmlIO.c
@@ -1604,7 +1604,7 @@
 	xmlFreeZMemBuff( buff );
 	buff = NULL;
 	xmlStrPrintf(msg, 500,
-		    (const xmlChar *) "xmlCreateZMemBuff:  %s %d\n",
+		    "xmlCreateZMemBuff:  %s %d\n",
 		    "Error initializing compression context.  ZLIB error:",
 		    z_err );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -1672,7 +1672,7 @@
     else {
 	xmlChar msg[500];
 	xmlStrPrintf(msg, 500,
-		    (const xmlChar *) "xmlZMemBuffExtend:  %s %lu bytes.\n",
+		    "xmlZMemBuffExtend:  %s %lu bytes.\n",
 		    "Allocation failure extending output buffer to",
 		    new_size );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -1718,7 +1718,7 @@
 	if ( z_err != Z_OK ) {
 	    xmlChar msg[500];
 	    xmlStrPrintf(msg, 500,
-			(const xmlChar *) "xmlZMemBuffAppend:  %s %d %s - %d",
+			"xmlZMemBuffAppend:  %s %d %s - %d",
 			"Compression error while appending",
 			len, "bytes to buffer.  ZLIB error", z_err );
 	    xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -1791,7 +1791,7 @@
     else {
 	xmlChar msg[500];
 	xmlStrPrintf(msg, 500,
-		    (const xmlChar *) "xmlZMemBuffGetContent:  %s - %d\n",
+		    "xmlZMemBuffGetContent:  %s - %d\n",
 		    "Error flushing zlib buffers.  Error code", z_err );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
     }
@@ -1996,7 +1996,7 @@
 	if ( len < 0 ) {
 	    xmlChar msg[500];
 	    xmlStrPrintf(msg, 500,
-			(const xmlChar *) "xmlIOHTTPWrite:  %s\n%s '%s'.\n",
+			"xmlIOHTTPWrite:  %s\n%s '%s'.\n",
 			"Error appending to internal buffer.",
 			"Error sending document to URI",
 			ctxt->uri );
@@ -2068,7 +2068,7 @@
     if ( http_content == NULL ) {
 	xmlChar msg[500];
 	xmlStrPrintf(msg, 500,
-		     (const xmlChar *) "xmlIOHTTPCloseWrite:  %s '%s' %s '%s'.\n",
+		     "xmlIOHTTPCloseWrite:  %s '%s' %s '%s'.\n",
 		     "Error retrieving content.\nUnable to",
 		     http_mthd, "data to URI", ctxt->uri );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -2140,7 +2140,7 @@
 	    else {
                 xmlChar msg[500];
                 xmlStrPrintf(msg, 500,
-    (const xmlChar *) "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n",
+                      "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n",
 			    http_mthd, content_lgth,
 			    "bytes to URI", ctxt->uri,
 			    "failed.  HTTP return code:", http_rtn );
diff --git a/third_party/libxml/src/xmlmemory.c b/third_party/libxml/src/xmlmemory.c
index f24fd6d4..f08c8c3 100644
--- a/third_party/libxml/src/xmlmemory.c
+++ b/third_party/libxml/src/xmlmemory.c
@@ -109,6 +109,7 @@
 #define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
 		      / ALIGN_SIZE ) * ALIGN_SIZE)
 
+#define MAX_SIZE_T ((size_t)-1)
 
 #define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
 #define HDR_2_CLIENT(a)    ((void *) (((char *) (a)) + RESERVE_SIZE))
@@ -217,7 +218,7 @@
 
 /**
  * xmlMallocAtomicLoc:
- * @size:  an int specifying the size in byte to allocate.
+ * @size:  an unsigned int specifying the size in byte to allocate.
  * @file:  the file name or NULL
  * @line:  the line number
  *
@@ -240,11 +241,18 @@
 
     TEST_POINT
 
+    if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlMallocAtomicLoc : Unsigned overflow prevented\n");
+	xmlMemoryDump();
+	return(NULL);
+    }
+
     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
 
     if (!p) {
 	xmlGenericError(xmlGenericErrorContext,
-		"xmlMallocLoc : Out of free space\n");
+		"xmlMallocAtomicLoc : Out of free space\n");
 	xmlMemoryDump();
 	return(NULL);
     }
diff --git a/third_party/libxml/src/xmlreader.c b/third_party/libxml/src/xmlreader.c
index d416dac..f285790b 100644
--- a/third_party/libxml/src/xmlreader.c
+++ b/third_party/libxml/src/xmlreader.c
@@ -4050,13 +4050,19 @@
 }
 
 #ifdef LIBXML_SCHEMAS_ENABLED
-static char *xmlTextReaderBuildMessage(const char *msg, va_list ap);
+static char *xmlTextReaderBuildMessage(const char *msg, va_list ap) LIBXML_ATTR_FORMAT(1,0);
 
 static void XMLCDECL
-xmlTextReaderValidityError(void *ctxt, const char *msg, ...);
+xmlTextReaderValidityError(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 
 static void XMLCDECL
-xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...);
+xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+static void XMLCDECL
+xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+static void XMLCDECL
+xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 
 static void XMLCDECL
 xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
@@ -4850,7 +4856,7 @@
     }
 }
 
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 xmlTextReaderError(void *ctxt, const char *msg, ...)
 {
     va_list ap;
@@ -4863,7 +4869,7 @@
 
 }
 
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 xmlTextReaderWarning(void *ctxt, const char *msg, ...)
 {
     va_list ap;
diff --git a/third_party/libxml/src/xmlregexp.c b/third_party/libxml/src/xmlregexp.c
index 727fef4..ca3b4f46 100644
--- a/third_party/libxml/src/xmlregexp.c
+++ b/third_party/libxml/src/xmlregexp.c
@@ -5057,11 +5057,12 @@
 	ERROR("Expecting the end of a char range");
 	return;
     }
-    NEXTL(len);
+
     /* TODO check that the values are acceptable character ranges for XML */
     if (end < start) {
 	ERROR("End of range is before start of range");
     } else {
+        NEXTL(len);
         xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
 		           XML_REGEXP_CHARVAL, start, end, NULL);
     }
diff --git a/third_party/libxml/src/xmlsave.c b/third_party/libxml/src/xmlsave.c
index 774404b..4a8e3f3 100644
--- a/third_party/libxml/src/xmlsave.c
+++ b/third_party/libxml/src/xmlsave.c
@@ -2097,8 +2097,8 @@
             xmlBufAdd(buf, BAD_CAST "&amp;", 5);
             cur++;
             base = cur;
-        } else if ((*cur >= 0x80) && ((doc == NULL) ||
-                                      (doc->encoding == NULL))) {
+        } else if ((*cur >= 0x80) && (cur[1] != 0) &&
+	           ((doc == NULL) || (doc->encoding == NULL))) {
             /*
              * We assume we have UTF-8 content.
              */
@@ -2121,14 +2121,14 @@
                 val <<= 6;
                 val |= (cur[1]) & 0x3F;
                 l = 2;
-            } else if (*cur < 0xF0) {
+            } else if ((*cur < 0xF0) && (cur [2] != 0)) {
                 val = (cur[0]) & 0x0F;
                 val <<= 6;
                 val |= (cur[1]) & 0x3F;
                 val <<= 6;
                 val |= (cur[2]) & 0x3F;
                 l = 3;
-            } else if (*cur < 0xF8) {
+            } else if ((*cur < 0xF8) && (cur [2] != 0) && (cur[3] != 0)) {
                 val = (cur[0]) & 0x07;
                 val <<= 6;
                 val |= (cur[1]) & 0x3F;
diff --git a/third_party/libxml/src/xmlschemas.c b/third_party/libxml/src/xmlschemas.c
index ee22a6d..e1b3a4f 100644
--- a/third_party/libxml/src/xmlschemas.c
+++ b/third_party/libxml/src/xmlschemas.c
@@ -1085,7 +1085,7 @@
 static void
 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 		     const char *funcName,
-		     const char *message);
+		     const char *message) LIBXML_ATTR_FORMAT(3,0);
 static int
 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
 			     xmlSchemaTypePtr type,
@@ -1769,7 +1769,7 @@
     }
     FREE_AND_NULL(str)
 
-    return (*buf);
+    return (xmlEscapeFormatString(buf));
 }
 
 /**
@@ -1889,7 +1889,7 @@
  *
  * Handle a parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
               const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
@@ -1922,7 +1922,7 @@
  *
  * Handle a parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                xmlNodePtr child, int error,
                const char *msg, const xmlChar * str1, const xmlChar * str2)
@@ -1951,7 +1951,7 @@
  *
  * Handle a parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(7,0)
 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 		const xmlChar * strData1, const xmlChar * strData2,
 		const xmlChar * strData3, const char *msg, const xmlChar * str1,
@@ -2002,7 +2002,7 @@
                      extra);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlSchemaPSimpleInternalErr(xmlNodePtr node,
 			    const char *msg, const xmlChar *str)
 {
@@ -2013,18 +2013,21 @@
 #define WXS_ERROR_TYPE_ERROR 1
 #define WXS_ERROR_TYPE_WARNING 2
 /**
- * xmlSchemaErr3:
+ * xmlSchemaErr4Line:
  * @ctxt: the validation context
- * @node: the context node
+ * @errorLevel: the error level
  * @error: the error code
+ * @node: the context node
+ * @line: the line number
  * @msg: the error message
  * @str1: extra data
  * @str2: extra data
  * @str3: extra data
+ * @str4: extra data
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(6,0)
 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
 		  xmlErrorLevel errorLevel,
 		  int error, xmlNodePtr node, int line, const char *msg,
@@ -2139,7 +2142,7 @@
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
 	      int error, xmlNodePtr node, const char *msg,
 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
@@ -2148,7 +2151,7 @@
 	msg, str1, str2, str3, NULL);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
 	      int error, xmlNodePtr node, const char *msg,
 	      const xmlChar *str1, const xmlChar *str2,
@@ -2158,7 +2161,7 @@
 	msg, str1, str2, str3, str4);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
 	     int error, xmlNodePtr node, const char *msg,
 	     const xmlChar *str1, const xmlChar *str2)
@@ -2181,7 +2184,7 @@
 	/*
 	* Don't try to format other nodes than element and
 	* attribute nodes.
-	* Play save and return an empty string.
+	* Play safe and return an empty string.
 	*/
 	*msg = xmlStrdup(BAD_CAST "");
 	return(*msg);
@@ -2246,6 +2249,13 @@
 	TODO
 	return (NULL);
     }
+
+    /*
+     * xmlSchemaFormatItemForReport() also returns an escaped format
+     * string, so do this before calling it below (in the future).
+     */
+    xmlEscapeFormatString(msg);
+
     /*
     * VAL TODO: The output of the given schema component is currently
     * disabled.
@@ -2262,7 +2272,7 @@
     return (*msg);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
 		     const char *funcName,
 		     const char *message,
@@ -2273,24 +2283,21 @@
 
     if (actxt == NULL)
         return;
-    msg = xmlStrdup(BAD_CAST "Internal error: ");
-    msg = xmlStrcat(msg, BAD_CAST funcName);
-    msg = xmlStrcat(msg, BAD_CAST ", ");
+    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
     msg = xmlStrcat(msg, BAD_CAST message);
     msg = xmlStrcat(msg, BAD_CAST ".\n");
 
     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
-	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
-	    (const char *) msg, str1, str2);
-
+	xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
+	    (const char *) msg, (const xmlChar *) funcName, str1, str2);
     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
-	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
-	    (const char *) msg, str1, str2);
+	xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
+	    (const char *) msg, (const xmlChar *) funcName, str1, str2);
 
     FREE_AND_NULL(msg)
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 		     const char *funcName,
 		     const char *message)
@@ -2299,7 +2306,7 @@
 }
 
 #if 0
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
 		     const char *funcName,
 		     const char *message,
@@ -2311,7 +2318,7 @@
 }
 #endif
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
 		   xmlParserErrors error,
 		   xmlNodePtr node,
@@ -2336,7 +2343,7 @@
     FREE_AND_NULL(msg)
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
 		   xmlParserErrors error,
 		   xmlNodePtr node,
@@ -2351,7 +2358,7 @@
 
 
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
 		   xmlParserErrors error,
 		   xmlNodePtr node,
@@ -2376,7 +2383,7 @@
 
 
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
 		   xmlParserErrors error,
 		   xmlSchemaPSVIIDCNodePtr idcNode,
@@ -2476,11 +2483,13 @@
 	msg = xmlStrcat(msg, BAD_CAST " '");
 	if (type->builtInType != 0) {
 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
-	    msg = xmlStrcat(msg, type->name);
-	} else
-	    msg = xmlStrcat(msg,
-		xmlSchemaFormatQName(&str,
-		    type->targetNamespace, type->name));
+	    str = xmlStrdup(type->name);
+	} else {
+	    const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
+	    if (!str)
+		str = xmlStrdup(qName);
+	}
+	msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
 	msg = xmlStrcat(msg, BAD_CAST "'");
 	FREE_AND_NULL(str);
     }
@@ -2525,7 +2534,7 @@
     FREE_AND_NULL(msg)
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 		        xmlParserErrors error,
 		        xmlNodePtr node,
@@ -2617,7 +2626,7 @@
 		str = xmlStrcat(str, BAD_CAST ", ");
 	}
 	str = xmlStrcat(str, BAD_CAST " ).\n");
-	msg = xmlStrcat(msg, BAD_CAST str);
+	msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
 	FREE_AND_NULL(str)
     } else
       msg = xmlStrcat(msg, BAD_CAST "\n");
@@ -2625,7 +2634,7 @@
     xmlFree(msg);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(8,0)
 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
 		  xmlParserErrors error,
 		  xmlNodePtr node,
@@ -2916,7 +2925,7 @@
  *
  * Reports an error during parsing.
  */
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
 		    xmlParserErrors error,
 		    xmlSchemaBasicItemPtr item,
@@ -2952,7 +2961,7 @@
  *
  * Reports an error during parsing.
  */
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
 		    xmlParserErrors error,
 		    xmlSchemaBasicItemPtr item,
@@ -2977,7 +2986,7 @@
  *
  * Reports an attribute use error during parsing.
  */
-static void
+static void LIBXML_ATTR_FORMAT(6,0)
 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
 		    xmlParserErrors error,
 		    xmlNodePtr node,
@@ -3099,7 +3108,7 @@
  * Reports a simple type validation error.
  * TODO: Should this report the value of an element as well?
  */
-static void
+static void LIBXML_ATTR_FORMAT(8,0)
 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
 			xmlParserErrors error,
 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
@@ -3141,11 +3150,13 @@
 		msg = xmlStrcat(msg, BAD_CAST " '");
 		if (type->builtInType != 0) {
 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
-		    msg = xmlStrcat(msg, type->name);
-		} else
-		    msg = xmlStrcat(msg,
-			xmlSchemaFormatQName(&str,
-			    type->targetNamespace, type->name));
+		    str = xmlStrdup(type->name);
+		} else {
+		    const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
+		    if (!str)
+			str = xmlStrdup(qName);
+		}
+		msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
 		msg = xmlStrcat(msg, BAD_CAST "'.");
 		FREE_AND_NULL(str);
 	    }
@@ -3158,7 +3169,9 @@
 	}
 	if (expected) {
 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
-	    msg = xmlStrcat(msg, BAD_CAST expected);
+	    xmlChar *expectedEscaped = xmlCharStrdup(expected);
+	    msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
+	    FREE_AND_NULL(expectedEscaped);
 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
 	} else
 	    msg = xmlStrcat(msg, BAD_CAST "\n");
diff --git a/third_party/libxml/src/xmlstring.c b/third_party/libxml/src/xmlstring.c
index b6dd101..9e704a9 100644
--- a/third_party/libxml/src/xmlstring.c
+++ b/third_party/libxml/src/xmlstring.c
@@ -457,6 +457,8 @@
         return(xmlStrndup(add, len));
 
     size = xmlStrlen(cur);
+    if (size < 0)
+        return(NULL);
     ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
     if (ret == NULL) {
         xmlErrMemory(NULL, NULL);
@@ -484,14 +486,19 @@
     int size;
     xmlChar *ret;
 
-    if (len < 0)
+    if (len < 0) {
         len = xmlStrlen(str2);
+        if (len < 0)
+            return(NULL);
+    }
     if ((str2 == NULL) || (len == 0))
         return(xmlStrdup(str1));
     if (str1 == NULL)
         return(xmlStrndup(str2, len));
 
     size = xmlStrlen(str1);
+    if (size < 0)
+        return(NULL);
     ret = (xmlChar *) xmlMalloc((size + len + 1) * sizeof(xmlChar));
     if (ret == NULL) {
         xmlErrMemory(NULL, NULL);
@@ -538,7 +545,7 @@
  * Returns the number of characters written to @buf or -1 if an error occurs.
  */
 int XMLCDECL
-xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) {
+xmlStrPrintf(xmlChar *buf, int len, const char *msg, ...) {
     va_list args;
     int ret;
 
@@ -566,7 +573,7 @@
  * Returns the number of characters written to @buf or -1 if an error occurs.
  */
 int
-xmlStrVPrintf(xmlChar *buf, int len, const xmlChar *msg, va_list ap) {
+xmlStrVPrintf(xmlChar *buf, int len, const char *msg, va_list ap) {
     int ret;
 
     if((buf == NULL) || (msg == NULL)) {
@@ -984,5 +991,60 @@
     return(xmlUTF8Strndup(utf, len));
 }
 
+/**
+ * xmlEscapeFormatString:
+ * @msg:  a pointer to the string in which to escape '%' characters.
+ * Must be a heap-allocated buffer created by libxml2 that may be
+ * returned, or that may be freed and replaced.
+ *
+ * Replaces the string pointed to by 'msg' with an escaped string.
+ * Returns the same string with all '%' characters escaped.
+ */
+xmlChar *
+xmlEscapeFormatString(xmlChar **msg)
+{
+    xmlChar *msgPtr = NULL;
+    xmlChar *result = NULL;
+    xmlChar *resultPtr = NULL;
+    size_t count = 0;
+    size_t msgLen = 0;
+    size_t resultLen = 0;
+
+    if (!msg || !*msg)
+        return(NULL);
+
+    for (msgPtr = *msg; *msgPtr != '\0'; ++msgPtr) {
+        ++msgLen;
+        if (*msgPtr == '%')
+            ++count;
+    }
+
+    if (count == 0)
+        return(*msg);
+
+    resultLen = msgLen + count + 1;
+    result = (xmlChar *) xmlMallocAtomic(resultLen * sizeof(xmlChar));
+    if (result == NULL) {
+        /* Clear *msg to prevent format string vulnerabilities in
+           out-of-memory situations. */
+        xmlFree(*msg);
+        *msg = NULL;
+        xmlErrMemory(NULL, NULL);
+        return(NULL);
+    }
+
+    for (msgPtr = *msg, resultPtr = result; *msgPtr != '\0'; ++msgPtr, ++resultPtr) {
+        *resultPtr = *msgPtr;
+        if (*msgPtr == '%')
+            *(++resultPtr) = '%';
+    }
+    result[resultLen - 1] = '\0';
+
+    xmlFree(*msg);
+    *msg = result;
+
+    return *msg;
+}
+
 #define bottom_xmlstring
 #include "elfgcchack.h"
diff --git a/third_party/libxml/src/xmlwriter.c b/third_party/libxml/src/xmlwriter.c
index fac20ac..69541b8 100644
--- a/third_party/libxml/src/xmlwriter.c
+++ b/third_party/libxml/src/xmlwriter.c
@@ -113,7 +113,7 @@
                                          const xmlChar * str, int len);
 static int xmlTextWriterCloseDocCallback(void *context);
 
-static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
+static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr) LIBXML_ATTR_FORMAT(1,0);
 static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
                                       const unsigned char *data);
 static void xmlTextWriterStartDocumentCallback(void *ctx);
@@ -153,7 +153,7 @@
  *
  * Handle a writer error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
                const char *msg, int val)
 {
diff --git a/third_party/libxml/src/xpath.c b/third_party/libxml/src/xpath.c
index 620e8144..113bce6 100644
--- a/third_party/libxml/src/xpath.c
+++ b/third_party/libxml/src/xpath.c
@@ -639,7 +639,7 @@
             xmlChar buf[200];
 
             xmlStrPrintf(buf, 200,
-                         BAD_CAST "Memory allocation failed : %s\n",
+                         "Memory allocation failed : %s\n",
                          extra);
             ctxt->lastError.message = (char *) xmlStrdup(buf);
         } else {
diff --git a/third_party/libxml/src/xpointer.c b/third_party/libxml/src/xpointer.c
index 4b4ac2ee5..676c510 100644
--- a/third_party/libxml/src/xpointer.c
+++ b/third_party/libxml/src/xpointer.c
@@ -85,7 +85,7 @@
  *
  * Handle a redefinition of attribute error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
            const char * msg, const xmlChar *extra)
 {
diff --git a/tools/grit/grit/format/html_inline.py b/tools/grit/grit/format/html_inline.py
index f532496..643052dd2 100755
--- a/tools/grit/grit/format/html_inline.py
+++ b/tools/grit/grit/format/html_inline.py
@@ -128,8 +128,9 @@
     self.inlined_files = inlined_files
 
 def DoInline(
-    input_filename, grd_node, allow_external_script=False, names_only=False,
-    rewrite_function=None, filename_expansion_function=None):
+    input_filename, grd_node, allow_external_script=False,
+    preprocess_only=False, names_only=False, rewrite_function=None,
+    filename_expansion_function=None):
   """Helper function that inlines the resources in a specified file.
 
   Reads input_filename, finds all the src attributes and attempts to
@@ -139,6 +140,7 @@
   Args:
     input_filename: name of file to read in
     grd_node: html node from the grd file for this include tag
+    preprocess_only: Skip all HTML processing, only handle <if> and <include>.
     names_only: |nil| will be returned for the inlined contents (faster).
     rewrite_function: function(filepath, text, distribution) which will be
         called to rewrite html content before inlining images.
@@ -234,7 +236,7 @@
       return ""
 
     return pattern % InlineToString(
-        filepath, grd_node, allow_external_script,
+        filepath, grd_node, allow_external_script=allow_external_script,
         filename_expansion_function=filename_expansion_function)
 
   def InlineIncludeFiles(src_match):
@@ -319,17 +321,18 @@
   # going to throw out anyway.
   flat_text = CheckConditionalElements(flat_text)
 
-  if not allow_external_script:
-    # We need to inline css and js before we inline images so that image
-    # references gets inlined in the css and js
-    flat_text = re.sub('<script (?P<attrs1>.*?)src="(?P<filename>[^"\']*)"' +
-                       '(?P<attrs2>.*?)></script>',
-                       InlineScript,
-                       flat_text)
+  if not preprocess_only:
+    if not allow_external_script:
+      # We need to inline css and js before we inline images so that image
+      # references gets inlined in the css and js
+      flat_text = re.sub('<script (?P<attrs1>.*?)src="(?P<filename>[^"\']*)"' +
+                         '(?P<attrs2>.*?)></script>',
+                         InlineScript,
+                         flat_text)
 
-  flat_text = _STYLESHEET_RE.sub(
-      lambda m: InlineCSSFile(m, '<style>%s</style>'),
-      flat_text)
+    flat_text = _STYLESHEET_RE.sub(
+        lambda m: InlineCSSFile(m, '<style>%s</style>'),
+        flat_text)
 
   flat_text = _INCLUDE_RE.sub(InlineIncludeFiles, flat_text)
 
@@ -337,24 +340,25 @@
   # of the text we just inlined.
   flat_text = CheckConditionalElements(flat_text)
 
-  # Allow custom modifications before inlining images.
-  if rewrite_function:
-    flat_text = rewrite_function(input_filepath, flat_text, distribution)
+  if not preprocess_only:
+    # Allow custom modifications before inlining images.
+    if rewrite_function:
+      flat_text = rewrite_function(input_filepath, flat_text, distribution)
+    flat_text = _SRC_RE.sub(SrcReplace, flat_text)
 
-  flat_text = _SRC_RE.sub(SrcReplace, flat_text)
+    # TODO(arv): Only do this inside <style> tags.
+    flat_text = InlineCSSImages(flat_text)
 
-  # TODO(arv): Only do this inside <style> tags.
-  flat_text = InlineCSSImages(flat_text)
-
-  flat_text = _ICON_RE.sub(SrcReplace, flat_text)
+    flat_text = _ICON_RE.sub(SrcReplace, flat_text)
 
   if names_only:
     flat_text = None  # Will contains garbage if the flag is set anyway.
   return InlinedData(flat_text, inlined_files)
 
 
-def InlineToString(input_filename, grd_node, allow_external_script=False,
-                   rewrite_function=None, filename_expansion_function=None):
+def InlineToString(input_filename, grd_node, preprocess_only = False,
+                   allow_external_script=False, rewrite_function=None,
+                   filename_expansion_function=None):
   """Inlines the resources in a specified file and returns it as a string.
 
   Args:
@@ -367,6 +371,7 @@
     return DoInline(
         input_filename,
         grd_node,
+        preprocess_only=preprocess_only,
         allow_external_script=allow_external_script,
         rewrite_function=rewrite_function,
         filename_expansion_function=filename_expansion_function).inlined_data
@@ -404,6 +409,7 @@
         filename,
         None,
         names_only=True,
+        preprocess_only=False,
         allow_external_script=allow_external_script,
         rewrite_function=rewrite_function,
         filename_expansion_function=filename_expansion_function).inlined_files
diff --git a/tools/grit/grit/gather/chrome_html.py b/tools/grit/grit/gather/chrome_html.py
index e7469bf..a8f8eb8 100755
--- a/tools/grit/grit/gather/chrome_html.py
+++ b/tools/grit/grit/gather/chrome_html.py
@@ -286,6 +286,7 @@
     super(ChromeHtml, self).__init__(*args, **kwargs)
     self.allow_external_script_ = False
     self.flatten_html_ = False
+    self.preprocess_only_ = False
     # 1x resources are implicitly already in the source and do not need to be
     # added.
     self.scale_factors_ = []
@@ -294,8 +295,10 @@
   def SetAttributes(self, attrs):
     self.allow_external_script_ = ('allowexternalscript' in attrs and
                                    attrs['allowexternalscript'] == 'true')
-    self.flatten_html_ = ('flattenhtml' in attrs and
-                          attrs['flattenhtml'] == 'true')
+    self.preprocess_only_ = ('preprocess' in attrs and
+                             attrs['preprocess'] == 'true')
+    self.flatten_html_ = (self.preprocess_only_ or ('flattenhtml' in attrs and
+                           attrs['flattenhtml'] == 'true'))
 
   def SetDefines(self, defines):
     if 'scale_factors' in defines:
@@ -346,6 +349,7 @@
           filename,
           self.grd_node,
           allow_external_script = self.allow_external_script_,
+          preprocess_only = self.preprocess_only_,
           rewrite_function=lambda fp, t, d: ProcessImageSets(
               fp, t, self.scale_factors_, d,
               filename_expansion_function=self.filename_expansion_function),
diff --git a/tools/grit/grit/node/include.py b/tools/grit/grit/node/include.py
index ebcd531..4780d5e 100755
--- a/tools/grit/grit/node/include.py
+++ b/tools/grit/grit/node/include.py
@@ -35,6 +35,7 @@
       filename = self.ToRealPath(self.GetInputPath())
       self._flattened_data = (
           grit.format.html_inline.InlineToString(filename, self,
+              preprocess_only=False,
               allow_external_script=allow_external_script))
     return self._flattened_data
 
diff --git a/tools/grit/grit/node/structure.py b/tools/grit/grit/node/structure.py
index 331a646..07fe649 100755
--- a/tools/grit/grit/node/structure.py
+++ b/tools/grit/grit/node/structure.py
@@ -138,6 +138,9 @@
              # output of platform.system().
              'run_command_on_platforms' : '',
              'allowexternalscript': 'false',
+             # preprocess takes the same code path as flattenhtml, but it
+             # disables any processing/inlining outside of <if> and <include>.
+             'preprocess': 'false',
              'flattenhtml': 'false',
              'fallback_to_low_resolution': 'default',
              # TODO(joi) this is a hack - should output all generated files
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 96df540..a43b3cc2 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -3445,6 +3445,26 @@
   <summary>Time spent initializing WindowProxy during a page loading.</summary>
 </histogram>
 
+<histogram name="Blink.Canvas.DrawImage" units="microseconds">
+  <owner>junov@chromium.org</owner>
+  <summary>Time spent on 2D canvas drawImage API call.</summary>
+</histogram>
+
+<histogram name="Blink.Canvas.GetImageData" units="microseconds">
+  <owner>junov@chromium.org</owner>
+  <summary>Time spent on 2D canvas getImageData API call.</summary>
+</histogram>
+
+<histogram name="Blink.Canvas.PutImageData" units="microseconds">
+  <owner>junov@chromium.org</owner>
+  <summary>Time spent on 2D canvas putImageData API call.</summary>
+</histogram>
+
+<histogram name="Blink.Canvas.ToDataURL" units="microseconds">
+  <owner>junov@chromium.org</owner>
+  <summary>Time spent on 2D canvas toDataURL API call.</summary>
+</histogram>
+
 <histogram name="Blink.Compositing.UpdateTime" units="microseconds">
   <owner>paint-dev@chromium.org</owner>
   <summary>
@@ -78867,6 +78887,7 @@
   <int value="1731522433" label="enable-offer-store-unmasked-wallet-cards"/>
   <int value="1747279677" label="disable-delegated-renderer"/>
   <int value="1752168018" label="enable-stale-while-revalidate"/>
+  <int value="1772454319" label="enable-storage-manager"/>
   <int value="1775475563" label="malware-interstitial-v3"/>
   <int value="1776475705" label="show-composited-layer-borders"/>
   <int value="1777059507" label="trust-autofill-server-name-types"/>
@@ -91255,6 +91276,40 @@
   <affected-histogram name="WebRTC.Stun.BatchSuccessPercent.UnknownNAT"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="BlinkCanvasDrawImageType" separator=".">
+  <suffix name="Canvas"/>
+  <suffix name="ImageBitmap"/>
+  <suffix name="Others"/>
+  <suffix name="SVG"/>
+  <suffix name="Video"/>
+  <affected-histogram name="Blink.Canvas.DrawImage"/>
+</histogram_suffixes>
+
+<histogram_suffixes name="BlinkCanvasDurationBySource" separator=".">
+  <suffix name="CPU"/>
+  <suffix name="DisplayList"/>
+  <suffix name="GPU"/>
+  <affected-histogram name="Blink.Canvas.DrawImage.Canvas"/>
+  <affected-histogram name="Blink.Canvas.DrawImage.ImageBitmap"/>
+  <affected-histogram name="Blink.Canvas.DrawImage.Others"/>
+  <affected-histogram name="Blink.Canvas.DrawImage.SVG"/>
+  <affected-histogram name="Blink.Canvas.DrawImage.Video"/>
+  <affected-histogram name="Blink.Canvas.GetImageData"/>
+  <affected-histogram name="Blink.Canvas.PutImageData"/>
+</histogram_suffixes>
+
+<histogram_suffixes name="BlinkCanvasToDataURLTime" separator=".">
+  <suffix name="BMP"/>
+  <suffix name="GIF"/>
+  <suffix name="ICON"/>
+  <suffix name="JPEG"/>
+  <suffix name="PNG"/>
+  <suffix name="TIFF"/>
+  <suffix name="Unknown"/>
+  <suffix name="WEBP"/>
+  <affected-histogram name="Blink.Canvas.ToDataURL"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="BlinkGCReason">
   <suffix name="IdleGC" label="Idle GC"/>
   <suffix name="PreciseGC" label="Precise GC"/>
diff --git a/ui/app_list/presenter/BUILD.gn b/ui/app_list/presenter/BUILD.gn
index 2977236b..fd6cb44 100644
--- a/ui/app_list/presenter/BUILD.gn
+++ b/ui/app_list/presenter/BUILD.gn
@@ -50,6 +50,10 @@
   sources = [
     "test/app_list_presenter_impl_test_api.cc",
     "test/app_list_presenter_impl_test_api.h",
+
+    # Temporary dependency to fix compile flake in http://crbug.com/611898.
+    # TODO(tapted): Remove once http://crbug.com/612382 is fixed.
+    "//ui/accessibility:ax_gen",
   ]
 
   public_deps = [
@@ -80,6 +84,10 @@
     "//ui/base",
     "//ui/gl:test_support",
     "//ui/wm:wm",
+
+    # Temporary dependency to fix compile flake in http://crbug.com/611898.
+    # TODO(tapted): Remove once http://crbug.com/612382 is fixed.
+    "//ui/accessibility:ax_gen",
   ]
 
   data_deps = [
diff --git a/ui/app_list/presenter/app_list_presenter.gyp b/ui/app_list/presenter/app_list_presenter.gyp
index 3b178b8a..a541a7d 100644
--- a/ui/app_list/presenter/app_list_presenter.gyp
+++ b/ui/app_list/presenter/app_list_presenter.gyp
@@ -52,6 +52,10 @@
         '../../../base/base.gyp:base',
         '../../../skia/skia.gyp:skia',
         'app_list_presenter',
+
+        # Temporary dependency to fix compile flake in http://crbug.com/611898.
+        # TODO(tapted): Remove once http://crbug.com/612382 is fixed.
+        '../../accessibility/accessibility.gyp:ax_gen',
       ],
       'sources': [
         # Note: sources list duplicated in GN build.
@@ -75,6 +79,10 @@
         '../app_list.gyp:app_list_test_support',
         'app_list_presenter',
         'app_list_presenter_test_support',
+
+        # Temporary dependency to fix compile flake in http://crbug.com/611898.
+        # TODO(tapted): Remove once http://crbug.com/612382 is fixed.
+        '../../accessibility/accessibility.gyp:ax_gen',
       ],
       'sources': [
         # Note: sources list duplicated in GN build.
diff --git a/ui/file_manager/file_manager/foreground/js/file_list_model.js b/ui/file_manager/file_manager/foreground/js/file_list_model.js
index 16ca2b9..3f52d20 100644
--- a/ui/file_manager/file_manager/foreground/js/file_list_model.js
+++ b/ui/file_manager/file_manager/foreground/js/file_list_model.js
@@ -142,12 +142,13 @@
 };
 
 /**
- * Returns true if image files are dominant in this file list.
+ * Returns true if image files are dominant in this file list (i.e. 80% or more
+ * files are images).
  * @return {boolean}
  */
 FileListModel.prototype.isImageDominant = function() {
-  return this.numFiles_ >= 0 &&
-      this.numImageFiles_ / this.numFiles_ >= 0.8;
+  return this.numFiles_ > 0 &&
+      this.numImageFiles_ * 10 >= this.numFiles_ * 8;
 };
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.html b/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.html
new file mode 100644
index 0000000..ddb406c
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- 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.
+  -->
+
+<script src="../../../../../ui/webui/resources/js/cr.js"></script>
+<script src="../../../../../ui/webui/resources/js/cr/ui.js"></script>
+<script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script>
+<script src="../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"></script>
+<script src="../../../../../ui/webui/resources/js/webui_resource_test.js"></script>
+<script src="../../common/js/util.js"></script>
+<script src="../../common/js/file_type.js"></script>
+<script src="file_list_model.js"></script>
+
+<script src="file_list_model_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.js b/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.js
new file mode 100644
index 0000000..4b5ce95
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/file_list_model_unittest.js
@@ -0,0 +1,209 @@
+// 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.
+
+var TEST_METADATA = {
+  'a.txt': {
+    contentMimeType: 'text/plain',
+    size: 1023,
+    modificationTime: new Date(2016, 1, 1, 0, 0, 2),
+  },
+  'b.html': {
+    contentMimeType: 'text/html',
+    size: 206,
+    modificationTime: new Date(2016, 1, 1, 0, 0, 1),
+  },
+  'c.jpg': {
+    contentMimeType: 'image/jpeg',
+    size: 342134,
+    modificationTime: new Date(2016, 1, 1, 0, 0, 0),
+  },
+};
+
+function assertFileListModelElementNames(fileListModel, names) {
+  assertEquals(fileListModel.length, names.length);
+  for (var i = 0; i < fileListModel.length; i++) {
+    assertEquals(fileListModel.item(i).name, names[i]);
+  }
+}
+
+function assertEntryArrayEquals(entryArray, names) {
+  assertEquals(entryArray.length, names.length);
+  assertArrayEquals(entryArray.map((e) => e.name), names);
+}
+
+function makeSimpleFileListModel(names) {
+  var fileListModel = new FileListModel(new TestMetadataModel({}));
+  for (var i = 0; i < names.length; i++)
+    fileListModel.push({ name: names[i], isDirectory: false });
+  return fileListModel;
+}
+
+// MetadataModel for this test.
+// It is supposed to provide metadata from TEST_METADATA to work with the
+// FileListModel.
+function TestMetadataModel(testdata) {
+  this.testdata_ = testdata;
+}
+
+TestMetadataModel.prototype = {
+  getCache : function(entries, names) {
+    var result = [];
+    for (var i = 0; i < entries.length; i++) {
+      var metadata = {};
+      if (!entries[i].isDirectory && this.testdata_[entries[i].name]) {
+        for (var j = 0; j < names.length; j++)
+          metadata[names[j]] = this.testdata_[entries[i].name][names[j]];
+      }
+      result.push(metadata);
+    }
+    return result;
+  },
+};
+
+function testIsImageDominant() {
+  var fileListModel = new FileListModel(new TestMetadataModel(TEST_METADATA));
+
+  assertEquals(fileListModel.isImageDominant(), false);
+
+  // Adding one image. Image should be dominant in this directory (100%).
+  fileListModel.push({ name: 'c.jpg', isDirectory: false});
+  assertEquals(fileListModel.isImageDominant(), true);
+
+  // Adding a directory shouldn't affect how the image is dominant (still 100%).
+  fileListModel.push({ name: 'tmp_folder', isDirectory: true});
+  assertEquals(fileListModel.isImageDominant(), true);
+
+  // Adding a non-image file, which will make the images not dominant (50%);
+  fileListModel.push({ name: 'a.txt', isDirectory: false});
+  assertEquals(fileListModel.isImageDominant(), false);
+
+  // Adding two image. Now 75%(3/4) files are images. Still not dominant.
+  fileListModel.push({ name: 'c.jpg', isDirectory: false});
+  fileListModel.push({ name: 'c.jpg', isDirectory: false});
+  assertEquals(fileListModel.isImageDominant(), false);
+
+  // Adding one more. Now 80%(4/5) files are images. Reached the threshold.
+  fileListModel.push({ name: 'c.jpg', isDirectory: false});
+  assertEquals(fileListModel.isImageDominant(), true);
+}
+
+function testSortWithFolders() {
+  var fileListModel = new FileListModel(new TestMetadataModel(TEST_METADATA));
+  fileListModel.push({ name: 'dirA', isDirectory: true });
+  fileListModel.push({ name: 'dirB', isDirectory: true });
+  fileListModel.push({ name: 'a.txt', isDirectory: false });
+  fileListModel.push({ name: 'b.html', isDirectory: false });
+  fileListModel.push({ name: 'c.jpg', isDirectory: false });
+
+  // In following sort tests, note that folders should always be prior to files.
+  fileListModel.sort('name', 'asc');
+  assertFileListModelElementNames(fileListModel,
+                                  ['dirA', 'dirB', 'a.txt', 'b.html', 'c.jpg']);
+  fileListModel.sort('name', 'desc');
+  assertFileListModelElementNames(fileListModel,
+                                  ['dirB', 'dirA', 'c.jpg', 'b.html', 'a.txt']);
+  // Sort files by size. Folders should be sorted by their names.
+  fileListModel.sort('size', 'asc');
+  assertFileListModelElementNames(fileListModel,
+                                  ['dirA', 'dirB', 'b.html', 'a.txt', 'c.jpg']);
+  fileListModel.sort('size', 'desc');
+  assertFileListModelElementNames(fileListModel,
+                                  ['dirB', 'dirA', 'c.jpg', 'a.txt', 'b.html']);
+  // Sort files by modification. Folders should be sorted by their names.
+  fileListModel.sort('modificationTime', 'asc');
+  assertFileListModelElementNames(fileListModel,
+                                  ['dirA', 'dirB', 'c.jpg', 'b.html', 'a.txt']);
+  fileListModel.sort('modificationTime', 'desc');
+  assertFileListModelElementNames(fileListModel,
+                                  ['dirB', 'dirA', 'a.txt', 'b.html', 'c.jpg']);
+}
+
+function testSplice() {
+  var fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']);
+  fileListModel.sort('name', 'asc');
+
+  fileListModel.addEventListener('splice', function(event) {
+    assertEntryArrayEquals(event.added, ['p', 'b']);
+    assertEntryArrayEquals(event.removed, ['n']);
+    // The first inserted item, 'p', should be at index:3 after splice.
+    assertEquals(event.index, 3);
+  });
+
+  fileListModel.addEventListener('permuted', function(event){
+    assertArrayEquals(event.permutation, [0, 2, -1, 4]);
+    assertEquals(event.newLength, 5);
+  });
+
+  fileListModel.splice(2, 1,
+      { name: 'p', isDirectory: false },
+      { name: 'b', isDirectory: false });
+  assertFileListModelElementNames(fileListModel, ['a', 'b', 'd', 'p', 'x']);
+}
+
+function testSpliceWithoutSortStatus() {
+  var fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']);
+
+  fileListModel.addEventListener('splice', function(event) {
+    assertEntryArrayEquals(event.added, ['p', 'b']);
+    assertEntryArrayEquals(event.removed, ['x']);
+    // The first inserted item, 'p', should be at index:2 after splice.
+    assertEquals(event.index, 2);
+  });
+
+  fileListModel.addEventListener('permuted', function(event){
+    assertArrayEquals(event.permutation, [0, 1, -1, 4]);
+    assertEquals(event.newLength, 5);
+  });
+
+  fileListModel.splice(2, 1,
+      { name: 'p', isDirectory: false },
+      { name: 'b', isDirectory: false });
+  // If the sort status is not specified, the original order should be kept.
+  // i.e. the 2nd element in the original array, 'x', should be removed, and
+  // 'p' and 'b' should be inserted at the position without changing the order.
+  assertFileListModelElementNames(fileListModel, ['d', 'a', 'p', 'b', 'n']);
+}
+
+function testSpliceWithoutAddingNewItems() {
+  var fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']);
+  fileListModel.sort('name', 'asc');
+
+  fileListModel.addEventListener('splice', function(event) {
+    assertEntryArrayEquals(event.added, []);
+    assertEntryArrayEquals(event.removed, ['n']);
+    // The first item after insertion/deletion point is 'x', which should be at
+    // 2nd position after the sort.
+    assertEquals(event.index, 2);
+  });
+
+  fileListModel.addEventListener('permuted', function(event){
+    assertArrayEquals(event.permutation, [0, 1, -1, 2]);
+    assertEquals(event.newLength, 3);
+  });
+
+  fileListModel.splice(2, 1);
+  assertFileListModelElementNames(fileListModel, ['a', 'd', 'x']);
+}
+
+function testSpliceWithoutDeletingItems() {
+  var fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']);
+  fileListModel.sort('name', 'asc');
+
+  fileListModel.addEventListener('splice', function(event) {
+    assertEntryArrayEquals(event.added, ['p', 'b']);
+    assertEntryArrayEquals(event.removed, []);
+    assertEquals(event.index, 4);
+  });
+
+  fileListModel.addEventListener('permuted', function(event){
+    assertArrayEquals(event.permutation, [0, 2, 3, 5]);
+    assertEquals(event.newLength, 6);
+  });
+
+  fileListModel.splice(2, 0,
+      { name: 'p', isDirectory: false },
+      { name: 'b', isDirectory: false });
+  assertFileListModelElementNames(fileListModel,
+                                  ['a', 'b', 'd', 'n', 'p', 'x']);
+}
diff --git a/mojo/converters/geometry/BUILD.gn b/ui/gfx/geometry/mojo/BUILD.gn
similarity index 60%
rename from mojo/converters/geometry/BUILD.gn
rename to ui/gfx/geometry/mojo/BUILD.gn
index ce047c3..5432581 100644
--- a/mojo/converters/geometry/BUILD.gn
+++ b/ui/gfx/geometry/mojo/BUILD.gn
@@ -1,10 +1,12 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
+# 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.
 
+import("//mojo/public/tools/bindings/mojom.gni")
+
 # This target does NOT depend on skia. One can depend on this target to avoid
 # picking up a dependency on skia.
-component("geometry") {
+component("mojo") {
   output_name = "mojo_geometry_lib"
 
   public_deps = [
@@ -12,7 +14,7 @@
   ]
   deps = [
     "//mojo/public/c/system:for_component",
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 
   defines = [ "MOJO_GEOMETRY_IMPLEMENTATION" ]
@@ -23,3 +25,19 @@
     "mojo_geometry_export.h",
   ]
 }
+
+mojom("interfaces") {
+  sources = [
+    "geometry.mojom",
+  ]
+}
+
+source_set("util") {
+  sources = [
+    "geometry_util.h",
+  ]
+
+  deps = [
+    ":interfaces",
+  ]
+}
diff --git a/mojo/converters/geometry/DEPS b/ui/gfx/geometry/mojo/DEPS
similarity index 100%
rename from mojo/converters/geometry/DEPS
rename to ui/gfx/geometry/mojo/DEPS
diff --git a/ui/mojo/geometry/geometry.mojom b/ui/gfx/geometry/mojo/geometry.mojom
similarity index 93%
rename from ui/mojo/geometry/geometry.mojom
rename to ui/gfx/geometry/mojo/geometry.mojom
index 95a4336..8621f69 100644
--- a/ui/mojo/geometry/geometry.mojom
+++ b/ui/gfx/geometry/mojo/geometry.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(beng): should be gfx.mojom;
 module mojo;
 
 struct Point {
diff --git a/mojo/converters/geometry/geometry_type_converters.cc b/ui/gfx/geometry/mojo/geometry_type_converters.cc
similarity index 96%
rename from mojo/converters/geometry/geometry_type_converters.cc
rename to ui/gfx/geometry/mojo/geometry_type_converters.cc
index 980adbcd..842560e 100644
--- a/mojo/converters/geometry/geometry_type_converters.cc
+++ b/ui/gfx/geometry/mojo/geometry_type_converters.cc
@@ -1,8 +1,8 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// 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 "mojo/converters/geometry/geometry_type_converters.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mojo {
 
diff --git a/mojo/converters/geometry/geometry_type_converters.h b/ui/gfx/geometry/mojo/geometry_type_converters.h
similarity index 88%
rename from mojo/converters/geometry/geometry_type_converters.h
rename to ui/gfx/geometry/mojo/geometry_type_converters.h
index f90aba7..9aedb36 100644
--- a/mojo/converters/geometry/geometry_type_converters.h
+++ b/ui/gfx/geometry/mojo/geometry_type_converters.h
@@ -1,18 +1,18 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// 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 MOJO_CONVERTERS_GEOMETRY_GEOMETRY_TYPE_CONVERTERS_H_
-#define MOJO_CONVERTERS_GEOMETRY_GEOMETRY_TYPE_CONVERTERS_H_
+#ifndef UI_GFX_GEOMETRY_MOJO_GEOMETRY_TYPE_CONVERTERS_H_
+#define UI_GFX_GEOMETRY_MOJO_GEOMETRY_TYPE_CONVERTERS_H_
 
-#include "mojo/converters/geometry/mojo_geometry_export.h"
 #include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/mojo/geometry.mojom.h"
+#include "ui/gfx/geometry/mojo/mojo_geometry_export.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/mojo/geometry/geometry.mojom.h"
 
 namespace mojo {
 
@@ -99,4 +99,4 @@
 
 }  // namespace mojo
 
-#endif  // MOJO_CONVERTERS_GEOMETRY_GEOMETRY_TYPE_CONVERTERS_H_
+#endif  // UI_GFX_GEOMETRY_MOJO_GEOMETRY_TYPE_CONVERTERS_H_
diff --git a/ui/mojo/geometry/geometry_util.h b/ui/gfx/geometry/mojo/geometry_util.h
similarity index 75%
rename from ui/mojo/geometry/geometry_util.h
rename to ui/gfx/geometry/mojo/geometry_util.h
index 2606be83..31da559 100644
--- a/ui/mojo/geometry/geometry_util.h
+++ b/ui/gfx/geometry/mojo/geometry_util.h
@@ -1,11 +1,11 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// 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 UI_MOJO_GEOMETRY_GEOMETRY_UTIL_H_
-#define UI_MOJO_GEOMETRY_GEOMETRY_UTIL_H_
+#ifndef UI_GFX_GEOMETRY_MOJO_GEOMETRY_UTIL_H_
+#define UI_GFX_GEOMETRY_MOJO_GEOMETRY_UTIL_H_
 
-#include "ui/mojo/geometry/geometry.mojom.h"
+#include "ui/gfx/geometry/mojo/geometry.mojom.h"
 
 namespace mojo {
 
@@ -36,4 +36,4 @@
 
 }
 
-#endif  // UI_MOJO_GEOMETRY_GEOMETRY_UTIL_H_
+#endif  // UI_GFX_GEOMETRY_MOJO_GEOMETRY_UTIL_H_
diff --git a/ui/gfx/geometry/mojo/mojo_bindings.gyp b/ui/gfx/geometry/mojo/mojo_bindings.gyp
new file mode 100644
index 0000000..55759376
--- /dev/null
+++ b/ui/gfx/geometry/mojo/mojo_bindings.gyp
@@ -0,0 +1,8 @@
+# Copyright 2015 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.
+
+{
+  'targets': [
+  ],
+}
diff --git a/mojo/converters/geometry/mojo_geometry_export.h b/ui/gfx/geometry/mojo/mojo_geometry_export.h
similarity index 100%
rename from mojo/converters/geometry/mojo_geometry_export.h
rename to ui/gfx/geometry/mojo/mojo_geometry_export.h
diff --git a/ui/gfx/gfx.gyp b/ui/gfx/gfx.gyp
index 4e6bf15..42a135cd 100644
--- a/ui/gfx/gfx.gyp
+++ b/ui/gfx/gfx.gyp
@@ -3,6 +3,9 @@
 # found in the LICENSE file.
 
 {
+  'includes': {
+    '../../mojo/mojo_variables.gypi',
+  },
   'variables': {
     'chromium_code': 1,
   },
@@ -68,6 +71,43 @@
       ],
     },
     {
+      # GN version: //ui/gfx/geometry/mojo:interfaces
+      'target_name': 'mojo_geometry_bindings_mojom',
+      'type': 'none',
+      'variables': {
+        'mojom_files': [
+          'geometry/mojo/geometry.mojom',
+        ],
+      },
+      'includes': [ '../../mojo/mojom_bindings_generator_explicit.gypi' ],
+    },
+    {
+      'target_name': 'mojo_geometry_bindings',
+      'type': 'static_library',
+      'dependencies': [
+        'mojo_geometry_bindings_mojom',
+        '../../mojo/mojo_public.gyp:mojo_cpp_bindings',
+      ],
+    },
+    {
+      # GN version: //ui/gfx/geometry/mojo
+      'target_name': 'mojo_geometry_lib',
+      'type': '<(component)',
+      'defines': [
+        'MOJO_GEOMETRY_IMPLEMENTATION',
+      ],
+      'dependencies': [
+        'mojo_geometry_bindings',
+        'gfx_geometry',
+        '<(mojo_system_for_component)',
+      ],
+      'sources': [
+        'geometry/mojo/geometry_type_converters.cc',
+        'geometry/mojo/geometry_type_converters.h',
+        'geometry/mojo/mojo_geometry_export.h',
+      ],
+    },
+    {
       'target_name': 'gfx_range',
       'type': '<(component)',
       'dependencies': [
diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn
index ae966b8..1af8a5f2b 100644
--- a/ui/keyboard/BUILD.gn
+++ b/ui/keyboard/BUILD.gn
@@ -132,7 +132,7 @@
     "keyboard.mojom",
   ]
   deps = [
-    "//ui/mojo/geometry:interfaces",
+    "//ui/gfx/geometry/mojo:interfaces",
   ]
 }
 
diff --git a/ui/keyboard/keyboard.mojom b/ui/keyboard/keyboard.mojom
index 212765b1..37d3ca3 100644
--- a/ui/keyboard/keyboard.mojom
+++ b/ui/keyboard/keyboard.mojom
@@ -4,7 +4,7 @@
 
 module keyboard.mojom;
 
-import "ui/mojo/geometry/geometry.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 interface KeyboardObserver {
   // Sent any time state changes in the keyboard.
diff --git a/ui/mojo/display/BUILD.gn b/ui/mojo/display/BUILD.gn
index 54f43e27..781c428 100644
--- a/ui/mojo/display/BUILD.gn
+++ b/ui/mojo/display/BUILD.gn
@@ -10,9 +10,9 @@
   ]
   deps = [
     "//components/mus/public/interfaces",
-    "//mojo/converters/geometry",
     "//mojo/public/c/system:for_component",
     "//ui/display",
+    "//ui/gfx/geometry/mojo",
   ]
 
   defines = [ "MOJO_DISPLAY_IMPLEMENTATION" ]
diff --git a/ui/mojo/display/DEPS b/ui/mojo/display/DEPS
index 412d630..edc7674 100644
--- a/ui/mojo/display/DEPS
+++ b/ui/mojo/display/DEPS
@@ -1,5 +1,5 @@
 include_rules = [
   "+components/mus/public/interfaces",
-  "+mojo/converters/geometry",
   "+ui/display",
+  "+ui/gfx/geometry/mojo",
 ]
diff --git a/ui/mojo/display/display_type_converters.cc b/ui/mojo/display/display_type_converters.cc
index bc1a55d0..920b9fa 100644
--- a/ui/mojo/display/display_type_converters.cc
+++ b/ui/mojo/display/display_type_converters.cc
@@ -4,8 +4,8 @@
 
 #include "ui/mojo/display/display_type_converters.h"
 
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "ui/display/display.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 
 namespace mojo {
 
diff --git a/ui/mojo/geometry/BUILD.gn b/ui/mojo/geometry/BUILD.gn
deleted file mode 100644
index b44586d..0000000
--- a/ui/mojo/geometry/BUILD.gn
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2014 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.
-
-import("//mojo/public/tools/bindings/mojom.gni")
-
-mojom("interfaces") {
-  sources = [
-    "geometry.mojom",
-  ]
-}
-
-source_set("util") {
-  sources = [
-    "geometry_util.h",
-  ]
-
-  deps = [
-    ":interfaces",
-  ]
-}
diff --git a/ui/mojo/geometry/mojo_bindings.gyp b/ui/mojo/geometry/mojo_bindings.gyp
deleted file mode 100644
index 28e1c98..0000000
--- a/ui/mojo/geometry/mojo_bindings.gyp
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2015 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.
-
-{
-  'targets': [
-    {
-      # GN version: //ui/mojo/geometry
-      'target_name': 'mojo_geometry_bindings_mojom',
-      'type': 'none',
-      'variables': {
-        'mojom_files': [
-          'geometry.mojom',
-        ],
-      },
-      'includes': [ '../../../mojo/mojom_bindings_generator_explicit.gypi' ],
-    },
-    {
-      'target_name': 'mojo_geometry_bindings',
-      'type': 'static_library',
-      'dependencies': [
-        'mojo_geometry_bindings_mojom',
-        '../../../mojo/mojo_public.gyp:mojo_cpp_bindings',
-      ],
-    },
-  ],
-}
diff --git a/ui/views/mus/BUILD.gn b/ui/views/mus/BUILD.gn
index 3e9ce23..7fbf996 100644
--- a/ui/views/mus/BUILD.gn
+++ b/ui/views/mus/BUILD.gn
@@ -58,7 +58,6 @@
     "//components/mus/gles2:lib",
     "//components/mus/public/cpp",
     "//components/mus/public/interfaces",
-    "//mojo/converters/geometry",
     "//mojo/converters/ime",
     "//mojo/converters/input_events",
     "//mojo/converters/surfaces",
@@ -77,6 +76,7 @@
     "//ui/events/devices",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/gfx/geometry/mojo",
     "//ui/gl",
     "//ui/mojo/display",
     "//ui/mojo/ime:interfaces_cpp_sources",
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc
index a732154..b759b534 100644
--- a/ui/views/mus/native_widget_mus.cc
+++ b/ui/views/mus/native_widget_mus.cc
@@ -17,7 +17,6 @@
 #include "components/mus/public/interfaces/window_manager.mojom.h"
 #include "components/mus/public/interfaces/window_manager_constants.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "ui/aura/client/default_capture_client.h"
 #include "ui/aura/client/window_tree_client.h"
 #include "ui/aura/env.h"
@@ -28,6 +27,7 @@
 #include "ui/base/hit_test.h"
 #include "ui/events/event.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/gfx/path.h"
 #include "ui/native_theme/native_theme_aura.h"
 #include "ui/platform_window/platform_window_delegate.h"
diff --git a/ui/views/mus/screen_mus.cc b/ui/views/mus/screen_mus.cc
index 663b2f9..07720cd6 100644
--- a/ui/views/mus/screen_mus.cc
+++ b/ui/views/mus/screen_mus.cc
@@ -4,12 +4,12 @@
 
 #include "ui/views/mus/screen_mus.h"
 
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "services/shell/public/cpp/connection.h"
 #include "services/shell/public/cpp/connector.h"
 #include "ui/aura/window.h"
 #include "ui/display/display_finder.h"
 #include "ui/display/display_observer.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/mojo/display/display_type_converters.h"
 #include "ui/views/mus/screen_mus_delegate.h"
 #include "ui/views/mus/window_manager_frame_values.h"
diff --git a/ui/views/mus/surface_binding.cc b/ui/views/mus/surface_binding.cc
index a3dc98f..a33f709 100644
--- a/ui/views/mus/surface_binding.cc
+++ b/ui/views/mus/surface_binding.cc
@@ -24,10 +24,10 @@
 #include "components/mus/public/cpp/window.h"
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "components/mus/public/interfaces/gpu.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "mojo/converters/surfaces/surfaces_type_converters.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/shell/public/cpp/connector.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/views/mus/window_tree_host_mus.h"
 
 namespace views {
diff --git a/ui/views/mus/window_manager_connection.cc b/ui/views/mus/window_manager_connection.cc
index a76ffa6..e628012 100644
--- a/ui/views/mus/window_manager_connection.cc
+++ b/ui/views/mus/window_manager_connection.cc
@@ -14,10 +14,10 @@
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "components/mus/public/interfaces/event_matcher.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "services/shell/public/cpp/connection.h"
 #include "services/shell/public/cpp/connector.h"
 #include "ui/events/devices/device_data_manager.h"
+#include "ui/gfx/geometry/mojo/geometry_type_converters.h"
 #include "ui/views/mus/native_widget_mus.h"
 #include "ui/views/mus/screen_mus.h"
 #include "ui/views/pointer_watcher.h"
diff --git a/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp b/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp
index 77b9eead..611febb 100644
--- a/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp
+++ b/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp
@@ -4,11 +4,18 @@
 {
   'targets': [
     {
-      'target_name': 'cr_search_field',
+      'target_name': 'cr_search_field_behavior',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
       ],
       'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
+    {
+      'target_name': 'cr_search_field',
+      'dependencies': [
+        'cr_search_field_behavior'
+      ],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
   ],
 }
diff --git a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.css b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.css
index ee849b4..1aa201a 100644
--- a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.css
+++ b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.css
@@ -9,14 +9,18 @@
   justify-content: flex-end;
 }
 
-:host paper-input-container {
+[hidden] {
+  display: none !important;
+}
+
+paper-input-container {
   margin-top: 2px;
   max-width: 200px;
   padding: 2px 0;
   width: 100%;
 }
 
-#search-term {
+#searchTerm {
   --paper-input-container-color: rgb(192, 199, 205);
   --paper-input-container-focus-color: rgb(192, 199, 205);
   --paper-input-container-input: {
@@ -29,13 +33,13 @@
   z-index: 0;
 }
 
-#search-term input[type='search']::-webkit-search-decoration,
-#search-term input[type='search']::-webkit-search-cancel-button,
-#search-term input[type='search']::-webkit-search-results-button {
+#searchTerm input[type='search']::-webkit-search-decoration,
+#searchTerm input[type='search']::-webkit-search-cancel-button,
+#searchTerm input[type='search']::-webkit-search-results-button {
   -webkit-appearance: none;
 }
 
-#search-term input[type='search']::-webkit-search-cancel-button {
+#searchTerm input[type='search']::-webkit-search-cancel-button {
   display: block;
   width: 20px;
 }
@@ -50,7 +54,7 @@
   };
 }
 
-#search-term paper-icon-button {
+#searchTerm paper-icon-button {
   --iron-icon-height: 16px;
   --iron-icon-width: 16px;
   --paper-icon-button: {
@@ -65,7 +69,7 @@
   z-index: 1;
 }
 
-:host-context([dir='rtl']) #search-term paper-icon-button {
+:host-context([dir='rtl']) #searchTerm paper-icon-button {
   left: 0;
   right: auto;
 }
diff --git a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html
index 4ff9b93..3d6da01 100644
--- a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html
+++ b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/cr_search_field/cr_search_field_behavior.html">
 <link rel="import" href="chrome://resources/cr_elements/icons.html">
 <link rel="import" href="chrome://resources/html/assert.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
@@ -7,20 +8,18 @@
 
 <dom-module id="cr-search-field">
   <template>
-    <paper-icon-button icon="cr:search" id="search-button"
-        disabled$="[[showingSearch_]]" title="[[label]]"
+    <paper-icon-button icon="cr:search" id="searchButton"
+        disabled$="[[showingSearch]]" title="[[label]]"
         on-click="toggleShowingSearch_"></paper-icon-button>
-    <template is="dom-if" if="[[showingSearch_]]" id="search-container">
-      <paper-input-container id="search-term" on-search="onSearchTermSearch_"
-          on-keydown="onSearchTermKeydown_" hidden$="[[!showingSearch_]]"
-          no-label-float>
-        <input is="iron-input" id="search-input" type="search"
-            placeholder="[[label]]" incremental>
-        <paper-icon-button icon="cr:cancel" id="clear-search"
-            on-click="toggleShowingSearch_" title="[[clearLabel]]"
-            hidden$="[[!showingSearch_]]"></paper-icon-button>
-      </paper-input-container>
-    </template>
+    <paper-input-container id="searchTerm" on-search="onSearchTermSearch_"
+        on-keydown="onSearchTermKeydown_" hidden$="[[!showingSearch]]"
+        no-label-float>
+      <input is="iron-input" id="searchInput" type="search"
+          placeholder="[[label]]" incremental>
+      <paper-icon-button icon="cr:cancel" id="clearSearch"
+          on-click="toggleShowingSearch_" title="[[clearLabel]]"
+          hidden$="[[!showingSearch]]"></paper-icon-button>
+    </paper-input-container>
   </template>
   <link rel="import" type="css" href="cr_search_field.css">
   <script src="cr_search_field.js"></script>
diff --git a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.js b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.js
index a507fc3..03c74d8 100644
--- a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.js
+++ b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.js
@@ -2,121 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/** @interface */
-var SearchFieldDelegate = function() {};
-
-SearchFieldDelegate.prototype = {
-  /**
-   * @param {string} value
-   */
-  onSearchTermSearch: assertNotReached,
-};
-
 var SearchField = Polymer({
   is: 'cr-search-field',
-
-  properties: {
-    label: {
-      type: String,
-      value: '',
-    },
-
-    clearLabel: {
-      type: String,
-      value: '',
-    },
-
-    showingSearch_: {
-      type: Boolean,
-      value: false,
-      observer: 'showingSearchChanged_',
-    },
-  },
-
-  /**
-   * Returns the value of the search field.
-   * @return {string}
-   */
-  getValue: function() {
-    var searchInput = this.getSearchInput_();
-    return searchInput ? searchInput.value : '';
-  },
-
-  /**
-   * Sets the value of the search field, if it exists.
-   * @param {string} value
-   */
-  setValue: function(value) {
-    var searchInput = this.getSearchInput_();
-    if (searchInput)
-      searchInput.value = value;
-  },
-
-  /** @param {SearchFieldDelegate} delegate */
-  setDelegate: function(delegate) {
-    this.delegate_ = delegate;
-  },
-
-  /** @return {Promise<boolean>} */
-  showAndFocus: function() {
-    this.showingSearch_ = true;
-    return this.focus_();
-  },
-
-  /**
-   * @return {Promise<boolean>}
-   * @private
-   */
-  focus_: function() {
-    return new Promise(function(resolve) {
-      this.async(function() {
-        if (this.showingSearch_) {
-          var searchInput = this.getSearchInput_();
-          if (searchInput)
-            searchInput.focus();
-        }
-        resolve(this.showingSearch_);
-      });
-    }.bind(this));
-  },
-
-  /**
-   * @return {?Element}
-   * @private
-   */
-  getSearchInput_: function() {
-    return this.$$('#search-input');
-  },
-
-  /** @private */
-  onSearchTermSearch_: function() {
-    if (this.delegate_)
-      this.delegate_.onSearchTermSearch(this.getValue());
-  },
-
-  /** @private */
-  onSearchTermKeydown_: function(e) {
-    if (e.keyIdentifier == 'U+001B')  // Escape.
-      this.showingSearch_ = false;
-  },
-
-  /** @private */
-  showingSearchChanged_: function() {
-    if (this.showingSearch_) {
-      this.focus_();
-      return;
-    }
-
-    var searchInput = this.getSearchInput_();
-    if (!searchInput)
-      return;
-
-    searchInput.value = '';
-    this.onSearchTermSearch_();
-  },
-
-  /** @private */
-  toggleShowingSearch_: function() {
-    this.showingSearch_ = !this.showingSearch_;
-  },
+  behaviors: [CrSearchFieldBehavior]
 });
diff --git a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.html b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.html
new file mode 100644
index 0000000..93defaec
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.html
@@ -0,0 +1 @@
+<script src="cr_search_field_behavior.js"></script>
diff --git a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.js b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.js
new file mode 100644
index 0000000..7e3b8bf
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.js
@@ -0,0 +1,116 @@
+// 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.
+
+/** @interface */
+var SearchFieldDelegate = function() {};
+
+SearchFieldDelegate.prototype = {
+  /**
+   * @param {string} value
+   */
+  onSearchTermSearch: assertNotReached,
+};
+
+/**
+ * Implements an incremental search field which can be shown and hidden.
+ * Canonical implementation is <cr-search-field>.
+ * @polymerBehavior
+ */
+var CrSearchFieldBehavior = {
+  properties: {
+    label: {
+      type: String,
+      value: '',
+    },
+
+    clearLabel: {
+      type: String,
+      value: '',
+    },
+
+    showingSearch: {
+      type: Boolean,
+      value: false,
+      notify: true,
+      observer: 'showingSearchChanged_',
+      reflectToAttribute: true
+    },
+
+    hasSearchText: Boolean,
+  },
+
+  /**
+   * @return {string} The value of the search field.
+   */
+  getValue: function() {
+    return this.$.searchInput.value;
+  },
+
+  /**
+   * Sets the value of the search field, if it exists.
+   * @param {string} value
+   */
+  setValue: function(value) {
+    // Use bindValue when setting the input value so that changes propagate
+    // correctly.
+    this.$.searchInput.bindValue = value;
+    this.hasSearchText = value != '';
+  },
+
+  /** @param {SearchFieldDelegate} delegate */
+  setDelegate: function(delegate) {
+    this.delegate_ = delegate;
+  },
+
+  /** @return {!Promise<boolean>} */
+  showAndFocus: function() {
+    this.showingSearch = true;
+    return this.focus_();
+  },
+
+  /**
+   * @return {!Promise<boolean>}
+   * @private
+   */
+  focus_: function() {
+    return new Promise(function(resolve) {
+      this.async(function() {
+        if (this.showingSearch) {
+          this.$.searchInput.focus();
+        }
+        resolve(this.showingSearch);
+      });
+    }.bind(this));
+  },
+
+  /** @private */
+  onSearchTermSearch_: function() {
+    this.hasSearchText = this.getValue() != '';
+    if (this.delegate_)
+      this.delegate_.onSearchTermSearch(this.getValue());
+  },
+
+  /** @private */
+  onSearchTermKeydown_: function(e) {
+    if (e.key == 'Escape')
+      this.showingSearch = false;
+  },
+
+  /** @private */
+  showingSearchChanged_: function() {
+    if (this.showingSearch) {
+      this.focus_();
+      return;
+    }
+
+    this.setValue('');
+    this.$.searchInput.blur();
+    this.onSearchTermSearch_();
+  },
+
+  /** @private */
+  toggleShowingSearch_: function() {
+    this.showingSearch = !this.showingSearch;
+  },
+};
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp b/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp
new file mode 100644
index 0000000..26d140f
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp
@@ -0,0 +1,21 @@
+# 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.
+{
+  'targets': [
+    {
+      'target_name': 'cr_toolbar_search_field',
+      'dependencies': [
+        '<(DEPTH)/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp:cr_search_field_behavior',
+      ],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
+      'target_name': 'cr_toolbar',
+      'dependencies': [
+        'cr_toolbar_search_field',
+      ],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+  ],
+}
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html
new file mode 100644
index 0000000..d052b32
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html
@@ -0,0 +1,56 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-media-query/iron-media-query.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html">
+
+<dom-module id="cr-toolbar">
+  <template>
+    <style>
+      :host {
+        color: #fff;
+        display: flex;
+        height: 56px;
+      }
+
+      h1 {
+        @apply(--layout-flex);
+        -webkit-padding-start: 24px;
+        font-size: 123%;
+        font-weight: 400;
+      }
+
+      #leftContent {
+        align-items: center;
+        display: flex;
+        width: var(--side-bar-width, 0);
+      }
+
+      #centeredContent {
+        -webkit-padding-end: 12px;
+        display: flex;
+        flex: 1 1 0;
+        justify-content: center;
+      }
+
+      :host([narrow_]) #centeredContent {
+        justify-content: flex-end;
+      }
+
+      :host([narrow_][showing-search_]) #leftContent {
+        display: none;
+      }
+    </style>
+    <div id="leftContent">
+      <h1>[[pageName]]</h1>
+    </div>
+
+    <div id="centeredContent">
+      <cr-toolbar-search-field id="search" narrow="[[narrow_]]"
+          label="[[searchPrompt]]" clear-label="[[clearLabel]]"
+          showing-search="{{showingSearch_}}">
+      </cr-toolbar-search-field>
+      <iron-media-query query="(max-width: 900px)" query-matches="{{narrow_}}">
+      </iron-media-query>
+    </div>
+  </template>
+  <script src="cr_toolbar.js"></script>
+</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.js b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.js
new file mode 100644
index 0000000..829b44e
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.js
@@ -0,0 +1,35 @@
+// 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.
+
+Polymer({
+  is: 'cr-toolbar',
+
+  properties: {
+    /** @private */
+    narrow_: {
+      type: Boolean,
+      reflectToAttribute: true
+    },
+
+    /** @private */
+    showingSearch_: {
+      type: Boolean,
+      reflectToAttribute: true,
+    },
+
+    // Name to display in the toolbar, in titlecase.
+    pageName: String,
+
+    // Prompt text to display in the search field.
+    searchPrompt: String,
+
+    // Tooltip to display on the clear search button.
+    clearLabel: String,
+  },
+
+  /** @return {!CrToolbarSearchFieldElement} */
+  getSearchField: function() {
+    return this.$.search;
+  }
+});
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
new file mode 100644
index 0000000..c65855b
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
@@ -0,0 +1,100 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-input/iron-input.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input-container.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_search_field/cr_search_field_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/icons.html">
+
+<dom-module id="cr-toolbar-search-field">
+  <template>
+    <style>
+      :host {
+        align-items: center;
+        display: flex;
+        height: 40px;
+        transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1),
+            width 150ms cubic-bezier(0.4, 0, 0.2, 1);
+        width: 44px;
+      }
+
+      [hidden] {
+        display: none !important;
+      }
+
+      paper-icon-button {
+        height: 32px;
+        margin: 6px;
+        padding: 6px;
+        width: 32px;
+      }
+
+      #icon {
+        --paper-icon-button-ink-color: white;
+      }
+
+      #prompt {
+        visibility: hidden;
+      }
+
+      paper-input-container {
+        --paper-input-container-input-color: white;
+        --paper-input-container-underline: {
+          display: none;
+        };
+        --paper-input-container-underline-focus: {
+          display: none;
+        };
+        --paper-input-container-label: {
+          color: inherit;
+          font-size: inherit;
+        };
+        -webkit-padding-start: 2px;
+        flex: 1;
+      }
+
+      input[type='search']::-webkit-search-decoration,
+      input[type='search']::-webkit-search-cancel-button,
+      input[type='search']::-webkit-search-results-button {
+        -webkit-appearance: none;
+      }
+
+      /** Wide layout, no search open. */
+      :host(:not([narrow]):not([showing-search])) {
+        -webkit-padding-end: 0;
+        background: rgba(0, 0, 0, 0.22);
+        border-radius: 2px;
+        cursor: text;
+        width: 580px;
+      }
+
+      :host(:not([narrow]):not([showing-search])) #icon,
+      :host(:not([narrow]):not([showing-search])) #prompt {
+        opacity: 0.6;
+        visibility: visible;
+      }
+
+      /* Any layout, search open. */
+      :host([showing-search]) {
+        width: 100%;
+      }
+
+      :host([narrow][showing-search]) #icon {
+        -webkit-margin-start: 18px;
+      }
+    </style>
+    <paper-icon-button id="icon" icon="cr:search"
+        title="[[label]]">
+    </paper-icon-button>
+    <paper-input-container on-search="onSearchTermSearch_"
+        on-keydown="onSearchTermKeydown_" no-label-float>
+      <label id="prompt" for="searchInput">[[label]]</label>
+      <input is="iron-input" id="searchInput" type="search"
+          on-blur="onInputBlur_" incremental></input>
+    </paper-input-container>
+    <paper-icon-button icon="cr:cancel" id="clearSearch"
+        title="[[clearLabel]]" hidden$="[[!hasSearchText]]"
+        on-tap="hideSearch_">
+    </paper-icon-button>
+  </template>
+  <script src="cr_toolbar_search_field.js"></script>
+</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.js b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.js
new file mode 100644
index 0000000..aac4268
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.js
@@ -0,0 +1,51 @@
+// 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.
+
+// TODO(tsergeant): Add tests for cr-toolbar-search-field.
+Polymer({
+  is: 'cr-toolbar-search-field',
+
+  behaviors: [CrSearchFieldBehavior],
+
+  properties: {
+    narrow: {
+      type: Boolean,
+      reflectToAttribute: true,
+    },
+
+    // Prompt text to display in the search field.
+    label: String,
+
+    // Tooltip to display on the clear search button.
+    clearLabel: String,
+  },
+
+  listeners: {
+    'tap': 'showSearch_',
+  },
+
+  /** @private */
+  onInputBlur_: function() {
+    if (!this.hasSearchText)
+      this.showingSearch = false;
+  },
+
+  /**
+   * @param {Event} e
+   * @private
+   */
+  showSearch_: function(e) {
+    if (e.target != this.$.clearSearch)
+      this.showingSearch = true;
+  },
+
+  /**
+   * @param {Event} e
+   * @private
+   */
+  hideSearch_: function(e) {
+    this.showingSearch = false;
+    e.stopPropagation();
+  }
+});
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp
index c7c4dcad..e1fa4fe 100644
--- a/ui/webui/resources/cr_elements_resources.grdp
+++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -86,6 +86,12 @@
   <structure name="IDR_CR_ELEMENTS_CR_POLICY_PREF_INDICATOR_HTML"
              file="../../webui/resources/cr_elements/policy/cr_policy_pref_indicator.html"
              type="chrome_html" />
+  <structure name="IDR_CR_ELEMENTS_CR_SEARCH_FIELD_BEHAVIOR_HTML"
+             file="../../webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.html"
+             type="chrome_html" />
+  <structure name="IDR_CR_ELEMENTS_CR_SEARCH_FIELD_BEHAVIOR_JS"
+             file="../../webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.js"
+             type="chrome_html" />
   <structure name="IDR_CR_ELEMENTS_CR_SEARCH_FIELD_CSS"
              file="../../webui/resources/cr_elements/cr_search_field/cr_search_field.css"
              type="chrome_html" />
@@ -101,6 +107,18 @@
   <structure name="IDR_CR_ELEMENTS_CR_SHARED_MENU_JS"
              file="../../webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js"
              type="chrome_html" />
+  <structure name="IDR_CR_ELEMENTS_CR_TOOLBAR_HTML"
+             file="../../webui/resources/cr_elements/cr_toolbar/cr_toolbar.html"
+             type="chrome_html" />
+  <structure name="IDR_CR_ELEMENTS_CR_TOOLBAR_JS"
+             file="../../webui/resources/cr_elements/cr_toolbar/cr_toolbar.js"
+             type="chrome_html" />
+  <structure name="IDR_CR_ELEMENTS_CR_TOOLBAR_SEARCH_FIELD_HTML"
+             file="../../webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html"
+             type="chrome_html" />
+  <structure name="IDR_CR_ELEMENTS_CR_TOOLBAR_SEARCH_FIELD_JS"
+             file="../../webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.js"
+             type="chrome_html" />
   <structure name="IDR_CR_ELEMENTS_SHARED_CSS"
              file="../../webui/resources/cr_elements/shared.css"
              type="chrome_html" />