diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py
index 44f18532..8c7d6b9 100755
--- a/build/vs_toolchain.py
+++ b/build/vs_toolchain.py
@@ -22,7 +22,7 @@
 
 
 # Use MSVS2015 as the default toolchain.
-CURRENT_DEFAULT_TOOLCHAIN_VERSION = '2017'
+CURRENT_DEFAULT_TOOLCHAIN_VERSION = '2015'
 
 
 def SetEnvironmentAndGetRuntimeDllDirs():
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
index 30172d7..c202aa8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
@@ -22,9 +22,12 @@
  */
 class TranslateCompactInfoBar extends InfoBar
         implements TabLayout.OnTabSelectedListener, TranslateMenuHelper.TranslateMenuListener {
+    public static final int TRANSLATING_INFOBAR = 1;
+
     private static final int SOURCE_TAB_INDEX = 0;
     private static final int TARGET_TAB_INDEX = 1;
 
+    private final int mInitialStep;
     private final TranslateOptions mOptions;
 
     private long mNativeTranslateInfoBarPtr;
@@ -33,18 +36,20 @@
     private TranslateMenuHelper mMenuHelper;
 
     @CalledByNative
-    private static InfoBar create(String sourceLanguageCode, String targetLanguageCode,
+    private static InfoBar create(int initialStep, String sourceLanguageCode,
+            String targetLanguageCode, boolean alwaysTranslate, boolean triggeredFromMenu,
             String[] languages, String[] codes) {
-        return new TranslateCompactInfoBar(
-                sourceLanguageCode, targetLanguageCode, languages, codes);
+        return new TranslateCompactInfoBar(initialStep, sourceLanguageCode, targetLanguageCode,
+                alwaysTranslate, triggeredFromMenu, languages, codes);
     }
 
-    TranslateCompactInfoBar(String sourceLanguageCode, String targetLanguageCode,
-            String[] languages, String[] codes) {
+    TranslateCompactInfoBar(int initialStep, String sourceLanguageCode, String targetLanguageCode,
+            boolean alwaysTranslate, boolean triggeredFromMenu, String[] languages,
+            String[] codes) {
         super(R.drawable.infobar_translate, null, null);
-        // TODO(googleo): Set correct values for the last 2.
-        mOptions = TranslateOptions.create(
-                sourceLanguageCode, targetLanguageCode, languages, codes, false, false);
+        mInitialStep = initialStep;
+        mOptions = TranslateOptions.create(sourceLanguageCode, targetLanguageCode, languages, codes,
+                alwaysTranslate, triggeredFromMenu);
     }
 
     @Override
@@ -60,6 +65,13 @@
 
         mTabLayout = (TranslateTabLayout) content.findViewById(R.id.translate_infobar_tabs);
         mTabLayout.addTabs(mOptions.sourceLanguageName(), mOptions.targetLanguageName());
+
+        // Set translating status in the beginning for pages translated automatically.
+        if (mInitialStep == TRANSLATING_INFOBAR) {
+            mTabLayout.getTabAt(TARGET_TAB_INDEX).select();
+            mTabLayout.showProgressBarOnTab(TARGET_TAB_INDEX);
+        }
+
         mTabLayout.addOnTabSelectedListener(this);
 
         content.findViewById(R.id.translate_infobar_menu_button)
diff --git a/chrome/browser/permissions/permission_request_manager_browsertest.cc b/chrome/browser/permissions/permission_request_manager_browsertest.cc
index c5700d3..a4db80a 100644
--- a/chrome/browser/permissions/permission_request_manager_browsertest.cc
+++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/metrics/field_trial.h"
+#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/custom_handlers/register_protocol_handler_permission_request.h"
@@ -19,6 +20,7 @@
 #include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/common/content_settings_types.h"
@@ -213,7 +215,12 @@
   // PermissionRequestImpl::GetMessageTextFragment() are valid.
   constexpr ContentSettingsType kMultipleRequests[] = {
       CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
-      CONTENT_SETTINGS_TYPE_MIDI_SYSEX};
+      CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
+  };
+  constexpr ContentSettingsType kMultipleRequestsWithMedia[] = {
+      CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
+      CONTENT_SETTINGS_TYPE_MIDI_SYSEX, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+      CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA};
   constexpr struct {
     const char* name;
     ContentSettingsType type;
@@ -249,7 +256,12 @@
       break;
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
-      AddMediaRequest(manager, it->type);
+      if (base::FeatureList::IsEnabled(
+              features::kUsePermissionManagerForMediaRequests)) {
+        manager->AddRequest(MakePermissionRequest(it->type));
+      } else {
+        AddMediaRequest(manager, it->type);
+      }
       break;
     // Regular permissions requests.
     case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
@@ -263,8 +275,15 @@
       break;
     case CONTENT_SETTINGS_TYPE_DEFAULT:
       EXPECT_EQ(kMultipleName, name);
-      for (auto request : kMultipleRequests)
-        manager->AddRequest(MakePermissionRequest(request));
+      if (base::FeatureList::IsEnabled(
+              features::kUsePermissionManagerForMediaRequests)) {
+        for (auto request : kMultipleRequestsWithMedia)
+          manager->AddRequest(MakePermissionRequest(request));
+      } else {
+        for (auto request : kMultipleRequests)
+          manager->AddRequest(MakePermissionRequest(request));
+      }
+
       break;
     default:
       ADD_FAILURE() << "Not a permission type, or one that doesn't prompt.";
@@ -469,11 +488,25 @@
 // Host wants to use your microphone.
 IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_mic) {
   RunDialog();
+
+  {
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeature(
+        features::kUsePermissionManagerForMediaRequests);
+    RunDialog();
+  }
 }
 
 // Host wants to use your camera.
 IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_camera) {
   RunDialog();
+
+  {
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeature(
+        features::kUsePermissionManagerForMediaRequests);
+    RunDialog();
+  }
 }
 
 // Host wants to open email links.
@@ -489,6 +522,13 @@
 // Shows a permissions bubble with multiple requests.
 IN_PROC_BROWSER_TEST_F(PermissionDialogTest, InvokeDialog_multiple) {
   RunDialog();
+
+  {
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeature(
+        features::kUsePermissionManagerForMediaRequests);
+    RunDialog();
+  }
 }
 
 // CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER is ChromeOS only.
diff --git a/chrome/browser/resources/md_bookmarks/app.html b/chrome/browser/resources/md_bookmarks/app.html
index 4e39697..faea753 100644
--- a/chrome/browser/resources/md_bookmarks/app.html
+++ b/chrome/browser/resources/md_bookmarks/app.html
@@ -15,9 +15,11 @@
   <template>
     <style>
       :host {
+        color: var(--primary-text-color);
         display: flex;
         flex-direction: column;
         height: 100%;
+        line-height: 154%;  /* 20px. */
       }
 
       #main-container {
diff --git a/chrome/browser/resources/md_bookmarks/dnd_manager.js b/chrome/browser/resources/md_bookmarks/dnd_manager.js
index 9f3d089..8bcc77518 100644
--- a/chrome/browser/resources/md_bookmarks/dnd_manager.js
+++ b/chrome/browser/resources/md_bookmarks/dnd_manager.js
@@ -205,7 +205,7 @@
      * Used to instantly remove the indicator style in tests.
      * @private {function((Function|null|string), number)}
      */
-    this.setTimeout_ = window.setTimeout.bind(window);
+    this.setTimeout = window.setTimeout.bind(window);
   }
 
   DropIndicator.prototype = {
@@ -260,16 +260,10 @@
       // The use of a timeout is in order to reduce flickering as we move
       // between valid drop targets.
       window.clearTimeout(this.removeDropIndicatorTimer_);
-      this.removeDropIndicatorTimer_ = this.setTimeout_(function() {
+      this.removeDropIndicatorTimer_ = this.setTimeout(function() {
         this.removeDropIndicatorStyle();
       }.bind(this), 100);
     },
-
-    disableTimeoutForTesting: function() {
-      this.setTimeout_ = function(fn, timeout) {
-        fn();
-      };
-    },
   };
 
   /**
@@ -288,6 +282,12 @@
 
     /** @private {Object<string, function(!Event)>} */
     this.documentListeners_ = null;
+
+    /**
+     * Used to instantly clearDragData in tests.
+     * @private {function((Function|null|string), number)}
+     */
+    this.setTimeout = window.setTimeout.bind(window);
   }
 
   DNDManager.prototype = {
@@ -384,9 +384,14 @@
 
     /** @private */
     clearDragData_: function() {
-      this.dragInfo_.clearDragData();
-      this.dropDestination_ = null;
-      this.dropIndicator_.finish();
+      // Defer the clearing of the data so that the bookmark manager API's drop
+      // event doesn't clear the drop data before the web drop event has a
+      // chance to execute (on Mac).
+      this.setTimeout_(function() {
+        this.dragInfo_.clearDragData();
+        this.dropDestination_ = null;
+        this.dropIndicator_.finish();
+      }.bind(this), 0);
     },
 
     /**
@@ -614,6 +619,13 @@
 
       return !this.dragInfo_.isDraggingChildBookmark(overElement.itemId)
     },
+
+    disableTimeoutsForTesting: function() {
+      this.setTimeout_ = function(fn) {
+        fn();
+      };
+      this.dropIndicator_.setTimeout = this.setTimeout_;
+    }
   };
 
   return {
diff --git a/chrome/browser/resources/md_bookmarks/folder_node.html b/chrome/browser/resources/md_bookmarks/folder_node.html
index 3166667c..c9bb16c 100644
--- a/chrome/browser/resources/md_bookmarks/folder_node.html
+++ b/chrome/browser/resources/md_bookmarks/folder_node.html
@@ -1,8 +1,7 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/cr_elements/icons.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
 <link rel="import" href="chrome://bookmarks/actions.html">
 <link rel="import" href="chrome://bookmarks/icons.html">
 <link rel="import" href="chrome://bookmarks/shared_style.html">
@@ -52,19 +51,14 @@
       }
 
       iron-icon {
-        --iron-icon-height: 20px;
-        --iron-icon-width: 20px;
-        min-width: 20px;
+        flex-shrink: 0;
       }
 
       #arrow {
         color: var(--secondary-text-color);
-        height: 36px;
         margin: 0 8px;
-        min-width: 36px;
         transform: rotate(-90deg);
         transition: transform 150ms;
-        width: 36px;
       }
 
       :host-context([dir='rtl']) #arrow {
@@ -84,9 +78,10 @@
         draggable="[[!isTopLevelFolder_(depth)]]"
         hidden="[[isRootFolder_(depth)]]">
       <template is="dom-if" if="[[hasChildFolder_(item_.children)]]">
-        <paper-icon-button id="arrow" icon="cr:arrow-drop-down"
+        <button is="paper-icon-button-light" id="arrow"
             is-open$="[[!isClosed_]]" on-tap="toggleFolder_">
-        </paper-icon-button>
+          <iron-icon icon="cr:arrow-drop-down"></iron-icon>
+        </button>
       </template>
       <div id="folder-label" class="v-centered">
         <iron-icon icon="[[getFolderIcon_(isSelectedFolder_)]]"
diff --git a/chrome/browser/resources/md_bookmarks/item.html b/chrome/browser/resources/md_bookmarks/item.html
index 1dba8c73..a60cfd9 100644
--- a/chrome/browser/resources/md_bookmarks/item.html
+++ b/chrome/browser/resources/md_bookmarks/item.html
@@ -22,7 +22,7 @@
       }
 
       :host([is-selected-item_]) {
-        background-color: rgb(225, 235, 253);
+        background-color: var(--highlight-color);
       }
 
       #website-title {
@@ -34,31 +34,27 @@
         white-space: nowrap;
       }
 
-      #icon {
-        background-repeat: no-repeat;
-        height: 16px;
-        margin: 2px;
-      }
-
       #icon-wrapper {
         -webkit-margin-end: 20px;
+        color: var(--secondary-text-color);
+        display: flex;
         height: 20px;
         width: 20px;
       }
 
-      .more-vert-button {
-        -webkit-margin-end: 12px;
+      #icon {
+        background-repeat: no-repeat;
+        height: 16px;
+        margin: 2px;
+        width: 16px;
       }
 
-      iron-icon {
-        --iron-icon-height: 20px;
-        --iron-icon-width: 20px;
-        color: var(--secondary-text-color);
+      button.more-vert-button {
+        -webkit-margin-end: 12px;
       }
-      </style>
+    </style>
     <div id="icon-wrapper">
-      <iron-icon id="folder-icon" icon="cr:folder"
-          hidden$="[[!isFolder_]]">
+      <iron-icon id="folder-icon" icon="cr:folder" hidden$="[[!isFolder_]]">
       </iron-icon>
       <div id="icon" hidden$="[[isFolder_]]"></div>
     </div>
diff --git a/chrome/browser/resources/md_bookmarks/shared_style.html b/chrome/browser/resources/md_bookmarks/shared_style.html
index c8d75709..037f6fa 100644
--- a/chrome/browser/resources/md_bookmarks/shared_style.html
+++ b/chrome/browser/resources/md_bookmarks/shared_style.html
@@ -1,13 +1,11 @@
 <link rel="import" href="chrome://bookmarks/shared_vars.html">
-<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
+<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
 
 <dom-module id="shared-style">
   <template>
-    <style include="cr-hidden-style">
+    <style include="cr-shared-style">
       button.more-vert-button {
-        height: 36px;
         padding: 8px;
-        width: 36px;
       }
 
       button.more-vert-button div {
@@ -25,11 +23,6 @@
         margin: 8px 0;
       }
 
-      paper-button {
-        height: 32px;
-        margin: 0;
-      }
-
       .drag-above::before,
       .drag-below::after {
         background-clip: padding-box;
@@ -59,7 +52,7 @@
       }
 
       .drag-on {
-        background-color: rgba(66, 133, 244, 0.16);
+        background-color: var(--highlight-color);
       }
     </style>
   </template>
diff --git a/chrome/browser/resources/md_bookmarks/shared_vars.html b/chrome/browser/resources/md_bookmarks/shared_vars.html
index b8b501a..e4a21a47 100644
--- a/chrome/browser/resources/md_bookmarks/shared_vars.html
+++ b/chrome/browser/resources/md_bookmarks/shared_vars.html
@@ -3,7 +3,11 @@
     --card-max-width: 960px;
     --card-padding-side: 32px;
     --folder-inactive-color: #5a5a5a;
+    /* --google-blue-500 at 16% alpha. */
+    --highlight-color: rgba(65, 132, 243, 0.16);
     --interactive-color: var(--google-blue-500);
+    --iron-icon-height: 20px;
+    --iron-icon-width: 20px;
     --min-sidebar-width: 256px;
     --paper-input-container-focus-color: var(--interactive-color);
     --paper-input-container-input: {
diff --git a/chrome/browser/ui/android/infobars/translate_compact_infobar.cc b/chrome/browser/ui/android/infobars/translate_compact_infobar.cc
index 077cee9c..d16b790 100644
--- a/chrome/browser/ui/android/infobars/translate_compact_infobar.cc
+++ b/chrome/browser/ui/android/infobars/translate_compact_infobar.cc
@@ -51,9 +51,10 @@
   ScopedJavaLocalRef<jstring> target_language_code =
       base::android::ConvertUTF8ToJavaString(env,
                                              delegate->target_language_code());
-  return Java_TranslateCompactInfoBar_create(env, source_language_code,
-                                             target_language_code,
-                                             java_languages, java_codes);
+  return Java_TranslateCompactInfoBar_create(
+      env, delegate->translate_step(), source_language_code,
+      target_language_code, delegate->ShouldAlwaysTranslate(),
+      delegate->triggered_from_menu(), java_languages, java_codes);
 }
 
 void TranslateCompactInfoBar::ProcessButton(int action) {
diff --git a/chrome/test/data/webui/md_bookmarks/dnd_manager_test.js b/chrome/test/data/webui/md_bookmarks/dnd_manager_test.js
index fea2865..15f6f9a 100644
--- a/chrome/test/data/webui/md_bookmarks/dnd_manager_test.js
+++ b/chrome/test/data/webui/md_bookmarks/dnd_manager_test.js
@@ -109,7 +109,7 @@
     list = app.$$('bookmarks-list');
     rootFolderNode = app.$$('bookmarks-folder-node');
     dndManager = app.dndManager_;
-    dndManager.dropIndicator_.disableTimeoutForTesting();
+    dndManager.disableTimeoutsForTesting();
     Polymer.dom.flush();
   });
 
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index f4e7668c..32403040 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -200,7 +200,12 @@
   SimpleTest(GetTestUrl("indexeddb", "cursor_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTestIncognito) {
+#if defined(OS_ANDROID)
+#define MAYBE_CursorTestIncognito DISABLED_CursorTestIncognito
+#else
+#define MAYBE_CursorTestIncognito CursorTestIncogntio
+#endif
+IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, MAYBE_CursorTestIncognito) {
   SimpleTest(GetTestUrl("indexeddb", "cursor_test.html"),
              true /* incognito */);
 }
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 804f92c..e67fbfb 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -231,6 +231,8 @@
               "lib/browser/headless_permission_manager.h",
               "lib/browser/headless_platform_event_source.cc",
               "lib/browser/headless_platform_event_source.h",
+              "lib/browser/headless_resource_dispatcher_host_delegate.cc",
+              "lib/browser/headless_resource_dispatcher_host_delegate.h",
               "lib/browser/headless_shell_application_mac.mm",
               "lib/browser/headless_shell_application_mac.h",
               "lib/browser/headless_tab_socket_impl.cc",
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc
index 9d0dde7..1e19a50 100644
--- a/headless/lib/browser/headless_content_browser_client.cc
+++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -17,6 +17,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
+#include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/service_names.mojom.h"
@@ -203,4 +204,11 @@
 #endif  // defined(HEADLESS_USE_BREAKPAD)
 }
 
+void HeadlessContentBrowserClient::ResourceDispatcherHostCreated() {
+  resource_dispatcher_host_delegate_.reset(
+      new HeadlessResourceDispatcherHostDelegate);
+  content::ResourceDispatcherHost::Get()->SetDelegate(
+      resource_dispatcher_host_delegate_.get());
+}
+
 }  // namespace headless
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h
index 53a95040..d1ca74cc 100644
--- a/headless/lib/browser/headless_content_browser_client.h
+++ b/headless/lib/browser/headless_content_browser_client.h
@@ -6,6 +6,7 @@
 #define HEADLESS_LIB_BROWSER_HEADLESS_CONTENT_BROWSER_CLIENT_H_
 
 #include "content/public/browser/content_browser_client.h"
+#include "headless/lib/browser/headless_resource_dispatcher_host_delegate.h"
 
 namespace headless {
 
@@ -37,9 +38,14 @@
   void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
                                       int child_process_id) override;
 
+  void ResourceDispatcherHostCreated() override;
+
  private:
   HeadlessBrowserImpl* browser_;  // Not owned.
 
+  std::unique_ptr<HeadlessResourceDispatcherHostDelegate>
+      resource_dispatcher_host_delegate_;
+
   DISALLOW_COPY_AND_ASSIGN(HeadlessContentBrowserClient);
 };
 
diff --git a/headless/lib/browser/headless_resource_dispatcher_host_delegate.cc b/headless/lib/browser/headless_resource_dispatcher_host_delegate.cc
new file mode 100644
index 0000000..595a088
--- /dev/null
+++ b/headless/lib/browser/headless_resource_dispatcher_host_delegate.cc
@@ -0,0 +1,15 @@
+// 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 "headless/lib/browser/headless_resource_dispatcher_host_delegate.h"
+
+namespace headless {
+
+HeadlessResourceDispatcherHostDelegate::
+    HeadlessResourceDispatcherHostDelegate() {}
+
+HeadlessResourceDispatcherHostDelegate::
+    ~HeadlessResourceDispatcherHostDelegate() {}
+
+}  // namespace headless
diff --git a/headless/lib/browser/headless_resource_dispatcher_host_delegate.h b/headless/lib/browser/headless_resource_dispatcher_host_delegate.h
new file mode 100644
index 0000000..7600c9bf
--- /dev/null
+++ b/headless/lib/browser/headless_resource_dispatcher_host_delegate.h
@@ -0,0 +1,24 @@
+// 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 HEADLESS_LIB_BROWSER_HEADLESS_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
+#define HEADLESS_LIB_BROWSER_HEADLESS_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
+
+#include "content/public/browser/resource_dispatcher_host_delegate.h"
+
+namespace headless {
+
+class HeadlessResourceDispatcherHostDelegate
+    : public content::ResourceDispatcherHostDelegate {
+ public:
+  HeadlessResourceDispatcherHostDelegate();
+  ~HeadlessResourceDispatcherHostDelegate() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HeadlessResourceDispatcherHostDelegate);
+};
+
+}  // namespace headless
+
+#endif  // HEADLESS_LIB_BROWSER_HEADLESS_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
diff --git a/mojo/public/js/associated_bindings.js b/mojo/public/js/associated_bindings.js
index 869eedb..5fa9533 100644
--- a/mojo/public/js/associated_bindings.js
+++ b/mojo/public/js/associated_bindings.js
@@ -3,11 +3,16 @@
 // found in the LICENSE file.
 
 define("mojo/public/js/associated_bindings", [
+  "mojo/public/js/bindings",
   "mojo/public/js/core",
   "mojo/public/js/interface_types",
   "mojo/public/js/lib/interface_endpoint_client",
   "mojo/public/js/lib/interface_endpoint_handle",
-], function(core, types, interfaceEndpointClient, interfaceEndpointHandle) {
+], function(bindings,
+            core,
+            types,
+            interfaceEndpointClient,
+            interfaceEndpointHandle) {
 
   var InterfaceEndpointClient = interfaceEndpointClient.InterfaceEndpointClient;
 
@@ -237,12 +242,23 @@
     return result;
   };
 
+  // ---------------------------------------------------------------------------
+
+  function AssociatedBindingSet(interfaceType) {
+    bindings.BindingSet.call(this, interfaceType);
+    this.bindingType_ = AssociatedBinding;
+  }
+
+  AssociatedBindingSet.prototype = Object.create(bindings.BindingSet.prototype);
+  AssociatedBindingSet.prototype.constructor = AssociatedBindingSet;
+
   var exports = {};
   exports.AssociatedInterfacePtrInfo = types.AssociatedInterfacePtrInfo;
   exports.AssociatedInterfaceRequest = types.AssociatedInterfaceRequest;
   exports.makeRequest = makeRequest;
   exports.AssociatedInterfacePtrController = AssociatedInterfacePtrController;
   exports.AssociatedBinding = AssociatedBinding;
+  exports.AssociatedBindingSet = AssociatedBindingSet;
 
   return exports;
 });
diff --git a/mojo/public/js/bindings.js b/mojo/public/js/bindings.js
index ed00554..0c12c4e 100644
--- a/mojo/public/js/bindings.js
+++ b/mojo/public/js/bindings.js
@@ -259,14 +259,15 @@
 
   // ---------------------------------------------------------------------------
 
-  function BindingSetEntry(bindingSet, interfaceType, impl, requestOrHandle,
-                           bindingId) {
+  function BindingSetEntry(bindingSet, interfaceType, bindingType, impl,
+      requestOrHandle, bindingId) {
     this.bindingSet_ = bindingSet;
     this.bindingId_ = bindingId;
-    this.binding_ = new Binding(interfaceType, impl, requestOrHandle);
+    this.binding_ = new bindingType(interfaceType, impl,
+        requestOrHandle);
 
-    this.binding_.setConnectionErrorHandler(function() {
-      this.bindingSet_.onConnectionError(bindingId);
+    this.binding_.setConnectionErrorHandler(function(reason) {
+      this.bindingSet_.onConnectionError(bindingId, reason);
     }.bind(this));
   }
 
@@ -279,6 +280,7 @@
     this.nextBindingId_ = 0;
     this.bindings_ = new Map();
     this.errorHandler_ = null;
+    this.bindingType_ = Binding;
   }
 
   BindingSet.prototype.isEmpty = function() {
@@ -288,8 +290,8 @@
   BindingSet.prototype.addBinding = function(impl, requestOrHandle) {
     this.bindings_.set(
         this.nextBindingId_,
-        new BindingSetEntry(this, this.interfaceType_, impl, requestOrHandle,
-                            this.nextBindingId_));
+        new BindingSetEntry(this, this.interfaceType_, this.bindingType_, impl,
+            requestOrHandle, this.nextBindingId_));
     ++this.nextBindingId_;
   };
 
@@ -303,11 +305,11 @@
     this.errorHandler_ = callback;
   };
 
-  BindingSet.prototype.onConnectionError = function(bindingId) {
+  BindingSet.prototype.onConnectionError = function(bindingId, reason) {
     this.bindings_.delete(bindingId);
 
     if (this.errorHandler_)
-      this.errorHandler_();
+      this.errorHandler_(reason);
   };
 
   var exports = {};
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 64e2678..7f23cd0 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3387,3 +3387,6 @@
 crbug.com/716569 [ Android ] tables/mozilla/core/bloomberg.html [ Failure ]
 crbug.com/716569 [ Android ] tables/mozilla_expected_failures/bugs/bug1055-2.html [ Failure ]
 crbug.com/716569 [ Android ] tables/mozilla_expected_failures/bugs/bug2479-5.html [ Failure ]
+
+# Sheriff flake 2017-05-01
+crbug.com/716729 external/wpt/WebCryptoAPI/generateKey/test_successes_RSA-OAEP.https.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/editing/selection/selectstart_detaches_frame.html b/third_party/WebKit/LayoutTests/editing/selection/selectstart_detaches_frame.html
new file mode 100644
index 0000000..c113d0b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/editing/selection/selectstart_detaches_frame.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<iframe></iframe>
+<script>
+iframe = document.querySelector('iframe');
+iframe.contentDocument.onselectstart = () => iframe.remove();
+
+test(() => iframe.contentDocument.execCommand('selectAll'),
+     'Should not crash if selectstart event handler detaches frame');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/events/event-listener-detached.html b/third_party/WebKit/LayoutTests/fast/events/event-listener-detached.html
new file mode 100644
index 0000000..1ceb56e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/events/event-listener-detached.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+var t = async_test("Updating attributes for detached nodes should not crash.");
+function test() {
+  frame.contentDocument.adoptNode(document.scrollingElement);
+  t.done();
+}
+</script>
+<iframe id="frame" onload="test()"></iframe>
+<div ontransitionend="g()" onwebkittransitionend="h()">
diff --git a/third_party/WebKit/LayoutTests/mojo/associated_binding.html b/third_party/WebKit/LayoutTests/mojo/associated_binding.html
new file mode 100644
index 0000000..c102fda
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/mojo/associated_binding.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../resources/mojo-helpers.js"></script>
+<script>
+'use strict';
+
+setup({ explicit_done: true });
+
+define([
+    "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom",
+    "mojo/public/js/associated_bindings",
+    "mojo/public/js/bindings",
+], function(testAssociatedInterfaces, associatedBindings, bindings) {
+
+  function SenderImpl(callback) {
+    this.callback = callback;
+  }
+
+  SenderImpl.prototype.echo = function(value) {
+    return Promise.resolve({value: value});
+  };
+
+  SenderImpl.prototype.send = function(value) {
+    if (this.callback) {
+      this.callback(value);
+    }
+  };
+
+  var IntegerSenderImpl = SenderImpl;
+
+  function IntegerSenderConnectionImpl() {
+    this.integerSenderBindings = new associatedBindings.AssociatedBindingSet(
+        testAssociatedInterfaces.IntegerSender);
+  }
+
+  IntegerSenderConnectionImpl.prototype.getSender = function(
+      integerSenderRequest) {
+    this.integerSenderBindings.addBinding(new IntegerSenderImpl(),
+        integerSenderRequest);
+  };
+
+  promise_test(async () => {
+    var integerSenderConnection =
+        new testAssociatedInterfaces.IntegerSenderConnectionPtr();
+    var integerSenderConnectionImpl = new IntegerSenderConnectionImpl();
+    var integerSenderConnectionBinding = new bindings.Binding(
+        testAssociatedInterfaces.IntegerSenderConnection,
+        integerSenderConnectionImpl,
+        bindings.makeRequest(integerSenderConnection));
+
+    // AssociatedInterfaceRequest for integerSender.
+    var integerSenderPtrInfo0 =
+        new associatedBindings.AssociatedInterfacePtrInfo();
+    var integerSenderRequest0 = associatedBindings.makeRequest(
+        integerSenderPtrInfo0);
+    var integerSender0 =
+        new testAssociatedInterfaces.AssociatedIntegerSenderPtr(
+            integerSenderPtrInfo0);
+
+    var integerSenderPtrInfo1 =
+        new associatedBindings.AssociatedInterfacePtrInfo();
+    var integerSenderRequest1 = associatedBindings.makeRequest(
+        integerSenderPtrInfo1);
+    var integerSender1 =
+        new testAssociatedInterfaces.AssociatedIntegerSenderPtr(
+            integerSenderPtrInfo1);
+
+    integerSenderConnection.getSender(integerSenderRequest0);
+    integerSenderConnection.getSender(integerSenderRequest1);
+
+    // Master Binding close triggers connection error handler on
+    // interface endpoint clients for all associated endpoints.
+    var connectionErrorHandler0 = new Promise((resolve, reject) => {
+      integerSender0.ptr.setConnectionErrorHandler(() => {
+        resolve();
+      });
+    });
+
+    var connectionErrorHandler1 = new Promise((resolve, reject) => {
+      integerSender1.ptr.setConnectionErrorHandler(() => {
+        resolve();
+      });
+    });
+
+    setTimeout(integerSenderConnectionBinding.close.bind(
+        integerSenderConnectionBinding), 0);
+    await Promise.all([connectionErrorHandler0, connectionErrorHandler1]);
+  }, 'all endpoints connectionErrorHandler called on master binding close');
+
+  promise_test(async () => {
+    var integerSenderConnection =
+        new testAssociatedInterfaces.IntegerSenderConnectionPtr();
+    var integerSenderConnectionImpl = new IntegerSenderConnectionImpl();
+    var integerSenderConnectionBinding = new bindings.Binding(
+        testAssociatedInterfaces.IntegerSenderConnection,
+        integerSenderConnectionImpl,
+        bindings.makeRequest(integerSenderConnection));
+
+    var integerSenders = [];
+    for (var i = 0; i < 3; i++) {
+      // AssociatedInterfaceRequest for integerSender.
+      var integerSenderPtrInfo =
+          new associatedBindings.AssociatedInterfacePtrInfo();
+      var integerSenderRequest = associatedBindings.makeRequest(
+          integerSenderPtrInfo);
+      var integerSender =
+          new testAssociatedInterfaces.AssociatedIntegerSenderPtr(
+              integerSenderPtrInfo);
+      integerSenderConnection.getSender(integerSenderRequest);
+
+      // Wait for integerSenderConnection getSender message to be received by
+      // integerSenderConnection's binding side and all integerSender binding
+      // to be created.
+      assert_equals((await integerSender.echo(3)).value, 3);
+      integerSenders.push(integerSender);
+    }
+
+    await new Promise((resolve, reject) => {
+      integerSenderConnectionImpl.integerSenderBindings
+          .setConnectionErrorHandler(() => {resolve();});
+      integerSenders[0].ptr.reset();
+    });
+
+    await new Promise((resolve, reject) => {
+      integerSenderConnectionImpl.integerSenderBindings
+          .setConnectionErrorHandler(function({custom_reason, description}) {
+        assert_equals(custom_reason, 32);
+        assert_equals(description, 'goodbye');
+        resolve();
+      });
+      integerSenders[1].ptr.resetWithReason({custom_reason: 32,
+          description: 'goodbye'});
+    });
+
+    // integerSender2's binding should still exist.
+    assert_equals((await integerSenders[2].echo(11)).value, 11);
+
+    integerSenderConnectionImpl.integerSenderBindings.closeAllBindings();
+    assert_true(integerSenderConnectionImpl.integerSenderBindings.isEmpty());
+  }, 'associated binding set');
+
+  done();
+});
+
+</script>
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
index f37c4371..3354ab4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
@@ -204,7 +204,8 @@
     return true;
   // If currently parsing, the parser could be accessing this listener
   // outside of any v8 context; check if it belongs to the main world.
-  if (!GetIsolate()->InContext() && execution_context->IsDocument()) {
+  if (!GetIsolate()->InContext() && execution_context &&
+      execution_context->IsDocument()) {
     Document* document = ToDocument(execution_context);
     if (document->Parser() && document->Parser()->IsParsing())
       return World().IsMainWorld();
diff --git a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
index b52ab45..7617332 100755
--- a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
+++ b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
@@ -17,6 +17,22 @@
 from collections import defaultdict, OrderedDict
 from itertools import chain
 
+# Heuristic ordering of types from largest to smallest, used to sort fields by their alignment sizes.
+# Specifying the exact alignment sizes for each type is impossible because it's platform specific,
+# so we define an ordering instead.
+# The ordering comes from the data obtained in:
+# https://codereview.chromium.org/2841413002
+# TODO(shend): Put alignment sizes into code form, rather than linking to a CL which may disappear.
+ALIGNMENT_ORDER = [
+    'double',
+    'FillLayer', 'BorderData',  # Aligns like a void * (can be 32 or 64 bits)
+    'LengthBox', 'Length', 'float',
+    'StyleColor', 'Color', 'unsigned', 'int',
+    'short',
+    'char',
+    'bool'
+]
+
 # TODO(shend): Improve documentation and add docstrings.
 
 
@@ -76,7 +92,6 @@
             - 'property': for fields that store CSS properties
             - 'inherited_flag': for single-bit flags that store whether a property is
                                 inherited by this style or set explicitly
-            - 'nonproperty': for fields that are not CSS properties
         name_for_methods: String used to form the names of getters and setters.
             Should be in upper camel case.
         property_name: Name of the property that the field is part of.
@@ -89,7 +104,7 @@
     """
 
     def __init__(self, field_role, name_for_methods, property_name, type_name,
-                 field_template, field_group, size, default_value,
+                 field_template, field_group, size, default_value, has_custom_compare_and_copy,
                  getter_method_name, setter_method_name, initial_method_name, **kwargs):
         """Creates a new field."""
         self.name = class_member_name(name_for_methods)
@@ -100,13 +115,13 @@
         self.group_member_name = class_member_name(join_name(field_group, 'data')) if field_group else None
         self.size = size
         self.default_value = default_value
+        self.has_custom_compare_and_copy = has_custom_compare_and_copy
 
         # Field role: one of these must be true
         self.is_property = field_role == 'property'
         self.is_inherited_flag = field_role == 'inherited_flag'
-        self.is_nonproperty = field_role == 'nonproperty'
-        assert (self.is_property, self.is_inherited_flag, self.is_nonproperty).count(True) == 1, \
-            'Field role has to be exactly one of: property, inherited_flag, nonproperty'
+        assert (self.is_property, self.is_inherited_flag).count(True) == 1, \
+            'Field role has to be exactly one of: property, inherited_flag'
 
         if not self.is_inherited_flag:
             self.is_inherited = kwargs.pop('inherited')
@@ -177,12 +192,10 @@
     return OrderedDict(sorted(enums.items(), key=lambda t: t[0]))
 
 
-def _create_field(field_role, property_):
+def _create_property_field(property_):
     """
-    Create a property or nonproperty field.
+    Create a property field.
     """
-    assert field_role in ('property', 'nonproperty')
-
     name_for_methods = property_['name_for_methods']
 
     assert property_['default_value'] is not None, \
@@ -213,7 +226,7 @@
         size = 1
 
     return Field(
-        field_role,
+        'property',
         name_for_methods,
         property_name=property_['name'],
         inherited=property_['inherited'],
@@ -223,6 +236,7 @@
         field_group=property_['field_group'],
         size=size,
         default_value=default_value,
+        has_custom_compare_and_copy=property_['has_custom_compare_and_copy'],
         getter_method_name=property_['getter'],
         setter_method_name=property_['setter'],
         initial_method_name=property_['initial'],
@@ -244,6 +258,7 @@
         field_group=property_['field_group'],
         size=1,
         default_value='true',
+        has_custom_compare_and_copy=False,
         getter_method_name=method_name(name_for_methods),
         setter_method_name=method_name(join_name('set', name_for_methods)),
         initial_method_name=method_name(join_name('initial', name_for_methods)),
@@ -252,7 +267,7 @@
 
 def _create_fields(properties):
     """
-    Create ComputedStyle fields from properties or nonproperties and return a list of Field objects.
+    Create ComputedStyle fields from properties and return a list of Field objects.
     """
     fields = []
     for property_ in properties:
@@ -263,23 +278,12 @@
             if property_['independent']:
                 fields.append(_create_inherited_flag_field(property_))
 
-            # TODO(shend): Get rid of the property/nonproperty field roles.
-            # If the field has_custom_compare_and_copy, then it does not appear in
-            # ComputedStyle::operator== and ComputedStyle::CopyNonInheritedFromCached.
-            field_role = 'nonproperty' if property_['has_custom_compare_and_copy'] else 'property'
-            fields.append(_create_field(field_role, property_))
+            fields.append(_create_property_field(property_))
 
     return fields
 
 
-def _reorder_fields(fields):
-    """
-    Returns a list of fields ordered to minimise padding.
-    """
-    # Separate out bit fields from non bit fields
-    bit_fields = [field for field in fields if field.is_bit_field]
-    non_bit_fields = [field for field in fields if not field.is_bit_field]
-
+def _reorder_bit_fields(bit_fields):
     # Since fields cannot cross word boundaries, in order to minimize
     # padding, group fields into buckets so that as many buckets as possible
     # are exactly 32 bits. Although this greedy approach may not always
@@ -305,8 +309,28 @@
         if not added_to_bucket:
             field_buckets.append([field])
 
+    return _flatten_list(field_buckets)
+
+
+def _reorder_non_bit_fields(non_bit_fields):
+    # A general rule of thumb is to sort members by their alignment requirement
+    # (from biggest aligned to smallest).
+    for field in non_bit_fields:
+        assert field.type_name in ALIGNMENT_ORDER, \
+            "Type {} has unknown alignment. Please update ALIGNMENT_ORDER to include it.".format(field.type_name)
+    return list(sorted(non_bit_fields, key=lambda f: ALIGNMENT_ORDER.index(f.type_name)))
+
+
+def _reorder_fields(fields):
+    """
+    Returns a list of fields ordered to minimise padding.
+    """
+    # Separate out bit fields from non bit fields
+    bit_fields = [field for field in fields if field.is_bit_field]
+    non_bit_fields = [field for field in fields if not field.is_bit_field]
+
     # Non bit fields go first, then the bit fields.
-    return list(non_bit_fields) + _flatten_list(field_buckets)
+    return _reorder_non_bit_fields(non_bit_fields) + _reorder_bit_fields(bit_fields)
 
 
 class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter):
diff --git a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.cpp.tmpl
index e28efac9..6f8132f 100644
--- a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.cpp.tmpl
@@ -25,6 +25,7 @@
 void ComputedStyleBase::InheritFrom(const ComputedStyleBase& other,
                                     IsAtShadowBoundary isAtShadowBoundary) {
   {{fieldwise_copy(computed_style, computed_style.all_fields
+      |selectattr("is_property")
       |selectattr("is_inherited")
       |list
     )|indent(2)}}
@@ -33,7 +34,7 @@
 void ComputedStyleBase::CopyNonInheritedFromCached(
     const ComputedStyleBase& other) {
   {{fieldwise_copy(computed_style, computed_style.all_fields
-      |rejectattr("is_nonproperty")
+      |rejectattr("has_custom_compare_and_copy")
       |rejectattr("is_inherited")
       |list
     )|indent(2)}}
diff --git a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl
index 65ce7ae7..4d6e6685 100644
--- a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl
@@ -39,6 +39,7 @@
   inline bool IndependentInheritedEqual(const ComputedStyleBase& o) const {
     return (
         {{fieldwise_compare(computed_style, computed_style.all_fields
+            |selectattr("is_property")
             |selectattr("is_inherited")
             |selectattr("is_independent")
             |list
@@ -50,6 +51,7 @@
   inline bool NonIndependentInheritedEqual(const ComputedStyleBase& o) const {
     return (
         {{fieldwise_compare(computed_style, computed_style.all_fields
+            |selectattr("is_property")
             |selectattr("is_inherited")
             |rejectattr("is_independent")
             |list
@@ -66,6 +68,7 @@
     return (
         {{fieldwise_compare(computed_style, computed_style.all_fields
             |selectattr("is_property")
+            |rejectattr("has_custom_compare_and_copy")
             |rejectattr("is_inherited")
             |list
           )|indent(8)}}
diff --git a/third_party/WebKit/Source/core/animation/AnimationEffectTiming.idl b/third_party/WebKit/Source/core/animation/AnimationEffectTiming.idl
index 5b0543f8..5f91c5a3 100644
--- a/third_party/WebKit/Source/core/animation/AnimationEffectTiming.idl
+++ b/third_party/WebKit/Source/core/animation/AnimationEffectTiming.idl
@@ -13,6 +13,6 @@
     [RaisesException=Setter] attribute double iterationStart;
     [RaisesException=Setter] attribute unrestricted double iterations;
     [RaisesException=Setter] attribute (unrestricted double or DOMString) duration;
-    attribute DOMString direction;
+    attribute PlaybackDirection direction;
     [RaisesException=Setter] attribute DOMString easing;
 };
diff --git a/third_party/WebKit/Source/core/animation/AnimationEffectTimingReadOnly.idl b/third_party/WebKit/Source/core/animation/AnimationEffectTimingReadOnly.idl
index 65c5676..773e9e48 100644
--- a/third_party/WebKit/Source/core/animation/AnimationEffectTimingReadOnly.idl
+++ b/third_party/WebKit/Source/core/animation/AnimationEffectTimingReadOnly.idl
@@ -14,6 +14,6 @@
     readonly attribute double iterationStart;
     readonly attribute unrestricted double iterations;
     readonly attribute (unrestricted double or DOMString) duration;
-    readonly attribute DOMString direction;
+    readonly attribute PlaybackDirection direction;
     readonly attribute DOMString easing;
 };
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp
index 2fe0b57..46d290b 100644
--- a/third_party/WebKit/Source/core/editing/Editor.cpp
+++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -1145,7 +1145,7 @@
     GetSpellChecker().UpdateMarkersForWordsAffectedByEditing(true);
     if (EnclosingTextControl(GetFrame()
                                  .Selection()
-                                 .ComputeVisibleSelectionInDOMTreeDeprecated()
+                                 .ComputeVisibleSelectionInDOMTree()
                                  .Start())) {
       String plain_text = GetFrame().SelectedTextForClipboard();
       Pasteboard::GeneralPasteboard()->WritePlainText(
@@ -1183,10 +1183,8 @@
   // we need clean layout to obtain the selected content.
   GetFrame().GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
 
-  if (EnclosingTextControl(GetFrame()
-                               .Selection()
-                               .ComputeVisibleSelectionInDOMTreeDeprecated()
-                               .Start())) {
+  if (EnclosingTextControl(
+          GetFrame().Selection().ComputeVisibleSelectionInDOMTree().Start())) {
     Pasteboard::GeneralPasteboard()->WritePlainText(
         GetFrame().SelectedTextForClipboard(),
         CanSmartCopyOrDelete() ? Pasteboard::kCanSmartReplace
@@ -1214,7 +1212,7 @@
 
   PasteMode paste_mode = GetFrame()
                                  .Selection()
-                                 .ComputeVisibleSelectionInDOMTreeDeprecated()
+                                 .ComputeVisibleSelectionInDOMTree()
                                  .IsContentRichlyEditable()
                              ? kAllMimeTypes
                              : kPlainTextOnly;
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index 87ec203..c29027d 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -658,6 +658,11 @@
     if (select_start_target->DispatchEvent(Event::CreateCancelableBubble(
             EventTypeNames::selectstart)) != DispatchEventResult::kNotCanceled)
       return;
+    // The frame may be detached due to selectstart event.
+    if (!IsAvailable()) {
+      // Reached by editing/selection/selectstart_detach_frame.html
+      return;
+    }
     // |root| may be detached due to selectstart event.
     if (!root->isConnected() || expected_document != root->GetDocument())
       return;
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommandTest.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommandTest.cpp
index 188a6f1..9f970adca 100644
--- a/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommandTest.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommandTest.cpp
@@ -78,4 +78,35 @@
       GetDocument().documentElement()->innerHTML());
 }
 
+// This is a regression test for https://crbug.com/712510
+TEST_F(ApplyBlockElementCommandTest, IndentHeadingIntoBlockquote) {
+  SetBodyContent(
+      "<div contenteditable=\"true\">"
+      "<h6><button><table></table></button></h6>"
+      "<object></object>"
+      "</div>");
+  Element* button = GetDocument().QuerySelector("button");
+  Element* object = GetDocument().QuerySelector("object");
+  Selection().SetSelection(SelectionInDOMTree::Builder()
+                               .Collapse(Position(button, 0))
+                               .Extend(Position(object, 0))
+                               .Build());
+
+  IndentOutdentCommand* command = IndentOutdentCommand::Create(
+      GetDocument(), IndentOutdentCommand::kIndent);
+  command->Apply();
+
+  // This only records the current behavior, which can be wrong.
+  EXPECT_EQ(
+      "<div contenteditable=\"true\">"
+      "<blockquote style=\"margin: 0 0 0 40px; border: none; padding: 0px;\">"
+      "<h6><button></button></h6>"
+      "<h6><button><table></table></button></h6>"
+      "</blockquote>"
+      "<h6><button></button></h6><br>"
+      "<object></object>"
+      "</div>",
+      GetDocument().body()->innerHTML());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
index 285363d..dbda1d3 100644
--- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -1266,9 +1266,10 @@
   DCHECK(outer_node);
   DCHECK(block_element);
 
-  VisiblePosition before_paragraph =
-      PreviousPositionOf(start_of_paragraph_to_move);
-  VisiblePosition after_paragraph = NextPositionOf(end_of_paragraph_to_move);
+  RelocatablePosition relocatable_before_paragraph(
+      PreviousPositionOf(start_of_paragraph_to_move).DeepEquivalent());
+  RelocatablePosition relocatable_after_paragraph(
+      NextPositionOf(end_of_paragraph_to_move).DeepEquivalent());
 
   // We upstream() the end and downstream() the start so that we don't include
   // collapsed whitespace in the move. When we paste a fragment, spaces after
@@ -1311,14 +1312,10 @@
   // would cause 'baz' to collapse onto the line with 'foobar' unless we insert
   // a br. Must recononicalize these two VisiblePositions after the pruning
   // above.
-  // TODO(yosin): We should abort when |beforeParagraph| is a orphan when
-  // we have a sample.
-  before_paragraph = CreateVisiblePosition(before_paragraph.DeepEquivalent());
-  if (after_paragraph.IsOrphan()) {
-    editing_state->Abort();
-    return;
-  }
-  after_paragraph = CreateVisiblePosition(after_paragraph.DeepEquivalent());
+  const VisiblePosition& before_paragraph =
+      CreateVisiblePosition(relocatable_before_paragraph.GetPosition());
+  const VisiblePosition& after_paragraph =
+      CreateVisiblePosition(relocatable_after_paragraph.GetPosition());
 
   if (before_paragraph.IsNotNull() &&
       !IsDisplayInsideTable(before_paragraph.DeepEquivalent().AnchorNode()) &&