diff --git a/AUTHORS b/AUTHORS
index ff352ef..6dc7d456 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -519,6 +519,7 @@
 Mohit Bhalla <bhallam@amazon.com>
 Mrunal Kapade <mrunal.kapade@intel.com>
 Myles C. Maxfield <mymax@amazon.com>
+Nagarajan Narayanan <nagarajan.n@samsung.com>
 Nagarjuna Atluri <nagarjuna.a@samsung.com>
 Naiem Shaik <naiem.shaik@gmail.com>
 Naoki Takano <takano.naoki@gmail.com>
diff --git a/WATCHLISTS b/WATCHLISTS
index 6002a8c..35c7f0d 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1504,6 +1504,20 @@
       'filepath': 'third_party/WebKit/Source/modules/screen_orientation/' \
                   '|third_party/WebKit/public/platform/modules/screen_orientation',
     },
+    'blink_script': {
+      'filepath': '|third_party/WebKit/Source/bindings/core/v8/.*Module.*' \
+                  '|third_party/WebKit/Source/bindings/core/v8/ScriptController.*' \
+                  '|third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.*' \
+                  '|third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.*'
+                  '|third_party/WebKit/Source/core/dom/.*Modul.*' \
+                  '!third_party/WebKit/Source/core/dom/.*Script.*' \
+                  '|third_party/WebKit/Source/core/html/HTMLScriptElement.*' \
+                  '|third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.*' \
+                  '|third_party/WebKit/Source/core/loader/modulescript/' \
+                  '|third_party/WebKit/Source/core/loader/resource/ScriptResource.*' \
+                  '|third_party/WebKit/Source/core/svg/SVGScriptElement.*' \
+                  '|third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.*'
+    },
     'blink_scheduler': {
       'filepath': 'third_party/WebKit/Source/platform/scheduler' \
                   '|third_party/WebKit/Source/core/html/parser/.*Scheduler'
@@ -1820,6 +1834,9 @@
                     'tzik@chromium.org'],
     'blink_scheduler': ['scheduler-bugs@chromium.org'],
     'blink_screen_orientation': ['mlamouri+watch-blink@chromium.org'],
+    'blink_script': ['kouhei+script@chromium.org',
+                     'hiroshige+script@chromium.org',
+                     'kochi+script@chromium.org'],
     'blink_serviceworkers': ['falken+watch@chromium.org',
                              'horo+watch@chromium.org',
                              'jsbell+serviceworker@chromium.org',
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 5b19530..fa4ec72c 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -137,7 +137,7 @@
   # to configure warnings.
   is_clang =
       current_os == "mac" || current_os == "ios" || current_os == "chromeos" ||
-      current_os == "fuchsia" || current_os == "win" ||
+      current_os == "fuchsia" ||
       (current_os == "linux" && current_cpu != "s390x" &&
        current_cpu != "s390" && current_cpu != "ppc64" && current_cpu != "ppc")
 
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 374770987..8353078 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -1400,79 +1400,9 @@
     ElementListType list_type,
     const PropertyAnimationState& mask,
     const PropertyAnimationState& state) {
-  // TODO(weiliangc): Most of the code is duplicated with LayerTeeHostImpl
-  // version of function. Should try to share code.
   DCHECK_EQ(ElementListType::ACTIVE, list_type);
-
-  for (int property = TargetProperty::FIRST_TARGET_PROPERTY;
-       property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) {
-    if (!mask.currently_running[property] &&
-        !mask.potentially_animating[property])
-      continue;
-
-    switch (property) {
-      case TargetProperty::TRANSFORM:
-        if (TransformNode* transform_node =
-                property_trees()->transform_tree.FindNodeFromElementId(
-                    element_id)) {
-          if (mask.currently_running[property])
-            transform_node->is_currently_animating =
-                state.currently_running[property];
-          if (mask.potentially_animating[property]) {
-            transform_node->has_potential_animation =
-                state.potentially_animating[property];
-            transform_node->has_only_translation_animations =
-                mutator_host()->HasOnlyTranslationTransforms(element_id,
-                                                             list_type);
-            property_trees()->transform_tree.set_needs_update(true);
-          }
-        } else {
-          if (state.currently_running[property] ||
-              state.potentially_animating[property])
-            DCHECK(property_trees()->needs_rebuild)
-                << "Attempting to animate non existent transform node";
-        }
-        break;
-      case TargetProperty::OPACITY:
-        if (EffectNode* effect_node =
-                property_trees()->effect_tree.FindNodeFromElementId(
-                    element_id)) {
-          if (mask.currently_running[property])
-            effect_node->is_currently_animating_opacity =
-                state.currently_running[property];
-          if (mask.potentially_animating[property]) {
-            effect_node->has_potential_opacity_animation =
-                state.potentially_animating[property];
-            property_trees()->effect_tree.set_needs_update(true);
-          }
-        } else {
-          if (state.currently_running[property] ||
-              state.potentially_animating[property])
-            DCHECK(property_trees()->needs_rebuild)
-                << "Attempting to animate opacity on non existent effect node";
-        }
-        break;
-      case TargetProperty::FILTER:
-        if (EffectNode* effect_node =
-                property_trees()->effect_tree.FindNodeFromElementId(
-                    element_id)) {
-          if (mask.currently_running[property])
-            effect_node->is_currently_animating_filter =
-                state.currently_running[property];
-          if (mask.potentially_animating[property])
-            effect_node->has_potential_filter_animation =
-                state.potentially_animating[property];
-        } else {
-          if (state.currently_running[property] ||
-              state.potentially_animating[property])
-            DCHECK(property_trees()->needs_rebuild)
-                << "Attempting to animate filter on non existent effect node";
-        }
-        break;
-      default:
-        break;
-    }
-  }
+  property_trees()->ElementIsAnimatingChanged(mutator_host(), element_id,
+                                              list_type, mask, state, true);
 }
 
 gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index ca294bf..75acee7 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -4210,69 +4210,13 @@
     ElementListType list_type,
     const PropertyAnimationState& mask,
     const PropertyAnimationState& state) {
-  // TODO(weiliangc): Most of the code is duplicated with LayerTeeHost version
-  // of function. Should try to share code.
   LayerTreeImpl* tree =
       list_type == ElementListType::ACTIVE ? active_tree() : pending_tree();
-  if (!tree)
-    return;
-  PropertyTrees* property_trees = tree->property_trees();
-
-  for (int property = TargetProperty::FIRST_TARGET_PROPERTY;
-       property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) {
-    if (!mask.currently_running[property] &&
-        !mask.potentially_animating[property])
-      continue;
-
-    switch (property) {
-      case TargetProperty::TRANSFORM:
-        if (TransformNode* transform_node =
-                property_trees->transform_tree.FindNodeFromElementId(
-                    element_id)) {
-          if (mask.currently_running[property])
-            transform_node->is_currently_animating =
-                state.currently_running[property];
-          if (mask.potentially_animating[property]) {
-            transform_node->has_potential_animation =
-                state.potentially_animating[property];
-            transform_node->has_only_translation_animations =
-                mutator_host()->HasOnlyTranslationTransforms(element_id,
-                                                             list_type);
-            property_trees->transform_tree.set_needs_update(true);
-            tree->set_needs_update_draw_properties();
-          }
-        }
-        break;
-      case TargetProperty::OPACITY:
-        if (EffectNode* effect_node =
-                property_trees->effect_tree.FindNodeFromElementId(element_id)) {
-          if (mask.currently_running[property])
-            effect_node->is_currently_animating_opacity =
-                state.currently_running[property];
-          if (mask.potentially_animating[property]) {
-            effect_node->has_potential_opacity_animation =
-                state.potentially_animating[property];
-            property_trees->effect_tree.set_needs_update(true);
-          }
-        }
-        break;
-      case TargetProperty::FILTER:
-        if (EffectNode* effect_node =
-                property_trees->effect_tree.FindNodeFromElementId(element_id)) {
-          if (mask.currently_running[property])
-            effect_node->is_currently_animating_filter =
-                state.currently_running[property];
-          if (mask.potentially_animating[property])
-            effect_node->has_potential_filter_animation =
-                state.potentially_animating[property];
-          // Filter animation changes only the node, and the subtree does not
-          // care. There is no need to request update on property trees here.
-        }
-        break;
-      default:
-        break;
-    }
-  }
+  // TODO(wkorman): Explore enabling DCHECK in ElementIsAnimatingChanged()
+  // below. Currently enabling causes batch of unit test failures.
+  if (tree && tree->property_trees()->ElementIsAnimatingChanged(
+                  mutator_host(), element_id, list_type, mask, state, false))
+    tree->set_needs_update_draw_properties();
 }
 
 void LayerTreeHostImpl::ScrollOffsetAnimationFinished() {
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index f450baa..50a7a7d 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -42,6 +42,12 @@
 template <typename T>
 PropertyTree<T>& PropertyTree<T>::operator=(const PropertyTree<T>&) = default;
 
+#define DCHECK_NODE_EXISTENCE(check_node_existence, state, property,           \
+                              needs_rebuild)                                   \
+  DCHECK(!check_node_existence || ((!state.currently_running[property] &&      \
+                                    !state.potentially_animating[property]) || \
+                                   needs_rebuild))
+
 TransformTree::TransformTree()
     : source_to_parent_updates_allowed_(true),
       page_scale_factor_(1.f),
@@ -1710,6 +1716,88 @@
   transform_tree.UpdateOuterViewportContainerBoundsDelta();
 }
 
+bool PropertyTrees::ElementIsAnimatingChanged(
+    const MutatorHost* mutator_host,
+    ElementId element_id,
+    ElementListType list_type,
+    const PropertyAnimationState& mask,
+    const PropertyAnimationState& state,
+    bool check_node_existence) {
+  bool updated_transform = false;
+  for (int property = TargetProperty::FIRST_TARGET_PROPERTY;
+       property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) {
+    if (!mask.currently_running[property] &&
+        !mask.potentially_animating[property])
+      continue;
+
+    switch (property) {
+      case TargetProperty::TRANSFORM:
+        if (TransformNode* transform_node =
+                transform_tree.FindNodeFromElementId(element_id)) {
+          if (mask.currently_running[property])
+            transform_node->is_currently_animating =
+                state.currently_running[property];
+          if (mask.potentially_animating[property]) {
+            transform_node->has_potential_animation =
+                state.potentially_animating[property];
+            transform_node->has_only_translation_animations =
+                mutator_host->HasOnlyTranslationTransforms(element_id,
+                                                           list_type);
+            transform_tree.set_needs_update(true);
+            // We track transform updates specifically, whereas we
+            // don't do so for opacity/filter, because whether a
+            // transform is animating can change what layer(s) we
+            // draw.
+            updated_transform = true;
+          }
+        } else {
+          DCHECK_NODE_EXISTENCE(check_node_existence, state, property,
+                                needs_rebuild)
+              << "Attempting to animate non existent transform node";
+        }
+        break;
+      case TargetProperty::OPACITY:
+        if (EffectNode* effect_node =
+                effect_tree.FindNodeFromElementId(element_id)) {
+          if (mask.currently_running[property])
+            effect_node->is_currently_animating_opacity =
+                state.currently_running[property];
+          if (mask.potentially_animating[property]) {
+            effect_node->has_potential_opacity_animation =
+                state.potentially_animating[property];
+            // We may need to propagate things like screen space opacity.
+            effect_tree.set_needs_update(true);
+          }
+        } else {
+          DCHECK_NODE_EXISTENCE(check_node_existence, state, property,
+                                needs_rebuild)
+              << "Attempting to animate opacity on non existent effect node";
+        }
+        break;
+      case TargetProperty::FILTER:
+        if (EffectNode* effect_node =
+                effect_tree.FindNodeFromElementId(element_id)) {
+          if (mask.currently_running[property])
+            effect_node->is_currently_animating_filter =
+                state.currently_running[property];
+          if (mask.potentially_animating[property])
+            effect_node->has_potential_filter_animation =
+                state.potentially_animating[property];
+          // Filter animation changes only the node, and the subtree does not
+          // care, thus there is no need to request property tree update.
+        } else {
+          DCHECK_NODE_EXISTENCE(check_node_existence, state, property,
+                                needs_rebuild)
+              << "Attempting to animate filter on non existent effect node";
+        }
+        break;
+      default:
+        break;
+    }
+  }
+  return updated_transform;
+}
+
 void PropertyTrees::SetInnerViewportScrollBoundsDelta(
     gfx::Vector2dF bounds_delta) {
   inner_viewport_scroll_bounds_delta_ = bounds_delta;
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index 3ea602a..08d4dcd 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -17,6 +17,7 @@
 #include "cc/cc_export.h"
 #include "cc/layers/layer_sticky_position_constraint.h"
 #include "cc/trees/element_id.h"
+#include "cc/trees/mutator_host_client.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/transform.h"
@@ -31,6 +32,7 @@
 
 class CopyOutputRequest;
 class LayerTreeImpl;
+class MutatorHost;
 class RenderSurfaceImpl;
 class ScrollState;
 struct ClipNode;
@@ -670,6 +672,15 @@
 
   void clear();
 
+  // Applies an animation state change for a particular element in
+  // this property tree. Returns whether a draw property update is
+  // needed.
+  bool ElementIsAnimatingChanged(const MutatorHost* mutator_host,
+                                 ElementId element_id,
+                                 ElementListType list_type,
+                                 const PropertyAnimationState& mask,
+                                 const PropertyAnimationState& state,
+                                 bool check_node_existence);
   void SetInnerViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta);
   void SetOuterViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta);
   void SetInnerViewportScrollBoundsDelta(gfx::Vector2dF bounds_delta);
diff --git a/chrome/browser/metrics/perf/perf_provider_chromeos.cc b/chrome/browser/metrics/perf/perf_provider_chromeos.cc
index 09e2f66e..5a348d5 100644
--- a/chrome/browser/metrics/perf/perf_provider_chromeos.cc
+++ b/chrome/browser/metrics/perf/perf_provider_chromeos.cc
@@ -316,6 +316,7 @@
 }
 
 PerfProvider::~PerfProvider() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   chromeos::LoginState::Get()->RemoveObserver(&login_observer_);
 }
 
@@ -460,7 +461,7 @@
 
 bool PerfProvider::GetSampledProfiles(
     std::vector<SampledProfile>* sampled_profiles) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (cached_perf_data_.empty()) {
     AddToPerfHistogram(NOT_READY_TO_UPLOAD);
     return false;
@@ -495,7 +496,7 @@
     std::unique_ptr<SampledProfile> sampled_profile,
     PerfSubcommand subcommand,
     const std::string& perf_stdout) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // |perf_output_call_| called us, and owns |perf_stdout|. We must delete it,
   // but not before parsing |perf_stdout|, and we may return early.
@@ -646,7 +647,7 @@
 }
 
 void PerfProvider::ScheduleIntervalCollection() {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (timer_.IsRunning())
     return;
 
@@ -678,7 +679,7 @@
 
 void PerfProvider::CollectIfNecessary(
     std::unique_ptr<SampledProfile> sampled_profile) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // Schedule another interval collection. This call makes sense regardless of
   // whether or not the current collection was interval-triggered. If it had
diff --git a/chrome/browser/metrics/perf/perf_provider_chromeos.h b/chrome/browser/metrics/perf/perf_provider_chromeos.h
index 15a5b8eb..945a09d 100644
--- a/chrome/browser/metrics/perf/perf_provider_chromeos.h
+++ b/chrome/browser/metrics/perf/perf_provider_chromeos.h
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "base/threading/non_thread_safe.h"
+#include "base/sequence_checker.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/metrics/perf/cpu_identity.h"
@@ -29,8 +29,7 @@
 // Provides access to ChromeOS perf data. perf aka "perf events" is a
 // performance profiling infrastructure built into the linux kernel. For more
 // information, see: https://perf.wiki.kernel.org/index.php/Main_Page.
-class PerfProvider : public base::NonThreadSafe,
-                     public chromeos::PowerManagerClient::Observer {
+class PerfProvider : public chromeos::PowerManagerClient::Observer {
  public:
   PerfProvider();
   ~PerfProvider() override;
@@ -255,6 +254,8 @@
   SessionRestore::CallbackSubscription
       on_session_restored_callback_subscription_;
 
+  SEQUENCE_CHECKER(sequence_checker_);
+
   // To pass around the "this" pointer across threads safely.
   base::WeakPtrFactory<PerfProvider> weak_factory_;
 
diff --git a/chrome/browser/permissions/permission_dialog_delegate.cc b/chrome/browser/permissions/permission_dialog_delegate.cc
index d6082290..a71d49d 100644
--- a/chrome/browser/permissions/permission_dialog_delegate.cc
+++ b/chrome/browser/permissions/permission_dialog_delegate.cc
@@ -20,12 +20,14 @@
 #include "chrome/browser/notifications/notification_permission_infobar_delegate.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_features.h"
+#include "chrome/grit/generated_resources.h"
 #include "components/variations/variations_associated_data.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 #include "jni/PermissionDialogController_jni.h"
 #include "jni/PermissionDialogDelegate_jni.h"
 #include "ui/android/window_android.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/base/window_open_disposition.h"
 
 using base::android::ConvertUTF16ToJavaString;
@@ -40,11 +42,28 @@
 // static
 void PermissionDialogDelegate::Create(
     content::WebContents* web_contents,
-    ContentSettingsType type,
-    const GURL& requesting_frame,
-    bool user_gesture,
-    Profile* profile,
-    const PermissionSetCallback& callback) {
+    PermissionPromptAndroid* permission_prompt) {
+  DCHECK(web_contents);
+
+  // If we don't have a tab, just act as though the prompt was dismissed.
+  TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
+  if (!tab) {
+    permission_prompt->Closing();
+    return;
+  }
+
+  // Dispatch the dialog to Java, which manages the lifetime of this object.
+  new PermissionDialogDelegate(tab, /*infobar_delegate=*/nullptr,
+                               permission_prompt);
+}
+
+// static
+void PermissionDialogDelegate::Create(content::WebContents* web_contents,
+                                      ContentSettingsType type,
+                                      const GURL& requesting_frame,
+                                      bool user_gesture,
+                                      Profile* profile,
+                                      const PermissionSetCallback& callback) {
   DCHECK(web_contents);
 
   // If we don't have a tab, just act as though the prompt was dismissed.
@@ -56,8 +75,10 @@
 
   // Dispatch the dialog to Java, which manages the lifetime of this object.
   new PermissionDialogDelegate(
-      tab, PermissionInfoBarDelegate::CreateDelegate(
-               type, requesting_frame, user_gesture, profile, callback));
+      tab,
+      PermissionInfoBarDelegate::CreateDelegate(
+          type, requesting_frame, user_gesture, profile, callback),
+      /*permission_prompt=*/nullptr);
 }
 
 // static
@@ -81,7 +102,8 @@
       user_gesture, std::move(request)));
 
   // Dispatch the dialog to Java, which manages the lifetime of this object.
-  new PermissionDialogDelegate(tab, std::move(infobar_delegate));
+  new PermissionDialogDelegate(tab, std::move(infobar_delegate),
+                               /*permission_prompt=*/nullptr);
 }
 
 // static
@@ -104,42 +126,83 @@
 }
 
 void PermissionDialogDelegate::CreateJavaDelegate(JNIEnv* env) {
+  base::android::ScopedJavaLocalRef<jstring> primaryButtonText =
+      ConvertUTF16ToJavaString(env,
+                               l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW));
+  base::android::ScopedJavaLocalRef<jstring> secondaryButtonText =
+      ConvertUTF16ToJavaString(env,
+                               l10n_util::GetStringUTF16(IDS_PERMISSION_DENY));
+
+  if (infobar_delegate_) {
+    std::vector<int> content_settings_types{
+        infobar_delegate_->content_settings_types()};
+
+    j_delegate_.Reset(Java_PermissionDialogDelegate_create(
+        env, reinterpret_cast<uintptr_t>(this), tab_->GetJavaObject(),
+        base::android::ToJavaIntArray(env, content_settings_types).obj(),
+        ResourceMapper::MapFromChromiumId(infobar_delegate_->GetIconId()),
+        ConvertUTF16ToJavaString(env, infobar_delegate_->GetMessageText()),
+        ConvertUTF16ToJavaString(env, infobar_delegate_->GetLinkText()),
+        primaryButtonText, secondaryButtonText,
+        infobar_delegate_->ShouldShowPersistenceToggle()));
+    return;
+  }
+
+  // TODO(timloh): Handle grouped media permissions (camera + microphone).
+  DCHECK_EQ(1u, permission_prompt_->PermissionCount());
+
   std::vector<int> content_settings_types{
-      infobar_delegate_->content_settings_types()};
+      permission_prompt_->GetContentSettingType(0)};
 
   j_delegate_.Reset(Java_PermissionDialogDelegate_create(
       env, reinterpret_cast<uintptr_t>(this), tab_->GetJavaObject(),
       base::android::ToJavaIntArray(env, content_settings_types).obj(),
-      ResourceMapper::MapFromChromiumId(infobar_delegate_->GetIconId()),
-      ConvertUTF16ToJavaString(env, infobar_delegate_->GetMessageText()),
-      ConvertUTF16ToJavaString(env, infobar_delegate_->GetLinkText()),
-      ConvertUTF16ToJavaString(env, infobar_delegate_->GetButtonLabel(
-                                        PermissionInfoBarDelegate::BUTTON_OK)),
+      ResourceMapper::MapFromChromiumId(
+          permission_prompt_->GetIconIdForPermission(0)),
+      // TODO(timloh): This is the wrong string.
       ConvertUTF16ToJavaString(env,
-                               infobar_delegate_->GetButtonLabel(
-                                   PermissionInfoBarDelegate::BUTTON_CANCEL)),
-      infobar_delegate_->ShouldShowPersistenceToggle()));
+                               permission_prompt_->GetMessageTextFragment(0)),
+      // TODO(timloh): Pass the actual link text for EME.
+      ConvertUTF16ToJavaString(env, base::string16()), primaryButtonText,
+      secondaryButtonText,
+      // TODO(timloh): Hook up the persistence toggle.
+      false));
 }
 
 void PermissionDialogDelegate::Accept(JNIEnv* env,
                                       const JavaParamRef<jobject>& obj,
                                       jboolean persist) {
-  if (infobar_delegate_->ShouldShowPersistenceToggle())
-    infobar_delegate_->set_persist(persist);
-  infobar_delegate_->Accept();
+  if (infobar_delegate_) {
+    if (infobar_delegate_->ShouldShowPersistenceToggle())
+      infobar_delegate_->set_persist(persist);
+    infobar_delegate_->Accept();
+    return;
+  }
+
+  permission_prompt_->Accept();
 }
 
 void PermissionDialogDelegate::Cancel(JNIEnv* env,
                                       const JavaParamRef<jobject>& obj,
                                       jboolean persist) {
-  if (infobar_delegate_->ShouldShowPersistenceToggle())
-    infobar_delegate_->set_persist(persist);
-  infobar_delegate_->Cancel();
+  if (infobar_delegate_) {
+    if (infobar_delegate_->ShouldShowPersistenceToggle())
+      infobar_delegate_->set_persist(persist);
+    infobar_delegate_->Cancel();
+    return;
+  }
+
+  permission_prompt_->Deny();
 }
 
 void PermissionDialogDelegate::Dismissed(JNIEnv* env,
                                          const JavaParamRef<jobject>& obj) {
-  infobar_delegate_->InfoBarDismissed();
+  if (infobar_delegate_) {
+    infobar_delegate_->InfoBarDismissed();
+    return;
+  }
+
+  permission_prompt_->Closing();
 }
 
 void PermissionDialogDelegate::LinkClicked(JNIEnv* env,
@@ -148,10 +211,14 @@
   // InfoBarService as an owner() to open the link. That will fail since the
   // wrapped delegate has no owner (it hasn't been added as an infobar).
   if (tab_->web_contents()) {
-    tab_->web_contents()->OpenURL(content::OpenURLParams(
-        infobar_delegate_->GetLinkURL(), content::Referrer(),
-        WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
-        false));
+    if (infobar_delegate_) {
+      tab_->web_contents()->OpenURL(content::OpenURLParams(
+          infobar_delegate_->GetLinkURL(), content::Referrer(),
+          WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
+          false));
+    }
+    // TODO(timloh): Show a 'learn more' link in the PermissionRequestManager
+    // codepath for EME.
   }
 }
 
@@ -162,12 +229,16 @@
 
 PermissionDialogDelegate::PermissionDialogDelegate(
     TabAndroid* tab,
-    std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate)
+    std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate,
+    PermissionPromptAndroid* permission_prompt)
     : content::WebContentsObserver(tab->web_contents()),
       tab_(tab),
-      infobar_delegate_(std::move(infobar_delegate)) {
+      infobar_delegate_(std::move(infobar_delegate)),
+      permission_prompt_(permission_prompt) {
   DCHECK(tab_);
-  DCHECK(infobar_delegate_);
+  // Only one of the PermissionPromptAndroid and PermissionInfoBarDelegate is
+  // used, depending on whether the PermissionRequestManager is enabled or not.
+  DCHECK(!!permission_prompt_ ^ !!infobar_delegate_);
 
   // Create our Java counterpart, which manages our lifetime.
   JNIEnv* env = base::android::AttachCurrentThread();
diff --git a/chrome/browser/permissions/permission_dialog_delegate.h b/chrome/browser/permissions/permission_dialog_delegate.h
index 9b699eea..e1a3ab5 100644
--- a/chrome/browser/permissions/permission_dialog_delegate.h
+++ b/chrome/browser/permissions/permission_dialog_delegate.h
@@ -11,6 +11,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h"
+#include "chrome/browser/permissions/permission_prompt_android.h"
 #include "chrome/browser/permissions/permission_util.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -29,16 +30,21 @@
 // the native to Java interface to allow Java to communicate the user's
 // decision.
 //
-// This class currently wraps a PermissionInfoBarDelegate. Future refactoring
-// will consolidate PermissionInfoBarDelegate and its subclasses together into
-// GroupedPermissionInfoBarDelegate, which will then source all of its data from
-// an underlying PermissionPromptAndroid object. At that time, this class will
-// also change to wrap a PermissionPromptAndroid.
+// This class owns a PermissionInfoBarDelegate if the PermissionRequestManager
+// is disabled and points to a PermissionPromptAndroid if it's enabled. When the
+// PermissionRequestManager is enabled by default, we can remove the code path
+// for using a PermissionInfoBarDelegate. This is tracked in crbug.com/606138.
 class PermissionDialogDelegate : public content::WebContentsObserver {
  public:
   using PermissionSetCallback = base::Callback<void(bool, PermissionAction)>;
 
-  // Creates a modal dialog for |type|.
+  // The interface for creating a modal dialog when the PermissionRequestManager
+  // is enabled.
+  static void Create(content::WebContents* web_contents,
+                     PermissionPromptAndroid* permission_prompt);
+
+  // The interface for creating a modal dialog when the PermissionRequestManager
+  // is disabled, i.e. we're using the PermissionQueueController.
   static void Create(content::WebContents* web_contents,
                      ContentSettingsType type,
                      const GURL& requesting_frame,
@@ -72,7 +78,8 @@
  private:
   PermissionDialogDelegate(
       TabAndroid* tab,
-      std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate_);
+      std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate,
+      PermissionPromptAndroid* permission_prompt);
   ~PermissionDialogDelegate() override;
 
   void CreateJavaDelegate(JNIEnv* env);
@@ -89,11 +96,15 @@
 
   TabAndroid* tab_;
 
-  // The InfoBarDelegate which this class is wrapping.
-  // TODO(dominickn,lshang) replace this with PermissionPromptAndroid as the
-  // permission prompt refactoring continues.
+  // TODO(timloh): Remove this when the refactoring is finished and we can
+  // delete the PermissionQueueController.
   std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate_;
 
+  // The PermissionPromptAndroid is alive until the tab navigates or is closed.
+  // We close the prompt on DidFinishNavigation and WebContentsDestroyed, so it
+  // should always be safe to use this pointer.
+  PermissionPromptAndroid* permission_prompt_;
+
   DISALLOW_COPY_AND_ASSIGN(PermissionDialogDelegate);
 };
 
diff --git a/chrome/browser/permissions/permission_prompt_android.cc b/chrome/browser/permissions/permission_prompt_android.cc
index e042101..ffef04a0 100644
--- a/chrome/browser/permissions/permission_prompt_android.cc
+++ b/chrome/browser/permissions/permission_prompt_android.cc
@@ -7,6 +7,7 @@
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/permissions/grouped_permission_infobar_delegate_android.h"
+#include "chrome/browser/permissions/permission_dialog_delegate.h"
 #include "chrome/browser/permissions/permission_request.h"
 
 PermissionPromptAndroid::PermissionPromptAndroid(
@@ -22,6 +23,17 @@
 }
 
 void PermissionPromptAndroid::Show() {
+  // Grouped permission requests are not yet supported in dialogs.
+  // TODO(timloh): Handle grouped media permissions (camera + microphone).
+  if (delegate_->Requests().size() == 1) {
+    bool has_gesture = delegate_->Requests()[0]->GetGestureType() ==
+                       PermissionRequestGestureType::GESTURE;
+    if (PermissionDialogDelegate::ShouldShowDialog(has_gesture)) {
+      PermissionDialogDelegate::Create(web_contents_, this);
+      return;
+    }
+  }
+
   InfoBarService* infobar_service =
       InfoBarService::FromWebContents(web_contents_);
   if (!infobar_service)
diff --git a/content/browser/memory/memory_coordinator_impl.cc b/content/browser/memory/memory_coordinator_impl.cc
index d0b138df..1f59ea67 100644
--- a/content/browser/memory/memory_coordinator_impl.cc
+++ b/content/browser/memory/memory_coordinator_impl.cc
@@ -147,11 +147,12 @@
 }
 
 MemoryCoordinatorImpl::~MemoryCoordinatorImpl() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   base::MemoryCoordinatorProxy::SetMemoryCoordinator(nullptr);
 }
 
 void MemoryCoordinatorImpl::Start() {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(last_state_change_.is_null());
 
   notification_registrar_.Add(
@@ -304,7 +305,7 @@
 
 MemoryState MemoryCoordinatorImpl::GetStateForProcess(
     base::ProcessHandle handle) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (handle == base::kNullProcessHandle)
     return MemoryState::UNKNOWN;
   if (handle == base::GetCurrentProcessHandle())
@@ -320,7 +321,7 @@
 
 void MemoryCoordinatorImpl::UpdateConditionIfNeeded(
     MemoryCondition next_condition) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (next_condition == MemoryCondition::WARNING)
     policy_->OnWarningCondition();
diff --git a/content/browser/memory/memory_coordinator_impl.h b/content/browser/memory/memory_coordinator_impl.h
index a832ec9..4d936a4 100644
--- a/content/browser/memory/memory_coordinator_impl.h
+++ b/content/browser/memory/memory_coordinator_impl.h
@@ -10,8 +10,8 @@
 #include "base/memory/memory_coordinator_client.h"
 #include "base/memory/memory_coordinator_proxy.h"
 #include "base/memory/memory_pressure_monitor.h"
+#include "base/sequence_checker.h"
 #include "base/single_thread_task_runner.h"
-#include "base/threading/non_thread_safe.h"
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
 #include "content/common/content_export.h"
@@ -45,8 +45,7 @@
 // MemoryCoordinatorImpl is an implementation of MemoryCoordinator.
 class CONTENT_EXPORT MemoryCoordinatorImpl : public base::MemoryCoordinator,
                                              public MemoryCoordinator,
-                                             public NotificationObserver,
-                                             public base::NonThreadSafe {
+                                             public NotificationObserver {
  public:
   static MemoryCoordinatorImpl* GetInstance();
 
@@ -256,6 +255,8 @@
   // disconnected.
   ChildInfoMap children_;
 
+  SEQUENCE_CHECKER(sequence_checker_);
+
   DISALLOW_COPY_AND_ASSIGN(MemoryCoordinatorImpl);
 };
 
diff --git a/content/browser/streams/stream_registry.cc b/content/browser/streams/stream_registry.cc
index 63c413b..b9cba5b 100644
--- a/content/browser/streams/stream_registry.cc
+++ b/content/browser/streams/stream_registry.cc
@@ -20,11 +20,12 @@
 }
 
 StreamRegistry::~StreamRegistry() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(register_observers_.empty());
 }
 
 void StreamRegistry::RegisterStream(Stream* stream) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(stream);
   DCHECK(!stream->url().is_empty());
 
@@ -41,7 +42,7 @@
 }
 
 scoped_refptr<Stream> StreamRegistry::GetStream(const GURL& url) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   StreamMap::const_iterator stream = streams_.find(url);
   if (stream != streams_.end())
     return stream->second;
@@ -50,7 +51,7 @@
 }
 
 bool StreamRegistry::CloneStream(const GURL& url, const GURL& src_url) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   scoped_refptr<Stream> stream(GetStream(src_url));
   if (stream.get()) {
     streams_[url] = stream;
@@ -60,7 +61,7 @@
 }
 
 void StreamRegistry::UnregisterStream(const GURL& url) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   StreamMap::iterator iter = streams_.find(url);
   if (iter == streams_.end())
@@ -80,7 +81,7 @@
 bool StreamRegistry::UpdateMemoryUsage(const GURL& url,
                                        size_t current_size,
                                        size_t increase) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   StreamMap::iterator iter = streams_.find(url);
   // A Stream must be registered with its parent registry to get memory.
@@ -103,18 +104,18 @@
 
 void StreamRegistry::SetRegisterObserver(const GURL& url,
                                          StreamRegisterObserver* observer) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(register_observers_.find(url) == register_observers_.end());
   register_observers_[url] = observer;
 }
 
 void StreamRegistry::RemoveRegisterObserver(const GURL& url) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   register_observers_.erase(url);
 }
 
 void StreamRegistry::AbortPendingStream(const GURL& url) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   reader_aborted_urls_.insert(url);
 }
 
diff --git a/content/browser/streams/stream_registry.h b/content/browser/streams/stream_registry.h
index c7b31ab..6ef17b1 100644
--- a/content/browser/streams/stream_registry.h
+++ b/content/browser/streams/stream_registry.h
@@ -12,7 +12,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/threading/non_thread_safe.h"
+#include "base/sequence_checker.h"
 #include "content/browser/streams/stream_register_observer.h"
 #include "content/common/content_export.h"
 #include "url/gurl.h"
@@ -22,7 +22,7 @@
 class Stream;
 
 // Maintains a mapping of blob: URLs to active streams.
-class CONTENT_EXPORT StreamRegistry : public base::NonThreadSafe {
+class CONTENT_EXPORT StreamRegistry {
  public:
   StreamRegistry();
   virtual ~StreamRegistry();
@@ -74,6 +74,8 @@
   // with this registry.
   size_t max_memory_usage_;
 
+  SEQUENCE_CHECKER(sequence_checker_);
+
   DISALLOW_COPY_AND_ASSIGN(StreamRegistry);
 };
 
diff --git a/services/identity/identity_manager.cc b/services/identity/identity_manager.cc
index 8ea9d72..7a8eddf 100644
--- a/services/identity/identity_manager.cc
+++ b/services/identity/identity_manager.cc
@@ -24,7 +24,7 @@
 IdentityManager::~IdentityManager() {}
 
 void IdentityManager::GetPrimaryAccountId(
-    const GetPrimaryAccountIdCallback& callback) {
+    GetPrimaryAccountIdCallback callback) {
   AccountId account_id = EmptyAccountId();
 
   if (signin_manager_->IsAuthenticated()) {
@@ -33,7 +33,7 @@
         AccountId::FromUserEmailGaiaId(account_info.email, account_info.gaia);
   }
 
-  callback.Run(account_id);
+  std::move(callback).Run(account_id);
 }
 
 }  // namespace identity
diff --git a/services/identity/identity_manager.h b/services/identity/identity_manager.h
index f024bf5..3f90e45 100644
--- a/services/identity/identity_manager.h
+++ b/services/identity/identity_manager.h
@@ -21,8 +21,7 @@
 
  private:
   // mojom::IdentityManager:
-  void GetPrimaryAccountId(
-      const GetPrimaryAccountIdCallback& callback) override;
+  void GetPrimaryAccountId(GetPrimaryAccountIdCallback callback) override;
 
   SigninManagerBase* signin_manager_;
 };
diff --git a/services/identity/public/interfaces/BUILD.gn b/services/identity/public/interfaces/BUILD.gn
index 08bfe4b..f2e15ffe 100644
--- a/services/identity/public/interfaces/BUILD.gn
+++ b/services/identity/public/interfaces/BUILD.gn
@@ -13,9 +13,6 @@
     ":constants",
     "//components/signin/public/interfaces",
   ]
-
-  # TODO(crbug.com/714018): Convert the implementation to use OnceCallback.
-  use_once_callback = false
 }
 
 mojom("constants") {
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index bc4e7fe..d66523ed 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -117,8 +117,6 @@
 # This test fails only when spv2 is enabled.
 crbug.com/719533 compositing/overflow/absolute-element-in-isolated-composited-ancestor.html [ Failure ]
 
-crbug.com/724567 fast/spatial-navigation/snav-z-index.html [ Pass Failure ]
-
 # ====== Paint team owned tests to here ======
 
 #### external/wpt/css/css-position-3
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-subgraph-404.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-subgraph-404.html
new file mode 100644
index 0000000..4911a071
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-subgraph-404.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module">
+import { delayedLoaded }  from "./resources/delayed-modulescript.py";
+import { A } from "./404.js";
+window.loadSuccess = delayedLoaded;
+</script>
+<script type="module">
+test(function () {
+    assert_equals(window.loadSuccess, undefined,
+      "module tree w/ its sub graph 404 should fail to load without crashing");
+}, "Import a module graph w/ sub-graph 404.");
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py
new file mode 100644
index 0000000..6ed1621
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py
@@ -0,0 +1,7 @@
+import time
+
+def main(request, response):
+    delay = float(request.GET.first("ms", 500))
+    time.sleep(delay / 1E3);
+
+    return [("Content-type", "text/javascript")], "export let delayedLoaded = true;"
diff --git a/third_party/WebKit/LayoutTests/fast/spatial-navigation/resources/spatial-navigation-utils.js b/third_party/WebKit/LayoutTests/fast/spatial-navigation/resources/spatial-navigation-utils.js
index c9205bac..bfe9f5b 100644
--- a/third_party/WebKit/LayoutTests/fast/spatial-navigation/resources/spatial-navigation-utils.js
+++ b/third_party/WebKit/LayoutTests/fast/spatial-navigation/resources/spatial-navigation-utils.js
@@ -63,7 +63,7 @@
   if (window.testRunner && direction)
     eventSender.keyDown(direction);
 
-  setTimeout(verifyAndAdvance, 15);
+  requestAnimationFrame(verifyAndAdvance);
 }
 
 function verifyAndAdvance()
diff --git a/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-unit-overflow-and-scroll-in-direction.html b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-unit-overflow-and-scroll-in-direction.html
index e914ccb8..2fda20d 100644
--- a/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-unit-overflow-and-scroll-in-direction.html
+++ b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-unit-overflow-and-scroll-in-direction.html
@@ -51,7 +51,7 @@
       // starting the test itself: get to a known place.
       document.getElementById("start").focus();
 
-      setTimeout(step1 , 0);
+      requestAnimationFrame(step1);
     }
 
     function step1()
@@ -76,7 +76,7 @@
 
     function step1Completed()
     {
-      setTimeout(step2 , 0);
+      requestAnimationFrame(step2);
     }
 
     function step2Completed()
diff --git a/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-z-index.html b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-z-index.html
index a76de85..15098fb 100644
--- a/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-z-index.html
+++ b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-z-index.html
@@ -37,8 +37,7 @@
     {
       // starting the test itself: get to a known place.
       document.getElementById("start").focus();
-
-      initTest(resultMap, testCompleted);
+      requestAnimationFrame(() => initTest(resultMap, testCompleted));
     }
 
     function testCompleted()
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/paint-arguments.html b/third_party/WebKit/LayoutTests/http/tests/csspaint/paint-arguments.html
index 6374131..b2177ee 100644
--- a/third_party/WebKit/LayoutTests/http/tests/csspaint/paint-arguments.html
+++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/paint-arguments.html
@@ -35,7 +35,7 @@
     static get alpha() { return true; }
     static get inputArguments() { return ['<color>']; }
     paint(ctx, geom, properties, args) {
-        ctx.strokeStyle = args[0].cssText;
+        ctx.strokeStyle = args[0].toString();
         ctx.lineWidth = 4;
         ctx.strokeRect(20, 20, 60, 60);
     }
@@ -47,4 +47,4 @@
   importPaintWorkletAndTerminateTestAfterAsyncPaint(document.getElementById('code').textContent);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/paint-function-arguments.html b/third_party/WebKit/LayoutTests/http/tests/csspaint/paint-function-arguments.html
index 69ad9568..6e2b07f9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/csspaint/paint-function-arguments.html
+++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/paint-function-arguments.html
@@ -35,8 +35,8 @@
     static get alpha() { return true; }
     static get inputArguments() { return ['<color>', '<length>']; }
     paint(ctx, geom, properties, args) {
-        ctx.strokeStyle = args[0].cssText;
-        ctx.lineWidth = args[1].cssText;
+        ctx.strokeStyle = args[0].toString();
+        ctx.lineWidth = args[1].toString();
         ctx.strokeRect(40, 40, 120, 120);
     }
 });
@@ -47,4 +47,4 @@
   importPaintWorkletAndTerminateTestAfterAsyncPaint(document.getElementById('code').textContent);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/csspaint/resources/generate-paint-style-logging.js b/third_party/WebKit/LayoutTests/http/tests/csspaint/resources/generate-paint-style-logging.js
index 7f114ba..f66b775d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/csspaint/resources/generate-paint-style-logging.js
+++ b/third_party/WebKit/LayoutTests/http/tests/csspaint/resources/generate-paint-style-logging.js
@@ -18,7 +18,7 @@
                     const value = styleMap.get(properties[i]);
                     let serialized;
                     if (value) {
-                        serialized = '[' + value.constructor.name + '=' + value.cssText + ']';
+                        serialized = '[' + value.constructor.name + '=' + value.toString() + ']';
                     } else {
                         serialized = '[null]';
                     }
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
index beea2da..72e6a1bd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
@@ -51,8 +51,8 @@
 CONSOLE MESSAGE: line 147:     method constructor
 CONSOLE MESSAGE: line 147: interface CSSStyleValue
 CONSOLE MESSAGE: line 147:     static method parse
-CONSOLE MESSAGE: line 147:     getter cssText
 CONSOLE MESSAGE: line 147:     method constructor
+CONSOLE MESSAGE: line 147:     method toString
 CONSOLE MESSAGE: line 147: interface CSSTransformComponent
 CONSOLE MESSAGE: line 147:     method asMatrix
 CONSOLE MESSAGE: line 147:     method constructor
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/background-image.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/background-image.html
index a21b5a06..cfd32e9 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/background-image.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/background-image.html
@@ -20,7 +20,7 @@
 function checks() {
   var result = computedStyleMap.get('background-image');
   assert_true(result instanceof CSSURLImageValue);
-  assert_equals(result.cssText, 'url(\"' + imagePath + '\")');
+  assert_equals(result.toString(), 'url(\"' + imagePath + '\")');
   assert_equals(result.state, 'loaded');
   assert_equals(result.intrinsicWidth, 1);
   assert_equals(result.intrinsicHeight, 1);
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/border-top-width.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/border-top-width.html
index 9e55e1d..bb224e00 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/border-top-width.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/border-top-width.html
@@ -13,7 +13,7 @@
 
   var result = computedStyleMap.get('border-top-width');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '10px');
+  assert_equals(result.toString(), '10px');
 }, "Getting a 10px border-top-width returns a CSSUnitValue");
 
 test(function() {
@@ -21,7 +21,7 @@
 
   var result = computedStyleMap.getAll('border-top-width');
   assert_equals(result.length, 1);
-  assert_equals(result[0].cssText, '20px');
+  assert_equals(result[0].toString(), '20px');
 }, "getAll for border-top-width returns a single value");
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap.html
index 6e3fbab..8fa276e 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap.html
@@ -27,7 +27,7 @@
   testElement.style.border = '1px solid #00ff00';
   var styleValue = computedStyleMap.get('border');
   assert_equals(styleValue.constructor, CSSStyleValue);
-  assert_equals(styleValue.cssText, testElement.style.border);
+  assert_equals(styleValue.toString(), testElement.style.border);
 }, 'Unsupported but serializable property returns a base CSSStyleValue.');
 
 test(function() {
@@ -65,9 +65,9 @@
 
 test(function() {
   testElement.style.width = '100px';
-  assert_equals(computedStyleMap.get('width').cssText, '100px');
+  assert_equals(computedStyleMap.get('width').toString(), '100px');
   testElement.style.display = 'none';
-  assert_equals(computedStyleMap.get('width').cssText, '100px');
+  assert_equals(computedStyleMap.get('width').toString(), '100px');
 }, 'get() returns correct values for an element with display: none.');
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/custom-properties.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/custom-properties.html
index 13f846c0..0c11913f 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/custom-properties.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/custom-properties.html
@@ -68,7 +68,7 @@
   assert_true(computedStyleMap.has('--my-length'));
   var result = computedStyleMap.get('--my-length');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '100px');
+  assert_equals(result.toString(), '100px');
 }, 'Getting a length type registered property returns a CSSUnitValue');
 
 var t1 = async_test('Getting a URL image type registered property returns a CSSURLImageValue');
@@ -77,7 +77,7 @@
     assert_true(computedStyleMap.has('--my-image'));
     var result = computedStyleMap.get('--my-image');
     assert_equals(result.constructor.name, CSSURLImageValue.name);
-    assert_equals(result.cssText, 'url(\"' + imagePath + '\")');
+    assert_equals(result.toString(), 'url(\"' + imagePath + '\")');
     // FIXME: This section of this test fails. It seems to be a bug in custom properties. See
     // crbug.com/719838
     assert_equals(result.state, 'loaded');
@@ -91,7 +91,7 @@
 test(function() {
   var result = computedStyleMap.get('width');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '100px');
+  assert_equals(result.toString(), '100px');
 }, 'Getting a width with a length type var value returns a CSSUnitValue');
 
 var t2 = async_test('Getting a background-image with a URL image type var value returns a CSSURLImageValue');
@@ -99,7 +99,7 @@
   t2.step(function() {
     var result = computedStyleMap.get('background-image');
     assert_equals(result.constructor.name, CSSURLImageValue.name);
-    assert_equals(result.cssText, 'url(\"' + imagePath + '\")');
+    assert_equals(result.toString(), 'url(\"' + imagePath + '\")');
     assert_equals(result.state, 'loaded');
     assert_equals(result.intrinsicWidth, 1);
     assert_equals(result.intrinsicHeight, 1);
@@ -112,14 +112,14 @@
   assert_true(childComputedStyleMap.has('--my-inherited-length'));
   var result = childComputedStyleMap.get('--my-inherited-length');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '200px');
+  assert_equals(result.toString(), '200px');
 }, 'Getting an inherited length type registered property returns a CSSUnitValue');
 
 test(function() {
   assert_true(childComputedStyleMap.has('--my-length'));
   result = childComputedStyleMap.get('--my-length');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '0px');
+  assert_equals(result.toString(), '0px');
 }, 'Getting a non-inherited length type registered property returns a CSSUnitValue');
 
 test(function() {
@@ -127,14 +127,14 @@
   assert_equals(result.constructor.name, CSSCalcValue.name);
   assert_equals(result.px, 115);
   assert_equals(result.percent, 10);
-  assert_equals(result.cssText, 'calc(10% + 115px)');
+  assert_equals(result.toString(), 'calc(10% + 115px)');
 }, 'Getting a height with a calc type containing var values returns a CSSCalcValue');
 
 test(function() {
   assert_true(computedStyleMap.has('--my-unused-property'));
   result = computedStyleMap.get('--my-unused-property');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '0%');
+  assert_equals(result.toString(), '0%');
 }, 'Getting the value of a registered property that isn\'t set on the element ' +
     'returns the initial value for the property');
 
@@ -147,7 +147,7 @@
   var result = computedStyleMap.getAll('--my-length');
   assert_equals(result.length, 1);
   assert_equals(result[0].constructor.name, CSSUnitValue.name);
-  assert_equals(result[0].cssText, '100px');
+  assert_equals(result[0].toString(), '100px');
 }, 'getAll for a length type registered property returns a single value');
 
 document.onreadystatechange = function() {
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/left.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/left.html
index 6807198..683edb3f 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/left.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/left.html
@@ -16,7 +16,7 @@
   t1.step(function() {
     var result = computedStyleMap.get('left');
     assert_equals(result.constructor.name, CSSUnitValue.name);
-    assert_equals(result.cssText, '10px');
+    assert_equals(result.toString(), '10px');
   });
   t1.done();
 }
@@ -27,7 +27,7 @@
     testElement.style.left = '20px';
     var result = computedStyleMap.getAll('left');
     assert_equals(result.length, 1);
-    assert_equals(result[0].cssText, '20px');
+    assert_equals(result[0].toString(), '20px');
   });
   t2.done();
 }
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/line-height.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/line-height.html
index e3b493ff..b45ffdae 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/line-height.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/line-height.html
@@ -17,42 +17,42 @@
 test(function() {
   var result = computedStyleMap.get('line-height');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '10px');
+  assert_equals(result.toString(), '10px');
 }, 'Getting a 10px lineHeight results in a CSSUnitValue');
 
 test(function() {
   testElement.style.lineHeight = '20px';
   var result = computedStyleMap.getAll('line-height');
   assert_equals(result.length, 1);
-  assert_equals(result[0].cssText, '20px');
+  assert_equals(result[0].toString(), '20px');
 }, 'getAll for lineHeight returns a single value');
 
 test(function() {
   testElement.style.lineHeight = '10%';
   var result = computedStyleMap.get('line-height');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '10px');
+  assert_equals(result.toString(), '10px');
 }, 'Getting a 10% lineHeight results in a CSSUnitValue');
 
 test(function() {
   testElement.style.lineHeight = '0.2';
   var result = computedStyleMap.get('line-height');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '20px');
+  assert_equals(result.toString(), '20px');
 }, 'Getting a number lineHeight results in a CSSUnitValue');
 
 test(function() {
   testElement.style.lineHeight = 'calc(10px + 10%)';
   var result = computedStyleMap.get('line-height');
   assert_equals(result.constructor.name, CSSUnitValue.name);
-  assert_equals(result.cssText, '20px');
+  assert_equals(result.toString(), '20px');
 }, 'Getting a calc lineHeight results in a CSSUnitValue');
 
 test(function() {
   testElement.style.lineHeight = 'normal';
   var result = computedStyleMap.get('line-height');
   assert_equals(result.constructor.name, CSSKeywordValue.name);
-  assert_equals(result.cssText, 'normal');
+  assert_equals(result.toString(), 'normal');
 }, 'Getting a normal lineHeight results in a CSSKeywordValue');
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/pseudo-elements.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/pseudo-elements.html
index dd8449f..4bbfff5 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/pseudo-elements.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/pseudo-elements.html
@@ -28,7 +28,7 @@
   t1.step(function() {
     var pseudoResult = pseudoComputedStyleMap.get('width');
     assert_equals(pseudoResult.constructor.name, CSSUnitValue.name);
-    assert_equals(pseudoResult.cssText, '100px');
+    assert_equals(pseudoResult.toString(), '100px');
   });
   t1.done();
 }
@@ -38,7 +38,7 @@
   t2.step(function() {
     var styleValueList = pseudoComputedStyleMap.getAll('width');
     assert_equals(styleValueList.length, 1);
-    assert_equals(styleValueList[0].cssText, '100px');
+    assert_equals(styleValueList[0].toString(), '100px');
   });
   t2.done();
 }
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/width.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/width.html
index 9d6a087..60e7d77f 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/width.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/width.html
@@ -16,7 +16,7 @@
   t1.step(function() {
     var result = computedStyleMap.get('width');
     assert_equals(result.constructor.name, CSSUnitValue.name);
-    assert_equals(result.cssText, '10px');
+    assert_equals(result.toString(), '10px');
   });
   t1.done();
 }
@@ -27,7 +27,7 @@
     testElement.style.width = '20px';
     var result = computedStyleMap.getAll('width');
     assert_equals(result.length, 1);
-    assert_equals(result[0].cssText, '20px');
+    assert_equals(result[0].toString(), '20px');
   });
   t2.done();
 }
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssKeywordValue.html b/third_party/WebKit/LayoutTests/typedcssom/cssKeywordValue.html
index c67b388..6fe1998 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssKeywordValue.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssKeywordValue.html
@@ -8,12 +8,12 @@
 }, "Constructor should throw an error if given an empty string");
 
 test(function() {
-  assert_equals(new CSSKeywordValue('initial').cssText, 'initial');
-  assert_equals(new CSSKeywordValue('center').cssText, 'center');
-  assert_equals(new CSSKeywordValue('customLemon').cssText, 'customLemon');
-  assert_equals(new CSSKeywordValue(' Hello World').cssText, CSS.escape(' Hello World'));
-  assert_equals(new CSSKeywordValue('3').cssText, CSS.escape('3'));
-}, 'cssText returns a string with a format similar to CSS.escape. This test also ' +
+  assert_equals(new CSSKeywordValue('initial').toString(), 'initial');
+  assert_equals(new CSSKeywordValue('center').toString(), 'center');
+  assert_equals(new CSSKeywordValue('customLemon').toString(), 'customLemon');
+  assert_equals(new CSSKeywordValue(' Hello World').toString(), CSS.escape(' Hello World'));
+  assert_equals(new CSSKeywordValue('3').toString(), CSS.escape('3'));
+}, 'toString() returns a string with a format similar to CSS.escape. This test also ' +
     'implies that toCSSValue supports all keywords including custom identifiers');
 
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssPerspective-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/cssPerspective-expected.txt
index 76329892..fb0ae99 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssPerspective-expected.txt
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssPerspective-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 FAIL Constructor should throw an error for CSSCalcValues with a percentage type CSSCalcValue is not defined
 FAIL Constructor should throw an error for CSSUnitValues with a percentage type assert_throws: function "function () { new CSSPerspective(simpleLength) }" did not throw
-FAIL cssText should return a string of form perspective(<CSSLengthValue.cssString()>) CSSCalcValue is not defined
+FAIL toString should return a string of form perspective(<CSSLengthValue.cssString()>) CSSCalcValue is not defined
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssPerspective.html b/third_party/WebKit/LayoutTests/typedcssom/cssPerspective.html
index 61ad98b..c10a520e 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssPerspective.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssPerspective.html
@@ -22,7 +22,7 @@
 
   assert_equals(perspectiveTransformSimple.toString(), 'perspective(10px)');
   assert_equals(perspectiveTransformCalc.toString(), 'perspective(calc(3.2em + 10px))');
-}, "cssText should return a string of form perspective(<CSSLengthValue.cssString()>)");
+}, "toString should return a string of form perspective(<CSSLengthValue.cssString()>)");
 
 </script>
 
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssPositionValue-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/cssPositionValue-expected.txt
index efa29065..38423ef 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssPositionValue-expected.txt
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssPositionValue-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL cssText returns a string with the x and y positions cssStrings separated by a space CSSCalcValue is not defined
+FAIL toString() returns a string with the x and y positions cssStrings separated by a space CSSCalcValue is not defined
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssPositionValue.html b/third_party/WebKit/LayoutTests/typedcssom/cssPositionValue.html
index 2f5f824..39298f2a 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssPositionValue.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssPositionValue.html
@@ -6,14 +6,14 @@
 
 test(function() {
   assert_equals(new CSSPositionValue(new CSSUnitValue(50, 'px'),
-    new CSSCalcValue({px: -10, em: -3.2, pt: 0})).cssText, '50px calc((-3.2em - 10px) + 0pt)');
+    new CSSCalcValue({px: -10, em: -3.2, pt: 0})).toString(), '50px calc((-3.2em - 10px) + 0pt)');
   assert_equals(new CSSPositionValue(new CSSUnitValue(50, 'px'),
-    new CSSUnitValue(2, 'em')).cssText, '50px 2em');
+    new CSSUnitValue(2, 'em')).toString(), '50px 2em');
   assert_equals(new CSSPositionValue(new CSSCalcValue({px: -10, em: -3.2, pt: 0}),
-    new CSSCalcValue({px: -10, em: 3.2})).cssText, 'calc((-3.2em - 10px) + 0pt) calc(3.2em - 10px)');
+    new CSSCalcValue({px: -10, em: 3.2})).toString(), 'calc((-3.2em - 10px) + 0pt) calc(3.2em - 10px)');
   assert_equals(new CSSPositionValue(new CSSCalcValue({px: -10, em: -3.2, pt: 0}),
-    new CSSUnitValue(10, 'percent')).cssText, 'calc((-3.2em - 10px) + 0pt) 10%');
-}, "cssText returns a string with the x and y positions cssStrings separated by a space");
+    new CSSUnitValue(10, 'percent')).toString(), 'calc((-3.2em - 10px) + 0pt) 10%');
+}, "toString() returns a string with the x and y positions cssStrings separated by a space");
 
 </script>
 
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssRotation.html b/third_party/WebKit/LayoutTests/typedcssom/cssRotation.html
index 5becb3b9..bb4a4f1 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssRotation.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssRotation.html
@@ -71,10 +71,10 @@
     for (var attribute in expectedMatrix) {
       if (attribute == "matrix") {
         assert_matrix_approx_equals(inputAsMatrix[attribute], expectedMatrix[attribute]);
-      } else if (attribute != "cssText") {
+      } else if (attribute != "toString") {
         // Due to the complex trigonometric calculations required for a CSSRotation matrix,
-        // the 6 significant figures of each value in the cssText might be different.
-        // Hence, do not check cssText.
+        // the 6 significant figures of each value in the toString might be different.
+        // Hence, do not check toString.
         assert_equals(inputAsMatrix[attribute], expectedMatrix[attribute]);
       }
     }
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssSkew-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/cssSkew-expected.txt
index 66d89ec..e94ed15 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssSkew-expected.txt
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssSkew-expected.txt
@@ -1,7 +1,7 @@
 This is a testharness.js-based test.
 FAIL (ax, ay) values for CSSSkew are correct. assert_approx_equals: expected a number but got a "undefined"
 PASS is2D values for CSSSkew are correct. 
-FAIL toString() for CSSSkew is correct. assert_equals: expected "skew(0deg, 0deg)" but got ""
+FAIL toString for CSSSkew is correct. assert_equals: expected "skew(0deg, 0deg)" but got ""
 PASS Invalid arguments for CSSSkew throws an exception. 
 FAIL asMatrix is constructed correctly for CSSSkew. Cannot read property 'is2D' of null
 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssSkew.html b/third_party/WebKit/LayoutTests/typedcssom/cssSkew.html
index f3135206..90afee5 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssSkew.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssSkew.html
@@ -38,7 +38,7 @@
   for (var i = 0; i < values.length; ++i) {
     assert_equals(values[i].input.toString(), values[i].cssText);
   }
-}, "toString() for CSSSkew is correct.");
+}, "toString for CSSSkew is correct.");
 
 test(function() {
   assert_throws(new TypeError(), function() { new CSSSkew(); });
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssTranslation.html b/third_party/WebKit/LayoutTests/typedcssom/cssTranslation.html
index de0f638..d3dfec0 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssTranslation.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssTranslation.html
@@ -53,9 +53,9 @@
 
 function expectedCssString(obj) {
   var cssText = obj.is2D ? "translate(" : "translate3d(";
-  cssText += obj.x.cssText + ", " + obj.y.cssText;
+  cssText += obj.x.toString() + ", " + obj.y.toString();
   if (!obj.is2D)
-    cssText += ", " + obj.z.cssText;
+    cssText += ", " + obj.z.toString();
   cssText += ")";
   return cssText;
 }
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssUnitValue.html b/third_party/WebKit/LayoutTests/typedcssom/cssUnitValue.html
index 183ea8c8..eed17fb 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssUnitValue.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssUnitValue.html
@@ -48,7 +48,7 @@
   assert_equals(unitValue.value, value, 'value');
   assert_equals(unitValue.unit, unit, 'unit');
   assert_equals(unitValue.type, type, 'type');
-  assert_equals(unitValue.cssText, cssText, 'cssText');
+  assert_equals(unitValue.toString(), cssText, 'cssText');
 }
 
 function generateTests(unitList, typeString) {
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_delete.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_delete.html
index b834dbd..dabdd21 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_delete.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_delete.html
@@ -9,7 +9,7 @@
 // Delete
 test(function() {
   testElement.style.width = '80px';
-  assert_equals(testElement.styleMap.get('width').cssText, '80px');
+  assert_equals(testElement.styleMap.get('width').toString(), '80px');
 
   testElement.styleMap.delete('width');
   assert_equals(testElement.styleMap.get('width'), null);
@@ -18,7 +18,7 @@
 
 test(function() {
   testElement.styleMap.set('width', new CSSUnitValue(100, 'px'));
-  assert_equals(testElement.styleMap.get('width').cssText, '100px');
+  assert_equals(testElement.styleMap.get('width').toString(), '100px');
 
   testElement.styleMap.delete('width');
   assert_equals(testElement.styleMap.get('width'), null);
@@ -27,7 +27,7 @@
 
 test(function() {
   testElement.style.width = '90px';
-  assert_equals(testElement.styleMap.get('width').cssText, '90px');
+  assert_equals(testElement.styleMap.get('width').toString(), '90px');
 
   testElement.styleMap.delete('WIdtH');
   assert_equals(testElement.styleMap.get('width'), null);
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getAll.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getAll.html
index 78c75a7..78569f4 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getAll.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_getAll.html
@@ -11,7 +11,7 @@
   testElement.styleMap.set('width', new CSSUnitValue(90, 'px'));
   var result = testElement.styleMap.getAll('width');
   assert_equals(result.length, 1);
-  assert_equals(result[0].cssText, '90px');
+  assert_equals(result[0].toString(), '90px');
 }, "getAll() returns a list of values");
 
 test(function() {
@@ -23,9 +23,9 @@
   assert_equals(lowerResult.length, 1);
   assert_equals(upperResult.length, 1);
   assert_equals(mixedResult.length, 1);
-  assert_equals(lowerResult[0].cssText, '100px');
-  assert_equals(upperResult[0].cssText, '100px');
-  assert_equals(mixedResult[0].cssText, '100px');
+  assert_equals(lowerResult[0].toString(), '100px');
+  assert_equals(upperResult[0].toString(), '100px');
+  assert_equals(mixedResult[0].toString(), '100px');
 }, "getAll is case-insensitive for the property name");
 
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iteration.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iteration.html
index f669834..b6336a5a 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iteration.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iteration.html
@@ -29,7 +29,7 @@
 
   assert_equals(entry.value[0], 'width');
   assert_equals(entry.value[1].constructor.name, CSSUnitValue.name);
-  assert_equals(entry.value[1].cssText, '50px');
+  assert_equals(entry.value[1].toString(), '50px');
 }, "Iterator for single entry returns iterator with a single value");
 
 test(function() {
@@ -54,7 +54,7 @@
   assert_true(iterator.next().done);
 
   assert_equals(entry.value.constructor.name, CSSUnitValue.name);
-  assert_equals(entry.value.cssText, '70px');
+  assert_equals(entry.value.toString(), '70px');
 }, "Iterator for single value returns iterator with a single value");
 
 test(function() {
@@ -68,26 +68,26 @@
   }
   assert_equals(numEntries, 17);
 
-  assert_equals(entries['border-top-width'].cssText, '5px');
-  assert_equals(entries['border-right-width'].cssText, '5px');
-  assert_equals(entries['border-bottom-width'].cssText, '5px');
-  assert_equals(entries['border-left-width'].cssText, '5px');
+  assert_equals(entries['border-top-width'].toString(), '5px');
+  assert_equals(entries['border-right-width'].toString(), '5px');
+  assert_equals(entries['border-bottom-width'].toString(), '5px');
+  assert_equals(entries['border-left-width'].toString(), '5px');
 
-  assert_equals(entries['border-top-style'].cssText, 'solid');
-  assert_equals(entries['border-right-style'].cssText, 'solid');
-  assert_equals(entries['border-bottom-style'].cssText, 'solid');
-  assert_equals(entries['border-left-style'].cssText, 'solid');
+  assert_equals(entries['border-top-style'].toString(), 'solid');
+  assert_equals(entries['border-right-style'].toString(), 'solid');
+  assert_equals(entries['border-bottom-style'].toString(), 'solid');
+  assert_equals(entries['border-left-style'].toString(), 'solid');
 
-  assert_equals(entries['border-top-color'].cssText, 'lightcoral');
-  assert_equals(entries['border-right-color'].cssText, 'lightcoral');
-  assert_equals(entries['border-bottom-color'].cssText, 'lightcoral');
-  assert_equals(entries['border-left-color'].cssText, 'lightcoral');
+  assert_equals(entries['border-top-color'].toString(), 'lightcoral');
+  assert_equals(entries['border-right-color'].toString(), 'lightcoral');
+  assert_equals(entries['border-bottom-color'].toString(), 'lightcoral');
+  assert_equals(entries['border-left-color'].toString(), 'lightcoral');
 
-  assert_equals(entries['border-image-source'].cssText, 'initial');
-  assert_equals(entries['border-image-slice'].cssText, 'initial');
-  assert_equals(entries['border-image-width'].cssText, 'initial');
-  assert_equals(entries['border-image-outset'].cssText, 'initial');
-  assert_equals(entries['border-image-repeat'].cssText, 'initial');
+  assert_equals(entries['border-image-source'].toString(), 'initial');
+  assert_equals(entries['border-image-slice'].toString(), 'initial');
+  assert_equals(entries['border-image-width'].toString(), 'initial');
+  assert_equals(entries['border-image-outset'].toString(), 'initial');
+  assert_equals(entries['border-image-repeat'].toString(), 'initial');
 }, "Iterating entries over border element expansion");
 
 test(function() {
@@ -96,7 +96,7 @@
 
   assert_equals(entries.length, 1);
   assert_equals(entries[0].constructor, CSSUnparsedValue);
-  assert_equals(entries[0].cssText, '--bg-color');
+  assert_equals(entries[0].toString(), '--bg-color');
   assert_equals([...entries[0]].length, 1);
   assert_equals([...entries[0]][0].variable, "--bg-color");
   assert_equals([...entries[0]][0].fallback, null);
@@ -113,7 +113,7 @@
 
   assert_equals(propertyAndValue[0], '--my-custom-property');
   assert_equals(propertyAndValue[1].constructor, CSSStyleValue);
-  assert_equals(propertyAndValue[1].cssText, '5px');
+  assert_equals(propertyAndValue[1].toString(), '5px');
 }, "Custom properties set on the element come out as CSSStyleValues");
 
 test(function() {
@@ -126,7 +126,7 @@
 
   assert_equals(propertyAndValue[0], '@apply');
   assert_equals(propertyAndValue[1].constructor, CSSStyleValue);
-  assert_equals(propertyAndValue[1].cssText, '--foo');
+  assert_equals(propertyAndValue[1].toString(), '--foo');
 }, "@apply rules come out as CSSStyleValues");
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iterationWithModification.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iterationWithModification.html
index 6306562..8aef2e76 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iterationWithModification.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_iterationWithModification.html
@@ -13,7 +13,7 @@
   var entry = iterator.next();
   assert_equals(entry.value[0], 'width');
   assert_equals(entry.value[1].constructor.name, CSSUnitValue.name);
-  assert_equals(entry.value[1].cssText, '60px');
+  assert_equals(entry.value[1].toString(), '60px');
 
   // This shouldn't appear in the iterator.
   testElement.style.borderTopWidth = '10px';
@@ -21,7 +21,7 @@
   entry = iterator.next();
   assert_equals(entry.value[0], 'border-left-width');
   assert_equals(entry.value[1].constructor.name, CSSUnitValue.name);
-  assert_equals(entry.value[1].cssText, '30px');
+  assert_equals(entry.value[1].toString(), '30px');
 
   assert_true(iterator.next().done);
 }, "Adding a property while iterating over entries() doesn't affect iterator");
@@ -32,14 +32,14 @@
   var iterator = testElement.styleMap.values();
   var entry = iterator.next();
   assert_equals(entry.value.constructor.name, CSSUnitValue.name);
-  assert_equals(entry.value.cssText, '60px');
+  assert_equals(entry.value.toString(), '60px');
 
   // This shouldn't appear in the iterator.
   testElement.style.borderTopWidth = '10px';
 
   entry = iterator.next();
   assert_equals(entry.value.constructor.name, CSSUnitValue.name);
-  assert_equals(entry.value.cssText, '30px');
+  assert_equals(entry.value.toString(), '30px');
 
   assert_true(iterator.next().done);
 }, "Adding a property while iterating over values() doesn't affect current iterator");
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_setGet.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_setGet.html
index f694fd8..f08f09c 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_setGet.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/inlineStylePropertyMap_setGet.html
@@ -8,19 +8,19 @@
 
 test(function() {
   testElement.styleMap.set('width', new CSSUnitValue(10, 'px'));
-  assert_equals(testElement.styleMap.get('width').cssText, '10px');
+  assert_equals(testElement.styleMap.get('width').toString(), '10px');
 }, "Setting and getting round trips");
 
 test(function() {
   testElement.styleMap.set('WIDTH', new CSSUnitValue(40, 'px'));
-  assert_equals(testElement.styleMap.get('WiDtH').cssText, '40px');
+  assert_equals(testElement.styleMap.get('WiDtH').toString(), '40px');
   testElement.styleMap.set('wIdTh', new CSSUnitValue(50, 'px'));
-  assert_equals(testElement.styleMap.get('width').cssText, '50px');
+  assert_equals(testElement.styleMap.get('width').toString(), '50px');
 }, "Setting and getting is not case sensitive");
 
 test(function() {
   testElement.style.width = '20px';
-  assert_equals(testElement.styleMap.get('width').cssText, '20px');
+  assert_equals(testElement.styleMap.get('width').toString(), '20px');
 }, "Changes to element.style are reflected in the element.styleMap");
 
 test(function() {
@@ -39,7 +39,7 @@
   assert_throws(new TypeError(), function() {
     testElement.styleMap.set('width', new CSSUnitValue(4, 'number'));
   });
-  assert_equals(testElement.styleMap.get('width').cssText, '2px');
+  assert_equals(testElement.styleMap.get('width').toString(), '2px');
 }, "Attempting to set an invalid type for a property does not change the value");
 
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/property-suite.js b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/property-suite.js
index a6e97ab..f16c85d9 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/property-suite.js
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/property-suite.js
@@ -92,12 +92,12 @@
     test(function() {
       element.style = '';
       element.styleMap.set(propertyName, validObject);
-      assert_equals(element.style[propertyName], validObject.cssText);
+      assert_equals(element.style[propertyName], validObject.toString());
       // Force a style recalc to check for crashes in style recalculation.
       getComputedStyle(element)[propertyName];
-      assert_equals(element.style[propertyName], validObject.cssText);
+      assert_equals(element.style[propertyName], validObject.toString());
     }, 'Setting ' + propertyName + ' to ' + validObject.constructor.name +
-        ' with value ' +  validObject.cssText);
+        ' with value ' +  validObject.toString());
   }
 
   // Negative tests
@@ -120,19 +120,19 @@
 
       let result = element.styleMap.get(propertyName);
       assert_equals(result.constructor.name, CSSKeywordValue.name);
-      assert_equals(result.cssText, keyword);
+      assert_equals(result.toString(), keyword);
     }, 'Getting ' + propertyName + ' when it is set to ' + keyword);
   }
   for (let validObject of validObjects) {
     test(function() {
-      element.style[propertyName] = validObject.cssText;
+      element.style[propertyName] = validObject.toString();
 
       let result = element.styleMap.get(propertyName);
       assert_equals(result.constructor.name, validObject.constructor.name,
           'typeof result');
-      assert_equals(result.cssText, validObject.cssText);
+      assert_equals(result.toString(), validObject.toString());
     }, 'Getting ' + propertyName + ' with a ' + validObject.constructor.name +
-        ' whose value is ' + validObject.cssText);
+        ' whose value is ' + validObject.toString());
   }
   for (let cssText in validStringMappings) {
     test(function() {
@@ -142,7 +142,7 @@
       assert_equals(result.constructor.name,
           validStringMappings[cssText].constructor.name,
           'typeof result');
-      assert_equals(result.cssText, validStringMappings[cssText].cssText);
+      assert_equals(result.toString(), validStringMappings[cssText].toString());
     }, 'Getting ' + propertyName + ' when it is set to "' +
         cssText + '" via a string');
   }
@@ -154,13 +154,13 @@
     element.style = '';
     element.styleMap.set(propertyName, [validObject, validObject]);
     assert_equals(
-        element.style[propertyName], validObject.cssText + ', ' +
-        validObject.cssText);
+        element.style[propertyName], validObject.toString() + ', ' +
+        validObject.toString());
     // Force a style recalc to check for crashes in style recalculation.
     getComputedStyle(element)[propertyName];
     assert_equals(
-        element.style[propertyName], validObject.cssText + ', ' +
-        validObject.cssText);
+        element.style[propertyName], validObject.toString() + ', ' +
+        validObject.toString());
   }, 'Set ' + propertyName + ' to a sequence');
 
   test(function() {
@@ -177,17 +177,17 @@
     element.style = '';
 
     element.styleMap.append(propertyName, validObject);
-    assert_equals(element.style[propertyName], validObject.cssText);
+    assert_equals(element.style[propertyName], validObject.toString());
 
     element.styleMap.append(propertyName, validObject);
     assert_equals(
-        element.style[propertyName], validObject.cssText + ', ' +
-        validObject.cssText);
+        element.style[propertyName], validObject.toString() + ', ' +
+        validObject.toString());
     // Force a style recalc to check for crashes in style recalculation.
     getComputedStyle(element)[propertyName];
     assert_equals(
-        element.style[propertyName], validObject.cssText + ', ' +
-        validObject.cssText);
+        element.style[propertyName], validObject.toString() + ', ' +
+        validObject.toString());
   }, 'Appending a ' + validObject.constructor.name + ' to ' + propertyName);
 
   test(function() {
@@ -195,13 +195,13 @@
 
     element.styleMap.append(propertyName, [validObject, validObject]);
     assert_equals(
-        element.style[propertyName], validObject.cssText + ', ' +
-        validObject.cssText);
+        element.style[propertyName], validObject.toString() + ', ' +
+        validObject.toString());
     // Force a style recalc to check for crashes in style recalculation.
     getComputedStyle(element)[propertyName];
     assert_equals(
-        element.style[propertyName], validObject.cssText + ', ' +
-        validObject.cssText);
+        element.style[propertyName], validObject.toString() + ', ' +
+        validObject.toString());
   }, 'Append a sequence to ' + propertyName);
 
   // Negative tests
@@ -225,14 +225,14 @@
     element.style = '';
     assert_array_equals(element.styleMap.getAll(propertyName), []);
 
-    element.style[propertyName] = validObject.cssText;
+    element.style[propertyName] = validObject.toString();
     let result = element.styleMap.getAll(propertyName);
     assert_equals(result.length, 1,
         'Expected getAll to retrieve an array containing a ' +
         'single CSSStyleValue');
     assert_equals(result[0].constructor.name, validObject.constructor.name,
         'Returned type is incorrect:');
-    assert_equals(result[0].cssText, validObject.cssText);
+    assert_equals(result[0].toString(), validObject.toString());
   }, 'getAll for single-valued ' + propertyName);
 
   if (supportsMultiple) {
@@ -245,15 +245,15 @@
           'of ' + validObject.constructor.name);
       assert_equals(result[0].constructor.name, validObject.constructor.name);
       assert_equals(result[1].constructor.name, validObject.constructor.name);
-      assert_equals(result[0].cssText, validObject.cssText);
-      assert_equals(result[1].cssText, validObject.cssText);
+      assert_equals(result[0].toString(), validObject.toString());
+      assert_equals(result[1].toString(), validObject.toString());
     }, 'getAll for list-valued ' + propertyName);
   }
 }
 
 function runDeletionTests(propertyName, validObject, element) {
   test(function() {
-    element.style[propertyName] = validObject.cssText;
+    element.style[propertyName] = validObject.toString();
 
     assert_not_equals(element.styleMap.get(propertyName), null);
 
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/transform.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/transform.html
index ad375fa..434eee75 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/transform.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/transform.html
@@ -117,7 +117,7 @@
   let result = testElement.styleMap.get('transform');
   assert_equals(result.constructor, CSSStyleValue,
       'result is a base CSSStyleValue');
-  assert_equals(result.cssText, 'rotate(calc(102.296deg))');
+  assert_equals(result.toString(), 'rotate(calc(102.296deg))');
 }, 'Getting transform when it has a rotate with a calc angle does not crash');
 
 test(function() {
@@ -125,25 +125,25 @@
   let result = testElement.styleMap.get('transform');
   assert_equals(result.constructor, CSSStyleValue,
       'result is a base CSSStyleValue');
-  assert_equals(result.cssText, 'rotate3d(1, 2, 3, calc(102.296deg))');
+  assert_equals(result.toString(), 'rotate3d(1, 2, 3, calc(102.296deg))');
 }, 'Getting transform when it has a rotate3d with a calc angle does not crash');
 
 test(function() {
   testElement.style.transform = 'skew(calc(5deg + 0.1rad))';
   let result = testElement.styleMap.get('transform');
-  assert_equals(result.cssText, 'skew(calc(10.7296deg))');
+  assert_equals(result.toString(), 'skew(calc(10.7296deg))');
   assert_equals(result.constructor,  CSSStyleValue);
 }, 'Getting transform when it has a skew with a calc angle does not crash');
 
 test(function() {
   testElement.style.transform = 'skew(calc(5deg + 0.1rad), 5deg)';
   let result = testElement.styleMap.get('transform');
-  assert_equals(result.cssText, 'skew(calc(10.7296deg), 5deg)');
+  assert_equals(result.toString(), 'skew(calc(10.7296deg), 5deg)');
   assert_equals(result.constructor,  CSSStyleValue);
 
   testElement.style.transform = 'skew(5deg, calc(5deg + 0.1rad))';
   result = testElement.styleMap.get('transform');
-  assert_equals(result.cssText, 'skew(5deg, calc(10.7296deg))');
+  assert_equals(result.toString(), 'skew(5deg, calc(10.7296deg))');
   assert_equals(result.constructor,  CSSStyleValue);
 }, 'Getting transform when it has a 2-argument skew with a calc angle ' +
    'does not crash');
@@ -151,14 +151,14 @@
 test(function() {
   testElement.style.transform = 'skewX(calc(5deg + 0.1rad))';
   let result = testElement.styleMap.get('transform');
-  assert_equals(result.cssText, 'skewX(calc(10.7296deg))');
+  assert_equals(result.toString(), 'skewX(calc(10.7296deg))');
   assert_equals(result.constructor,  CSSStyleValue);
 }, 'Getting transform when it has a skewX with a calc angle does not crash');
 
 test(function() {
   testElement.style.transform = 'skewY(calc(5deg + 0.1rad))';
   let result = testElement.styleMap.get('transform');
-  assert_equals(result.cssText, 'skewY(calc(10.7296deg))');
+  assert_equals(result.toString(), 'skewY(calc(10.7296deg))');
   assert_equals(result.constructor,  CSSStyleValue);
 }, 'Getting transform when it has a skewY with a calc angle does not crash');
 
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-perspective.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-perspective.html
index c4923a9..0757133 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-perspective.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-perspective.html
@@ -29,7 +29,7 @@
     testElement.style.transform = cssText;
 
     var result = testElement.styleMap.get('transform');
-    assert_equals(result.cssText, cssText);
+    assert_equals(result.toString(), cssText);
     assert_equals(result.constructor.name, CSSTransformValue.name);
 
     var components = [...result.values()];
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-scale.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-scale.html
index 3e2d599..72b2caf 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-scale.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/transform-scale.html
@@ -6,7 +6,7 @@
 var EPSILON = 1e-6; // float epsilon
 
 function validateTransformWithSingleScale(transform, x, y, z, cssText) {
-  assert_equals(transform.cssText, cssText);
+  assert_equals(transform.toString(), cssText);
 
   // Shouldn't be base StyleValue as for unsupported values.
   assert_equals(transform.constructor.name, CSSTransformValue.name);
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/unsupported-properties.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/unsupported-properties.html
index 948d002..b8fae9f 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/unsupported-properties.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/unsupported-properties.html
@@ -16,8 +16,8 @@
 
   var result = testElement.styleMap.get('background-color');
   assert_equals(result.constructor, CSSStyleValue);
-  assert_equals(result.cssText, 'rgb(0, 255, 0)');
-}, 'Unsupported property returns a base StyleValue with the correct cssText.');
+  assert_equals(result.toString(), 'rgb(0, 255, 0)');
+}, 'Unsupported property returns a base StyleValue with the correct toString().');
 
 test(function() {
   testElement.style.backgroundColor = '#00FF00';
@@ -26,7 +26,7 @@
 
   var result = secondElement.styleMap.get('background-color');
   assert_equals(result.constructor, CSSStyleValue);
-  assert_equals(result.cssText, 'rgb(0, 255, 0)');
+  assert_equals(result.toString(), 'rgb(0, 255, 0)');
 }, 'Setting the same property using the result of getting an unknown value works');
 
 test(function() {
@@ -36,7 +36,7 @@
 
   var result = secondElement.styleMap.get('border-left-color');
   assert_equals(result.constructor, CSSStyleValue);
-  assert_equals(result.cssText, 'rgb(0, 255, 0)');
+  assert_equals(result.toString(), 'rgb(0, 255, 0)');
 }, 'Setting a different property using the result of getting an unknown value works');
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/styleValue-stringifier-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/styleValue-stringifier-expected.txt
new file mode 100644
index 0000000..2861e3d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/styleValue-stringifier-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS Style value with type CSSKeywordValuewith value "initial" serializes correctly 
+PASS Style value with type CSSUnitValuewith value "10px" serializes correctly 
+FAIL Style value with type CSSTransformValuewith value "rotate(10deg)" serializes correctly assert_equals: expected "rotate(10deg)" but got ""
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/typedcssom/styleValue-stringifier.html b/third_party/WebKit/LayoutTests/typedcssom/styleValue-stringifier.html
new file mode 100644
index 0000000..b77c0f7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/styleValue-stringifier.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<script src='../resources/testharness.js'></script>
+<script src='../resources/testharnessreport.js'></script>
+<script>
+
+var styleValues = {
+  // TODO(meade): Add each CSSStyleValue type here.
+  'initial': new CSSKeywordValue('initial'),
+  '10px': new CSSUnitValue(10, 'px'),
+  'rotate(10deg)': new CSSTransformValue(
+      [new CSSRotation(new CSSUnitValue(10, 'deg'))]),
+};
+
+for (var cssText in styleValues) {
+  test(function() {
+    assert_equals(styleValues[cssText].toString(), cssText);
+    assert_equals(styleValues[cssText].toString(), cssText);
+  }, 'Style value with type ' + styleValues[cssText].constructor.name +
+      'with value "' + cssText + '" serializes correctly');
+}
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
index 8f6fc9f..c40dfa5 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
@@ -745,8 +745,8 @@
 interface CSSStyleValue
     static method parse
     attribute @@toStringTag
-    getter cssText
     method constructor
+    method toString
 interface CSSSupportsRule : CSSConditionRule
     attribute @@toStringTag
     method constructor
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 3f564ad..5645069 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -745,8 +745,8 @@
 interface CSSStyleValue
     static method parse
     attribute @@toStringTag
-    getter cssText
     method constructor
+    method toString
 interface CSSSupportsRule : CSSConditionRule
     attribute @@toStringTag
     method constructor
diff --git a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
index 6ebe78f..44ec192 100644
--- a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
+++ b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
@@ -54,7 +54,6 @@
 DoNotCheckConstants
 DoNotTestNewObject
 EnforceRange
-ExperimentalCallbackFunction
 Exposed=*
 FeaturePolicy=*
 FlexibleArrayBufferView
diff --git a/third_party/WebKit/Source/bindings/core/v8/V0CustomElementConstructorBuilder.cpp b/third_party/WebKit/Source/bindings/core/v8/V0CustomElementConstructorBuilder.cpp
index 11eb8416..906e5c5 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V0CustomElementConstructorBuilder.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V0CustomElementConstructorBuilder.cpp
@@ -343,7 +343,7 @@
                                  "CustomElement");
   V0CustomElementProcessingStack::CallbackDeliveryScope delivery_scope;
   Element* element = document->createElementNS(
-      nullptr, namespace_uri, tag_name,
+      namespace_uri, tag_name,
       StringOrDictionary::fromString(maybe_type->IsNull() ? g_null_atom : type),
       exception_state);
   if (element) {
diff --git a/third_party/WebKit/Source/bindings/modules/v8/generated.gni b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
index e0f7507..fda0235 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/generated.gni
+++ b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
@@ -73,6 +73,8 @@
 ]
 
 generated_modules_callback_function_files = [
+  "$bindings_modules_v8_output_dir/DatabaseCallback.cpp",
+  "$bindings_modules_v8_output_dir/DatabaseCallback.h",
   "$bindings_modules_v8_output_dir/IDBObserverCallback.cpp",
   "$bindings_modules_v8_output_dir/IDBObserverCallback.h",
   "$bindings_modules_v8_output_dir/MediaSessionActionHandler.cpp",
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_callback_function.py b/third_party/WebKit/Source/bindings/scripts/v8_callback_function.py
index 4a0cd8c..1641d10b 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_callback_function.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_callback_function.py
@@ -20,6 +20,7 @@
 CALLBACK_FUNCTION_CPP_INCLUDES = frozenset([
     'bindings/core/v8/ExceptionState.h',
     'platform/bindings/ScriptState.h',
+    'bindings/core/v8/NativeValueTraitsImpl.h',
     'bindings/core/v8/ToV8ForCore.h',
     'bindings/core/v8/V8BindingForCore.h',
     'core/dom/ExecutionContext.h',
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/AnyCallbackFunctionOptionalAnyArg.cpp b/third_party/WebKit/Source/bindings/tests/results/core/AnyCallbackFunctionOptionalAnyArg.cpp
index c28a203a..0654295b5 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/AnyCallbackFunctionOptionalAnyArg.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/AnyCallbackFunctionOptionalAnyArg.cpp
@@ -13,6 +13,7 @@
 #include "AnyCallbackFunctionOptionalAnyArg.h"
 
 #include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/ScriptValue.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunction.cpp b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunction.cpp
index 0263298..d03a9a7 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunction.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunction.cpp
@@ -13,6 +13,7 @@
 #include "VoidCallbackFunction.h"
 
 #include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "core/dom/ExecutionContext.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionInterfaceArg.cpp b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionInterfaceArg.cpp
index 37706f4..6d583ef 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionInterfaceArg.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/VoidCallbackFunctionInterfaceArg.cpp
@@ -13,6 +13,7 @@
 #include "VoidCallbackFunctionInterfaceArg.h"
 
 #include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8HTMLDivElement.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/VoidCallbackFunctionModules.cpp b/third_party/WebKit/Source/bindings/tests/results/modules/VoidCallbackFunctionModules.cpp
index 73202cf5..a9d5082 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/VoidCallbackFunctionModules.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/VoidCallbackFunctionModules.cpp
@@ -13,6 +13,7 @@
 #include "VoidCallbackFunctionModules.h"
 
 #include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "core/dom/ExecutionContext.h"
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 58367eb..2b586df 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -457,6 +457,7 @@
     "$blink_core_output_dir/css/properties/CSSPropertyAPIAlignItems.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIAlignOrJustifyContent.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIAlignOrJustifySelf.h",
+    "$blink_core_output_dir/css/properties/CSSPropertyAPIAnimationName.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIBaselineShift.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIBorderImageOutset.h",
     "$blink_core_output_dir/css/properties/CSSPropertyAPIBorderImageRepeat.h",
diff --git a/third_party/WebKit/Source/core/animation/BUILD.gn b/third_party/WebKit/Source/core/animation/BUILD.gn
index 5bf65dd6..cbf02c6f 100644
--- a/third_party/WebKit/Source/core/animation/BUILD.gn
+++ b/third_party/WebKit/Source/core/animation/BUILD.gn
@@ -97,6 +97,9 @@
     "ColorPropertyFunctions.h",
     "CompositorAnimations.cpp",
     "CompositorAnimations.h",
+    "CompositorAnimator.h",
+    "CompositorMutatorImpl.cpp",
+    "CompositorMutatorImpl.h",
     "CompositorPendingAnimations.cpp",
     "CompositorPendingAnimations.h",
     "CustomCompositorAnimationManager.cpp",
diff --git a/third_party/WebKit/Source/web/CompositorAnimator.h b/third_party/WebKit/Source/core/animation/CompositorAnimator.h
similarity index 87%
rename from third_party/WebKit/Source/web/CompositorAnimator.h
rename to third_party/WebKit/Source/core/animation/CompositorAnimator.h
index b7efa56..e613e3a1 100644
--- a/third_party/WebKit/Source/web/CompositorAnimator.h
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimator.h
@@ -5,12 +5,13 @@
 #ifndef CompositorAnimator_h
 #define CompositorAnimator_h
 
+#include "core/CoreExport.h"
 #include "platform/graphics/CompositorMutableStateProvider.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
 
-class CompositorAnimator : public GarbageCollectedMixin {
+class CORE_EXPORT CompositorAnimator : public GarbageCollectedMixin {
  public:
   // Runs the animation frame callback for the frame starting at the given time.
   // Returns true if another animation frame was requested (i.e. should be
diff --git a/third_party/WebKit/Source/web/CompositorMutatorImpl.cpp b/third_party/WebKit/Source/core/animation/CompositorMutatorImpl.cpp
similarity index 96%
rename from third_party/WebKit/Source/web/CompositorMutatorImpl.cpp
rename to third_party/WebKit/Source/core/animation/CompositorMutatorImpl.cpp
index ff18628f..b81dbbc 100644
--- a/third_party/WebKit/Source/web/CompositorMutatorImpl.cpp
+++ b/third_party/WebKit/Source/core/animation/CompositorMutatorImpl.cpp
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "web/CompositorMutatorImpl.h"
+#include "core/animation/CompositorMutatorImpl.h"
 
+#include "core/animation/CompositorAnimator.h"
 #include "core/animation/CustomCompositorAnimationManager.h"
 #include "core/dom/CompositorProxy.h"
 #include "platform/CrossThreadFunctional.h"
@@ -14,7 +15,6 @@
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/wtf/PtrUtil.h"
 #include "public/platform/Platform.h"
-#include "web/CompositorAnimator.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/web/CompositorMutatorImpl.h b/third_party/WebKit/Source/core/animation/CompositorMutatorImpl.h
similarity index 95%
rename from third_party/WebKit/Source/web/CompositorMutatorImpl.h
rename to third_party/WebKit/Source/core/animation/CompositorMutatorImpl.h
index ffa70007..8ec8fcc 100644
--- a/third_party/WebKit/Source/web/CompositorMutatorImpl.h
+++ b/third_party/WebKit/Source/core/animation/CompositorMutatorImpl.h
@@ -25,7 +25,7 @@
 //
 // Owned by the control thread (unless threaded compositing is disabled).
 // Should be accessed only on the compositor thread.
-class CompositorMutatorImpl final : public CompositorMutator {
+class CORE_EXPORT CompositorMutatorImpl final : public CompositorMutator {
   WTF_MAKE_NONCOPYABLE(CompositorMutatorImpl);
 
  public:
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index 3a6467c..df0bb61b 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -378,6 +378,7 @@
     "properties/CSSPropertyAPIAlignItems.cpp",
     "properties/CSSPropertyAPIAlignOrJustifyContent.cpp",
     "properties/CSSPropertyAPIAlignOrJustifySelf.cpp",
+    "properties/CSSPropertyAPIAnimationName.cpp",
     "properties/CSSPropertyAPIBaselineShift.cpp",
     "properties/CSSPropertyAPIBorderImageOutset.cpp",
     "properties/CSSPropertyAPIBorderImageRepeat.cpp",
@@ -489,6 +490,8 @@
     "properties/CSSPropertyAPIZoom.cpp",
     "properties/CSSPropertyAlignmentUtils.cpp",
     "properties/CSSPropertyAlignmentUtils.h",
+    "properties/CSSPropertyAnimationNameUtils.cpp",
+    "properties/CSSPropertyAnimationNameUtils.h",
     "properties/CSSPropertyColumnUtils.cpp",
     "properties/CSSPropertyColumnUtils.h",
     "properties/CSSPropertyCounterUtils.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index 2ce9f012..2fee1825 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -1066,25 +1066,25 @@
 inline CSSIdentifierValue::CSSIdentifierValue(TextAlignLast e)
     : CSSValue(kIdentifierClass) {
   switch (e) {
-    case kTextAlignLastStart:
+    case TextAlignLast::kStart:
       value_id_ = CSSValueStart;
       break;
-    case kTextAlignLastEnd:
+    case TextAlignLast::kEnd:
       value_id_ = CSSValueEnd;
       break;
-    case kTextAlignLastLeft:
+    case TextAlignLast::kLeft:
       value_id_ = CSSValueLeft;
       break;
-    case kTextAlignLastRight:
+    case TextAlignLast::kRight:
       value_id_ = CSSValueRight;
       break;
-    case kTextAlignLastCenter:
+    case TextAlignLast::kCenter:
       value_id_ = CSSValueCenter;
       break;
-    case kTextAlignLastJustify:
+    case TextAlignLast::kJustify:
       value_id_ = CSSValueJustify;
       break;
-    case kTextAlignLastAuto:
+    case TextAlignLast::kAuto:
       value_id_ = CSSValueAuto;
       break;
   }
@@ -1094,25 +1094,25 @@
 inline TextAlignLast CSSIdentifierValue::ConvertTo() const {
   switch (value_id_) {
     case CSSValueAuto:
-      return kTextAlignLastAuto;
+      return TextAlignLast::kAuto;
     case CSSValueStart:
-      return kTextAlignLastStart;
+      return TextAlignLast::kStart;
     case CSSValueEnd:
-      return kTextAlignLastEnd;
+      return TextAlignLast::kEnd;
     case CSSValueLeft:
-      return kTextAlignLastLeft;
+      return TextAlignLast::kLeft;
     case CSSValueRight:
-      return kTextAlignLastRight;
+      return TextAlignLast::kRight;
     case CSSValueCenter:
-      return kTextAlignLastCenter;
+      return TextAlignLast::kCenter;
     case CSSValueJustify:
-      return kTextAlignLastJustify;
+      return TextAlignLast::kJustify;
     default:
       break;
   }
 
   NOTREACHED();
-  return kTextAlignLastAuto;
+  return TextAlignLast::kAuto;
 }
 
 template <>
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index c0d189ac..8c2b6e3 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -322,6 +322,8 @@
     },
     {
       name: "animation-name",
+      api_class: true,
+      api_methods: ["parseSingleValue"],
       custom_all: true,
       priority: "Animation",
     },
@@ -2015,7 +2017,7 @@
       inherited: true,
       field_template: "storage_only",
       type_name: "TextAlignLast",
-      default_value: "kTextAlignLastAuto",
+      default_value: "TextAlignLast::kAuto",
       field_size: 3,
       field_group: "rare-inherited",
     },
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h
index b97ab66a..b14739a 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h
@@ -54,7 +54,7 @@
   virtual const CSSValue* ToCSSValueWithProperty(CSSPropertyID) const {
     return ToCSSValue();
   }
-  virtual String cssText() const {
+  virtual String toString() const {
     const CSSValue* result = ToCSSValue();
     // TODO(meade): Remove this once all the number and length types are
     // rewritten.
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.idl b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.idl
index e23c654..582f76d7 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.idl
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.idl
@@ -7,10 +7,10 @@
 // base CSSStyleValues.
 // Spec: https://drafts.css-houdini.org/css-typed-om/#stylevalue-objects
 [
-    Exposed=(Window,PaintWorklet),
-    RuntimeEnabled=CSSTypedOM,
+  Exposed=(Window,PaintWorklet),
+  RuntimeEnabled=CSSTypedOM,
 ] interface CSSStyleValue {
-    readonly attribute DOMString cssText;
-    // TODO(meade): Should be (CSSStyleValue or sequence<CSSStyleValue>)? instead of object?. Fix when the code generator supports this.
-    [RaisesException, CallWith=ScriptState] static object? parse(DOMString property, DOMString cssText);
+  stringifier;
+  // TODO(meade): Should be (CSSStyleValue or sequence<CSSStyleValue>)? instead of object?. Fix when the code generator supports this.
+  [RaisesException, CallWith=ScriptState] static object? parse(DOMString property, DOMString cssText);
 };
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSURLImageValue.idl b/third_party/WebKit/Source/core/css/cssom/CSSURLImageValue.idl
index 97280b1..7798570 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSURLImageValue.idl
+++ b/third_party/WebKit/Source/core/css/cssom/CSSURLImageValue.idl
@@ -5,7 +5,7 @@
 // Represents image values that are specified using "url(...)".
 // Spec: https://drafts.css-houdini.org/css-typed-om/#cssurlimagevalue
 [
-    Constructor(DOMString url),
+    Constructor(USVString url),
     Exposed=(Window,PaintWorklet),
     RuntimeEnabled=CSSTypedOM
 ] interface CSSURLImageValue : CSSImageValue {
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.h b/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.h
index ef6dca71..2c94926 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.h
@@ -23,7 +23,7 @@
   StyleValueType GetType() const override { return StyleValueType::kUnknown; }
   const CSSValue* ToCSSValue() const override;
   const CSSValue* ToCSSValueWithProperty(CSSPropertyID) const override;
-  String cssText() const override { return css_text_; }
+  String toString() const override { return css_text_; }
 
  private:
   CSSUnsupportedStyleValue(const String& css_text) : css_text_(css_text) {}
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 43e2c01..5270cc2c 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -42,6 +42,7 @@
 #include "core/css/parser/FontVariantNumericParser.h"
 #include "core/css/properties/CSSPropertyAPI.h"
 #include "core/css/properties/CSSPropertyAlignmentUtils.h"
+#include "core/css/properties/CSSPropertyAnimationNameUtils.h"
 #include "core/css/properties/CSSPropertyColumnUtils.h"
 #include "core/css/properties/CSSPropertyDescriptor.h"
 #include "core/css/properties/CSSPropertyFontUtils.h"
@@ -331,25 +332,6 @@
   return ConsumeNumber(range, kValueRangeNonNegative);
 }
 
-static CSSValue* ConsumeAnimationName(CSSParserTokenRange& range,
-                                      const CSSParserContext* context,
-                                      bool allow_quoted_name) {
-  if (range.Peek().Id() == CSSValueNone)
-    return ConsumeIdent(range);
-
-  if (allow_quoted_name && range.Peek().GetType() == kStringToken) {
-    // Legacy support for strings in prefixed animations.
-    context->Count(UseCounter::kQuotedAnimationName);
-
-    const CSSParserToken& token = range.ConsumeIncludingWhitespace();
-    if (EqualIgnoringASCIICase(token.Value(), "none"))
-      return CSSIdentifierValue::Create(CSSValueNone);
-    return CSSCustomIdentValue::Create(token.Value().ToAtomicString());
-  }
-
-  return ConsumeCustomIdent(range);
-}
-
 static CSSValue* ConsumeTransitionProperty(CSSParserTokenRange& range) {
   const CSSParserToken& token = range.Peek();
   if (token.GetType() != kIdentToken)
@@ -479,7 +461,8 @@
     case CSSPropertyAnimationIterationCount:
       return ConsumeAnimationIterationCount(range);
     case CSSPropertyAnimationName:
-      return ConsumeAnimationName(range, context, use_legacy_parsing);
+      return CSSPropertyAnimationNameUtils::ConsumeAnimationName(
+          range, context, use_legacy_parsing);
     case CSSPropertyAnimationPlayState:
       return ConsumeIdent<CSSValueRunning, CSSValuePaused>(range);
     case CSSPropertyTransitionProperty:
@@ -1689,10 +1672,6 @@
           range_);
     case CSSPropertyAnimationIterationCount:
       return ConsumeCommaSeparatedList(ConsumeAnimationIterationCount, range_);
-    case CSSPropertyAnimationName:
-      return ConsumeCommaSeparatedList(
-          ConsumeAnimationName, range_, context_,
-          unresolved_property == CSSPropertyAliasWebkitAnimationName);
     case CSSPropertyAnimationPlayState:
       return ConsumeCommaSeparatedList(
           ConsumeIdent<CSSValueRunning, CSSValuePaused>, range_);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAnimationName.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAnimationName.cpp
new file mode 100644
index 0000000..bd63423
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIAnimationName.cpp
@@ -0,0 +1,25 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSPropertyAPIAnimationName.h"
+
+#include "core/css/parser/CSSParserLocalContext.h"
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+#include "core/css/properties/CSSPropertyAnimationNameUtils.h"
+
+class CSSParserContext;
+
+namespace blink {
+
+const CSSValue* CSSPropertyAPIAnimationName::parseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    const CSSParserLocalContext& local_context) {
+  // Allow quoted name if this is an alias property.
+  return CSSPropertyParserHelpers::ConsumeCommaSeparatedList(
+      CSSPropertyAnimationNameUtils::ConsumeAnimationName, range, &context,
+      local_context.GetUseAliasParsing());
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationNameUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationNameUtils.cpp
new file mode 100644
index 0000000..074d4dcf
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationNameUtils.cpp
@@ -0,0 +1,32 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSPropertyAnimationNameUtils.h"
+
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+#include "core/frame/UseCounter.h"
+
+namespace blink {
+
+CSSValue* CSSPropertyAnimationNameUtils::ConsumeAnimationName(
+    CSSParserTokenRange& range,
+    const CSSParserContext* context,
+    bool allow_quoted_name) {
+  if (range.Peek().Id() == CSSValueNone)
+    return CSSPropertyParserHelpers::ConsumeIdent(range);
+
+  if (allow_quoted_name && range.Peek().GetType() == kStringToken) {
+    // Legacy support for strings in prefixed animations.
+    context->Count(UseCounter::kQuotedAnimationName);
+
+    const CSSParserToken& token = range.ConsumeIncludingWhitespace();
+    if (EqualIgnoringASCIICase(token.Value(), "none"))
+      return CSSIdentifierValue::Create(CSSValueNone);
+    return CSSCustomIdentValue::Create(token.Value().ToAtomicString());
+  }
+
+  return CSSPropertyParserHelpers::ConsumeCustomIdent(range);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationNameUtils.h b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationNameUtils.h
new file mode 100644
index 0000000..f471f8a
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAnimationNameUtils.h
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSSPropertyAnimationNameUtils_h
+#define CSSPropertyAnimationNameUtils_h
+
+#include "core/css/parser/CSSParserContext.h"
+#include "platform/wtf/Allocator.h"
+
+namespace blink {
+
+class CSSParserTokenRange;
+class CSSValue;
+
+class CSSPropertyAnimationNameUtils {
+  STATIC_ONLY(CSSPropertyAnimationNameUtils);
+
+  static CSSValue* ConsumeAnimationName(CSSParserTokenRange&,
+                                        const CSSParserContext*,
+                                        bool allow_quoted_name);
+};
+
+}  // namespace blink
+
+#endif  // CSSPropertyAnimationNameUtils_h
diff --git a/third_party/WebKit/Source/core/dom/DOMImplementation.cpp b/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
index 372b21d4..279597f 100644
--- a/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
+++ b/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
@@ -77,7 +77,6 @@
 }
 
 XMLDocument* DOMImplementation::createDocument(
-    const LocalDOMWindow* window,
     const AtomicString& namespace_uri,
     const AtomicString& qualified_name,
     DocumentType* doctype,
@@ -99,8 +98,8 @@
 
   Node* document_element = nullptr;
   if (!qualified_name.IsEmpty()) {
-    document_element = doc->createElementNS(window, namespace_uri,
-                                            qualified_name, exception_state);
+    document_element =
+        doc->createElementNS(namespace_uri, qualified_name, exception_state);
     if (exception_state.HadException())
       return nullptr;
   }
diff --git a/third_party/WebKit/Source/core/dom/DOMImplementation.h b/third_party/WebKit/Source/core/dom/DOMImplementation.h
index d8534d6..0fde0fda8 100644
--- a/third_party/WebKit/Source/core/dom/DOMImplementation.h
+++ b/third_party/WebKit/Source/core/dom/DOMImplementation.h
@@ -34,7 +34,6 @@
 class DocumentType;
 class ExceptionState;
 class HTMLDocument;
-class LocalDOMWindow;
 class XMLDocument;
 
 class CORE_EXPORT DOMImplementation final
@@ -55,8 +54,7 @@
                                    const String& public_id,
                                    const String& system_id,
                                    ExceptionState&);
-  XMLDocument* createDocument(const LocalDOMWindow*,
-                              const AtomicString& namespace_uri,
+  XMLDocument* createDocument(const AtomicString& namespace_uri,
                               const AtomicString& qualified_name,
                               DocumentType*,
                               ExceptionState&);
diff --git a/third_party/WebKit/Source/core/dom/DOMImplementation.idl b/third_party/WebKit/Source/core/dom/DOMImplementation.idl
index a7c41a1..cd19db5 100644
--- a/third_party/WebKit/Source/core/dom/DOMImplementation.idl
+++ b/third_party/WebKit/Source/core/dom/DOMImplementation.idl
@@ -24,8 +24,7 @@
     DependentLifetime,
 ] interface DOMImplementation {
     [NewObject, RaisesException] DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
-    // TODO(dominicc): Remove CallWith= when crbug/648179 is fixed.
-    [CallWith=EnteredWindow, NewObject, RaisesException] XMLDocument createDocument(DOMString? namespaceURI, [TreatNullAs=EmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
+    [NewObject, RaisesException] XMLDocument createDocument(DOMString? namespaceURI, [TreatNullAs=EmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
     // FIXME: createHTMLDocument should return a Document. crbug.com/238368
     // FIXME: The title argument should not have a default value. crbug.com/335871
     [NewObject] HTMLDocument createHTMLDocument(optional DOMString title = null);
diff --git a/third_party/WebKit/Source/core/dom/DOMTokenList.cpp b/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
index 11dbfc79..60e9c7f6f 100644
--- a/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
+++ b/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
@@ -126,29 +126,44 @@
   RemoveTokens(tokens);
 }
 
+// https://dom.spec.whatwg.org/#dom-domtokenlist-toggle
 bool DOMTokenList::toggle(const AtomicString& token,
                           ExceptionState& exception_state) {
   if (!ValidateToken(token, exception_state))
     return false;
 
+  // 4. If context object’s token set[token] exists, then:
   if (contains(token)) {
-    RemoveInternal(token);
+    // 1. If force is either not given or is false, then remove token from
+    // context object’s token set.
+    RemoveTokens(Vector<String>({token}));
     return false;
   }
-  AddInternal(token);
+  // 5. Otherwise, if force not given or is true, append token to context
+  // object’s token set and set result to true.
+  AddTokens(Vector<String>({token}));
   return true;
 }
 
+// https://dom.spec.whatwg.org/#dom-domtokenlist-toggle
 bool DOMTokenList::toggle(const AtomicString& token,
                           bool force,
                           ExceptionState& exception_state) {
   if (!ValidateToken(token, exception_state))
     return false;
 
-  if (force)
-    AddInternal(token);
-  else
-    RemoveInternal(token);
+  // 4. If context object’s token set[token] exists, then:
+  if (contains(token)) {
+    // 1. If force is either not given or is false, then remove token from
+    // context object’s token set.
+    if (!force)
+      RemoveTokens(Vector<String>({token}));
+  } else {
+    // 5. Otherwise, if force not given or is true, append token to context
+    // object’s token set and set result to true.
+    if (force)
+      AddTokens(Vector<String>({token}));
+  }
 
   return force;
 }
@@ -158,23 +173,6 @@
   return ValidateTokenValue(token, exception_state);
 }
 
-void DOMTokenList::AddInternal(const AtomicString& token) {
-  if (contains(token))
-    return;
-  Vector<String> tokens;
-  tokens.push_back(token.GetString());
-  AddTokens(tokens);
-}
-
-void DOMTokenList::RemoveInternal(const AtomicString& token) {
-  // Check using contains first to skip unnecessary reserialization.
-  if (!contains(token))
-    return;
-  Vector<String> tokens;
-  tokens.push_back(token.GetString());
-  RemoveTokens(tokens);
-}
-
 // https://dom.spec.whatwg.org/#dom-domtokenlist-add
 void DOMTokenList::AddTokens(const Vector<String>& tokens) {
   // 2. For each token in tokens, append token to context object’s token set.
diff --git a/third_party/WebKit/Source/core/dom/DOMTokenList.h b/third_party/WebKit/Source/core/dom/DOMTokenList.h
index f494264..ed19f01 100644
--- a/third_party/WebKit/Source/core/dom/DOMTokenList.h
+++ b/third_party/WebKit/Source/core/dom/DOMTokenList.h
@@ -78,8 +78,6 @@
   DOMTokenList(Element& element, const QualifiedName& attr)
       : element_(element), attribute_name_(attr) {}
   Element& GetElement() const { return *element_; }
-  void AddInternal(const AtomicString&);
-  void RemoveInternal(const AtomicString&);
 
   bool ValidateToken(const String&, ExceptionState&) const;
   bool ValidateTokens(const Vector<String>&, ExceptionState&) const;
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 92c8598..fb19b475 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -410,12 +410,14 @@
 // Tests whether |name| is a valid name per DOM spec. Also checks
 // whether the HTML parser would accept this element name and counts
 // cases of mismatches.
-static bool IsValidElementName(const LocalDOMWindow* window,
-                               const String& name) {
+static bool IsValidElementName(Document* document, const String& name) {
   bool is_valid_dom_name = Document::IsValidName(name);
   bool is_valid_html_name = IsValidElementNamePerHTMLParser(name);
-  if (UNLIKELY(is_valid_html_name != is_valid_dom_name && window)) {
-    UseCounter::Count(window->GetFrame(),
+  if (UNLIKELY(is_valid_html_name != is_valid_dom_name)) {
+    // This is inaccurate because it will not report activity in
+    // detached documents. However retrieving the frame from the
+    // bindings is too slow.
+    UseCounter::Count(document,
                       is_valid_dom_name
                           ? UseCounter::kElementNameDOMValidHTMLParserInvalid
                           : UseCounter::kElementNameDOMInvalidHTMLParserValid);
@@ -751,10 +753,9 @@
 }
 
 // https://dom.spec.whatwg.org/#dom-document-createelement
-Element* Document::createElement(const LocalDOMWindow* window,
-                                 const AtomicString& name,
+Element* Document::createElement(const AtomicString& name,
                                  ExceptionState& exception_state) {
-  if (!IsValidElementName(window, name)) {
+  if (!IsValidElementName(this, name)) {
     exception_state.ThrowDOMException(
         kInvalidCharacterError,
         "The tag name provided ('" + name + "') is not a valid name.");
@@ -804,12 +805,11 @@
 }
 
 // https://dom.spec.whatwg.org/#dom-document-createelement
-Element* Document::createElement(const LocalDOMWindow* window,
-                                 const AtomicString& local_name,
+Element* Document::createElement(const AtomicString& local_name,
                                  const StringOrDictionary& string_or_options,
                                  ExceptionState& exception_state) {
   // 1. If localName does not match Name production, throw InvalidCharacterError
-  if (!IsValidElementName(window, local_name)) {
+  if (!IsValidElementName(this, local_name)) {
     exception_state.ThrowDOMException(
         kInvalidCharacterError,
         "The tag name provided ('" + local_name + "') is not a valid name.");
@@ -865,7 +865,7 @@
         *this,
         QualifiedName(g_null_atom, converted_local_name, xhtmlNamespaceURI));
   } else {
-    element = createElement(window, local_name, exception_state);
+    element = createElement(local_name, exception_state);
     if (exception_state.HadException())
       return nullptr;
   }
@@ -905,8 +905,7 @@
   return q_name;
 }
 
-Element* Document::createElementNS(const LocalDOMWindow* window,
-                                   const AtomicString& namespace_uri,
+Element* Document::createElementNS(const AtomicString& namespace_uri,
                                    const AtomicString& qualified_name,
                                    ExceptionState& exception_state) {
   QualifiedName q_name(
@@ -920,8 +919,7 @@
 }
 
 // https://dom.spec.whatwg.org/#internal-createelementns-steps
-Element* Document::createElementNS(const LocalDOMWindow* window,
-                                   const AtomicString& namespace_uri,
+Element* Document::createElementNS(const AtomicString& namespace_uri,
                                    const AtomicString& qualified_name,
                                    const StringOrDictionary& string_or_options,
                                    ExceptionState& exception_state) {
@@ -943,7 +941,7 @@
       AtomicString(GetTypeExtension(this, string_or_options, exception_state));
   const AtomicString& name = should_create_builtin ? is : qualified_name;
 
-  if (!IsValidElementName(window, qualified_name)) {
+  if (!IsValidElementName(this, qualified_name)) {
     exception_state.ThrowDOMException(
         kInvalidCharacterError, "The tag name provided ('" + qualified_name +
                                     "') is not a valid name.");
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 1b4703b..eb72c7c 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -322,9 +322,6 @@
 
   Location* location() const;
 
-  Element* createElement(const LocalDOMWindow*,
-                         const AtomicString& name,
-                         ExceptionState&);
   DocumentFragment* createDocumentFragment();
   Text* createTextNode(const String& data);
   Comment* createComment(const String& data);
@@ -338,8 +335,7 @@
                           ExceptionState&,
                           bool should_ignore_namespace_checks = false);
   Node* importNode(Node* imported_node, bool deep, ExceptionState&);
-  Element* createElementNS(const LocalDOMWindow*,
-                           const AtomicString& namespace_uri,
+  Element* createElementNS(const AtomicString& namespace_uri,
                            const AtomicString& qualified_name,
                            ExceptionState&);
   Element* createElement(const QualifiedName&, CreateElementFlags);
@@ -1150,17 +1146,12 @@
 
   TextAutosizer* GetTextAutosizer();
 
-  Element* createElement(
-      const AtomicString& local_name,
-      ExceptionState& exception_state = ASSERT_NO_EXCEPTION) {
-    return createElement(nullptr, local_name, exception_state);
-  }
-  Element* createElement(const LocalDOMWindow*,
-                         const AtomicString& local_name,
+  Element* createElement(const AtomicString& local_name,
+                         ExceptionState& = ASSERT_NO_EXCEPTION);
+  Element* createElement(const AtomicString& local_name,
                          const StringOrDictionary&,
                          ExceptionState& = ASSERT_NO_EXCEPTION);
-  Element* createElementNS(const LocalDOMWindow*,
-                           const AtomicString& namespace_uri,
+  Element* createElementNS(const AtomicString& namespace_uri,
                            const AtomicString& qualified_name,
                            const StringOrDictionary&,
                            ExceptionState&);
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl
index 48f4f0c..87c2fc6 100644
--- a/third_party/WebKit/Source/core/dom/Document.idl
+++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -57,10 +57,8 @@
     HTMLCollection getElementsByTagNameNS(DOMString? namespaceURI, DOMString localName);
     HTMLCollection getElementsByClassName(DOMString classNames);
 
-    // TODO(dominicc): Remove CallWith= when crbug/648179 is fixed.
-    [CallWith=EnteredWindow, NewObject, DoNotTestNewObject, CustomElementCallbacks, PerWorldBindings, RaisesException] Element createElement(DOMString localName);
-    // TODO(dominicc): Remove CallWith= when crbug/648179 is fixed.
-    [CallWith=EnteredWindow, NewObject, DoNotTestNewObject, CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName);
+    [NewObject, DoNotTestNewObject, CustomElementCallbacks, PerWorldBindings, RaisesException] Element createElement(DOMString localName);
+    [NewObject, DoNotTestNewObject, CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName);
     [NewObject] DocumentFragment createDocumentFragment();
     [NewObject] Text createTextNode(DOMString data);
     [NewObject, RaisesException] CDATASection createCDATASection(DOMString data);
@@ -180,10 +178,8 @@
     [CallWith=ScriptState, CustomElementCallbacks, RaisesException, MeasureAs=DocumentRegisterElement] CustomElementConstructor registerElement(DOMString type, optional ElementRegistrationOptions options);
     // https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-instantiate
     // FIXME: The typeExtension arguments should not be nullable.
-    // TODO(dominicc): Remove CallWith= when crbug/648179 is fixed.
-    [CallWith=EnteredWindow, CustomElementCallbacks, PerWorldBindings, RaisesException] Element createElement(DOMString localName, (DOMString or Dictionary)? options);
-    // TODO(dominicc): Remove CallWith= when crbug/648179 is fixed.
-    [CallWith=EnteredWindow, CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName, (DOMString or Dictionary)? options);
+    [CustomElementCallbacks, PerWorldBindings, RaisesException] Element createElement(DOMString localName, (DOMString or Dictionary)? options);
+    [CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName, (DOMString or Dictionary)? options);
 
     // Page Visibility
     // https://w3c.github.io/page-visibility/#extensions-to-the-document-interface
diff --git a/third_party/WebKit/Source/core/dom/Modulator.h b/third_party/WebKit/Source/core/dom/Modulator.h
index 68f072e..9c53af3a 100644
--- a/third_party/WebKit/Source/core/dom/Modulator.h
+++ b/third_party/WebKit/Source/core/dom/Modulator.h
@@ -94,7 +94,8 @@
 
   // Synchronously retrieves a single module script from existing module map
   // entry.
-  // Note: returns nullptr if the module map entry is still "fetching".
+  // Note: returns nullptr if the module map entry doesn't exist, or
+  // is still "fetching".
   virtual ModuleScript* GetFetchedModuleScript(const KURL&) = 0;
 
   // https://html.spec.whatwg.org/#resolve-a-module-specifier
diff --git a/third_party/WebKit/Source/core/dom/ModuleMap.cpp b/third_party/WebKit/Source/core/dom/ModuleMap.cpp
index ea685c36..f5e15a51 100644
--- a/third_party/WebKit/Source/core/dom/ModuleMap.cpp
+++ b/third_party/WebKit/Source/core/dom/ModuleMap.cpp
@@ -96,7 +96,6 @@
 }
 
 ModuleScript* ModuleMap::Entry::GetModuleScript() const {
-  DCHECK(!is_fetching_);
   return module_script_.Get();
 }
 
@@ -146,7 +145,8 @@
 
 ModuleScript* ModuleMap::GetFetchedModuleScript(const KURL& url) const {
   MapImpl::const_iterator it = map_.find(url);
-  CHECK_NE(it, map_.end());
+  if (it == map_.end())
+    return nullptr;
   return it->value->GetModuleScript();
 }
 
diff --git a/third_party/WebKit/Source/core/dom/ModuleMap.h b/third_party/WebKit/Source/core/dom/ModuleMap.h
index dcf51d17..a7e10be 100644
--- a/third_party/WebKit/Source/core/dom/ModuleMap.h
+++ b/third_party/WebKit/Source/core/dom/ModuleMap.h
@@ -41,8 +41,8 @@
                                SingleModuleClient*);
 
   // Synchronously get the ModuleScript for a given URL.
-  // Note: fetchSingleModuleScript of the ModuleScript must be complete before
-  // calling this.
+  // If the URL wasn't fetched, or is currently being fetched, this returns a
+  // nullptr.
   ModuleScript* GetFetchedModuleScript(const KURL&) const;
 
   Modulator* GetModulator() { return modulator_; }
diff --git a/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp b/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp
index 9b9c1206..7bf29e4 100644
--- a/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp
+++ b/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp
@@ -16,8 +16,7 @@
   Document* document = Document::Create();
   EXPECT_EQ(document, document->CommonAncestorTreeScope(*document));
 
-  Element* html =
-      document->createElement(nullptr, "html", StringOrDictionary());
+  Element* html = document->createElement("html", StringOrDictionary());
   document->AppendChild(html);
   ShadowRoot* shadow_root =
       html->CreateShadowRootInternal(ShadowRootType::V0, ASSERT_NO_EXCEPTION);
@@ -30,8 +29,7 @@
   // shadowRoot
 
   Document* document = Document::Create();
-  Element* html =
-      document->createElement(nullptr, "html", StringOrDictionary());
+  Element* html = document->createElement("html", StringOrDictionary());
   document->AppendChild(html);
   ShadowRoot* shadow_root =
       html->CreateShadowRootInternal(ShadowRootType::V0, ASSERT_NO_EXCEPTION);
@@ -46,14 +44,11 @@
   //  A      B
 
   Document* document = Document::Create();
-  Element* html =
-      document->createElement(nullptr, "html", StringOrDictionary());
+  Element* html = document->createElement("html", StringOrDictionary());
   document->AppendChild(html);
-  Element* head =
-      document->createElement(nullptr, "head", StringOrDictionary());
+  Element* head = document->createElement("head", StringOrDictionary());
   html->AppendChild(head);
-  Element* body =
-      document->createElement(nullptr, "body", StringOrDictionary());
+  Element* body = document->createElement("body", StringOrDictionary());
   html->AppendChild(body);
 
   ShadowRoot* shadow_root_a =
@@ -73,14 +68,11 @@
   // A
 
   Document* document = Document::Create();
-  Element* html =
-      document->createElement(nullptr, "html", StringOrDictionary());
+  Element* html = document->createElement("html", StringOrDictionary());
   document->AppendChild(html);
-  Element* head =
-      document->createElement(nullptr, "head", StringOrDictionary());
+  Element* head = document->createElement("head", StringOrDictionary());
   html->AppendChild(head);
-  Element* body =
-      document->createElement(nullptr, "body", StringOrDictionary());
+  Element* body = document->createElement("body", StringOrDictionary());
   html->AppendChild(body);
 
   ShadowRoot* shadow_root_y =
@@ -88,8 +80,7 @@
   ShadowRoot* shadow_root_b =
       body->CreateShadowRootInternal(ShadowRootType::V0, ASSERT_NO_EXCEPTION);
 
-  Element* div_in_y =
-      document->createElement(nullptr, "div", StringOrDictionary());
+  Element* div_in_y = document->createElement("div", StringOrDictionary());
   shadow_root_y->AppendChild(div_in_y);
   ShadowRoot* shadow_root_a = div_in_y->CreateShadowRootInternal(
       ShadowRootType::V0, ASSERT_NO_EXCEPTION);
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementTest.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementTest.cpp
index 192b94e..059e36cf 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementTest.cpp
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementTest.cpp
@@ -189,13 +189,13 @@
     EXPECT_EQ(data.state, element->GetCustomElementState()) << data.name;
     EXPECT_EQ(data.v0state, element->GetV0CustomElementState()) << data.name;
 
-    element = document.createElementNS(nullptr, HTMLNames::xhtmlNamespaceURI,
-                                       data.name, ASSERT_NO_EXCEPTION);
+    element = document.createElementNS(HTMLNames::xhtmlNamespaceURI, data.name,
+                                       ASSERT_NO_EXCEPTION);
     EXPECT_EQ(data.state, element->GetCustomElementState()) << data.name;
     EXPECT_EQ(data.v0state, element->GetV0CustomElementState()) << data.name;
 
-    element = document.createElementNS(nullptr, SVGNames::svgNamespaceURI,
-                                       data.name, ASSERT_NO_EXCEPTION);
+    element = document.createElementNS(SVGNames::svgNamespaceURI, data.name,
+                                       ASSERT_NO_EXCEPTION);
     EXPECT_EQ(CustomElementState::kUncustomized,
               element->GetCustomElementState())
         << data.name;
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementTestHelpers.h b/third_party/WebKit/Source/core/dom/custom/CustomElementTestHelpers.h
index 04ef280..f710de0 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementTestHelpers.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementTestHelpers.h
@@ -123,8 +123,8 @@
     if (!document)
       document = HTMLDocument::Create();
     NonThrowableExceptionState no_exceptions;
-    Element* element = document->createElementNS(nullptr, namespace_uri_,
-                                                 local_name_, no_exceptions);
+    Element* element =
+        document->createElementNS(namespace_uri_, local_name_, no_exceptions);
     for (const auto& attribute : attributes_)
       element->setAttribute(attribute.first, attribute.second);
     return element;
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeSorterTest.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeSorterTest.cpp
index d79cf30..4118020 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeSorterTest.cpp
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeSorterTest.cpp
@@ -30,7 +30,7 @@
   Element* CreateElementWithId(const char* local_name, const char* id) {
     NonThrowableExceptionState no_exceptions;
     Element* element = GetDocument()->createElement(
-        nullptr, local_name, StringOrDictionary(), no_exceptions);
+        local_name, StringOrDictionary(), no_exceptions);
     element->setAttribute(HTMLNames::idAttr, id);
     return element;
   }
@@ -55,8 +55,8 @@
 
 TEST_F(CustomElementUpgradeSorterTest, inOtherDocument_notInSet) {
   NonThrowableExceptionState no_exceptions;
-  Element* element = GetDocument()->createElement(
-      nullptr, "a-a", StringOrDictionary(), no_exceptions);
+  Element* element =
+      GetDocument()->createElement("a-a", StringOrDictionary(), no_exceptions);
 
   Document* other_document = HTMLDocument::Create();
   other_document->AppendChild(element);
@@ -74,8 +74,8 @@
 
 TEST_F(CustomElementUpgradeSorterTest, oneCandidate) {
   NonThrowableExceptionState no_exceptions;
-  Element* element = GetDocument()->createElement(
-      nullptr, "a-a", StringOrDictionary(), no_exceptions);
+  Element* element =
+      GetDocument()->createElement("a-a", StringOrDictionary(), no_exceptions);
   GetDocument()->documentElement()->AppendChild(element);
 
   CustomElementUpgradeSorter sorter;
diff --git a/third_party/WebKit/Source/core/editing/BUILD.gn b/third_party/WebKit/Source/core/editing/BUILD.gn
index c241a44..1ee533e 100644
--- a/third_party/WebKit/Source/core/editing/BUILD.gn
+++ b/third_party/WebKit/Source/core/editing/BUILD.gn
@@ -66,6 +66,7 @@
     "SelectionEditor.h",
     "SelectionModifier.cpp",
     "SelectionModifier.h",
+    "SelectionModifierWord.cpp",
     "SelectionStrategy.h",
     "SelectionTemplate.cpp",
     "SelectionTemplate.h",
@@ -185,12 +186,12 @@
     "iterators/TextIterator.h",
     "iterators/TextIteratorBehavior.cpp",
     "iterators/TextIteratorBehavior.h",
+    "iterators/TextIteratorTextNodeHandler.cpp",
+    "iterators/TextIteratorTextNodeHandler.h",
     "iterators/TextIteratorTextState.cpp",
     "iterators/TextIteratorTextState.h",
     "iterators/TextSearcherICU.cpp",
     "iterators/TextSearcherICU.h",
-    "iterators/WordAwareIterator.cpp",
-    "iterators/WordAwareIterator.h",
     "markers/CompositionMarkerListImpl.cpp",
     "markers/CompositionMarkerListImpl.h",
     "markers/DocumentMarker.cpp",
diff --git a/third_party/WebKit/Source/core/editing/SelectionModifier.cpp b/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
index 2f5e3c9..63c4f218 100644
--- a/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
@@ -264,28 +264,22 @@
 
 VisiblePosition SelectionModifier::ModifyMovingRight(
     TextGranularity granularity) {
-  VisiblePosition pos;
   switch (granularity) {
     case kCharacterGranularity:
-      if (selection_.IsRange()) {
-        if (DirectionOfSelection() == TextDirection::kLtr)
-          pos = CreateVisiblePosition(selection_.end(), selection_.Affinity());
-        else
-          pos =
-              CreateVisiblePosition(selection_.Start(), selection_.Affinity());
-      } else {
-        pos = RightPositionOf(
+      if (!selection_.IsRange()) {
+        return RightPositionOf(
             CreateVisiblePosition(selection_.Extent(), selection_.Affinity()));
       }
-      break;
+      if (DirectionOfSelection() == TextDirection::kLtr)
+        return CreateVisiblePosition(selection_.end(), selection_.Affinity());
+      return CreateVisiblePosition(selection_.Start(), selection_.Affinity());
     case kWordGranularity: {
-      bool skips_space_when_moving_right =
+      const bool skips_space_when_moving_right =
           GetFrame() &&
           GetFrame()->GetEditor().Behavior().ShouldSkipSpaceWhenMovingRight();
-      pos = RightWordPosition(
+      return RightWordPosition(
           CreateVisiblePosition(selection_.Extent(), selection_.Affinity()),
           skips_space_when_moving_right);
-      break;
     }
     case kSentenceGranularity:
     case kLineGranularity:
@@ -293,15 +287,14 @@
     case kSentenceBoundary:
     case kParagraphBoundary:
     case kDocumentBoundary:
-      // FIXME: Implement all of the above.
-      pos = ModifyMovingForward(granularity);
-      break;
+      // TODO(editing-dev): Implement all of the above.
+      return ModifyMovingForward(granularity);
     case kLineBoundary:
-      pos =
-          RightBoundaryOfLine(StartForPlatform(), DirectionOfEnclosingBlock());
-      break;
+      return RightBoundaryOfLine(StartForPlatform(),
+                                 DirectionOfEnclosingBlock());
   }
-  return pos;
+  NOTREACHED() << granularity;
+  return VisiblePosition();
 }
 
 VisiblePosition SelectionModifier::ModifyMovingForward(
diff --git a/third_party/WebKit/Source/core/editing/SelectionModifierWord.cpp b/third_party/WebKit/Source/core/editing/SelectionModifierWord.cpp
new file mode 100644
index 0000000..e60408d
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/SelectionModifierWord.cpp
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "core/editing/EditingUtilities.h"
+#include "core/editing/RenderedPosition.h"
+#include "core/editing/VisibleUnits.h"
+#include "core/layout/line/InlineTextBox.h"
+#include "core/layout/line/RootInlineBox.h"
+#include "platform/text/TextBreakIterator.h"
+
+namespace blink {
+
+namespace {
+
+// This class holds a list of |InlineBox| in logical order.
+// TDOO(editing-dev): We should utilize |CachedLogicallyOrderedLeafBoxes| class
+// in |CompositeEditCommand::DeleteInsignificantText()|.
+class CachedLogicallyOrderedLeafBoxes final {
+ public:
+  CachedLogicallyOrderedLeafBoxes() = default;
+
+  const InlineTextBox* PreviousTextBox(const RootInlineBox*,
+                                       const InlineTextBox*);
+  const InlineTextBox* NextTextBox(const RootInlineBox*, const InlineTextBox*);
+
+  size_t size() const { return leaf_boxes_.size(); }
+  const InlineBox* FirstBox() const { return leaf_boxes_[0]; }
+
+ private:
+  const Vector<InlineBox*>& CollectBoxes(const RootInlineBox*);
+  int BoxIndexInLeaves(const InlineTextBox*) const;
+
+  const RootInlineBox* root_inline_box_ = nullptr;
+  Vector<InlineBox*> leaf_boxes_;
+};
+
+const InlineTextBox* CachedLogicallyOrderedLeafBoxes::PreviousTextBox(
+    const RootInlineBox* root,
+    const InlineTextBox* box) {
+  if (!root)
+    return nullptr;
+
+  CollectBoxes(root);
+
+  // If box is null, root is box's previous RootInlineBox, and previousBox is
+  // the last logical box in root.
+  int box_index = leaf_boxes_.size() - 1;
+  if (box)
+    box_index = BoxIndexInLeaves(box) - 1;
+
+  for (int i = box_index; i >= 0; --i) {
+    if (leaf_boxes_[i]->IsInlineTextBox())
+      return ToInlineTextBox(leaf_boxes_[i]);
+  }
+
+  return nullptr;
+}
+
+const InlineTextBox* CachedLogicallyOrderedLeafBoxes::NextTextBox(
+    const RootInlineBox* root,
+    const InlineTextBox* box) {
+  if (!root)
+    return nullptr;
+
+  CollectBoxes(root);
+
+  // If box is null, root is box's next RootInlineBox, and nextBox is the first
+  // logical box in root. Otherwise, root is box's RootInlineBox, and nextBox is
+  // the next logical box in the same line.
+  size_t next_box_index = 0;
+  if (box)
+    next_box_index = BoxIndexInLeaves(box) + 1;
+
+  for (size_t i = next_box_index; i < leaf_boxes_.size(); ++i) {
+    if (leaf_boxes_[i]->IsInlineTextBox())
+      return ToInlineTextBox(leaf_boxes_[i]);
+  }
+
+  return nullptr;
+}
+
+const Vector<InlineBox*>& CachedLogicallyOrderedLeafBoxes::CollectBoxes(
+    const RootInlineBox* root) {
+  if (root_inline_box_ != root) {
+    root_inline_box_ = root;
+    leaf_boxes_.clear();
+    root->CollectLeafBoxesInLogicalOrder(leaf_boxes_);
+  }
+  return leaf_boxes_;
+}
+
+int CachedLogicallyOrderedLeafBoxes::BoxIndexInLeaves(
+    const InlineTextBox* box) const {
+  for (size_t i = 0; i < leaf_boxes_.size(); ++i) {
+    if (box == leaf_boxes_[i])
+      return i;
+  }
+  return 0;
+}
+
+const InlineTextBox* LogicallyPreviousBox(
+    const VisiblePosition& visible_position,
+    const InlineTextBox* text_box,
+    bool& previous_box_in_different_block,
+    CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
+  DCHECK(visible_position.IsValid()) << visible_position;
+  const InlineBox* start_box = text_box;
+
+  const InlineTextBox* previous_box =
+      leaf_boxes.PreviousTextBox(&start_box->Root(), text_box);
+  if (previous_box)
+    return previous_box;
+
+  previous_box =
+      leaf_boxes.PreviousTextBox(start_box->Root().PrevRootBox(), nullptr);
+  if (previous_box)
+    return previous_box;
+
+  for (;;) {
+    Node* start_node = start_box->GetLineLayoutItem().NonPseudoNode();
+    if (!start_node)
+      break;
+
+    Position position = PreviousRootInlineBoxCandidatePosition(
+        start_node, visible_position, kContentIsEditable);
+    if (position.IsNull())
+      break;
+
+    RenderedPosition rendered_position(position, TextAffinity::kDownstream);
+    RootInlineBox* previous_root = rendered_position.RootBox();
+    if (!previous_root)
+      break;
+
+    previous_box = leaf_boxes.PreviousTextBox(previous_root, nullptr);
+    if (previous_box) {
+      previous_box_in_different_block = true;
+      return previous_box;
+    }
+
+    if (!leaf_boxes.size())
+      break;
+    start_box = leaf_boxes.FirstBox();
+  }
+  return nullptr;
+}
+
+const InlineTextBox* LogicallyNextBox(
+    const VisiblePosition& visible_position,
+    const InlineTextBox* text_box,
+    bool& next_box_in_different_block,
+    CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
+  DCHECK(visible_position.IsValid()) << visible_position;
+  const InlineBox* start_box = text_box;
+
+  const InlineTextBox* next_box =
+      leaf_boxes.NextTextBox(&start_box->Root(), text_box);
+  if (next_box)
+    return next_box;
+
+  next_box = leaf_boxes.NextTextBox(start_box->Root().NextRootBox(), nullptr);
+  if (next_box)
+    return next_box;
+
+  for (;;) {
+    Node* start_node = start_box->GetLineLayoutItem().NonPseudoNode();
+    if (!start_node)
+      break;
+
+    Position position = NextRootInlineBoxCandidatePosition(
+        start_node, visible_position, kContentIsEditable);
+    if (position.IsNull())
+      break;
+
+    RenderedPosition rendered_position(position, TextAffinity::kDownstream);
+    RootInlineBox* next_root = rendered_position.RootBox();
+    if (!next_root)
+      break;
+
+    next_box = leaf_boxes.NextTextBox(next_root, nullptr);
+    if (next_box) {
+      next_box_in_different_block = true;
+      return next_box;
+    }
+
+    if (!leaf_boxes.size())
+      break;
+    start_box = leaf_boxes.FirstBox();
+  }
+  return nullptr;
+}
+
+TextBreakIterator* WordBreakIteratorForMinOffsetBoundary(
+    const VisiblePosition& visible_position,
+    const InlineTextBox* text_box,
+    int& previous_box_length,
+    bool& previous_box_in_different_block,
+    Vector<UChar, 1024>& string,
+    CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
+  DCHECK(visible_position.IsValid()) << visible_position;
+  previous_box_in_different_block = false;
+
+  // TODO(editing-dev) Handle the case when we don't have an inline text box.
+  const InlineTextBox* previous_box = LogicallyPreviousBox(
+      visible_position, text_box, previous_box_in_different_block, leaf_boxes);
+
+  int len = 0;
+  string.clear();
+  if (previous_box) {
+    previous_box_length = previous_box->Len();
+    previous_box->GetLineLayoutItem().GetText().AppendTo(
+        string, previous_box->Start(), previous_box_length);
+    len += previous_box_length;
+  }
+  text_box->GetLineLayoutItem().GetText().AppendTo(string, text_box->Start(),
+                                                   text_box->Len());
+  len += text_box->Len();
+
+  return WordBreakIterator(string.data(), len);
+}
+
+TextBreakIterator* WordBreakIteratorForMaxOffsetBoundary(
+    const VisiblePosition& visible_position,
+    const InlineTextBox* text_box,
+    bool& next_box_in_different_block,
+    Vector<UChar, 1024>& string,
+    CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
+  DCHECK(visible_position.IsValid()) << visible_position;
+  next_box_in_different_block = false;
+
+  // TODO(editing-dev) Handle the case when we don't have an inline text box.
+  const InlineTextBox* next_box = LogicallyNextBox(
+      visible_position, text_box, next_box_in_different_block, leaf_boxes);
+
+  int len = 0;
+  string.clear();
+  text_box->GetLineLayoutItem().GetText().AppendTo(string, text_box->Start(),
+                                                   text_box->Len());
+  len += text_box->Len();
+  if (next_box) {
+    next_box->GetLineLayoutItem().GetText().AppendTo(string, next_box->Start(),
+                                                     next_box->Len());
+    len += next_box->Len();
+  }
+
+  return WordBreakIterator(string.data(), len);
+}
+
+bool IsLogicalStartOfWord(TextBreakIterator* iter,
+                          int position,
+                          bool hard_line_break) {
+  bool boundary = hard_line_break ? true : iter->isBoundary(position);
+  if (!boundary)
+    return false;
+
+  iter->following(position);
+  // isWordTextBreak returns true after moving across a word and false after
+  // moving across a punctuation/space.
+  return IsWordTextBreak(iter);
+}
+
+bool IslogicalEndOfWord(TextBreakIterator* iter,
+                        int position,
+                        bool hard_line_break) {
+  bool boundary = iter->isBoundary(position);
+  return (hard_line_break || boundary) && IsWordTextBreak(iter);
+}
+
+enum CursorMovementDirection { kMoveLeft, kMoveRight };
+
+VisiblePosition VisualWordPosition(const VisiblePosition& visible_position,
+                                   CursorMovementDirection direction,
+                                   bool skips_space_when_moving_right) {
+  DCHECK(visible_position.IsValid()) << visible_position;
+  if (visible_position.IsNull())
+    return VisiblePosition();
+
+  TextDirection block_direction =
+      DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
+  InlineBox* previously_visited_box = nullptr;
+  VisiblePosition current = visible_position;
+  TextBreakIterator* iter = nullptr;
+
+  CachedLogicallyOrderedLeafBoxes leaf_boxes;
+  Vector<UChar, 1024> string;
+
+  for (;;) {
+    VisiblePosition adjacent_character_position = direction == kMoveRight
+                                                      ? RightPositionOf(current)
+                                                      : LeftPositionOf(current);
+    if (adjacent_character_position.DeepEquivalent() ==
+            current.DeepEquivalent() ||
+        adjacent_character_position.IsNull())
+      return VisiblePosition();
+
+    InlineBoxPosition box_position = ComputeInlineBoxPosition(
+        adjacent_character_position.DeepEquivalent(), TextAffinity::kUpstream);
+    InlineBox* box = box_position.inline_box;
+    int offset_in_box = box_position.offset_in_box;
+
+    if (!box)
+      break;
+    if (!box->IsInlineTextBox()) {
+      current = adjacent_character_position;
+      continue;
+    }
+
+    InlineTextBox* text_box = ToInlineTextBox(box);
+    int previous_box_length = 0;
+    bool previous_box_in_different_block = false;
+    bool next_box_in_different_block = false;
+    bool moving_into_new_box = previously_visited_box != box;
+
+    if (offset_in_box == box->CaretMinOffset()) {
+      iter = WordBreakIteratorForMinOffsetBoundary(
+          visible_position, text_box, previous_box_length,
+          previous_box_in_different_block, string, leaf_boxes);
+    } else if (offset_in_box == box->CaretMaxOffset()) {
+      iter = WordBreakIteratorForMaxOffsetBoundary(visible_position, text_box,
+                                                   next_box_in_different_block,
+                                                   string, leaf_boxes);
+    } else if (moving_into_new_box) {
+      iter = WordBreakIterator(text_box->GetLineLayoutItem().GetText(),
+                               text_box->Start(), text_box->Len());
+      previously_visited_box = box;
+    }
+
+    if (!iter)
+      break;
+
+    iter->first();
+    int offset_in_iterator =
+        offset_in_box - text_box->Start() + previous_box_length;
+
+    bool is_word_break;
+    bool box_has_same_directionality_as_block =
+        box->Direction() == block_direction;
+    bool moving_backward =
+        (direction == kMoveLeft && box->Direction() == TextDirection::kLtr) ||
+        (direction == kMoveRight && box->Direction() == TextDirection::kRtl);
+    if ((skips_space_when_moving_right &&
+         box_has_same_directionality_as_block) ||
+        (!skips_space_when_moving_right && moving_backward)) {
+      bool logical_start_in_layout_object =
+          offset_in_box == static_cast<int>(text_box->Start()) &&
+          previous_box_in_different_block;
+      is_word_break = IsLogicalStartOfWord(iter, offset_in_iterator,
+                                           logical_start_in_layout_object);
+    } else {
+      bool logical_end_in_layout_object =
+          offset_in_box ==
+              static_cast<int>(text_box->Start() + text_box->Len()) &&
+          next_box_in_different_block;
+      is_word_break = IslogicalEndOfWord(iter, offset_in_iterator,
+                                         logical_end_in_layout_object);
+    }
+
+    if (is_word_break)
+      return adjacent_character_position;
+
+    current = adjacent_character_position;
+  }
+  return VisiblePosition();
+}
+
+}  // namespace
+
+// TODO(yosin): Once we move |SelectionModifier::ModifyMovingLeft()| in this
+// file, we can make |LeftWordPosition()| as file local function.
+VisiblePosition LeftWordPosition(const VisiblePosition& visible_position,
+                                 bool skips_space_when_moving_right) {
+  DCHECK(visible_position.IsValid()) << visible_position;
+  VisiblePosition left_word_break = VisualWordPosition(
+      visible_position, kMoveLeft, skips_space_when_moving_right);
+  left_word_break = HonorEditingBoundaryAtOrBefore(
+      left_word_break, visible_position.DeepEquivalent());
+
+  // TODO(editing-dev) How should we handle a non-editable position?
+  if (left_word_break.IsNull() &&
+      IsEditablePosition(visible_position.DeepEquivalent())) {
+    TextDirection block_direction =
+        DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
+    left_word_break = block_direction == TextDirection::kLtr
+                          ? StartOfEditableContent(visible_position)
+                          : EndOfEditableContent(visible_position);
+  }
+  return left_word_break;
+}
+
+// TODO(yosin): Once we move |SelectionModifier::ModifyMovingRight()| in this
+// file, we can make |RightWordPosition()| as file local function.
+VisiblePosition RightWordPosition(const VisiblePosition& visible_position,
+                                  bool skips_space_when_moving_right) {
+  DCHECK(visible_position.IsValid()) << visible_position;
+  VisiblePosition right_word_break = VisualWordPosition(
+      visible_position, kMoveRight, skips_space_when_moving_right);
+  right_word_break = HonorEditingBoundaryAtOrBefore(
+      right_word_break, visible_position.DeepEquivalent());
+
+  // TODO(editing-dev) How should we handle a non-editable position?
+  if (right_word_break.IsNull() &&
+      IsEditablePosition(visible_position.DeepEquivalent())) {
+    TextDirection block_direction =
+        DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
+    right_word_break = block_direction == TextDirection::kLtr
+                           ? EndOfEditableContent(visible_position)
+                           : StartOfEditableContent(visible_position);
+  }
+  return right_word_break;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index 22bac6e..c4a7f76 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -199,7 +199,7 @@
 }
 
 template <typename Strategy>
-static VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrBefore(
+VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrBeforeAlgorithm(
     const VisiblePositionTemplate<Strategy>& pos,
     const PositionTemplate<Strategy>& anchor) {
   DCHECK(pos.IsValid()) << pos;
@@ -207,6 +207,18 @@
       HonorEditingBoundaryAtOrBefore(pos.ToPositionWithAffinity(), anchor));
 }
 
+VisiblePosition HonorEditingBoundaryAtOrBefore(
+    const VisiblePosition& visiblePosition,
+    const Position& anchor) {
+  return HonorEditingBoundaryAtOrBeforeAlgorithm(visiblePosition, anchor);
+}
+
+VisiblePositionInFlatTree HonorEditingBoundaryAtOrBefore(
+    const VisiblePositionInFlatTree& visiblePosition,
+    const PositionInFlatTree& anchor) {
+  return HonorEditingBoundaryAtOrBeforeAlgorithm(visiblePosition, anchor);
+}
+
 template <typename Strategy>
 static VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrAfter(
     const VisiblePositionTemplate<Strategy>& pos,
@@ -317,7 +329,7 @@
 }
 
 // FIXME: consolidate with code in previousLinePosition.
-static Position PreviousRootInlineBoxCandidatePosition(
+Position PreviousRootInlineBoxCandidatePosition(
     Node* node,
     const VisiblePosition& visible_position,
     EditableType editable_type) {
@@ -353,7 +365,7 @@
   return Position();
 }
 
-static Position NextRootInlineBoxCandidatePosition(
+Position NextRootInlineBoxCandidatePosition(
     Node* node,
     const VisiblePosition& visible_position,
     EditableType editable_type) {
@@ -383,396 +395,6 @@
   return Position();
 }
 
-class CachedLogicallyOrderedLeafBoxes {
- public:
-  CachedLogicallyOrderedLeafBoxes();
-
-  const InlineTextBox* PreviousTextBox(const RootInlineBox*,
-                                       const InlineTextBox*);
-  const InlineTextBox* NextTextBox(const RootInlineBox*, const InlineTextBox*);
-
-  size_t size() const { return leaf_boxes_.size(); }
-  const InlineBox* FirstBox() const { return leaf_boxes_[0]; }
-
- private:
-  const Vector<InlineBox*>& CollectBoxes(const RootInlineBox*);
-  int BoxIndexInLeaves(const InlineTextBox*) const;
-
-  const RootInlineBox* root_inline_box_;
-  Vector<InlineBox*> leaf_boxes_;
-};
-
-CachedLogicallyOrderedLeafBoxes::CachedLogicallyOrderedLeafBoxes()
-    : root_inline_box_(0) {}
-
-const InlineTextBox* CachedLogicallyOrderedLeafBoxes::PreviousTextBox(
-    const RootInlineBox* root,
-    const InlineTextBox* box) {
-  if (!root)
-    return 0;
-
-  CollectBoxes(root);
-
-  // If box is null, root is box's previous RootInlineBox, and previousBox is
-  // the last logical box in root.
-  int box_index = leaf_boxes_.size() - 1;
-  if (box)
-    box_index = BoxIndexInLeaves(box) - 1;
-
-  for (int i = box_index; i >= 0; --i) {
-    if (leaf_boxes_[i]->IsInlineTextBox())
-      return ToInlineTextBox(leaf_boxes_[i]);
-  }
-
-  return 0;
-}
-
-const InlineTextBox* CachedLogicallyOrderedLeafBoxes::NextTextBox(
-    const RootInlineBox* root,
-    const InlineTextBox* box) {
-  if (!root)
-    return 0;
-
-  CollectBoxes(root);
-
-  // If box is null, root is box's next RootInlineBox, and nextBox is the first
-  // logical box in root. Otherwise, root is box's RootInlineBox, and nextBox is
-  // the next logical box in the same line.
-  size_t next_box_index = 0;
-  if (box)
-    next_box_index = BoxIndexInLeaves(box) + 1;
-
-  for (size_t i = next_box_index; i < leaf_boxes_.size(); ++i) {
-    if (leaf_boxes_[i]->IsInlineTextBox())
-      return ToInlineTextBox(leaf_boxes_[i]);
-  }
-
-  return 0;
-}
-
-const Vector<InlineBox*>& CachedLogicallyOrderedLeafBoxes::CollectBoxes(
-    const RootInlineBox* root) {
-  if (root_inline_box_ != root) {
-    root_inline_box_ = root;
-    leaf_boxes_.clear();
-    root->CollectLeafBoxesInLogicalOrder(leaf_boxes_);
-  }
-  return leaf_boxes_;
-}
-
-int CachedLogicallyOrderedLeafBoxes::BoxIndexInLeaves(
-    const InlineTextBox* box) const {
-  for (size_t i = 0; i < leaf_boxes_.size(); ++i) {
-    if (box == leaf_boxes_[i])
-      return i;
-  }
-  return 0;
-}
-
-static const InlineTextBox* LogicallyPreviousBox(
-    const VisiblePosition& visible_position,
-    const InlineTextBox* text_box,
-    bool& previous_box_in_different_block,
-    CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
-  DCHECK(visible_position.IsValid()) << visible_position;
-  const InlineBox* start_box = text_box;
-
-  const InlineTextBox* previous_box =
-      leaf_boxes.PreviousTextBox(&start_box->Root(), text_box);
-  if (previous_box)
-    return previous_box;
-
-  previous_box = leaf_boxes.PreviousTextBox(start_box->Root().PrevRootBox(), 0);
-  if (previous_box)
-    return previous_box;
-
-  while (1) {
-    Node* start_node = start_box->GetLineLayoutItem().NonPseudoNode();
-    if (!start_node)
-      break;
-
-    Position position = PreviousRootInlineBoxCandidatePosition(
-        start_node, visible_position, kContentIsEditable);
-    if (position.IsNull())
-      break;
-
-    RenderedPosition rendered_position(position, TextAffinity::kDownstream);
-    RootInlineBox* previous_root = rendered_position.RootBox();
-    if (!previous_root)
-      break;
-
-    previous_box = leaf_boxes.PreviousTextBox(previous_root, 0);
-    if (previous_box) {
-      previous_box_in_different_block = true;
-      return previous_box;
-    }
-
-    if (!leaf_boxes.size())
-      break;
-    start_box = leaf_boxes.FirstBox();
-  }
-  return 0;
-}
-
-static const InlineTextBox* LogicallyNextBox(
-    const VisiblePosition& visible_position,
-    const InlineTextBox* text_box,
-    bool& next_box_in_different_block,
-    CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
-  DCHECK(visible_position.IsValid()) << visible_position;
-  const InlineBox* start_box = text_box;
-
-  const InlineTextBox* next_box =
-      leaf_boxes.NextTextBox(&start_box->Root(), text_box);
-  if (next_box)
-    return next_box;
-
-  next_box = leaf_boxes.NextTextBox(start_box->Root().NextRootBox(), 0);
-  if (next_box)
-    return next_box;
-
-  while (1) {
-    Node* start_node = start_box->GetLineLayoutItem().NonPseudoNode();
-    if (!start_node)
-      break;
-
-    Position position = NextRootInlineBoxCandidatePosition(
-        start_node, visible_position, kContentIsEditable);
-    if (position.IsNull())
-      break;
-
-    RenderedPosition rendered_position(position, TextAffinity::kDownstream);
-    RootInlineBox* next_root = rendered_position.RootBox();
-    if (!next_root)
-      break;
-
-    next_box = leaf_boxes.NextTextBox(next_root, 0);
-    if (next_box) {
-      next_box_in_different_block = true;
-      return next_box;
-    }
-
-    if (!leaf_boxes.size())
-      break;
-    start_box = leaf_boxes.FirstBox();
-  }
-  return 0;
-}
-
-static TextBreakIterator* WordBreakIteratorForMinOffsetBoundary(
-    const VisiblePosition& visible_position,
-    const InlineTextBox* text_box,
-    int& previous_box_length,
-    bool& previous_box_in_different_block,
-    Vector<UChar, 1024>& string,
-    CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
-  DCHECK(visible_position.IsValid()) << visible_position;
-  previous_box_in_different_block = false;
-
-  // FIXME: Handle the case when we don't have an inline text box.
-  const InlineTextBox* previous_box = LogicallyPreviousBox(
-      visible_position, text_box, previous_box_in_different_block, leaf_boxes);
-
-  int len = 0;
-  string.clear();
-  if (previous_box) {
-    previous_box_length = previous_box->Len();
-    previous_box->GetLineLayoutItem().GetText().AppendTo(
-        string, previous_box->Start(), previous_box_length);
-    len += previous_box_length;
-  }
-  text_box->GetLineLayoutItem().GetText().AppendTo(string, text_box->Start(),
-                                                   text_box->Len());
-  len += text_box->Len();
-
-  return WordBreakIterator(string.data(), len);
-}
-
-static TextBreakIterator* WordBreakIteratorForMaxOffsetBoundary(
-    const VisiblePosition& visible_position,
-    const InlineTextBox* text_box,
-    bool& next_box_in_different_block,
-    Vector<UChar, 1024>& string,
-    CachedLogicallyOrderedLeafBoxes& leaf_boxes) {
-  DCHECK(visible_position.IsValid()) << visible_position;
-  next_box_in_different_block = false;
-
-  // FIXME: Handle the case when we don't have an inline text box.
-  const InlineTextBox* next_box = LogicallyNextBox(
-      visible_position, text_box, next_box_in_different_block, leaf_boxes);
-
-  int len = 0;
-  string.clear();
-  text_box->GetLineLayoutItem().GetText().AppendTo(string, text_box->Start(),
-                                                   text_box->Len());
-  len += text_box->Len();
-  if (next_box) {
-    next_box->GetLineLayoutItem().GetText().AppendTo(string, next_box->Start(),
-                                                     next_box->Len());
-    len += next_box->Len();
-  }
-
-  return WordBreakIterator(string.data(), len);
-}
-
-static bool IsLogicalStartOfWord(TextBreakIterator* iter,
-                                 int position,
-                                 bool hard_line_break) {
-  bool boundary = hard_line_break ? true : iter->isBoundary(position);
-  if (!boundary)
-    return false;
-
-  iter->following(position);
-  // isWordTextBreak returns true after moving across a word and false after
-  // moving across a punctuation/space.
-  return IsWordTextBreak(iter);
-}
-
-static bool IslogicalEndOfWord(TextBreakIterator* iter,
-                               int position,
-                               bool hard_line_break) {
-  bool boundary = iter->isBoundary(position);
-  return (hard_line_break || boundary) && IsWordTextBreak(iter);
-}
-
-enum CursorMovementDirection { kMoveLeft, kMoveRight };
-
-static VisiblePosition VisualWordPosition(
-    const VisiblePosition& visible_position,
-    CursorMovementDirection direction,
-    bool skips_space_when_moving_right) {
-  DCHECK(visible_position.IsValid()) << visible_position;
-  if (visible_position.IsNull())
-    return VisiblePosition();
-
-  TextDirection block_direction =
-      DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
-  InlineBox* previously_visited_box = 0;
-  VisiblePosition current = visible_position;
-  TextBreakIterator* iter = 0;
-
-  CachedLogicallyOrderedLeafBoxes leaf_boxes;
-  Vector<UChar, 1024> string;
-
-  while (1) {
-    VisiblePosition adjacent_character_position = direction == kMoveRight
-                                                      ? RightPositionOf(current)
-                                                      : LeftPositionOf(current);
-    if (adjacent_character_position.DeepEquivalent() ==
-            current.DeepEquivalent() ||
-        adjacent_character_position.IsNull())
-      return VisiblePosition();
-
-    InlineBoxPosition box_position = ComputeInlineBoxPosition(
-        adjacent_character_position.DeepEquivalent(), TextAffinity::kUpstream);
-    InlineBox* box = box_position.inline_box;
-    int offset_in_box = box_position.offset_in_box;
-
-    if (!box)
-      break;
-    if (!box->IsInlineTextBox()) {
-      current = adjacent_character_position;
-      continue;
-    }
-
-    InlineTextBox* text_box = ToInlineTextBox(box);
-    int previous_box_length = 0;
-    bool previous_box_in_different_block = false;
-    bool next_box_in_different_block = false;
-    bool moving_into_new_box = previously_visited_box != box;
-
-    if (offset_in_box == box->CaretMinOffset()) {
-      iter = WordBreakIteratorForMinOffsetBoundary(
-          visible_position, text_box, previous_box_length,
-          previous_box_in_different_block, string, leaf_boxes);
-    } else if (offset_in_box == box->CaretMaxOffset()) {
-      iter = WordBreakIteratorForMaxOffsetBoundary(visible_position, text_box,
-                                                   next_box_in_different_block,
-                                                   string, leaf_boxes);
-    } else if (moving_into_new_box) {
-      iter = WordBreakIterator(text_box->GetLineLayoutItem().GetText(),
-                               text_box->Start(), text_box->Len());
-      previously_visited_box = box;
-    }
-
-    if (!iter)
-      break;
-
-    iter->first();
-    int offset_in_iterator =
-        offset_in_box - text_box->Start() + previous_box_length;
-
-    bool is_word_break;
-    bool box_has_same_directionality_as_block =
-        box->Direction() == block_direction;
-    bool moving_backward =
-        (direction == kMoveLeft && box->Direction() == TextDirection::kLtr) ||
-        (direction == kMoveRight && box->Direction() == TextDirection::kRtl);
-    if ((skips_space_when_moving_right &&
-         box_has_same_directionality_as_block) ||
-        (!skips_space_when_moving_right && moving_backward)) {
-      bool logical_start_in_layout_object =
-          offset_in_box == static_cast<int>(text_box->Start()) &&
-          previous_box_in_different_block;
-      is_word_break = IsLogicalStartOfWord(iter, offset_in_iterator,
-                                           logical_start_in_layout_object);
-    } else {
-      bool logical_end_in_layout_object =
-          offset_in_box ==
-              static_cast<int>(text_box->Start() + text_box->Len()) &&
-          next_box_in_different_block;
-      is_word_break = IslogicalEndOfWord(iter, offset_in_iterator,
-                                         logical_end_in_layout_object);
-    }
-
-    if (is_word_break)
-      return adjacent_character_position;
-
-    current = adjacent_character_position;
-  }
-  return VisiblePosition();
-}
-
-VisiblePosition LeftWordPosition(const VisiblePosition& visible_position,
-                                 bool skips_space_when_moving_right) {
-  DCHECK(visible_position.IsValid()) << visible_position;
-  VisiblePosition left_word_break = VisualWordPosition(
-      visible_position, kMoveLeft, skips_space_when_moving_right);
-  left_word_break = HonorEditingBoundaryAtOrBefore(
-      left_word_break, visible_position.DeepEquivalent());
-
-  // FIXME: How should we handle a non-editable position?
-  if (left_word_break.IsNull() &&
-      IsEditablePosition(visible_position.DeepEquivalent())) {
-    TextDirection block_direction =
-        DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
-    left_word_break = block_direction == TextDirection::kLtr
-                          ? StartOfEditableContent(visible_position)
-                          : EndOfEditableContent(visible_position);
-  }
-  return left_word_break;
-}
-
-VisiblePosition RightWordPosition(const VisiblePosition& visible_position,
-                                  bool skips_space_when_moving_right) {
-  DCHECK(visible_position.IsValid()) << visible_position;
-  VisiblePosition right_word_break = VisualWordPosition(
-      visible_position, kMoveRight, skips_space_when_moving_right);
-  right_word_break = HonorEditingBoundaryAtOrBefore(
-      right_word_break, visible_position.DeepEquivalent());
-
-  // FIXME: How should we handle a non-editable position?
-  if (right_word_break.IsNull() &&
-      IsEditablePosition(visible_position.DeepEquivalent())) {
-    TextDirection block_direction =
-        DirectionOfEnclosingBlock(visible_position.DeepEquivalent());
-    right_word_break = block_direction == TextDirection::kLtr
-                           ? EndOfEditableContent(visible_position)
-                           : StartOfEditableContent(visible_position);
-  }
-  return right_word_break;
-}
-
 template <typename Strategy>
 static ContainerNode* NonShadowBoundaryParentNode(Node* node) {
   ContainerNode* parent = Strategy::Parent(*node);
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.h b/third_party/WebKit/Source/core/editing/VisibleUnits.h
index 0042273..60f1bb35 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.h
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.h
@@ -183,8 +183,12 @@
 EndOfWord(const VisiblePositionInFlatTree&, EWordSide = kRightWordIfOnBoundary);
 VisiblePosition PreviousWordPosition(const VisiblePosition&);
 VisiblePosition NextWordPosition(const VisiblePosition&);
+// TODO(yosin): We'll move |RightPositionOf()| as file location function
+// for |SelectionModifier| class.
 VisiblePosition RightWordPosition(const VisiblePosition&,
                                   bool skips_space_when_moving_right);
+// TODO(yosin): We'll move |LeftPositionOf()| as file location function
+// for |SelectionModifier| class.
 VisiblePosition LeftWordPosition(const VisiblePosition&,
                                  bool skips_space_when_moving_right);
 
@@ -346,6 +350,18 @@
 IntRect ComputeTextRect(const EphemeralRangeInFlatTree&);
 FloatRect ComputeTextFloatRect(const EphemeralRange&);
 
+// Export below functions only for |SelectionModifier|.
+VisiblePosition HonorEditingBoundaryAtOrBefore(const VisiblePosition&,
+                                               const Position&);
+
+Position NextRootInlineBoxCandidatePosition(Node*,
+                                            const VisiblePosition&,
+                                            EditableType);
+
+Position PreviousRootInlineBoxCandidatePosition(Node*,
+                                                const VisiblePosition&,
+                                                EditableType);
+
 }  // namespace blink
 
 #endif  // VisibleUnits_h
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
index 63417b4..2fe453e 100644
--- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
@@ -28,12 +28,10 @@
 #include "core/editing/iterators/TextIterator.h"
 
 #include <unicode/utf16.h>
-#include <algorithm>
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/HTMLNames.h"
 #include "core/InputTypeNames.h"
 #include "core/dom/Document.h"
-#include "core/dom/FirstLetterPseudoElement.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/editing/EditingUtilities.h"
 #include "core/editing/EphemeralRange.h"
@@ -41,7 +39,6 @@
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/iterators/CharacterIterator.h"
-#include "core/editing/iterators/WordAwareIterator.h"
 #include "core/frame/LocalFrameView.h"
 #include "core/frame/UseCounter.h"
 #include "core/html/HTMLElement.h"
@@ -50,8 +47,6 @@
 #include "core/html/TextControlElement.h"
 #include "core/layout/LayoutTableCell.h"
 #include "core/layout/LayoutTableRow.h"
-#include "core/layout/LayoutTextFragment.h"
-#include "core/layout/line/InlineTextBox.h"
 #include "platform/fonts/Font.h"
 #include "platform/wtf/text/CString.h"
 #include "platform/wtf/text/StringBuilder.h"
@@ -152,11 +147,6 @@
 
 }  // namespace
 
-TextIteratorTextNodeHandler::TextIteratorTextNodeHandler(
-    const TextIteratorBehavior& behavior,
-    TextIteratorTextState* text_state)
-    : behavior_(behavior), text_state_(*text_state) {}
-
 template <typename Strategy>
 TextIteratorAlgorithm<Strategy>::TextIteratorAlgorithm(
     const PositionTemplate<Strategy>& start,
@@ -193,22 +183,6 @@
              end.ComputeContainerNode(), end.ComputeOffsetInContainerNode());
 }
 
-void TextIteratorTextNodeHandler::Initialize(Node* start_container,
-                                             int start_offset,
-                                             Node* end_container,
-                                             int end_offset) {
-  // This function should be called only once.
-  DCHECK(!start_container_);
-  DCHECK_EQ(start_offset_, 0);
-  DCHECK(!end_container_);
-  DCHECK_EQ(end_offset_, 0);
-
-  start_container_ = start_container;
-  start_offset_ = start_offset;
-  end_container_ = end_container;
-  end_offset_ = end_offset;
-}
-
 template <typename Strategy>
 void TextIteratorAlgorithm<Strategy>::Initialize(Node* start_container,
                                                  int start_offset,
@@ -281,21 +255,6 @@
   return layout_object && layout_object->IsAtomicInlineLevel();
 }
 
-bool TextIteratorTextNodeHandler::HandleRemainingTextRuns() {
-  if (ShouldProceedToRemainingText())
-    ProceedToRemainingText();
-  // Handle remembered text box
-  if (text_box_) {
-    HandleTextBox();
-    return text_state_.PositionNode();
-  }
-  // Handle remembered pre-formatted text node.
-  if (!needs_handle_pre_formatted_text_node_)
-    return false;
-  HandlePreFormattedTextNode();
-  return text_state_.PositionNode();
-}
-
 template <typename Strategy>
 void TextIteratorAlgorithm<Strategy>::Advance() {
   if (should_stop_)
@@ -508,91 +467,6 @@
   }
 }
 
-static bool HasVisibleTextNode(LayoutText* layout_object) {
-  if (layout_object->Style()->Visibility() == EVisibility::kVisible)
-    return true;
-
-  if (!layout_object->IsTextFragment())
-    return false;
-
-  LayoutTextFragment* fragment = ToLayoutTextFragment(layout_object);
-  if (!fragment->IsRemainingTextLayoutObject())
-    return false;
-
-  DCHECK(fragment->GetFirstLetterPseudoElement());
-  LayoutObject* pseudo_element_layout_object =
-      fragment->GetFirstLetterPseudoElement()->GetLayoutObject();
-  return pseudo_element_layout_object &&
-         pseudo_element_layout_object->Style()->Visibility() ==
-             EVisibility::kVisible;
-}
-
-bool TextIteratorTextNodeHandler::ShouldHandleFirstLetter(
-    const LayoutText& layout_text) const {
-  if (handled_first_letter_)
-    return false;
-  if (!layout_text.IsTextFragment())
-    return false;
-  const LayoutTextFragment& text_fragment = ToLayoutTextFragment(layout_text);
-  return offset_ < static_cast<int>(text_fragment.TextStartOffset());
-}
-
-void TextIteratorTextNodeHandler::HandlePreFormattedTextNode() {
-  // TODO(xiaochengh): Get rid of repeated computation of these fields.
-  LayoutText* const layout_object = text_node_->GetLayoutObject();
-  const String str = layout_object->GetText();
-
-  needs_handle_pre_formatted_text_node_ = false;
-
-  if (last_text_node_ended_with_collapsed_space_ &&
-      HasVisibleTextNode(layout_object)) {
-    if (!behavior_.CollapseTrailingSpace() ||
-        (offset_ > 0 && str[offset_ - 1] == ' ')) {
-      SpliceBuffer(kSpaceCharacter, text_node_, 0, offset_, offset_);
-      needs_handle_pre_formatted_text_node_ = true;
-      return;
-    }
-  }
-  if (ShouldHandleFirstLetter(*layout_object)) {
-    HandleTextNodeFirstLetter(ToLayoutTextFragment(layout_object));
-    if (first_letter_text_) {
-      const String first_letter = first_letter_text_->GetText();
-      const unsigned run_start = offset_;
-      const bool stops_in_first_letter =
-          text_node_ == end_container_ &&
-          end_offset_ <= static_cast<int>(first_letter.length());
-      const unsigned run_end =
-          stops_in_first_letter ? end_offset_ : first_letter.length();
-      EmitText(text_node_, first_letter_text_, run_start, run_end);
-      first_letter_text_ = nullptr;
-      text_box_ = 0;
-      offset_ = run_end;
-      if (!stops_in_first_letter)
-        needs_handle_pre_formatted_text_node_ = true;
-      return;
-    }
-    // We are here only if the DOM and/or layout trees are broken.
-    // For robustness, we should stop processing this node.
-    NOTREACHED();
-    return;
-  }
-  if (layout_object->Style()->Visibility() != EVisibility::kVisible &&
-      !IgnoresStyleVisibility())
-    return;
-  DCHECK_GE(static_cast<unsigned>(offset_), layout_object->TextStartOffset());
-  const unsigned run_start = offset_ - layout_object->TextStartOffset();
-  const unsigned str_length = str.length();
-  const unsigned end = (text_node_ == end_container_)
-                           ? end_offset_ - layout_object->TextStartOffset()
-                           : str_length;
-  const unsigned run_end = std::min(str_length, end);
-
-  if (run_start >= run_end)
-    return;
-
-  EmitText(text_node_, text_node_->GetLayoutObject(), run_start, run_end);
-}
-
 template <typename Strategy>
 bool TextIteratorAlgorithm<Strategy>::HandleTextNode() {
   if (ExcludesAutofilledValue()) {
@@ -609,267 +483,6 @@
   return text_node_handler_.HandleTextNode(ToText(node_));
 }
 
-bool TextIteratorTextNodeHandler::HandleTextNode(Text* node) {
-  text_node_ = node;
-  offset_ = text_node_ == start_container_ ? start_offset_ : 0;
-  handled_first_letter_ = false;
-  first_letter_text_ = nullptr;
-
-  LayoutText* layout_object = text_node_->GetLayoutObject();
-  String str = layout_object->GetText();
-
-  // handle pre-formatted text
-  if (!layout_object->Style()->CollapseWhiteSpace()) {
-    HandlePreFormattedTextNode();
-    return true;
-  }
-
-  if (layout_object->FirstTextBox())
-    text_box_ = layout_object->FirstTextBox();
-
-  const bool should_handle_first_letter =
-      ShouldHandleFirstLetter(*layout_object);
-  if (should_handle_first_letter)
-    HandleTextNodeFirstLetter(ToLayoutTextFragment(layout_object));
-
-  if (!layout_object->FirstTextBox() && str.length() > 0 &&
-      !should_handle_first_letter) {
-    if (layout_object->Style()->Visibility() != EVisibility::kVisible &&
-        !IgnoresStyleVisibility())
-      return false;
-    last_text_node_ended_with_collapsed_space_ =
-        true;  // entire block is collapsed space
-    return true;
-  }
-
-  if (first_letter_text_)
-    layout_object = first_letter_text_;
-
-  // Used when text boxes are out of order (Hebrew/Arabic w/ embeded LTR text)
-  if (layout_object->ContainsReversedText()) {
-    sorted_text_boxes_.clear();
-    for (InlineTextBox* text_box = layout_object->FirstTextBox(); text_box;
-         text_box = text_box->NextTextBox()) {
-      sorted_text_boxes_.push_back(text_box);
-    }
-    std::sort(sorted_text_boxes_.begin(), sorted_text_boxes_.end(),
-              InlineTextBox::CompareByStart);
-    sorted_text_boxes_position_ = 0;
-    text_box_ = sorted_text_boxes_.IsEmpty() ? 0 : sorted_text_boxes_[0];
-  }
-
-  HandleTextBox();
-  return true;
-}
-
-// Restore the collapsed space for copy & paste. See http://crbug.com/318925
-size_t TextIteratorTextNodeHandler::RestoreCollapsedTrailingSpace(
-    InlineTextBox* next_text_box,
-    size_t subrun_end) {
-  if (next_text_box || !text_box_->Root().NextRootBox() ||
-      text_box_->Root().LastChild() != text_box_)
-    return subrun_end;
-
-  const String& text = text_node_->GetLayoutObject()->GetText();
-  if (text.EndsWith(' ') == 0 || subrun_end != text.length() - 1 ||
-      text[subrun_end - 1] == ' ')
-    return subrun_end;
-
-  // If there is the leading space in the next line, we don't need to restore
-  // the trailing space.
-  // Example: <div style="width: 2em;"><b><i>foo </i></b> bar</div>
-  InlineBox* first_box_of_next_line =
-      text_box_->Root().NextRootBox()->FirstChild();
-  if (!first_box_of_next_line)
-    return subrun_end + 1;
-  Node* first_node_of_next_line =
-      first_box_of_next_line->GetLineLayoutItem().GetNode();
-  if (!first_node_of_next_line ||
-      first_node_of_next_line->nodeValue()[0] != ' ')
-    return subrun_end + 1;
-
-  return subrun_end;
-}
-
-void TextIteratorTextNodeHandler::HandleTextBox() {
-  LayoutText* layout_object =
-      first_letter_text_ ? first_letter_text_ : text_node_->GetLayoutObject();
-  const unsigned text_start_offset = layout_object->TextStartOffset();
-
-  if (layout_object->Style()->Visibility() != EVisibility::kVisible &&
-      !IgnoresStyleVisibility()) {
-    text_box_ = nullptr;
-  } else {
-    String str = layout_object->GetText();
-    // Start and end offsets in |str|, i.e., str[start..end - 1] should be
-    // emitted (after handling whitespace collapsing).
-    const unsigned start = offset_ - layout_object->TextStartOffset();
-    const unsigned end =
-        (text_node_ == end_container_)
-            ? static_cast<unsigned>(end_offset_) - text_start_offset
-            : INT_MAX;
-    while (text_box_) {
-      const unsigned text_box_start = text_box_->Start();
-      const unsigned run_start = std::max(text_box_start, start);
-
-      // Check for collapsed space at the start of this run.
-      InlineTextBox* first_text_box =
-          layout_object->ContainsReversedText()
-              ? (sorted_text_boxes_.IsEmpty() ? 0 : sorted_text_boxes_[0])
-              : layout_object->FirstTextBox();
-      const bool need_space = last_text_node_ended_with_collapsed_space_ ||
-                              (text_box_ == first_text_box &&
-                               text_box_start == run_start && run_start > 0);
-      if (need_space &&
-          !layout_object->Style()->IsCollapsibleWhiteSpace(
-              text_state_.LastCharacter()) &&
-          text_state_.LastCharacter()) {
-        if (run_start > 0 && str[run_start - 1] == ' ') {
-          unsigned space_run_start = run_start - 1;
-          while (space_run_start > 0 && str[space_run_start - 1] == ' ')
-            --space_run_start;
-          EmitText(text_node_, layout_object, space_run_start,
-                   space_run_start + 1);
-        } else {
-          SpliceBuffer(kSpaceCharacter, text_node_, 0, run_start, run_start);
-        }
-        return;
-      }
-      const unsigned text_box_end = text_box_start + text_box_->Len();
-      const unsigned run_end = std::min(text_box_end, end);
-
-      // Determine what the next text box will be, but don't advance yet
-      InlineTextBox* next_text_box = nullptr;
-      if (layout_object->ContainsReversedText()) {
-        if (sorted_text_boxes_position_ + 1 < sorted_text_boxes_.size())
-          next_text_box = sorted_text_boxes_[sorted_text_boxes_position_ + 1];
-      } else {
-        next_text_box = text_box_->NextTextBox();
-      }
-
-      // FIXME: Based on the outcome of crbug.com/446502 it's possible we can
-      //   remove this block. The reason we new it now is because BIDI and
-      //   FirstLetter seem to have different ideas of where things can split.
-      //   FirstLetter takes the punctuation + first letter, and BIDI will
-      //   split out the punctuation and possibly reorder it.
-      if (next_text_box &&
-          !(next_text_box->GetLineLayoutItem().IsEqual(layout_object))) {
-        text_box_ = 0;
-        return;
-      }
-      DCHECK(!next_text_box ||
-             next_text_box->GetLineLayoutItem().IsEqual(layout_object));
-
-      if (run_start < run_end) {
-        // Handle either a single newline character (which becomes a space),
-        // or a run of characters that does not include a newline.
-        // This effectively translates newlines to spaces without copying the
-        // text.
-        if (str[run_start] == '\n') {
-          // We need to preserve new lines in case of PreLine.
-          // See bug crbug.com/317365.
-          if (layout_object->Style()->WhiteSpace() == EWhiteSpace::kPreLine) {
-            SpliceBuffer('\n', text_node_, 0, run_start, run_start);
-          } else {
-            SpliceBuffer(kSpaceCharacter, text_node_, 0, run_start,
-                         run_start + 1);
-          }
-          offset_ = text_start_offset + run_start + 1;
-        } else {
-          size_t subrun_end = str.find('\n', run_start);
-          if (subrun_end == kNotFound || subrun_end > run_end) {
-            subrun_end = run_end;
-            subrun_end =
-                RestoreCollapsedTrailingSpace(next_text_box, subrun_end);
-          }
-
-          offset_ = text_start_offset + subrun_end;
-          EmitText(text_node_, layout_object, run_start, subrun_end);
-        }
-
-        // If we are doing a subrun that doesn't go to the end of the text box,
-        // come back again to finish handling this text box; don't advance to
-        // the next one.
-        if (static_cast<unsigned>(text_state_.PositionEndOffset()) <
-            text_box_end)
-          return;
-
-        if (behavior_.DoesNotEmitSpaceBeyondRangeEnd()) {
-          // If the subrun went to the text box end and this end is also the end
-          // of the range, do not advance to the next text box and do not
-          // generate a space, just stop.
-          if (text_box_end == end) {
-            text_box_ = nullptr;
-            return;
-          }
-        }
-
-        // Advance and return
-        const unsigned next_run_start =
-            next_text_box ? next_text_box->Start() : str.length();
-        if (next_run_start > run_end)
-          last_text_node_ended_with_collapsed_space_ =
-              true;  // collapsed space between runs or at the end
-
-        text_box_ = next_text_box;
-        if (layout_object->ContainsReversedText())
-          ++sorted_text_boxes_position_;
-        return;
-      }
-      // Advance and continue
-      text_box_ = next_text_box;
-      if (layout_object->ContainsReversedText())
-        ++sorted_text_boxes_position_;
-    }
-  }
-
-  if (ShouldProceedToRemainingText()) {
-    ProceedToRemainingText();
-    HandleTextBox();
-  }
-}
-
-bool TextIteratorTextNodeHandler::ShouldProceedToRemainingText() const {
-  if (text_box_ || !remaining_text_box_)
-    return false;
-  if (text_node_ != end_container_)
-    return true;
-  return offset_ < end_offset_;
-}
-
-void TextIteratorTextNodeHandler::ProceedToRemainingText() {
-  text_box_ = remaining_text_box_;
-  remaining_text_box_ = 0;
-  first_letter_text_ = nullptr;
-  offset_ = text_node_->GetLayoutObject()->TextStartOffset();
-}
-
-void TextIteratorTextNodeHandler::HandleTextNodeFirstLetter(
-    LayoutTextFragment* layout_object) {
-  handled_first_letter_ = true;
-
-  if (!layout_object->IsRemainingTextLayoutObject())
-    return;
-
-  FirstLetterPseudoElement* first_letter_element =
-      layout_object->GetFirstLetterPseudoElement();
-  if (!first_letter_element)
-    return;
-
-  LayoutObject* pseudo_layout_object = first_letter_element->GetLayoutObject();
-  if (pseudo_layout_object->Style()->Visibility() != EVisibility::kVisible &&
-      !IgnoresStyleVisibility())
-    return;
-
-  LayoutObject* first_letter = pseudo_layout_object->SlowFirstChild();
-
-  sorted_text_boxes_.clear();
-  remaining_text_box_ = text_box_;
-  CHECK(first_letter && first_letter->IsText());
-  first_letter_text_ = ToLayoutText(first_letter);
-  text_box_ = first_letter_text_->FirstTextBox();
-}
-
 template <typename Strategy>
 bool TextIteratorAlgorithm<Strategy>::SupportsAltText(Node* node) {
   if (!node->IsHTMLElement())
@@ -885,28 +498,6 @@
   return false;
 }
 
-bool TextIteratorTextNodeHandler::FixLeadingWhiteSpaceForReplacedElement(
-    Node* parent) {
-  // This is a hacky way for white space fixup in legacy layout. With LayoutNG,
-  // we can get rid of this function.
-
-  if (behavior_.CollapseTrailingSpace()) {
-    if (text_node_) {
-      String str = text_node_->GetLayoutObject()->GetText();
-      if (last_text_node_ended_with_collapsed_space_ && offset_ > 0 &&
-          str[offset_ - 1] == ' ') {
-        SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1);
-        return true;
-      }
-    }
-  } else if (last_text_node_ended_with_collapsed_space_) {
-    SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1);
-    return true;
-  }
-
-  return false;
-}
-
 template <typename Strategy>
 bool TextIteratorAlgorithm<Strategy>::HandleReplacedElement() {
   if (fully_clipped_stack_.Top())
@@ -1227,12 +818,6 @@
                  1);
 }
 
-void TextIteratorTextNodeHandler::ResetCollapsedWhiteSpaceFixup() {
-  // This is a hacky way for white space fixup in legacy layout. With LayoutNG,
-  // we can get rid of this function.
-  last_text_node_ended_with_collapsed_space_ = false;
-}
-
 template <typename Strategy>
 void TextIteratorAlgorithm<Strategy>::SpliceBuffer(UChar c,
                                                    Node* text_node,
@@ -1244,25 +829,6 @@
   text_node_handler_.ResetCollapsedWhiteSpaceFixup();
 }
 
-void TextIteratorTextNodeHandler::SpliceBuffer(UChar c,
-                                               Node* text_node,
-                                               Node* offset_base_node,
-                                               int text_start_offset,
-                                               int text_end_offset) {
-  text_state_.SpliceBuffer(c, text_node, offset_base_node, text_start_offset,
-                           text_end_offset);
-  ResetCollapsedWhiteSpaceFixup();
-}
-
-void TextIteratorTextNodeHandler::EmitText(Node* text_node,
-                                           LayoutText* layout_object,
-                                           int text_start_offset,
-                                           int text_end_offset) {
-  text_state_.EmitText(text_node, layout_object, text_start_offset,
-                       text_end_offset);
-  ResetCollapsedWhiteSpaceFixup();
-}
-
 template <typename Strategy>
 EphemeralRangeTemplate<Strategy> TextIteratorAlgorithm<Strategy>::Range()
     const {
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.h b/third_party/WebKit/Source/core/editing/iterators/TextIterator.h
index 2c3e4ec4..fd420e0 100644
--- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.h
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.h
@@ -32,16 +32,12 @@
 #include "core/editing/FindOptions.h"
 #include "core/editing/iterators/FullyClippedStateStack.h"
 #include "core/editing/iterators/TextIteratorBehavior.h"
+#include "core/editing/iterators/TextIteratorTextNodeHandler.h"
 #include "core/editing/iterators/TextIteratorTextState.h"
 #include "platform/heap/Handle.h"
-#include "platform/wtf/Vector.h"
 
 namespace blink {
 
-class InlineTextBox;
-class LayoutText;
-class LayoutTextFragment;
-
 CORE_EXPORT String
 PlainText(const EphemeralRange&,
           const TextIteratorBehavior& = TextIteratorBehavior());
@@ -49,102 +45,6 @@
 String PlainText(const EphemeralRangeInFlatTree&,
                  const TextIteratorBehavior& = TextIteratorBehavior());
 
-// TODO(xiaochengh): Move the class to dedicated files.
-// TextIteratorTextNodeHandler extracts plain text from a text node by calling
-// HandleTextNode() function. It should be used only by TextIterator.
-class TextIteratorTextNodeHandler final {
-  STACK_ALLOCATED();
-
- public:
-  TextIteratorTextNodeHandler(const TextIteratorBehavior&,
-                              TextIteratorTextState*);
-
-  // Initializes the full iteration range of the TextIterator. This function
-  // should be called only once from TextIterator::Initialize.
-  // TODO(xiaochengh): TextNodeHandler doesn't need to know the full iteration
-  // range; The offset range in the current node suffices. Remove this function.
-  void Initialize(Node* start_container,
-                  int start_offset,
-                  Node* end_container,
-                  int end_offset);
-
-  Text* GetNode() const { return text_node_; }
-
-  // Returns true if more text is emitted without traversing to the next node.
-  bool HandleRemainingTextRuns();
-
-  // Returns true if a leading white space is emitted before a replaced element.
-  bool FixLeadingWhiteSpaceForReplacedElement(Node*);
-
-  void ResetCollapsedWhiteSpaceFixup();
-
-  // TODO(xiaochengh): Make the return type |void|. The current return value is
-  // not very meaningful.
-  bool HandleTextNode(Text*);
-
- private:
-  void HandlePreFormattedTextNode();
-  void HandleTextBox();
-  void HandleTextNodeFirstLetter(LayoutTextFragment*);
-  bool ShouldHandleFirstLetter(const LayoutText&) const;
-  bool ShouldProceedToRemainingText() const;
-  void ProceedToRemainingText();
-  size_t RestoreCollapsedTrailingSpace(InlineTextBox* next_text_box,
-                                       size_t subrun_end);
-
-  // Used when the visibility of the style should not affect text gathering.
-  bool IgnoresStyleVisibility() const {
-    return behavior_.IgnoresStyleVisibility();
-  }
-
-  void SpliceBuffer(UChar,
-                    Node* text_node,
-                    Node* offset_base_node,
-                    int text_start_offset,
-                    int text_end_offset);
-  void EmitText(Node* text_node,
-                LayoutText* layout_object,
-                int text_start_offset,
-                int text_end_offset);
-
-  // The range.
-  Member<Node> start_container_;
-  int start_offset_ = 0;
-  Member<Node> end_container_;
-  int end_offset_ = 0;
-
-  // The current text node and offset, from which text is being emitted.
-  Member<Text> text_node_;
-  int offset_ = 0;
-
-  InlineTextBox* text_box_ = nullptr;
-
-  // Remember if we are in the middle of handling a pre-formatted text node.
-  bool needs_handle_pre_formatted_text_node_ = false;
-  // Used when deciding text fragment created by :first-letter should be looked
-  // into.
-  bool handled_first_letter_ = false;
-  // Used when iteration over :first-letter text to save pointer to
-  // remaining text box.
-  InlineTextBox* remaining_text_box_ = nullptr;
-  // Used to point to LayoutText object for :first-letter.
-  LayoutText* first_letter_text_ = nullptr;
-
-  // Used to do the whitespace collapsing logic.
-  bool last_text_node_ended_with_collapsed_space_ = false;
-
-  // Used when text boxes are out of order (Hebrew/Arabic w/ embeded LTR text)
-  Vector<InlineTextBox*> sorted_text_boxes_;
-  size_t sorted_text_boxes_position_ = 0;
-
-  const TextIteratorBehavior behavior_;
-
-  // Contains state of emitted text.
-  TextIteratorTextState& text_state_;
-
-  DISALLOW_COPY_AND_ASSIGN(TextIteratorTextNodeHandler);
-};
-
 // Iterates through the DOM range, returning all the text, and 0-length
 // boundaries at points where replaced elements break up the text flow.  The
 // text comes back in chunks so as to optimize for performance of the iteration.
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.cpp
new file mode 100644
index 0000000..4c6c9dd
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.cpp
@@ -0,0 +1,446 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/editing/iterators/TextIteratorTextNodeHandler.h"
+
+#include <algorithm>
+#include "core/dom/FirstLetterPseudoElement.h"
+#include "core/editing/iterators/TextIteratorTextState.h"
+#include "core/layout/LayoutTextFragment.h"
+#include "core/layout/line/InlineTextBox.h"
+#include "core/layout/line/RootInlineBox.h"
+
+namespace blink {
+
+TextIteratorTextNodeHandler::TextIteratorTextNodeHandler(
+    const TextIteratorBehavior& behavior,
+    TextIteratorTextState* text_state)
+    : behavior_(behavior), text_state_(*text_state) {}
+
+void TextIteratorTextNodeHandler::Initialize(Node* start_container,
+                                             int start_offset,
+                                             Node* end_container,
+                                             int end_offset) {
+  // This function should be called only once.
+  DCHECK(!start_container_);
+  DCHECK_EQ(start_offset_, 0);
+  DCHECK(!end_container_);
+  DCHECK_EQ(end_offset_, 0);
+
+  start_container_ = start_container;
+  start_offset_ = start_offset;
+  end_container_ = end_container;
+  end_offset_ = end_offset;
+}
+
+bool TextIteratorTextNodeHandler::HandleRemainingTextRuns() {
+  if (ShouldProceedToRemainingText())
+    ProceedToRemainingText();
+  // Handle remembered text box
+  if (text_box_) {
+    HandleTextBox();
+    return text_state_.PositionNode();
+  }
+  // Handle remembered pre-formatted text node.
+  if (!needs_handle_pre_formatted_text_node_)
+    return false;
+  HandlePreFormattedTextNode();
+  return text_state_.PositionNode();
+}
+
+bool TextIteratorTextNodeHandler::ShouldHandleFirstLetter(
+    const LayoutText& layout_text) const {
+  if (handled_first_letter_)
+    return false;
+  if (!layout_text.IsTextFragment())
+    return false;
+  const LayoutTextFragment& text_fragment = ToLayoutTextFragment(layout_text);
+  return offset_ < static_cast<int>(text_fragment.TextStartOffset());
+}
+
+static bool HasVisibleTextNode(LayoutText* layout_object) {
+  if (layout_object->Style()->Visibility() == EVisibility::kVisible)
+    return true;
+
+  if (!layout_object->IsTextFragment())
+    return false;
+
+  LayoutTextFragment* fragment = ToLayoutTextFragment(layout_object);
+  if (!fragment->IsRemainingTextLayoutObject())
+    return false;
+
+  DCHECK(fragment->GetFirstLetterPseudoElement());
+  LayoutObject* pseudo_element_layout_object =
+      fragment->GetFirstLetterPseudoElement()->GetLayoutObject();
+  return pseudo_element_layout_object &&
+         pseudo_element_layout_object->Style()->Visibility() ==
+             EVisibility::kVisible;
+}
+
+void TextIteratorTextNodeHandler::HandlePreFormattedTextNode() {
+  // TODO(xiaochengh): Get rid of repeated computation of these fields.
+  LayoutText* const layout_object = text_node_->GetLayoutObject();
+  const String str = layout_object->GetText();
+
+  needs_handle_pre_formatted_text_node_ = false;
+
+  if (last_text_node_ended_with_collapsed_space_ &&
+      HasVisibleTextNode(layout_object)) {
+    if (!behavior_.CollapseTrailingSpace() ||
+        (offset_ > 0 && str[offset_ - 1] == ' ')) {
+      SpliceBuffer(kSpaceCharacter, text_node_, 0, offset_, offset_);
+      needs_handle_pre_formatted_text_node_ = true;
+      return;
+    }
+  }
+  if (ShouldHandleFirstLetter(*layout_object)) {
+    HandleTextNodeFirstLetter(ToLayoutTextFragment(layout_object));
+    if (first_letter_text_) {
+      const String first_letter = first_letter_text_->GetText();
+      const unsigned run_start = offset_;
+      const bool stops_in_first_letter =
+          text_node_ == end_container_ &&
+          end_offset_ <= static_cast<int>(first_letter.length());
+      const unsigned run_end =
+          stops_in_first_letter ? end_offset_ : first_letter.length();
+      EmitText(text_node_, first_letter_text_, run_start, run_end);
+      first_letter_text_ = nullptr;
+      text_box_ = 0;
+      offset_ = run_end;
+      if (!stops_in_first_letter)
+        needs_handle_pre_formatted_text_node_ = true;
+      return;
+    }
+    // We are here only if the DOM and/or layout trees are broken.
+    // For robustness, we should stop processing this node.
+    NOTREACHED();
+    return;
+  }
+  if (layout_object->Style()->Visibility() != EVisibility::kVisible &&
+      !IgnoresStyleVisibility())
+    return;
+  DCHECK_GE(static_cast<unsigned>(offset_), layout_object->TextStartOffset());
+  const unsigned run_start = offset_ - layout_object->TextStartOffset();
+  const unsigned str_length = str.length();
+  const unsigned end = (text_node_ == end_container_)
+                           ? end_offset_ - layout_object->TextStartOffset()
+                           : str_length;
+  const unsigned run_end = std::min(str_length, end);
+
+  if (run_start >= run_end)
+    return;
+
+  EmitText(text_node_, text_node_->GetLayoutObject(), run_start, run_end);
+}
+
+bool TextIteratorTextNodeHandler::HandleTextNode(Text* node) {
+  text_node_ = node;
+  offset_ = text_node_ == start_container_ ? start_offset_ : 0;
+  handled_first_letter_ = false;
+  first_letter_text_ = nullptr;
+
+  LayoutText* layout_object = text_node_->GetLayoutObject();
+  String str = layout_object->GetText();
+
+  // handle pre-formatted text
+  if (!layout_object->Style()->CollapseWhiteSpace()) {
+    HandlePreFormattedTextNode();
+    return true;
+  }
+
+  if (layout_object->FirstTextBox())
+    text_box_ = layout_object->FirstTextBox();
+
+  const bool should_handle_first_letter =
+      ShouldHandleFirstLetter(*layout_object);
+  if (should_handle_first_letter)
+    HandleTextNodeFirstLetter(ToLayoutTextFragment(layout_object));
+
+  if (!layout_object->FirstTextBox() && str.length() > 0 &&
+      !should_handle_first_letter) {
+    if (layout_object->Style()->Visibility() != EVisibility::kVisible &&
+        !IgnoresStyleVisibility())
+      return false;
+    last_text_node_ended_with_collapsed_space_ =
+        true;  // entire block is collapsed space
+    return true;
+  }
+
+  if (first_letter_text_)
+    layout_object = first_letter_text_;
+
+  // Used when text boxes are out of order (Hebrew/Arabic w/ embeded LTR text)
+  if (layout_object->ContainsReversedText()) {
+    sorted_text_boxes_.clear();
+    for (InlineTextBox* text_box = layout_object->FirstTextBox(); text_box;
+         text_box = text_box->NextTextBox()) {
+      sorted_text_boxes_.push_back(text_box);
+    }
+    std::sort(sorted_text_boxes_.begin(), sorted_text_boxes_.end(),
+              InlineTextBox::CompareByStart);
+    sorted_text_boxes_position_ = 0;
+    text_box_ = sorted_text_boxes_.IsEmpty() ? 0 : sorted_text_boxes_[0];
+  }
+
+  HandleTextBox();
+  return true;
+}
+
+// Restore the collapsed space for copy & paste. See http://crbug.com/318925
+size_t TextIteratorTextNodeHandler::RestoreCollapsedTrailingSpace(
+    InlineTextBox* next_text_box,
+    size_t subrun_end) {
+  if (next_text_box || !text_box_->Root().NextRootBox() ||
+      text_box_->Root().LastChild() != text_box_)
+    return subrun_end;
+
+  const String& text = text_node_->GetLayoutObject()->GetText();
+  if (text.EndsWith(' ') == 0 || subrun_end != text.length() - 1 ||
+      text[subrun_end - 1] == ' ')
+    return subrun_end;
+
+  // If there is the leading space in the next line, we don't need to restore
+  // the trailing space.
+  // Example: <div style="width: 2em;"><b><i>foo </i></b> bar</div>
+  InlineBox* first_box_of_next_line =
+      text_box_->Root().NextRootBox()->FirstChild();
+  if (!first_box_of_next_line)
+    return subrun_end + 1;
+  Node* first_node_of_next_line =
+      first_box_of_next_line->GetLineLayoutItem().GetNode();
+  if (!first_node_of_next_line ||
+      first_node_of_next_line->nodeValue()[0] != ' ')
+    return subrun_end + 1;
+
+  return subrun_end;
+}
+
+void TextIteratorTextNodeHandler::HandleTextBox() {
+  LayoutText* layout_object =
+      first_letter_text_ ? first_letter_text_ : text_node_->GetLayoutObject();
+  const unsigned text_start_offset = layout_object->TextStartOffset();
+
+  if (layout_object->Style()->Visibility() != EVisibility::kVisible &&
+      !IgnoresStyleVisibility()) {
+    text_box_ = nullptr;
+  } else {
+    String str = layout_object->GetText();
+    // Start and end offsets in |str|, i.e., str[start..end - 1] should be
+    // emitted (after handling whitespace collapsing).
+    const unsigned start = offset_ - layout_object->TextStartOffset();
+    const unsigned end =
+        (text_node_ == end_container_)
+            ? static_cast<unsigned>(end_offset_) - text_start_offset
+            : INT_MAX;
+    while (text_box_) {
+      const unsigned text_box_start = text_box_->Start();
+      const unsigned run_start = std::max(text_box_start, start);
+
+      // Check for collapsed space at the start of this run.
+      InlineTextBox* first_text_box =
+          layout_object->ContainsReversedText()
+              ? (sorted_text_boxes_.IsEmpty() ? 0 : sorted_text_boxes_[0])
+              : layout_object->FirstTextBox();
+      const bool need_space = last_text_node_ended_with_collapsed_space_ ||
+                              (text_box_ == first_text_box &&
+                               text_box_start == run_start && run_start > 0);
+      if (need_space &&
+          !layout_object->Style()->IsCollapsibleWhiteSpace(
+              text_state_.LastCharacter()) &&
+          text_state_.LastCharacter()) {
+        if (run_start > 0 && str[run_start - 1] == ' ') {
+          unsigned space_run_start = run_start - 1;
+          while (space_run_start > 0 && str[space_run_start - 1] == ' ')
+            --space_run_start;
+          EmitText(text_node_, layout_object, space_run_start,
+                   space_run_start + 1);
+        } else {
+          SpliceBuffer(kSpaceCharacter, text_node_, 0, run_start, run_start);
+        }
+        return;
+      }
+      const unsigned text_box_end = text_box_start + text_box_->Len();
+      const unsigned run_end = std::min(text_box_end, end);
+
+      // Determine what the next text box will be, but don't advance yet
+      InlineTextBox* next_text_box = nullptr;
+      if (layout_object->ContainsReversedText()) {
+        if (sorted_text_boxes_position_ + 1 < sorted_text_boxes_.size())
+          next_text_box = sorted_text_boxes_[sorted_text_boxes_position_ + 1];
+      } else {
+        next_text_box = text_box_->NextTextBox();
+      }
+
+      // FIXME: Based on the outcome of crbug.com/446502 it's possible we can
+      //   remove this block. The reason we new it now is because BIDI and
+      //   FirstLetter seem to have different ideas of where things can split.
+      //   FirstLetter takes the punctuation + first letter, and BIDI will
+      //   split out the punctuation and possibly reorder it.
+      if (next_text_box &&
+          !(next_text_box->GetLineLayoutItem().IsEqual(layout_object))) {
+        text_box_ = 0;
+        return;
+      }
+      DCHECK(!next_text_box ||
+             next_text_box->GetLineLayoutItem().IsEqual(layout_object));
+
+      if (run_start < run_end) {
+        // Handle either a single newline character (which becomes a space),
+        // or a run of characters that does not include a newline.
+        // This effectively translates newlines to spaces without copying the
+        // text.
+        if (str[run_start] == '\n') {
+          // We need to preserve new lines in case of PreLine.
+          // See bug crbug.com/317365.
+          if (layout_object->Style()->WhiteSpace() == EWhiteSpace::kPreLine) {
+            SpliceBuffer('\n', text_node_, 0, run_start, run_start);
+          } else {
+            SpliceBuffer(kSpaceCharacter, text_node_, 0, run_start,
+                         run_start + 1);
+          }
+          offset_ = text_start_offset + run_start + 1;
+        } else {
+          size_t subrun_end = str.find('\n', run_start);
+          if (subrun_end == kNotFound || subrun_end > run_end) {
+            subrun_end = run_end;
+            subrun_end =
+                RestoreCollapsedTrailingSpace(next_text_box, subrun_end);
+          }
+
+          offset_ = text_start_offset + subrun_end;
+          EmitText(text_node_, layout_object, run_start, subrun_end);
+        }
+
+        // If we are doing a subrun that doesn't go to the end of the text box,
+        // come back again to finish handling this text box; don't advance to
+        // the next one.
+        if (static_cast<unsigned>(text_state_.PositionEndOffset()) <
+            text_box_end)
+          return;
+
+        if (behavior_.DoesNotEmitSpaceBeyondRangeEnd()) {
+          // If the subrun went to the text box end and this end is also the end
+          // of the range, do not advance to the next text box and do not
+          // generate a space, just stop.
+          if (text_box_end == end) {
+            text_box_ = nullptr;
+            return;
+          }
+        }
+
+        // Advance and return
+        const unsigned next_run_start =
+            next_text_box ? next_text_box->Start() : str.length();
+        if (next_run_start > run_end) {
+          last_text_node_ended_with_collapsed_space_ =
+              true;  // collapsed space between runs or at the end
+        }
+
+        text_box_ = next_text_box;
+        if (layout_object->ContainsReversedText())
+          ++sorted_text_boxes_position_;
+        return;
+      }
+      // Advance and continue
+      text_box_ = next_text_box;
+      if (layout_object->ContainsReversedText())
+        ++sorted_text_boxes_position_;
+    }
+  }
+
+  if (ShouldProceedToRemainingText()) {
+    ProceedToRemainingText();
+    HandleTextBox();
+  }
+}
+
+bool TextIteratorTextNodeHandler::ShouldProceedToRemainingText() const {
+  if (text_box_ || !remaining_text_box_)
+    return false;
+  if (text_node_ != end_container_)
+    return true;
+  return offset_ < end_offset_;
+}
+
+void TextIteratorTextNodeHandler::ProceedToRemainingText() {
+  text_box_ = remaining_text_box_;
+  remaining_text_box_ = 0;
+  first_letter_text_ = nullptr;
+  offset_ = text_node_->GetLayoutObject()->TextStartOffset();
+}
+
+void TextIteratorTextNodeHandler::HandleTextNodeFirstLetter(
+    LayoutTextFragment* layout_object) {
+  handled_first_letter_ = true;
+
+  if (!layout_object->IsRemainingTextLayoutObject())
+    return;
+
+  FirstLetterPseudoElement* first_letter_element =
+      layout_object->GetFirstLetterPseudoElement();
+  if (!first_letter_element)
+    return;
+
+  LayoutObject* pseudo_layout_object = first_letter_element->GetLayoutObject();
+  if (pseudo_layout_object->Style()->Visibility() != EVisibility::kVisible &&
+      !IgnoresStyleVisibility())
+    return;
+
+  LayoutObject* first_letter = pseudo_layout_object->SlowFirstChild();
+
+  sorted_text_boxes_.clear();
+  remaining_text_box_ = text_box_;
+  CHECK(first_letter && first_letter->IsText());
+  first_letter_text_ = ToLayoutText(first_letter);
+  text_box_ = first_letter_text_->FirstTextBox();
+}
+
+bool TextIteratorTextNodeHandler::FixLeadingWhiteSpaceForReplacedElement(
+    Node* parent) {
+  // This is a hacky way for white space fixup in legacy layout. With LayoutNG,
+  // we can get rid of this function.
+
+  if (behavior_.CollapseTrailingSpace()) {
+    if (text_node_) {
+      String str = text_node_->GetLayoutObject()->GetText();
+      if (last_text_node_ended_with_collapsed_space_ && offset_ > 0 &&
+          str[offset_ - 1] == ' ') {
+        SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1);
+        return true;
+      }
+    }
+  } else if (last_text_node_ended_with_collapsed_space_) {
+    SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1);
+    return true;
+  }
+
+  return false;
+}
+
+void TextIteratorTextNodeHandler::ResetCollapsedWhiteSpaceFixup() {
+  // This is a hacky way for white space fixup in legacy layout. With LayoutNG,
+  // we can get rid of this function.
+  last_text_node_ended_with_collapsed_space_ = false;
+}
+
+void TextIteratorTextNodeHandler::SpliceBuffer(UChar c,
+                                               Node* text_node,
+                                               Node* offset_base_node,
+                                               int text_start_offset,
+                                               int text_end_offset) {
+  text_state_.SpliceBuffer(c, text_node, offset_base_node, text_start_offset,
+                           text_end_offset);
+  ResetCollapsedWhiteSpaceFixup();
+}
+
+void TextIteratorTextNodeHandler::EmitText(Node* text_node,
+                                           LayoutText* layout_object,
+                                           int text_start_offset,
+                                           int text_end_offset) {
+  text_state_.EmitText(text_node, layout_object, text_start_offset,
+                       text_end_offset);
+  ResetCollapsedWhiteSpaceFixup();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.h b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.h
new file mode 100644
index 0000000..dc794df
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextNodeHandler.h
@@ -0,0 +1,117 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TextIteratorTextNodeHandler_h
+#define TextIteratorTextNodeHandler_h
+
+#include "core/dom/Text.h"
+#include "core/editing/iterators/TextIteratorBehavior.h"
+#include "platform/heap/Handle.h"
+#include "platform/wtf/Vector.h"
+
+namespace blink {
+
+class InlineTextBox;
+class LayoutText;
+class LayoutTextFragment;
+class TextIteratorTextState;
+
+// TextIteratorTextNodeHandler extracts plain text from a text node by calling
+// HandleTextNode() function. It should be used only by TextIterator.
+class TextIteratorTextNodeHandler final {
+  STACK_ALLOCATED();
+
+ public:
+  TextIteratorTextNodeHandler(const TextIteratorBehavior&,
+                              TextIteratorTextState*);
+
+  // Initializes the full iteration range of the TextIterator. This function
+  // should be called only once from TextIterator::Initialize.
+  // TODO(xiaochengh): TextNodeHandler doesn't need to know the full iteration
+  // range; The offset range in the current node suffices. Remove this function.
+  void Initialize(Node* start_container,
+                  int start_offset,
+                  Node* end_container,
+                  int end_offset);
+
+  Text* GetNode() const { return text_node_; }
+
+  // Returns true if more text is emitted without traversing to the next node.
+  bool HandleRemainingTextRuns();
+
+  // Returns true if a leading white space is emitted before a replaced element.
+  bool FixLeadingWhiteSpaceForReplacedElement(Node*);
+
+  void ResetCollapsedWhiteSpaceFixup();
+
+  // TODO(xiaochengh): Make the return type |void|. The current return value is
+  // not very meaningful.
+  bool HandleTextNode(Text*);
+
+ private:
+  void HandlePreFormattedTextNode();
+  void HandleTextBox();
+  void HandleTextNodeFirstLetter(LayoutTextFragment*);
+  bool ShouldHandleFirstLetter(const LayoutText&) const;
+  bool ShouldProceedToRemainingText() const;
+  void ProceedToRemainingText();
+  size_t RestoreCollapsedTrailingSpace(InlineTextBox* next_text_box,
+                                       size_t subrun_end);
+
+  // Used when the visibility of the style should not affect text gathering.
+  bool IgnoresStyleVisibility() const {
+    return behavior_.IgnoresStyleVisibility();
+  }
+
+  void SpliceBuffer(UChar,
+                    Node* text_node,
+                    Node* offset_base_node,
+                    int text_start_offset,
+                    int text_end_offset);
+  void EmitText(Node* text_node,
+                LayoutText* layout_object,
+                int text_start_offset,
+                int text_end_offset);
+
+  // The range.
+  Member<Node> start_container_;
+  int start_offset_ = 0;
+  Member<Node> end_container_;
+  int end_offset_ = 0;
+
+  // The current text node and offset, from which text is being emitted.
+  Member<Text> text_node_;
+  int offset_ = 0;
+
+  InlineTextBox* text_box_ = nullptr;
+
+  // Remember if we are in the middle of handling a pre-formatted text node.
+  bool needs_handle_pre_formatted_text_node_ = false;
+  // Used when deciding text fragment created by :first-letter should be looked
+  // into.
+  bool handled_first_letter_ = false;
+  // Used when iteration over :first-letter text to save pointer to
+  // remaining text box.
+  InlineTextBox* remaining_text_box_ = nullptr;
+  // Used to point to LayoutText object for :first-letter.
+  LayoutText* first_letter_text_ = nullptr;
+
+  // Used to do the whitespace collapsing logic.
+  bool last_text_node_ended_with_collapsed_space_ = false;
+
+  // Used when text boxes are out of order (Hebrew/Arabic w/ embeded LTR text)
+  Vector<InlineTextBox*> sorted_text_boxes_;
+  size_t sorted_text_boxes_position_ = 0;
+
+  const TextIteratorBehavior behavior_;
+
+  // Contains state of emitted text.
+  TextIteratorTextState& text_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(TextIteratorTextNodeHandler);
+};
+
+}  // namespace blink
+
+#endif  // TextIteratorTextNodeHandler_h
diff --git a/third_party/WebKit/Source/core/editing/iterators/WordAwareIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/WordAwareIterator.cpp
deleted file mode 100644
index 59c70bd..0000000
--- a/third_party/WebKit/Source/core/editing/iterators/WordAwareIterator.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All
- * rights reserved.
- * Copyright (C) 2005 Alexey Proskuryakov.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "core/editing/iterators/WordAwareIterator.h"
-
-namespace blink {
-
-WordAwareIterator::WordAwareIterator(const Position& start, const Position& end)
-    // So we consider the first chunk from the text iterator.
-    : did_look_ahead_(true), text_iterator_(start, end) {
-  Advance();  // Get in position over the first chunk of text.
-}
-
-WordAwareIterator::~WordAwareIterator() {}
-
-// FIXME: Performance could be bad for huge spans next to each other that don't
-// fall on word boundaries.
-
-void WordAwareIterator::Advance() {
-  buffer_.Clear();
-
-  // If last time we did a look-ahead, start with that looked-ahead chunk now
-  if (!did_look_ahead_) {
-    DCHECK(!text_iterator_.AtEnd());
-    text_iterator_.Advance();
-  }
-  did_look_ahead_ = false;
-
-  // Go to next non-empty chunk.
-  while (!text_iterator_.AtEnd() && !text_iterator_.length())
-    text_iterator_.Advance();
-
-  if (text_iterator_.AtEnd())
-    return;
-
-  while (1) {
-    // If this chunk ends in whitespace we can just use it as our chunk.
-    if (IsSpaceOrNewline(
-            text_iterator_.CharacterAt(text_iterator_.length() - 1)))
-      return;
-
-    // If this is the first chunk that failed, save it in m_buffer before look
-    // ahead.
-    if (buffer_.IsEmpty())
-      text_iterator_.CopyTextTo(&buffer_);
-
-    // Look ahead to next chunk. If it is whitespace or a break, we can use the
-    // previous stuff
-    text_iterator_.Advance();
-    if (text_iterator_.AtEnd() || !text_iterator_.length() ||
-        IsSpaceOrNewline(text_iterator_.GetText().CharacterAt(0))) {
-      did_look_ahead_ = true;
-      return;
-    }
-
-    // Start gobbling chunks until we get to a suitable stopping point
-    text_iterator_.CopyTextTo(&buffer_);
-  }
-}
-
-int WordAwareIterator::length() const {
-  if (!buffer_.IsEmpty())
-    return buffer_.Size();
-  return text_iterator_.length();
-}
-
-String WordAwareIterator::Substring(unsigned position, unsigned length) const {
-  if (!buffer_.IsEmpty())
-    return String(buffer_.Data() + position, length);
-  return text_iterator_.GetText().Substring(position, length);
-}
-
-UChar WordAwareIterator::CharacterAt(unsigned index) const {
-  if (!buffer_.IsEmpty())
-    return buffer_[index];
-  return text_iterator_.GetText().CharacterAt(index);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/iterators/WordAwareIterator.h b/third_party/WebKit/Source/core/editing/iterators/WordAwareIterator.h
deleted file mode 100644
index 91be0549..0000000
--- a/third_party/WebKit/Source/core/editing/iterators/WordAwareIterator.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WordAwareIterator_h
-#define WordAwareIterator_h
-
-#include "core/editing/iterators/TextIterator.h"
-#include "platform/heap/Heap.h"
-#include "platform/wtf/Vector.h"
-
-namespace blink {
-
-// Very similar to the TextIterator, except that the chunks of text returned are
-// "well behaved", meaning they never end split up a word.  This is useful for
-// spellcheck or (perhaps one day) searching.
-class WordAwareIterator {
-  STACK_ALLOCATED();
-
- public:
-  explicit WordAwareIterator(const Position& start, const Position& end);
-  ~WordAwareIterator();
-
-  bool AtEnd() const { return !did_look_ahead_ && text_iterator_.AtEnd(); }
-  void Advance();
-
-  String Substring(unsigned position, unsigned length) const;
-  UChar CharacterAt(unsigned index) const;
-  int length() const;
-
- private:
-  ForwardsTextBuffer buffer_;
-  // Did we have to look ahead in the textIterator to confirm the current chunk?
-  bool did_look_ahead_;
-  TextIterator text_iterator_;
-};
-
-}  // namespace blink
-
-#endif  // WordAwareIterator_h
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
index 1617f67..5d32340 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -367,19 +367,19 @@
 
   TextAlignLast alignment_last = Style()->GetTextAlignLast();
   switch (alignment_last) {
-    case kTextAlignLastStart:
+    case TextAlignLast::kStart:
       return ETextAlign::kStart;
-    case kTextAlignLastEnd:
+    case TextAlignLast::kEnd:
       return ETextAlign::kEnd;
-    case kTextAlignLastLeft:
+    case TextAlignLast::kLeft:
       return ETextAlign::kLeft;
-    case kTextAlignLastRight:
+    case TextAlignLast::kRight:
       return ETextAlign::kRight;
-    case kTextAlignLastCenter:
+    case TextAlignLast::kCenter:
       return ETextAlign::kCenter;
-    case kTextAlignLastJustify:
+    case TextAlignLast::kJustify:
       return ETextAlign::kJustify;
-    case kTextAlignLastAuto:
+    case TextAlignLast::kAuto:
       if (alignment == ETextAlign::kJustify)
         return ETextAlign::kStart;
       return alignment;
diff --git a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
index 3a59fbf..01e36ed 100644
--- a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
+++ b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
@@ -1560,8 +1560,9 @@
                                       bool is_after_hard_line_break,
                                       const ComputedStyle& style) {
   IndentTextOrNot indent_text = kDoNotIndentText;
-  if (is_first_line || (is_after_hard_line_break &&
-                        style.GetTextIndentLine()) == TextIndentLine::kEachLine)
+  if (is_first_line ||
+      (is_after_hard_line_break &&
+       style.GetTextIndentLine() != TextIndentLine::kFirstLine))
     indent_text = kIndentText;
 
   if (style.GetTextIndentType() == TextIndentType::kHanging)
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.cpp b/third_party/WebKit/Source/core/loader/PingLoader.cpp
index 85b173d5..132141c 100644
--- a/third_party/WebKit/Source/core/loader/PingLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/PingLoader.cpp
@@ -198,8 +198,7 @@
   PingLoaderImpl(LocalFrame*,
                  ResourceRequest&,
                  const AtomicString&,
-                 StoredCredentials,
-                 bool);
+                 StoredCredentials);
   ~PingLoaderImpl() override;
 
   DECLARE_VIRTUAL_TRACE();
@@ -231,8 +230,6 @@
   SelfKeepAlive<PingLoaderImpl> keep_alive_;
   AtomicString initiator_;
 
-  bool is_beacon_;
-
   RefPtr<SecurityOrigin> origin_;
   CORSEnabled cors_mode_;
 };
@@ -240,15 +237,13 @@
 PingLoaderImpl::PingLoaderImpl(LocalFrame* frame,
                                ResourceRequest& request,
                                const AtomicString& initiator,
-                               StoredCredentials credentials_allowed,
-                               bool is_beacon)
+                               StoredCredentials credentials_allowed)
     : ContextClient(frame),
       timeout_(this, &PingLoaderImpl::Timeout),
       url_(request.Url()),
       identifier_(CreateUniqueIdentifier()),
       keep_alive_(this),
       initiator_(initiator),
-      is_beacon_(is_beacon),
       origin_(frame->GetDocument()->GetSecurityOrigin()),
       cors_mode_(kIsCORSEnabled) {
   const AtomicString content_type = request.HttpContentType();
@@ -306,7 +301,7 @@
 bool PingLoaderImpl::WillFollowRedirect(
     WebURLRequest& passed_new_request,
     const WebURLResponse& passed_redirect_response) {
-  if (is_beacon_ && cors_mode_ == kIsCORSEnabled) {
+  if (cors_mode_ == kIsCORSEnabled) {
     DCHECK(passed_new_request.AllowStoredCredentials());
 
     ResourceRequest& new_request(passed_new_request.ToMutableResourceRequest());
@@ -418,15 +413,14 @@
 bool SendPingCommon(LocalFrame* frame,
                     ResourceRequest& request,
                     const AtomicString& initiator,
-                    StoredCredentials credentials_allowed,
-                    bool is_beacon) {
+                    StoredCredentials credentials_allowed) {
   if (MixedContentChecker::ShouldBlockFetch(frame, request, request.Url()))
     return false;
 
   // The loader keeps itself alive until it receives a response and disposes
   // itself.
   PingLoaderImpl* loader =
-      new PingLoaderImpl(frame, request, initiator, credentials_allowed, true);
+      new PingLoaderImpl(frame, request, initiator, credentials_allowed);
   DCHECK(loader);
 
   return true;
@@ -476,7 +470,7 @@
   beacon.Serialize(request);
 
   return SendPingCommon(frame, request, FetchInitiatorTypeNames::beacon,
-                        kAllowStoredCredentials, true);
+                        kAllowStoredCredentials);
 }
 
 }  // namespace
@@ -488,7 +482,7 @@
                                   WebURLRequest::kRequestContextPing);
 
   SendPingCommon(frame, request, FetchInitiatorTypeNames::ping,
-                 kAllowStoredCredentials, false);
+                 kAllowStoredCredentials);
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing
@@ -528,7 +522,7 @@
   }
 
   SendPingCommon(frame, request, FetchInitiatorTypeNames::ping,
-                 kAllowStoredCredentials, false);
+                 kAllowStoredCredentials);
 }
 
 void PingLoader::SendViolationReport(LocalFrame* frame,
@@ -555,7 +549,7 @@
           ? kAllowStoredCredentials
           : kDoNotAllowStoredCredentials;
   SendPingCommon(frame, request, FetchInitiatorTypeNames::violationreport,
-                 credentials_allowed, false);
+                 credentials_allowed);
 }
 
 bool PingLoader::SendBeacon(LocalFrame* frame,
diff --git a/third_party/WebKit/Source/core/style/BorderValue.h b/third_party/WebKit/Source/core/style/BorderValue.h
index 35b2f8d..22e75640 100644
--- a/third_party/WebKit/Source/core/style/BorderValue.h
+++ b/third_party/WebKit/Source/core/style/BorderValue.h
@@ -49,7 +49,7 @@
               const StyleColor& color,
               float width,
               OutlineIsAuto is_auto) {
-    SetColor(color.Resolve(Color()));
+    SetColor(color);
     SetStyle(style);
     SetWidth(width);
     SetIsAuto(is_auto);
diff --git a/third_party/WebKit/Source/core/style/BorderValueTest.cpp b/third_party/WebKit/Source/core/style/BorderValueTest.cpp
index 732063c2..f6be747f 100644
--- a/third_party/WebKit/Source/core/style/BorderValueTest.cpp
+++ b/third_party/WebKit/Source/core/style/BorderValueTest.cpp
@@ -54,4 +54,14 @@
   EXPECT_EQ(kMaxForBorderWidth, border.Width());
 }
 
+TEST(BorderValueTest, BorderValueColor) {
+  BorderValue border1 = BorderValue(
+      EBorderStyle::kSolid, StyleColor::CurrentColor(), 5, kOutlineIsAutoOff);
+  EXPECT_EQ(border1.ColorIsCurrentColor(), true);
+
+  BorderValue border2 = BorderValue(
+      EBorderStyle::kSolid, StyleColor(Color(128, 0, 0)), 5, kOutlineIsAutoOff);
+  EXPECT_EQ(border2.ColorIsCurrentColor(), false);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index 3d103410..0f044fd 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -1579,10 +1579,12 @@
 
   // -webkit-app-region
   DraggableRegionMode GetDraggableRegionMode() const {
-    return rare_non_inherited_data_->draggable_region_mode_;
+    return static_cast<DraggableRegionMode>(
+        rare_non_inherited_data_->draggable_region_mode_);
   }
   void SetDraggableRegionMode(DraggableRegionMode v) {
-    SET_VAR(rare_non_inherited_data_, draggable_region_mode_, v);
+    SET_VAR(rare_non_inherited_data_, draggable_region_mode_,
+            static_cast<unsigned>(v));
   }
 
   // -webkit-appearance
@@ -1658,15 +1660,6 @@
   StyleImage* ListStyleImage() const;
   void SetListStyleImage(StyleImage*);
 
-  // overflow-wrap (aka word-wrap)
-  static EOverflowWrap InitialOverflowWrap() { return EOverflowWrap::kNormal; }
-  EOverflowWrap OverflowWrap() const {
-    return static_cast<EOverflowWrap>(rare_inherited_data_->overflow_wrap_);
-  }
-  void SetOverflowWrap(EOverflowWrap b) {
-    SET_VAR(rare_inherited_data_, overflow_wrap_, static_cast<unsigned>(b));
-  }
-
   // quotes
   static QuotesData* InitialQuotes() { return 0; }
   QuotesData* Quotes() const { return rare_inherited_data_->quotes_.Get(); }
@@ -1674,22 +1667,13 @@
 
   bool QuotesDataEquivalent(const ComputedStyle&) const;
 
-  // speak
-  static ESpeak InitialSpeak() { return ESpeak::kNormal; }
-  ESpeak Speak() const {
-    return static_cast<ESpeak>(rare_inherited_data_->speak_);
-  }
-  void SetSpeak(ESpeak s) {
-    SET_VAR(rare_inherited_data_, speak_, static_cast<unsigned>(s));
-  }
-
   // text-align-last
-  static TextAlignLast InitialTextAlignLast() { return kTextAlignLastAuto; }
+  static TextAlignLast InitialTextAlignLast() { return TextAlignLast::kAuto; }
   TextAlignLast GetTextAlignLast() const {
     return static_cast<TextAlignLast>(rare_inherited_data_->text_align_last_);
   }
   void SetTextAlignLast(TextAlignLast v) {
-    SET_VAR(rare_inherited_data_, text_align_last_, v);
+    SET_VAR(rare_inherited_data_, text_align_last_, static_cast<unsigned>(v));
   }
 
   // text-combine-upright (aka -webkit-text-combine, -epub-text-combine)
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index caf0271..8558fe23 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -248,14 +248,14 @@
   return a = a | b;
 }
 
-enum TextAlignLast {
-  kTextAlignLastAuto,
-  kTextAlignLastStart,
-  kTextAlignLastEnd,
-  kTextAlignLastLeft,
-  kTextAlignLastRight,
-  kTextAlignLastCenter,
-  kTextAlignLastJustify
+enum class TextAlignLast {
+  kAuto,
+  kStart,
+  kEnd,
+  kLeft,
+  kRight,
+  kCenter,
+  kJustify
 };
 
 enum TextUnderlinePosition {
@@ -406,7 +406,7 @@
 // platforms (such as Windows).
 static const float kMaximumAllowedFontSize = 10000.0f;
 
-enum TextIndentLine { kFirstLine, kEachLine };
+enum class TextIndentLine { kFirstLine, kEachLine };
 enum class TextIndentType { kNormal, kHanging };
 
 enum CSSBoxType {
diff --git a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.cpp b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.cpp
index 7a26d696..b35cf74 100644
--- a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.cpp
+++ b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.cpp
@@ -78,7 +78,7 @@
       perspective_origin_(ComputedStyle::InitialPerspectiveOrigin()),
       object_position_(ComputedStyle::InitialObjectPosition()),
       line_clamp(ComputedStyle::InitialLineClamp()),
-      draggable_region_mode_(kDraggableRegionNone),
+      draggable_region_mode_(static_cast<unsigned>(kDraggableRegionNone)),
       shape_outside_(ComputedStyle::InitialShapeOutside()),
       clip_path_(ComputedStyle::InitialClipPath()),
       mask_(kMaskFillLayer, true),
diff --git a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h
index 83dd304..03c4febe 100644
--- a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h
+++ b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h
@@ -107,7 +107,7 @@
   LengthPoint object_position_;
 
   LineClampValue line_clamp;  // An Apple extension.
-  DraggableRegionMode draggable_region_mode_;
+  unsigned draggable_region_mode_ : 2;  // DraggableRegionMode
 
   DataRef<StyleDeprecatedFlexibleBoxData>
       deprecated_flexible_box_;  // Flexible box properties
diff --git a/third_party/WebKit/Source/core/testing/CallbackFunctionTest.idl b/third_party/WebKit/Source/core/testing/CallbackFunctionTest.idl
index d3994d8..a0ca345 100644
--- a/third_party/WebKit/Source/core/testing/CallbackFunctionTest.idl
+++ b/third_party/WebKit/Source/core/testing/CallbackFunctionTest.idl
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-[ExperimentalCallbackFunction] callback TestCallback = DOMString (DOMString message1, DOMString message2);
-[ExperimentalCallbackFunction] callback TestInterfaceCallback = void (HTMLDivElement divElement);
-[ExperimentalCallbackFunction] callback TestReceiverObjectCallback = void ();
-[ExperimentalCallbackFunction] callback TestSequenceCallback = sequence<DOMString> (sequence<long> numbers);
+callback TestCallback = DOMString (DOMString message1, DOMString message2);
+callback TestInterfaceCallback = void (HTMLDivElement divElement);
+callback TestReceiverObjectCallback = void ();
+callback TestSequenceCallback = sequence<DOMString> (sequence<long> numbers);
 
 interface CallbackFunctionTest {
     [RaisesException] DOMString testCallback(TestCallback callback, DOMString message1, DOMString message2);
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni
index c63ba604..f6d59f9 100644
--- a/third_party/WebKit/Source/modules/modules_idl_files.gni
+++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -317,7 +317,6 @@
                     "webauth/WebAuthentication.idl",
                     "webauth/AuthenticationAssertion.idl",
                     "webdatabase/Database.idl",
-                    "webdatabase/DatabaseCallback.idl",
                     "webdatabase/SQLError.idl",
                     "webdatabase/SQLResultSet.idl",
                     "webdatabase/SQLResultSetRowList.idl",
diff --git a/third_party/WebKit/Source/modules/webdatabase/BUILD.gn b/third_party/WebKit/Source/modules/webdatabase/BUILD.gn
index e5c9e51c..d4b6398 100644
--- a/third_party/WebKit/Source/modules/webdatabase/BUILD.gn
+++ b/third_party/WebKit/Source/modules/webdatabase/BUILD.gn
@@ -16,7 +16,6 @@
     "DatabaseAuthorizer.cpp",
     "DatabaseAuthorizer.h",
     "DatabaseBasicTypes.h",
-    "DatabaseCallback.h",
     "DatabaseClient.cpp",
     "DatabaseClient.h",
     "DatabaseContext.cpp",
diff --git a/third_party/WebKit/Source/modules/webdatabase/DOMWindowWebDatabase.cpp b/third_party/WebKit/Source/modules/webdatabase/DOMWindowWebDatabase.cpp
index c7516a1..126ae264 100644
--- a/third_party/WebKit/Source/modules/webdatabase/DOMWindowWebDatabase.cpp
+++ b/third_party/WebKit/Source/modules/webdatabase/DOMWindowWebDatabase.cpp
@@ -27,16 +27,26 @@
 #include "modules/webdatabase/DOMWindowWebDatabase.h"
 
 #include "bindings/core/v8/ExceptionState.h"
+#include "bindings/modules/v8/DatabaseCallback.h"
 #include "core/dom/Document.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "modules/webdatabase/Database.h"
-#include "modules/webdatabase/DatabaseCallback.h"
 #include "modules/webdatabase/DatabaseManager.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
 namespace blink {
 
+Database* DOMWindowWebDatabase::openDatabase(LocalDOMWindow& window,
+                                             const String& name,
+                                             const String& version,
+                                             const String& display_name,
+                                             unsigned estimated_size,
+                                             ExceptionState& exception_state) {
+  return openDatabase(window, name, version, display_name, estimated_size,
+                      nullptr, exception_state);
+}
+
 Database* DOMWindowWebDatabase::openDatabase(
     LocalDOMWindow& window,
     const String& name,
diff --git a/third_party/WebKit/Source/modules/webdatabase/DOMWindowWebDatabase.h b/third_party/WebKit/Source/modules/webdatabase/DOMWindowWebDatabase.h
index bb1b9ac7..7d3fb52a 100644
--- a/third_party/WebKit/Source/modules/webdatabase/DOMWindowWebDatabase.h
+++ b/third_party/WebKit/Source/modules/webdatabase/DOMWindowWebDatabase.h
@@ -46,6 +46,12 @@
                                 const String& version,
                                 const String& display_name,
                                 unsigned estimated_size,
+                                ExceptionState&);
+  static Database* openDatabase(LocalDOMWindow&,
+                                const String& name,
+                                const String& version,
+                                const String& display_name,
+                                unsigned estimated_size,
                                 DatabaseCallback* creation_callback,
                                 ExceptionState&);
 };
diff --git a/third_party/WebKit/Source/modules/webdatabase/Database.cpp b/third_party/WebKit/Source/modules/webdatabase/Database.cpp
index a83a41b4..0c4e7ff9 100644
--- a/third_party/WebKit/Source/modules/webdatabase/Database.cpp
+++ b/third_party/WebKit/Source/modules/webdatabase/Database.cpp
@@ -26,11 +26,13 @@
 #include "modules/webdatabase/Database.h"
 
 #include <memory>
+#include "bindings/modules/v8/DatabaseCallback.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/html/VoidCallback.h"
 #include "core/inspector/ConsoleMessage.h"
+#include "core/probe/CoreProbes.h"
 #include "modules/webdatabase/ChangeVersionData.h"
 #include "modules/webdatabase/ChangeVersionWrapper.h"
 #include "modules/webdatabase/DatabaseAuthorizer.h"
@@ -224,7 +226,8 @@
                    const String& name,
                    const String& expected_version,
                    const String& display_name,
-                   unsigned estimated_size)
+                   unsigned estimated_size,
+                   DatabaseCallback* creation_callback)
     : database_context_(database_context),
       name_(name.IsolatedCopy()),
       expected_version_(expected_version.IsolatedCopy()),
@@ -233,6 +236,7 @@
       guid_(0),
       opened_(0),
       new_(false),
+      creation_callback_(this, creation_callback),
       transaction_in_progress_(false),
       is_transaction_queue_enabled_(true) {
   DCHECK(IsMainThread());
@@ -279,6 +283,11 @@
   visitor->Trace(database_context_);
   visitor->Trace(sqlite_database_);
   visitor->Trace(database_authorizer_);
+  visitor->Trace(creation_callback_);
+}
+
+DEFINE_TRACE_WRAPPERS(Database) {
+  visitor->TraceWrappers(creation_callback_);
 }
 
 bool Database::OpenAndVerifyVersion(bool set_version_in_new_database,
@@ -294,10 +303,30 @@
       this, set_version_in_new_database, &event, error, error_message, success);
   GetDatabaseContext()->GetDatabaseThread()->ScheduleTask(std::move(task));
   event.Wait();
+  if (creation_callback_) {
+    if (success && IsNew()) {
+      STORAGE_DVLOG(1)
+          << "Scheduling DatabaseCreationCallbackTask for database " << this;
+      probe::AsyncTaskScheduled(GetExecutionContext(), "openDatabase",
+                                creation_callback_);
+      TaskRunnerHelper::Get(TaskType::kDatabaseAccess, GetExecutionContext())
+          ->PostTask(BLINK_FROM_HERE, WTF::Bind(&Database::RunCreationCallback,
+                                                WrapPersistent(this)));
+    } else {
+      creation_callback_ = nullptr;
+    }
+  }
 
   return success;
 }
 
+void Database::RunCreationCallback() {
+  probe::AsyncTask async_task(GetExecutionContext(), creation_callback_);
+  bool return_value;
+  creation_callback_->call(nullptr, this, return_value);
+  creation_callback_ = nullptr;
+}
+
 void Database::Close() {
   DCHECK(GetDatabaseContext()->GetDatabaseThread());
   DCHECK(GetDatabaseContext()->GetDatabaseThread()->IsDatabaseThread());
diff --git a/third_party/WebKit/Source/modules/webdatabase/Database.h b/third_party/WebKit/Source/modules/webdatabase/Database.h
index de98214d..d59a9d8a 100644
--- a/third_party/WebKit/Source/modules/webdatabase/Database.h
+++ b/third_party/WebKit/Source/modules/webdatabase/Database.h
@@ -30,6 +30,7 @@
 #include "modules/webdatabase/DatabaseError.h"
 #include "modules/webdatabase/sqlite/SQLiteDatabase.h"
 #include "platform/bindings/ScriptWrappable.h"
+#include "platform/bindings/TraceWrapperMember.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "platform/wtf/Deque.h"
 #include "platform/wtf/text/WTFString.h"
@@ -38,6 +39,7 @@
 
 class ChangeVersionData;
 class DatabaseAuthorizer;
+class DatabaseCallback;
 class DatabaseContext;
 class ExecutionContext;
 class SQLTransaction;
@@ -55,6 +57,7 @@
  public:
   virtual ~Database();
   DECLARE_TRACE();
+  DECLARE_TRACE_WRAPPERS();
 
   bool OpenAndVerifyVersion(bool set_version_in_new_database,
                             DatabaseError&,
@@ -127,10 +130,12 @@
            const String& name,
            const String& expected_version,
            const String& display_name,
-           unsigned estimated_size);
+           unsigned estimated_size,
+           DatabaseCallback* creation_callback);
   bool PerformOpenAndVerify(bool set_version_in_new_database,
                             DatabaseError&,
                             String& error_message);
+  void RunCreationCallback();
 
   void ScheduleTransaction();
 
@@ -196,7 +201,7 @@
   SQLiteDatabase sqlite_database_;
 
   Member<DatabaseAuthorizer> database_authorizer_;
-
+  TraceWrapperMember<DatabaseCallback> creation_callback_;
   Deque<CrossThreadPersistent<SQLTransactionBackend>> transaction_queue_;
   Mutex transaction_in_progress_mutex_;
   bool transaction_in_progress_;
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseCallback.h b/third_party/WebKit/Source/modules/webdatabase/DatabaseCallback.h
deleted file mode 100644
index 3a30737..0000000
--- a/third_party/WebKit/Source/modules/webdatabase/DatabaseCallback.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DatabaseCallback_h
-#define DatabaseCallback_h
-
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-class Database;
-
-class DatabaseCallback : public GarbageCollectedFinalized<DatabaseCallback> {
- public:
-  virtual ~DatabaseCallback() {}
-  DEFINE_INLINE_VIRTUAL_TRACE() {}
-  virtual bool handleEvent(Database*) = 0;
-};
-
-}  // namespace blink
-
-#endif  // DatabaseCallback_h
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseCallback.idl b/third_party/WebKit/Source/modules/webdatabase/DatabaseCallback.idl
deleted file mode 100644
index 1259772a..0000000
--- a/third_party/WebKit/Source/modules/webdatabase/DatabaseCallback.idl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// https://www.w3.org/TR/webdatabase/#databasecallback
-callback interface DatabaseCallback {
-    boolean handleEvent(Database database);
-};
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.cpp b/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.cpp
index a0e83e7..89a1cb1c 100644
--- a/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.cpp
+++ b/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.cpp
@@ -31,9 +31,7 @@
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/inspector/ConsoleMessage.h"
-#include "core/probe/CoreProbes.h"
 #include "modules/webdatabase/Database.h"
-#include "modules/webdatabase/DatabaseCallback.h"
 #include "modules/webdatabase/DatabaseClient.h"
 #include "modules/webdatabase/DatabaseContext.h"
 #include "modules/webdatabase/DatabaseTask.h"
@@ -60,13 +58,6 @@
 
 DatabaseManager::~DatabaseManager() {}
 
-// This is just for ignoring DatabaseCallback::handleEvent()'s return value.
-static void DatabaseCallbackHandleEvent(DatabaseCallback* callback,
-                                        Database* database) {
-  probe::AsyncTask async_task(database->GetExecutionContext(), callback);
-  callback->handleEvent(database);
-}
-
 DatabaseContext* DatabaseManager::ExistingDatabaseContextFor(
     ExecutionContext* context) {
 #if DCHECK_IS_ON()
@@ -147,6 +138,7 @@
     const String& expected_version,
     const String& display_name,
     unsigned estimated_size,
+    DatabaseCallback* creation_callback,
     bool set_version_in_new_database,
     DatabaseError& error,
     String& error_message) {
@@ -155,8 +147,9 @@
   DatabaseContext* backend_context = DatabaseContextFor(context)->Backend();
   if (DatabaseTracker::Tracker().CanEstablishDatabase(
           backend_context, name, display_name, estimated_size, error)) {
-    Database* backend = new Database(backend_context, name, expected_version,
-                                     display_name, estimated_size);
+    Database* backend =
+        new Database(backend_context, name, expected_version, display_name,
+                     estimated_size, creation_callback);
     if (backend->OpenAndVerifyVersion(set_version_in_new_database, error,
                                       error_message))
       return backend;
@@ -191,26 +184,13 @@
   bool set_version_in_new_database = !creation_callback;
   Database* database = OpenDatabaseInternal(
       context, name, expected_version, display_name, estimated_size,
-      set_version_in_new_database, error, error_message);
+      creation_callback, set_version_in_new_database, error, error_message);
   if (!database)
     return nullptr;
 
   DatabaseContextFor(context)->SetHasOpenDatabases();
   DatabaseClient::From(context)->DidOpenDatabase(
       database, context->GetSecurityOrigin()->Host(), name, expected_version);
-
-  if (database->IsNew() && creation_callback) {
-    STORAGE_DVLOG(1) << "Scheduling DatabaseCreationCallbackTask for database "
-                     << database;
-    probe::AsyncTaskScheduled(database->GetExecutionContext(), "openDatabase",
-                              creation_callback);
-    TaskRunnerHelper::Get(TaskType::kDatabaseAccess,
-                          database->GetExecutionContext())
-        ->PostTask(BLINK_FROM_HERE, WTF::Bind(&DatabaseCallbackHandleEvent,
-                                              WrapPersistent(creation_callback),
-                                              WrapPersistent(database)));
-  }
-
   DCHECK(database);
   return database;
 }
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.h b/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.h
index 2dea015..bcded10a8 100644
--- a/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.h
+++ b/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.h
@@ -95,6 +95,7 @@
                                  const String& expected_version,
                                  const String& display_name,
                                  unsigned estimated_size,
+                                 DatabaseCallback*,
                                  bool set_version_in_new_database,
                                  DatabaseError&,
                                  String& error_message);
diff --git a/third_party/WebKit/Source/modules/webdatabase/WindowWebDatabase.idl b/third_party/WebKit/Source/modules/webdatabase/WindowWebDatabase.idl
index 47213b8..8e3d762 100644
--- a/third_party/WebKit/Source/modules/webdatabase/WindowWebDatabase.idl
+++ b/third_party/WebKit/Source/modules/webdatabase/WindowWebDatabase.idl
@@ -24,6 +24,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.w3.org/TR/webdatabase/#databasecallback
+callback DatabaseCallback = boolean (Database database);
+
 // https://www.w3.org/TR/webdatabase/#databases
 [
     ImplementedAs=DOMWindowWebDatabase,
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorMutator.h b/third_party/WebKit/Source/platform/graphics/CompositorMutator.h
index 118643e..d7c3776 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorMutator.h
+++ b/third_party/WebKit/Source/platform/graphics/CompositorMutator.h
@@ -5,13 +5,15 @@
 #ifndef CompositorMutator_h
 #define CompositorMutator_h
 
+#include "platform/PlatformExport.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
 
 class CompositorMutableStateProvider;
 
-class CompositorMutator : public GarbageCollectedFinalized<CompositorMutator> {
+class PLATFORM_EXPORT CompositorMutator
+    : public GarbageCollectedFinalized<CompositorMutator> {
  public:
   virtual ~CompositorMutator() {}
 
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
index 405a5348..0b76d332 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -63,8 +63,6 @@
   return !memcmp(contents, "BM", 2);
 }
 
-// This needs to be updated if we ever add a Matches*Signature() which requires
-// more characters.
 static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1;
 
 std::unique_ptr<ImageDecoder> ImageDecoder::Create(
@@ -72,8 +70,7 @@
     bool data_complete,
     AlphaOption alpha_option,
     const ColorBehavior& color_behavior) {
-  // We need at least kLongestSignatureLength bytes to run the signature
-  // matcher.
+  // At least kLongestSignatureLength bytes are needed to sniff the signature.
   if (data->size() < kLongestSignatureLength)
     return nullptr;
 
@@ -85,38 +82,28 @@
   // (note: FastSharedBufferReader only makes a copy if the bytes are segmented)
   char buffer[kLongestSignatureLength];
   const FastSharedBufferReader fast_reader(data);
-  const ImageDecoder::SniffResult sniff_result = DetermineImageType(
-      fast_reader.GetConsecutiveData(0, kLongestSignatureLength, buffer),
-      kLongestSignatureLength);
+  const char* contents =
+      fast_reader.GetConsecutiveData(0, kLongestSignatureLength, buffer);
 
   std::unique_ptr<ImageDecoder> decoder;
-  switch (sniff_result) {
-    case SniffResult::JPEG:
-      decoder.reset(new JPEGImageDecoder(alpha_option, color_behavior,
-                                         max_decoded_bytes));
-      break;
-    case SniffResult::PNG:
-      decoder.reset(
-          new PNGImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
-      break;
-    case SniffResult::GIF:
-      decoder.reset(
-          new GIFImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
-      break;
-    case SniffResult::WEBP:
-      decoder.reset(new WEBPImageDecoder(alpha_option, color_behavior,
-                                         max_decoded_bytes));
-      break;
-    case SniffResult::ICO:
-      decoder.reset(
-          new ICOImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
-      break;
-    case SniffResult::BMP:
-      decoder.reset(
-          new BMPImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
-      break;
-    case SniffResult::kInvalid:
-      break;
+  if (MatchesJPEGSignature(contents)) {
+    decoder.reset(
+        new JPEGImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
+  } else if (MatchesPNGSignature(contents)) {
+    decoder.reset(
+        new PNGImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
+  } else if (MatchesGIFSignature(contents)) {
+    decoder.reset(
+        new GIFImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
+  } else if (MatchesWebPSignature(contents)) {
+    decoder.reset(
+        new WEBPImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
+  } else if (MatchesICOSignature(contents) || MatchesCURSignature(contents)) {
+    decoder.reset(
+        new ICOImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
+  } else if (MatchesBMPSignature(contents)) {
+    decoder.reset(
+        new BMPImageDecoder(alpha_option, color_behavior, max_decoded_bytes));
   }
 
   if (decoder)
@@ -129,25 +116,6 @@
   return data.size() >= kLongestSignatureLength;
 }
 
-ImageDecoder::SniffResult ImageDecoder::DetermineImageType(const char* contents,
-                                                           size_t length) {
-  DCHECK_GE(length, kLongestSignatureLength);
-
-  if (MatchesJPEGSignature(contents))
-    return SniffResult::JPEG;
-  if (MatchesPNGSignature(contents))
-    return SniffResult::PNG;
-  if (MatchesGIFSignature(contents))
-    return SniffResult::GIF;
-  if (MatchesWebPSignature(contents))
-    return SniffResult::WEBP;
-  if (MatchesICOSignature(contents) || MatchesCURSignature(contents))
-    return SniffResult::ICO;
-  if (MatchesBMPSignature(contents))
-    return SniffResult::BMP;
-  return SniffResult::kInvalid;
-}
-
 size_t ImageDecoder::FrameCount() {
   const size_t old_size = frame_buffer_cache_.size();
   const size_t new_size = DecodeFrameCount();
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
index d32a08f2..2b00aa0 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
@@ -402,10 +402,6 @@
   }
 
  private:
-  enum class SniffResult { JPEG, PNG, GIF, WEBP, ICO, BMP, kInvalid };
-
-  static SniffResult DetermineImageType(const char* data, size_t length);
-
   // Some code paths compute the size of the image as "width * height * 4"
   // and return it as a (signed) int.  Avoid overflow.
   static bool SizeCalculationMayOverflow(unsigned width, unsigned height) {
diff --git a/third_party/WebKit/Source/web/AnimationWorkletProxyClientImpl.cpp b/third_party/WebKit/Source/web/AnimationWorkletProxyClientImpl.cpp
index f5095fe8..41ae51d 100644
--- a/third_party/WebKit/Source/web/AnimationWorkletProxyClientImpl.cpp
+++ b/third_party/WebKit/Source/web/AnimationWorkletProxyClientImpl.cpp
@@ -4,9 +4,9 @@
 
 #include "web/AnimationWorkletProxyClientImpl.h"
 
+#include "core/animation/CompositorMutatorImpl.h"
 #include "core/dom/CompositorProxy.h"
 #include "platform/graphics/CompositorMutableStateProvider.h"
-#include "web/CompositorMutatorImpl.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/web/AnimationWorkletProxyClientImpl.h b/third_party/WebKit/Source/web/AnimationWorkletProxyClientImpl.h
index 147b9d12..94de72d2 100644
--- a/third_party/WebKit/Source/web/AnimationWorkletProxyClientImpl.h
+++ b/third_party/WebKit/Source/web/AnimationWorkletProxyClientImpl.h
@@ -5,10 +5,10 @@
 #ifndef AnimationWorkletProxyClientImpl_h
 #define AnimationWorkletProxyClientImpl_h
 
+#include "core/animation/CompositorAnimator.h"
 #include "core/dom/AnimationWorkletProxyClient.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Noncopyable.h"
-#include "web/CompositorAnimator.h"
 #include "web/CompositorProxyClientImpl.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/web/BUILD.gn b/third_party/WebKit/Source/web/BUILD.gn
index e535237..674a8a04 100644
--- a/third_party/WebKit/Source/web/BUILD.gn
+++ b/third_party/WebKit/Source/web/BUILD.gn
@@ -47,9 +47,6 @@
     "ColorChooserPopupUIController.h",
     "ColorChooserUIController.cpp",
     "ColorChooserUIController.h",
-    "CompositorAnimator.h",
-    "CompositorMutatorImpl.cpp",
-    "CompositorMutatorImpl.h",
     "CompositorProxyClientImpl.cpp",
     "CompositorProxyClientImpl.h",
     "CompositorWorkerProxyClientImpl.cpp",
diff --git a/third_party/WebKit/Source/web/CompositorWorkerProxyClientImpl.cpp b/third_party/WebKit/Source/web/CompositorWorkerProxyClientImpl.cpp
index 997b6c5..9d12da3 100644
--- a/third_party/WebKit/Source/web/CompositorWorkerProxyClientImpl.cpp
+++ b/third_party/WebKit/Source/web/CompositorWorkerProxyClientImpl.cpp
@@ -4,12 +4,12 @@
 
 #include "web/CompositorWorkerProxyClientImpl.h"
 
+#include "core/animation/CompositorMutatorImpl.h"
 #include "core/dom/CompositorProxy.h"
 #include "modules/compositorworker/CompositorWorkerGlobalScope.h"
 #include "platform/graphics/CompositorMutableStateProvider.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/wtf/CurrentTime.h"
-#include "web/CompositorMutatorImpl.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/web/CompositorWorkerProxyClientImpl.h b/third_party/WebKit/Source/web/CompositorWorkerProxyClientImpl.h
index e96ab38b..10cce10e 100644
--- a/third_party/WebKit/Source/web/CompositorWorkerProxyClientImpl.h
+++ b/third_party/WebKit/Source/web/CompositorWorkerProxyClientImpl.h
@@ -5,10 +5,10 @@
 #ifndef CompositorWorkerProxyClientImpl_h
 #define CompositorWorkerProxyClientImpl_h
 
+#include "core/animation/CompositorAnimator.h"
 #include "core/dom/CompositorWorkerProxyClient.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Noncopyable.h"
-#include "web/CompositorAnimator.h"
 #include "web/CompositorProxyClientImpl.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
index c30f044..5b818322 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -32,6 +32,7 @@
 
 #include <memory>
 
+#include "core/animation/CompositorMutatorImpl.h"
 #include "core/dom/UserGestureIndicator.h"
 #include "core/editing/CompositionUnderlineVectorBuilder.h"
 #include "core/editing/EditingUtilities.h"
@@ -70,7 +71,6 @@
 #include "public/web/WebRange.h"
 #include "public/web/WebWidgetClient.h"
 #include "web/AnimationWorkletProxyClientImpl.h"
-#include "web/CompositorMutatorImpl.h"
 #include "web/CompositorWorkerProxyClientImpl.h"
 #include "web/WebDevToolsAgentImpl.h"
 #include "web/WebPagePopupImpl.h"
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
index 0c64adb3..326e918 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
@@ -31,6 +31,7 @@
 #ifndef WebFrameWidgetImpl_h
 #define WebFrameWidgetImpl_h
 
+#include "core/animation/CompositorMutatorImpl.h"
 #include "core/frame/WebFrameWidgetBase.h"
 #include "core/frame/WebLocalFrameBase.h"
 #include "platform/graphics/GraphicsLayer.h"
@@ -42,7 +43,6 @@
 #include "public/platform/WebPoint.h"
 #include "public/platform/WebSize.h"
 #include "public/web/WebInputMethodController.h"
-#include "web/CompositorMutatorImpl.h"
 #include "web/PageWidgetDelegate.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 8f98f9b..f7feb39e 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -33,6 +33,7 @@
 #include <memory>
 #include "core/CSSValueKeywords.h"
 #include "core/HTMLNames.h"
+#include "core/animation/CompositorMutatorImpl.h"
 #include "core/clipboard/DataObject.h"
 #include "core/dom/ContextFeaturesClientImpl.h"
 #include "core/dom/Document.h"
@@ -161,7 +162,6 @@
 #include "public/web/WebViewClient.h"
 #include "public/web/WebWindowFeatures.h"
 #include "web/AnimationWorkletProxyClientImpl.h"
-#include "web/CompositorMutatorImpl.h"
 #include "web/CompositorWorkerProxyClientImpl.h"
 #include "web/DedicatedWorkerMessagingProxyProviderImpl.h"
 #include "web/DevToolsEmulator.h"
diff --git a/tools/clang/traffic_annotation_extractor/README.md b/tools/clang/traffic_annotation_extractor/README.md
index f972bc6..22f8663 100644
--- a/tools/clang/traffic_annotation_extractor/README.md
+++ b/tools/clang/traffic_annotation_extractor/README.md
@@ -25,16 +25,26 @@
   `tools/clang/scripts/run_tool.py --tool=traffic_annotation_extractor
      --generate-compdb -p=out/Debug components/spellcheck/browser`
 
-The executable extracts network traffic annotations from given file paths based
-  on build parameters in build path, and writes them to llvm::outs.
-  Each output will have the following format:
-  - Line 1: File path.
-  - Line 2: Name of the function in which annotation is defined.
-  - Line 3: Line number of annotation.
-  - Line 4: Function type ("Definition", "Partial", "Completing",
+The executable extracts network traffic annotations and calls to network request
+  generation functions from given file paths based on build parameters in build
+  path, and writes them to llvm::outs.
+
+Each annotation output will have the following format:
+  - Line 1: "==== NEW ANNOTATION ===="
+  - Line 2: File path.
+  - Line 3: Name of the function in which the annotation is defined.
+  - Line 4: Line number of the annotation.
+  - Line 5: Function type ("Definition", "Partial", "Completing",
             "BranchedCompleting").
-  - Line 5: Unique id of annotation.
-  - Line 6: Completing id or group id, when applicable, empty otherwise.
-  - Line 7-: Serialized protobuf of the annotation.
-Outputs are enclosed by "==== NEW ANNOTATION ====" and
-  "==== ANNOTATION ENDS ===="
+  - Line 6: Unique id of annotation.
+  - Line 7: Completing id or group id, when applicable, empty otherwise.
+  - Line 8-: Serialized protobuf of the annotation. (Several lines)
+  - Last line:  "==== ANNOTATION ENDS ===="
+
+Each function call output will have the following format:
+  - Line 1: "==== NEW CALL ===="
+  - Line 2: File path.
+  - Line 3: Name of the function in which the call is made.
+  - Line 4: Name of the called function.
+  - Line 5: Does the call have an annotation?
+  - Line 6: "==== CALL ENDS ===="
diff --git a/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp b/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp
index 7005fec..c9b7acc 100644
--- a/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp
+++ b/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp
@@ -8,8 +8,18 @@
 //   - net::CompleteNetworkTrafficAnnotation
 //   - net::BranchedCompleteNetworkTrafficAnnotation
 // It extracts the location info and content of annotation tags, and outputs
-// them to llvm::outs. Please refer to README.md for build and usage
-// instructions.
+// them to llvm::outs. It also extracts all calls of the following network
+// request creation functions and returns their source location and availability
+// of a net::[Partial]NetworkTrafficAnnotation parameter in them:
+//   - SSLClientSocket::SSLClientSocket
+//   - TCPClientSocket::TCPClientSocket
+//   - UDPClientSocket::UDPClientSocket
+//   - URLFetcher::Create
+//   - ClientSocketFactory::CreateDatagramClientSocket
+//   - ClientSocketFactory::CreateSSLClientSocket
+//   - ClientSocketFactory::CreateTransportClientSocket
+//   - URLRequestContext::CreateRequest
+// Please refer to README.md for build and usage instructions.
 
 #include <memory>
 #include <vector>
@@ -28,26 +38,26 @@
 
 namespace {
 
+// Information about location of a line of code.
+struct Location {
+  std::string file_path;
+  int line_number = -1;
+
+  // Name of the function including this line. E.g., in the following code,
+  // |function_name| will be 'foo' for all |line_number| values 101-103.
+  //
+  // 100 void foo() {
+  // 101   NetworkTrafficAnnotationTag baz =
+  // 102       net::DefineNetworkTrafficAnnotation(...); }
+  // 103   bar(baz);
+  // 104 }
+  // If no function is found, 'Global Namespace' will be returned.
+  std::string function_name;
+};
+
 // An instance of a call to either of the 4 network traffic annotation
 // definition functions.
 struct NetworkAnnotationInstance {
-  // Information about where the call has happened.
-  struct Location {
-    std::string file_path;
-    int line_number = -1;
-
-    // Name of the function including this line. E.g., in the following code,
-    // |function_name| will be 'foo' for all |line_number| values 101-103.
-    //
-    // 100 void foo() {
-    // 101   NetworkTrafficAnnotationTag baz =
-    // 102       net::DefineNetworkTrafficAnnotation(...); }
-    // 103   bar(baz);
-    // 104 }
-    // If no function is found, 'Global Namespace' will be returned.
-    std::string function_name;
-  };
-
   // Annotation content. These are the arguments of the call to either of the 4
   // network traffic annotation definition functions.
   struct Annotation {
@@ -90,7 +100,23 @@
   }
 };
 
-using Collector = std::vector<NetworkAnnotationInstance>;
+// An instance of a call to one of the monitored function.
+struct CallInstance {
+  // Location of the call.
+  Location location;
+
+  // Whether the function is annotated.
+  bool has_annotation = false;
+
+  // Name of the called function.
+  std::string called_function_name;
+};
+
+// A structure to keep detected annotation and call instances.
+struct Collector {
+  std::vector<NetworkAnnotationInstance> annotations;
+  std::vector<CallInstance> calls;
+};
 
 // This class implements the call back functions for AST Matchers. The matchers
 // are defined in RunMatchers function. When a pattern is found there,
@@ -105,6 +131,60 @@
   // Is called on any pattern found by ASTMathers that are defined in RunMathers
   // function.
   virtual void run(const MatchFinder::MatchResult& result) override {
+    if (const clang::CallExpr* call_expr =
+            result.Nodes.getNodeAs<clang::CallExpr>("monitored_function")) {
+      AddFunction(call_expr, result);
+    } else {
+      AddAnnotation(result);
+    }
+  }
+
+  void GetInstanceLocation(const MatchFinder::MatchResult& result,
+                           const clang::CallExpr* call_expr,
+                           const clang::FunctionDecl* ancestor,
+                           Location* instance_location) {
+    clang::SourceLocation source_location = call_expr->getLocStart();
+    if (source_location.isMacroID()) {
+      source_location =
+          result.SourceManager->getImmediateMacroCallerLoc(source_location);
+    }
+    instance_location->file_path =
+        result.SourceManager->getFilename(source_location);
+    instance_location->line_number =
+        result.SourceManager->getSpellingLineNumber(source_location);
+    if (ancestor)
+      instance_location->function_name = ancestor->getQualifiedNameAsString();
+    else
+      instance_location->function_name = "Global Namespace";
+
+    std::replace(instance_location->file_path.begin(),
+                 instance_location->file_path.end(), '\\', '/');
+
+    // Trim leading "../"s from file path.
+    while (instance_location->file_path.length() > 3 &&
+           instance_location->file_path.substr(0, 3) == "../") {
+      instance_location->file_path = instance_location->file_path.substr(
+          3, instance_location->file_path.length() - 3);
+    }
+  }
+
+  // Stores a function call that should be monitored.
+  void AddFunction(const clang::CallExpr* call_expr,
+                   const MatchFinder::MatchResult& result) {
+    CallInstance instance;
+
+    const clang::FunctionDecl* ancestor =
+        result.Nodes.getNodeAs<clang::FunctionDecl>("function_context");
+    GetInstanceLocation(result, call_expr, ancestor, &instance.location);
+    instance.called_function_name =
+        call_expr->getDirectCallee()->getQualifiedNameAsString();
+    instance.has_annotation =
+        (result.Nodes.getNodeAs<clang::RecordDecl>("annotation") != nullptr);
+    collector_->calls.push_back(instance);
+  }
+
+  // Stores an annotation.
+  void AddAnnotation(const MatchFinder::MatchResult& result) {
     NetworkAnnotationInstance instance;
 
     const clang::StringLiteral* unique_id =
@@ -143,31 +223,9 @@
     instance.annotation.unique_id = unique_id->getString();
     instance.annotation.text = annotation_text->getString();
 
-    // Get annotation location.
-    clang::SourceLocation source_location = call_expr->getLocStart();
-    if (source_location.isMacroID()) {
-      source_location =
-          result.SourceManager->getImmediateMacroCallerLoc(source_location);
-    }
-    instance.location.file_path =
-        result.SourceManager->getFilename(source_location);
-    instance.location.line_number =
-        result.SourceManager->getSpellingLineNumber(source_location);
-    if (ancestor)
-      instance.location.function_name = ancestor->getQualifiedNameAsString();
-    else
-      instance.location.function_name = "Global Namespace";
+    GetInstanceLocation(result, call_expr, ancestor, &instance.location);
 
-    // Trim leading "../"s from file path.
-    std::replace(instance.location.file_path.begin(),
-                 instance.location.file_path.end(), '\\', '/');
-    while (instance.location.file_path.length() > 3 &&
-           instance.location.file_path.substr(0, 3) == "../") {
-      instance.location.file_path = instance.location.file_path.substr(
-          3, instance.location.file_path.length() - 3);
-    }
-
-    collector_->push_back(instance);
+    collector_->annotations.push_back(instance);
   }
 
  private:
@@ -182,14 +240,24 @@
 
   // Set up patterns to find network traffic annotation definition functions,
   // their arguments, and their ancestor function (when possible).
+  auto bind_function_context_if_present =
+      anyOf(hasAncestor(functionDecl().bind("function_context")),
+            unless(hasAncestor(functionDecl())));
+  auto has_annotation_parameter = anyOf(
+      hasAnyParameter(hasType(
+          recordDecl(anyOf(hasName("net::NetworkTrafficAnnotationTag"),
+                           hasName("net::PartialNetworkTrafficAnnotationTag")))
+              .bind("annotation"))),
+      unless(hasAnyParameter(hasType(recordDecl(
+          anyOf(hasName("net::NetworkTrafficAnnotationTag"),
+                hasName("net::PartialNetworkTrafficAnnotationTag")))))));
   match_finder.addMatcher(
       callExpr(hasDeclaration(functionDecl(
                    anyOf(hasName("DefineNetworkTrafficAnnotation"),
                          hasName("net::DefineNetworkTrafficAnnotation")))),
                hasArgument(0, stringLiteral().bind("unique_id")),
                hasArgument(1, stringLiteral().bind("annotation_text")),
-               anyOf(hasAncestor(functionDecl().bind("function_context")),
-                     unless(hasAncestor(functionDecl()))))
+               bind_function_context_if_present)
           .bind("definition_function"),
       &callback);
   match_finder.addMatcher(
@@ -199,8 +267,7 @@
                hasArgument(0, stringLiteral().bind("unique_id")),
                hasArgument(1, stringLiteral().bind("completing_id")),
                hasArgument(2, stringLiteral().bind("annotation_text")),
-               anyOf(hasAncestor(functionDecl().bind("function_context")),
-                     unless(hasAncestor(functionDecl()))))
+               bind_function_context_if_present)
           .bind("partial_function"),
       &callback);
   match_finder.addMatcher(
@@ -209,8 +276,7 @@
                          hasName("net::CompleteNetworkTrafficAnnotation")))),
                hasArgument(0, stringLiteral().bind("unique_id")),
                hasArgument(2, stringLiteral().bind("annotation_text")),
-               anyOf(hasAncestor(functionDecl().bind("function_context")),
-                     unless(hasAncestor(functionDecl()))))
+               bind_function_context_if_present)
           .bind("completing_function"),
       &callback);
   match_finder.addMatcher(
@@ -220,10 +286,27 @@
                hasArgument(0, stringLiteral().bind("unique_id")),
                hasArgument(1, stringLiteral().bind("group_id")),
                hasArgument(3, stringLiteral().bind("annotation_text")),
-               anyOf(hasAncestor(functionDecl().bind("function_context")),
-                     unless(hasAncestor(functionDecl()))))
+               bind_function_context_if_present)
           .bind("branched_completing_function"),
       &callback);
+
+  // Setup patterns to find functions that should be monitored.
+  match_finder.addMatcher(
+      callExpr(
+          hasDeclaration(functionDecl(
+              anyOf(hasName("SSLClientSocket::SSLClientSocket"),
+                    hasName("TCPClientSocket::TCPClientSocket"),
+                    hasName("UDPClientSocket::UDPClientSocket"),
+                    hasName("URLFetcher::Create"),
+                    hasName("ClientSocketFactory::CreateDatagramClientSocket"),
+                    hasName("ClientSocketFactory::CreateSSLClientSocket"),
+                    hasName("ClientSocketFactory::CreateTransportClientSocket"),
+                    hasName("URLRequestContext::CreateRequest")),
+              has_annotation_parameter)),
+          bind_function_context_if_present)
+          .bind("monitored_function"),
+      &callback);
+
   std::unique_ptr<clang::tooling::FrontendActionFactory> frontend_factory =
       clang::tooling::newFrontendActionFactory(&match_finder);
   return clang_tool->run(frontend_factory.get());
@@ -249,17 +332,28 @@
 
   // For each call to any of the functions that define a network traffic
   // annotation, write annotation text and relevant meta data into llvm::outs().
-  for (const NetworkAnnotationInstance& call : collector) {
+  for (const NetworkAnnotationInstance& instance : collector.annotations) {
     llvm::outs() << "==== NEW ANNOTATION ====\n";
-    llvm::outs() << call.location.file_path << "\n";
-    llvm::outs() << call.location.function_name << "\n";
-    llvm::outs() << call.location.line_number << "\n";
-    llvm::outs() << call.GetTypeName() << "\n";
-    llvm::outs() << call.annotation.unique_id << "\n";
-    llvm::outs() << call.annotation.extra_id << "\n";
-    llvm::outs() << call.annotation.text << "\n";
+    llvm::outs() << instance.location.file_path << "\n";
+    llvm::outs() << instance.location.function_name << "\n";
+    llvm::outs() << instance.location.line_number << "\n";
+    llvm::outs() << instance.GetTypeName() << "\n";
+    llvm::outs() << instance.annotation.unique_id << "\n";
+    llvm::outs() << instance.annotation.extra_id << "\n";
+    llvm::outs() << instance.annotation.text << "\n";
     llvm::outs() << "==== ANNOTATION ENDS ====\n";
   }
 
+  // For each call, write annotation text and relevant meta data.
+  for (const CallInstance& instance : collector.calls) {
+    llvm::outs() << "==== NEW CALL ====\n";
+    llvm::outs() << instance.location.file_path << "\n";
+    llvm::outs() << instance.location.function_name << "\n";
+    llvm::outs() << instance.location.line_number << "\n";
+    llvm::outs() << instance.called_function_name << "\n";
+    llvm::outs() << instance.has_annotation << "\n";
+    llvm::outs() << "==== CALL ENDS ====\n";
+  }
+
   return 0;
 }
\ No newline at end of file
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 2013e30f..7d0095a 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -137,11 +137,10 @@
 
       # if CrWinClang is modified, please update CrWinClangGoma in the same way.
       'CrWinClang': 'clang_official_release_bot_minimal_symbols_x86',
+
       'CrWinClang(dbg)': 'clang_debug_bot_minimal_symbols_x86',
-      'CrWinClang(shared)': 'clang_minimal_symbols_shared_release_bot_x86',
       'CrWinClang64': 'clang_official_release_bot_minimal_symbols',
       'CrWinClang64(dll)': 'clang_shared_release_bot',
-      'CrWinClang64(dbg)': 'win_clang_debug_bot',
       'CrWinClangGoma': 'clang_official_optimize_release_bot_minimal_symbols_x86',
       'CrWinGoma': 'release_bot_x86',
       'CrWinGoma(dll)': 'shared_release_bot_x86',
@@ -171,6 +170,8 @@
       'CrWinAsan': 'asan_clang_fuzzer_static_v8_heap_x86_full_symbols_release',
       'CrWinAsan(dll)': 'asan_clang_shared_v8_heap_x86_full_symbols_release',
       'CrWinAsanCov': 'asan_clang_edge_fuzzer_static_v8_heap_x86_full_symbols_release',
+      'CrWinClang(shared)': 'clang_minimal_symbols_shared_release_bot_x86',
+      'CrWinClang64(dbg)': 'win_clang_debug_bot',
       'CrWinClangLLD': 'clang_tot_official_static_use_lld_x86',
       'CrWinClangLLD64': 'clang_tot_shared_release_use_lld',
       'CrWinClngLLD64dbg': 'clang_tot_full_symbols_shared_debug_use_lld',
@@ -1039,10 +1040,7 @@
     ],
 
     'clang_debug_bot_minimal_symbols_x86': [
-      # Now that the default win bots use clang, use a "clang" bot to make sure
-      # things stay compilable with msvc. TODO(thakis): Having a "clang" bot
-      # check that is very confusing, so rename the bot to "msvc".
-      'no_clang', 'debug_bot', 'minimal_symbols', 'x86',
+      'clang', 'debug_bot', 'minimal_symbols', 'x86',
     ],
 
     'clang_release_bot_minimal_symbols_x86': [
@@ -1050,24 +1048,15 @@
     ],
 
     'clang_minimal_symbols_shared_release_bot_x86': [
-      # Now that the default win bots use clang, use a "clang" bot to make sure
-      # things stay compilable with msvc. TODO(thakis): Having a "clang" bot
-      # check that is very confusing, so rename the bot to "msvc".
-      'no_clang', 'minimal_symbols', 'shared_release_bot', 'x86',
+      'clang', 'minimal_symbols', 'shared_release_bot', 'x86',
     ],
 
     'clang_official_release_bot_minimal_symbols': [
-      # Now that the default win bots use clang, use a "clang" bot to make sure
-      # things stay compilable with msvc. TODO(thakis): Having a "clang" bot
-      # check that is very confusing, so rename the bot to "msvc".
-      'no_clang', 'official', 'release_bot', 'minimal_symbols',
+      'clang', 'official', 'release_bot', 'minimal_symbols',
     ],
 
     'clang_official_release_bot_minimal_symbols_x86': [
-      # Now that the default win bots use clang, use a "clang" bot to make sure
-      # things stay compilable with msvc. TODO(thakis): Having a "clang" bot
-      # check that is very confusing, so rename the bot to "msvc".
-      'no_clang', 'official', 'release_bot', 'minimal_symbols', 'x86',
+      'clang', 'official', 'release_bot', 'minimal_symbols', 'x86',
     ],
 
     'clang_official_optimize_release_bot_minimal_symbols_x86': [
@@ -1083,10 +1072,7 @@
     ],
 
     'clang_shared_release_bot': [
-      # Now that the default win bots use clang, use a "clang" bot to make sure
-      # things stay compilable with msvc. TODO(thakis): Having a "clang" bot
-      # check that is very confusing, so rename the bot to "msvc".
-      'no_clang', 'shared_release_bot',
+      'clang', 'shared_release_bot',
     ],
 
     'clang_tot_asan_lsan_static_release': [
@@ -1487,10 +1473,7 @@
     ],
 
     'win_clang_debug_bot': [
-      # Now that the default win bots use clang, use a "clang" bot to make sure
-      # things stay compilable with msvc. TODO(thakis): Having a "clang" bot
-      # check that is very confusing, so rename the bot to "msvc".
-      'no_clang', 'debug_bot', 'minimal_symbols',
+      'clang', 'debug_bot', 'minimal_symbols',
     ],
 
     'windows_analyze': [
@@ -1580,11 +1563,11 @@
     },
 
     'chrome_pgo_phase_1': {
-      'gn_args': 'chrome_pgo_phase=1 is_clang=false',
+      'gn_args': 'chrome_pgo_phase=1',
     },
 
     'chrome_pgo_phase_2': {
-      'gn_args': 'chrome_pgo_phase=2 is_clang=false',
+      'gn_args': 'chrome_pgo_phase=2',
     },
 
     'chrome_with_codecs': {
@@ -1612,10 +1595,6 @@
       'gn_args': 'is_clang=true',
     },
 
-    'no_clang': {
-      'gn_args': 'is_clang=false',
-    },
-
     'cronet': {
       'gn_args': ('disable_file_support=true disable_ftp_support=true '
                   'enable_websockets=false use_platform_icu_alternatives=true '
@@ -1860,8 +1839,7 @@
     },
 
     'syzyasan': {
-      # TODO(thakis): Figure out SyzyASan + clang story.
-      'gn_args': 'is_syzyasan=true is_clang=false',
+      'gn_args': 'is_syzyasan=true',
     },
 
     'thin_lto': {
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.py b/tools/traffic_annotation/auditor/traffic_annotation_auditor.py
index 56e82d99..631b6dc3 100755
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.py
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.py
@@ -75,7 +75,7 @@
   """Parses raw annotations texts which are received from the clang tool.
   Args:
     raw_annotations: str Serialization of annotations and metadata. Each
-        annotation should have the following lines:
+        annotation should have either of the following lines:
         1- "==== NEW ANNOTATION ===="
         2- File path.
         3- Name of the function including this position.
@@ -85,6 +85,13 @@
         7- Completing id or group id, when applicable, empty otherwise.
         8- Serialization of annotation text (several lines)
         n- "==== ANNOTATION ENDS ===="
+        or:
+        1: "==== NEW CALL ===="
+        2: File path.
+        3: Name of the function in which the call is made.
+        4: Name of the called function.
+        5: Does the call have an annotation?
+        6: "==== CALL ENDS ===="
 
   Returns:
     annotations: ExtractedNetworkTrafficAnnotation A protobuf including all
@@ -104,58 +111,71 @@
 
   try:
     while current < len(lines) - 1:
-      if lines[current] != "==== NEW ANNOTATION ====":
-        raise Exception(
-            "Error at line %i, expected starting new annotaion." % current)
-      if current + 5 >= len(lines):
-        raise Exception(
-            "Not enough header lines at line %i." % current)
+      if lines[current] == "==== NEW ANNOTATION ====":
+        if current + 6 >= len(lines):
+          raise Exception(
+              "Not enough header lines at line %i." % current)
 
-      # Extract header lines.
-      source = traffic_annotation_pb2.NetworkTrafficAnnotation.TrafficSource()
-      source.file = lines[current + 1]
-      source.function = lines[current + 2]
-      source.line = int(lines[current + 3])
-      unique_id = lines[current + 5]
+        # Extract header lines.
+        source = traffic_annotation_pb2.NetworkTrafficAnnotation.TrafficSource()
+        source.file = lines[current + 1]
+        source.function = lines[current + 2]
+        source.line = int(lines[current + 3])
+        unique_id = lines[current + 5]
 
-      new_metadata = {'function_type': lines[current + 4],
-                      'extra_id': lines[current + 6],
-                      'unique_id_hash': _ComputeStringHash(unique_id)}
-      # Extract serialized proto.
-      current += 7
-      annotation_text = ""
+        new_metadata = {'function_type': lines[current + 4],
+                        'extra_id': lines[current + 6],
+                        'unique_id_hash': _ComputeStringHash(unique_id)}
+        # Extract serialized proto.
+        current += 7
+        annotation_text = ""
 
-      while current < len(lines):
-        current += 1
-        if lines[current - 1] == "==== ANNOTATION ENDS ====":
-          break
+        while current < len(lines):
+          if lines[current] == "==== ANNOTATION ENDS ====":
+            break
+          else:
+            annotation_text += lines[current]
+          current += 1
         else:
-          annotation_text += lines[current - 1]
-      else:
+          raise Exception(
+            "Error at line %i, expected annotation end tag." % current)
+        current += 1
+
+        # Process unittests and undefined tags.
+        if unique_id in ("test", "test_partial"):
+          continue
+        if unique_id in ("undefined", "missing"):
+          errors.append("Annotation is not defined for file '%s', line %i." %
+              (source.file, source.line))
+          continue
+
+        # Decode serialized proto.
+        annotation_proto = traffic_annotation_pb2.NetworkTrafficAnnotation()
+        try:
+          text_format.Parse(annotation_text, annotation_proto)
+        except Exception as error:
+          errors.append("Annotation in file '%s', line %i, has an error: %s" %
+              (source.file, source.line, error))
+
+        # Add new proto.
+        annotation_proto.unique_id = unique_id
+        annotation_proto.source.CopyFrom(source)
+        annotations.network_traffic_annotation.add().CopyFrom(annotation_proto)
+        metadata.append(new_metadata)
+      elif lines[current] == "==== NEW CALL ====":
+        # Ignore calls for now.
+        while current < len(lines):
+          if lines[current] == "==== CALL ENDS ====":
+            break
+          current += 1
+        else:
+          raise Exception(
+              "Error at line %i, expected call end tag." % current)
+        current += 1
+      else: # The line is neither new annotation nor new call.
         raise Exception(
-          "Error at line %i, expected annotation end tag." % current)
-
-      # Process unittests and undefined tags.
-      if unique_id in ("test", "test_partial"):
-        continue
-      if unique_id in ("undefined", "missing"):
-        errors.append("Annotation is not defined for file '%s', line %i." %
-            (source.file, source.line))
-        continue
-
-      # Decode serialized proto.
-      annotation_proto = traffic_annotation_pb2.NetworkTrafficAnnotation()
-      try:
-        text_format.Parse(annotation_text, annotation_proto)
-      except Exception as error:
-        errors.append("Annotation in file '%s', line %i, has error: %s" %
-            (source.file, source.line, error))
-
-      # Add new proto.
-      annotation_proto.unique_id = unique_id
-      annotation_proto.source.CopyFrom(source)
-      annotations.network_traffic_annotation.add().CopyFrom(annotation_proto)
-      metadata.append(new_metadata)
+            "Error at line %i, expected starting new annotation or call." %
+            current)
 
   except Exception as error:
     errors.append(str(error))