diff --git a/android_webview/browser/net/aw_network_delegate.cc b/android_webview/browser/net/aw_network_delegate.cc index e37915c3..144f5e5 100644 --- a/android_webview/browser/net/aw_network_delegate.cc +++ b/android_webview/browser/net/aw_network_delegate.cc
@@ -147,8 +147,10 @@ options); } -bool AwNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const { +bool AwNetworkDelegate::OnCanAccessFile( + const net::URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { return true; }
diff --git a/android_webview/browser/net/aw_network_delegate.h b/android_webview/browser/net/aw_network_delegate.h index 0954513..2ebd620 100644 --- a/android_webview/browser/net/aw_network_delegate.h +++ b/android_webview/browser/net/aw_network_delegate.h
@@ -59,7 +59,8 @@ const std::string& cookie_line, net::CookieOptions* options) override; bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; // Used to filter URL requests. Owned by AwBrowserContext. const policy::URLBlacklistManager* url_blacklist_manager_;
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 3eec53a..83f6dc1 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -523,8 +523,9 @@ "//chrome/test/data/translate/", "//chrome/test/media_router/resources/", "//content/test/data/android/geolocation.html", - "//content/test/data/android/quota_permissions.html", "//content/test/data/android/media_permissions.html", + "//content/test/data/android/permission_navigation.html", + "//content/test/data/android/quota_permissions.html", "//content/test/data/android/webshare.html", "//content/test/data/media/bear.webm", "//content/test/data/media/getusermedia.html",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java index d38dc9b..fcb0b97 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java
@@ -89,6 +89,7 @@ */ private void queueDialog(PermissionDialogDelegate delegate) { mRequestQueue.add(delegate); + delegate.setDialogController(this); scheduleDisplay(); } @@ -101,6 +102,11 @@ return mDialog; } + @VisibleForTesting + public int getQueueLengthForTesting() { + return mRequestQueue.size(); + } + @Override public void onAndroidPermissionAccepted() { mDialogDelegate.onAccept(mSwitchView.isChecked()); @@ -193,9 +199,10 @@ mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { - // For some reason this is ocassionally null. See crbug.com/708562. + // Null if dismiss initiated by C++, or for some unknown reason (crbug.com/708562). if (mDialogDelegate == null) { scheduleDisplay(); + return; } mDialog = null; @@ -253,6 +260,19 @@ return fullString; } + public void dismissFromNative(PermissionDialogDelegate delegate) { + if (mDialogDelegate == delegate) { + mDialogDelegate = null; + AlertDialog dialog = mDialog; + mDialog = null; + dialog.dismiss(); + } else { + assert mRequestQueue.contains(delegate); + mRequestQueue.remove(delegate); + } + delegate.destroy(); + } + private void destroyDelegate() { mDialogDelegate.destroy(); mDialogDelegate = null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java index 3397d3f..01917fff 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java
@@ -21,6 +21,9 @@ /** The native-side counterpart of this class */ private long mNativeDelegatePtr; + /** The controller for this class */ + private PermissionDialogController mDialogController; + /** The tab for which to create the dialog. */ private Tab mTab; @@ -103,6 +106,18 @@ nativeLinkClicked(mNativeDelegatePtr); } + public void setDialogController(PermissionDialogController controller) { + mDialogController = controller; + } + + /** + * Called from C++ by |nativeDelegatePtr| to destroy the dialog. + */ + @CalledByNative + private void dismissFromNative() { + mDialogController.dismissFromNative(this); + } + /** * Called from C++ by |nativeDelegatePtr| to instantiate this class. *
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 25586dc33..bfa009d8 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1566,6 +1566,7 @@ "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUseStatsTest.java", "javatests/src/org/chromium/chrome/browser/permissions/GeolocationTest.java", "javatests/src/org/chromium/chrome/browser/permissions/MediaTest.java", + "javatests/src/org/chromium/chrome/browser/permissions/PermissionNavigationTest.java", "javatests/src/org/chromium/chrome/browser/permissions/PermissionTestCaseBase.java", "javatests/src/org/chromium/chrome/browser/permissions/QuotaTest.java", "javatests/src/org/chromium/chrome/browser/precache/MockPrecacheController.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionNavigationTest.java new file mode 100644 index 0000000..fe0168b21 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionNavigationTest.java
@@ -0,0 +1,73 @@ +// 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. + +package org.chromium.chrome.browser.permissions; + +import android.support.test.filters.MediumTest; + +import org.junit.Assert; + +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.RetryOnFailure; +import org.chromium.chrome.browser.tab.EmptyTabObserver; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; + +/** + * Test suite for interaction between permissions requests and navigation. + */ +@RetryOnFailure +public class PermissionNavigationTest extends PermissionTestCaseBase { + private static final String TEST_FILE = "/content/test/data/android/permission_navigation.html"; + + public PermissionNavigationTest() {} + + /** + * Check that modal permission prompts and queued permission requests are removed upon + * navigation. + * + * @throws Exception + */ + @MediumTest + @Feature({"Permissions"}) + @CommandLineFlags.Add({NO_GESTURE_FEATURE, FORCE_FIELDTRIAL, FORCE_FIELDTRIAL_PARAMS}) + public void testNavigationDismissesModalPermissionPrompt() throws Exception { + setUpUrl(TEST_FILE); + runJavaScriptCodeInCurrentTab("requestGeolocationPermission()"); + DialogShownCriteria criteriaShown = new DialogShownCriteria("Dialog not shown", true); + CriteriaHelper.pollUiThread(criteriaShown); + Assert.assertEquals(0, PermissionDialogController.getInstance().getQueueLengthForTesting()); + + runJavaScriptCodeInCurrentTab("requestNotificationPermission()"); + CriteriaHelper.pollInstrumentationThread(new Criteria("Request not queued") { + @Override + public boolean isSatisfied() { + return PermissionDialogController.getInstance().getQueueLengthForTesting() == 1; + } + }); + + runJavaScriptCodeInCurrentTab("navigate()"); + + Tab tab = getActivity().getActivityTab(); + final CallbackHelper callbackHelper = new CallbackHelper(); + EmptyTabObserver navigationWaiter = new EmptyTabObserver() { + @Override + public void onDidFinishNavigation(Tab tab, String url, boolean isInMainFrame, + boolean isErrorPage, boolean hasCommitted, boolean isSameDocument, + boolean isFragmentNavigation, Integer pageTransition, int errorCode, + int httpStatusCode) { + callbackHelper.notifyCalled(); + } + }; + tab.addObserver(navigationWaiter); + callbackHelper.waitForCallback(0); + tab.removeObserver(navigationWaiter); + + DialogShownCriteria criteriaNotShown = new DialogShownCriteria("Dialog shown", false); + CriteriaHelper.pollUiThread(criteriaNotShown); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionTestCaseBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionTestCaseBase.java index 063c362..43ace6a5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionTestCaseBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionTestCaseBase.java
@@ -88,11 +88,13 @@ /** * Criteria class to detect whether the permission dialog is shown. */ - private static class DialogShownCriteria extends Criteria { + protected static class DialogShownCriteria extends Criteria { private AlertDialog mDialog; + private boolean mExpectDialog; - public DialogShownCriteria(String error) { + public DialogShownCriteria(String error, boolean expectDialog) { super(error); + mExpectDialog = expectDialog; } public AlertDialog getDialog() { @@ -107,7 +109,7 @@ public Boolean call() { mDialog = PermissionDialogController.getInstance() .getCurrentDialogForTesting(); - return mDialog != null; + return (mDialog != null) == mExpectDialog; } }); } catch (ExecutionException e) { @@ -136,6 +138,10 @@ super.tearDown(); } + protected void setUpUrl(final String url) throws InterruptedException { + loadUrl(mTestServer.getURL(url)); + } + /** * Simulates clicking a button on an AlertDialog. */ @@ -165,8 +171,7 @@ protected void runAllowTest(PermissionUpdateWaiter updateWaiter, final String url, String javascript, int nUpdates, boolean withGesture, boolean isDialog, boolean hasSwitch, boolean toggleSwitch) throws Exception { - final String test_url = mTestServer.getURL(url); - loadUrl(test_url); + setUpUrl(url); if (withGesture) { runJavaScriptCodeInCurrentTab("functionToRun = '" + javascript + "'"); @@ -176,7 +181,7 @@ } if (isDialog) { - DialogShownCriteria criteria = new DialogShownCriteria("Dialog not shown"); + DialogShownCriteria criteria = new DialogShownCriteria("Dialog not shown", true); CriteriaHelper.pollUiThread(criteria); replyToDialogAndWaitForUpdates( updateWaiter, criteria.getDialog(), nUpdates, true, hasSwitch, toggleSwitch);
diff --git a/chrome/browser/android/offline_pages/offline_page_request_job.cc b/chrome/browser/android/offline_pages/offline_page_request_job.cc index 32a6685..3401b11 100644 --- a/chrome/browser/android/offline_pages/offline_page_request_job.cc +++ b/chrome/browser/android/offline_pages/offline_page_request_job.cc
@@ -707,6 +707,13 @@ URLRequestJob::NotifyHeadersComplete(); } +// Returns true to disable the file path checking for file: scheme in +// URLRequestFileJob, that's not relevant for this class. +bool OfflinePageRequestJob::CanAccessFile(const base::FilePath& original_path, + const base::FilePath& absolute_path) { + return true; +} + void OfflinePageRequestJob::SetDelegateForTesting( std::unique_ptr<Delegate> delegate) { delegate_ = std::move(delegate);
diff --git a/chrome/browser/android/offline_pages/offline_page_request_job.h b/chrome/browser/android/offline_pages/offline_page_request_job.h index 500af977..b3fcf777 100644 --- a/chrome/browser/android/offline_pages/offline_page_request_job.h +++ b/chrome/browser/android/offline_pages/offline_page_request_job.h
@@ -103,6 +103,10 @@ void SetDelegateForTesting(std::unique_ptr<Delegate> delegate); private: + // net::URLRequestFileJob overrides: + bool CanAccessFile(const base::FilePath& original_path, + const base::FilePath& absolute_path) override; + OfflinePageRequestJob(net::URLRequest* request, net::NetworkDelegate* network_delegate, previews::PreviewsDecider* previews_decider);
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index a7c2bfb9..f6417c0 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm
@@ -1017,7 +1017,6 @@ break; } case IDC_SHOW_BOOKMARK_MANAGER: - base::RecordAction(UserMetricsAction("ShowBookmarkManager")); if (Browser* browser = ActivateBrowser(lastProfile)) { chrome::ShowBookmarkManager(browser); } else {
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.cc b/chrome/browser/bookmarks/bookmark_model_factory.cc index 46069a63..e6d62d6 100644 --- a/chrome/browser/bookmarks/bookmark_model_factory.cc +++ b/chrome/browser/bookmarks/bookmark_model_factory.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/bookmarks/startup_task_runner_service_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.h" #include "chrome/browser/undo/bookmark_undo_service_factory.h" #include "chrome/common/chrome_switches.h" #include "components/bookmarks/browser/bookmark_model.h" @@ -27,6 +28,21 @@ using bookmarks::BookmarkModel; +namespace { + +bool IsBookmarkUndoServiceEnabled() { + bool register_bookmark_undo_service_as_observer = true; +#if !defined(OS_ANDROID) + register_bookmark_undo_service_as_observer = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBookmarkUndo) || + MdBookmarksUI::IsEnabled(); +#endif // !defined(OS_ANDROID) + return register_bookmark_undo_service_as_observer; +} + +} // namespace + // static BookmarkModel* BookmarkModelFactory::GetForBrowserContext( content::BrowserContext* context) { @@ -69,13 +85,7 @@ ->GetBookmarkTaskRunner(), content::BrowserThread::GetTaskRunnerForThread( content::BrowserThread::UI)); - bool register_bookmark_undo_service_as_observer = true; -#if !defined(OS_ANDROID) - register_bookmark_undo_service_as_observer = - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableBookmarkUndo); -#endif // !defined(OS_ANDROID) - if (register_bookmark_undo_service_as_observer) + if (IsBookmarkUndoServiceEnabled()) BookmarkUndoServiceFactory::GetForProfile(profile)->Start(bookmark_model); return bookmark_model;
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc index 6686bd3c..b11644ad 100644 --- a/chrome/browser/net/chrome_network_delegate.cc +++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -447,8 +447,10 @@ return allow; } -bool ChromeNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const { +bool ChromeNetworkDelegate::OnCanAccessFile( + const net::URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { #if defined(OS_CHROMEOS) // browser_tests and interactive_ui_tests rely on the ability to open any // files via file: scheme. @@ -456,7 +458,14 @@ return true; #endif - return IsAccessAllowed(path, profile_path_); +#if defined(OS_ANDROID) + // Android's whitelist relies on symbolic links (ex. /sdcard is whitelisted + // and commonly a symbolic link), thus do not check absolute paths. + return IsAccessAllowed(original_path, profile_path_); +#else + return (IsAccessAllowed(original_path, profile_path_) && + IsAccessAllowed(absolute_path, profile_path_)); +#endif } // static
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h index d4e94a9e..8937c09 100644 --- a/chrome/browser/net/chrome_network_delegate.h +++ b/chrome/browser/net/chrome_network_delegate.h
@@ -173,7 +173,8 @@ const std::string& cookie_line, net::CookieOptions* options) override; bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; bool OnCanEnablePrivacyMode( const GURL& url, const GURL& first_party_for_cookies) const override;
diff --git a/chrome/browser/net/chrome_network_delegate_unittest.cc b/chrome/browser/net/chrome_network_delegate_unittest.cc index 5020876..c7132e7 100644 --- a/chrome/browser/net/chrome_network_delegate_unittest.cc +++ b/chrome/browser/net/chrome_network_delegate_unittest.cc
@@ -601,6 +601,8 @@ // Chrome OS and Android don't have access to random files. EXPECT_FALSE(IsAccessAllowed("/", "")); EXPECT_FALSE(IsAccessAllowed("/foo.txt", "")); + // Empty path should not be allowed. + EXPECT_FALSE(IsAccessAllowed("", "")); #endif #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/permissions/permission_dialog_delegate.cc b/chrome/browser/permissions/permission_dialog_delegate.cc index 1c1e81c..d6082290 100644 --- a/chrome/browser/permissions/permission_dialog_delegate.cc +++ b/chrome/browser/permissions/permission_dialog_delegate.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_features.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" @@ -102,14 +103,12 @@ return RegisterNativesImpl(env); } -ScopedJavaLocalRef<jobject> PermissionDialogDelegate::CreateJavaDelegate( - JNIEnv* env) { +void PermissionDialogDelegate::CreateJavaDelegate(JNIEnv* env) { std::vector<int> content_settings_types{ infobar_delegate_->content_settings_types()}; - return Java_PermissionDialogDelegate_create( - env, reinterpret_cast<uintptr_t>(this), - tab_->GetJavaObject(), + 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()), @@ -119,7 +118,7 @@ ConvertUTF16ToJavaString(env, infobar_delegate_->GetButtonLabel( PermissionInfoBarDelegate::BUTTON_CANCEL)), - infobar_delegate_->ShouldShowPersistenceToggle()); + infobar_delegate_->ShouldShowPersistenceToggle())); } void PermissionDialogDelegate::Accept(JNIEnv* env, @@ -164,19 +163,40 @@ PermissionDialogDelegate::PermissionDialogDelegate( TabAndroid* tab, std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate) - : tab_(tab), infobar_delegate_(std::move(infobar_delegate)) { + : content::WebContentsObserver(tab->web_contents()), + tab_(tab), + infobar_delegate_(std::move(infobar_delegate)) { DCHECK(tab_); DCHECK(infobar_delegate_); // Create our Java counterpart, which manages our lifetime. JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jobject> j_delegate = - CreateJavaDelegate(env); + CreateJavaDelegate(env); // Send the Java delegate to the Java PermissionDialogController for display. // The controller takes over lifetime management; when the Java delegate is no // longer needed it will in turn free the native delegate. - Java_PermissionDialogController_createDialog(env, j_delegate.obj()); + Java_PermissionDialogController_createDialog(env, j_delegate_.obj()); } PermissionDialogDelegate::~PermissionDialogDelegate() {} + +void PermissionDialogDelegate::DismissDialog() { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_PermissionDialogDelegate_dismissFromNative(env, j_delegate_.obj()); +} + +void PermissionDialogDelegate::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame() || + !navigation_handle->HasCommitted() || + navigation_handle->IsSameDocument()) { + return; + } + + DismissDialog(); +} + +void PermissionDialogDelegate::WebContentsDestroyed() { + DismissDialog(); +}
diff --git a/chrome/browser/permissions/permission_dialog_delegate.h b/chrome/browser/permissions/permission_dialog_delegate.h index 76c4b6cd0..9b699eea 100644 --- a/chrome/browser/permissions/permission_dialog_delegate.h +++ b/chrome/browser/permissions/permission_dialog_delegate.h
@@ -13,9 +13,9 @@ #include "chrome/browser/media/webrtc/media_stream_devices_controller.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" using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; namespace content { class WebContents; @@ -34,7 +34,7 @@ // 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. -class PermissionDialogDelegate { +class PermissionDialogDelegate : public content::WebContentsObserver { public: using PermissionSetCallback = base::Callback<void(bool, PermissionAction)>; @@ -73,9 +73,19 @@ PermissionDialogDelegate( TabAndroid* tab, std::unique_ptr<PermissionInfoBarDelegate> infobar_delegate_); - ~PermissionDialogDelegate(); + ~PermissionDialogDelegate() override; - ScopedJavaLocalRef<jobject> CreateJavaDelegate(JNIEnv* env); + void CreateJavaDelegate(JNIEnv* env); + + // On navigation or page destruction, hide the dialog. + void DismissDialog(); + + // WebContentsObserver: + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + void WebContentsDestroyed() override; + + base::android::ScopedJavaGlobalRef<jobject> j_delegate_; TabAndroid* tab_;
diff --git a/chrome/browser/renderer_context_menu/spelling_menu_observer.cc b/chrome/browser/renderer_context_menu/spelling_menu_observer.cc index 61de0fd2..355d84d 100644 --- a/chrome/browser/renderer_context_menu/spelling_menu_observer.cc +++ b/chrome/browser/renderer_context_menu/spelling_menu_observer.cc
@@ -315,9 +315,7 @@ typedef std::vector<SpellCheckResult> SpellCheckResults; for (SpellCheckResults::const_iterator it = results.begin(); it != results.end(); ++it) { - // If there's more than one replacement, we can't automatically apply it - if (it->replacements.size() == 1) - result_.replace(it->location, it->length, it->replacements[0]); + result_.replace(it->location, it->length, it->replacement); } base::string16 result = base::i18n::ToLower(result_); for (std::vector<base::string16>::const_iterator it = suggestions_.begin();
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.js b/chrome/browser/resources/md_bookmarks/command_manager.js index 7dbf8d07..aef8c5a 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.js +++ b/chrome/browser/resources/md_bookmarks/command_manager.js
@@ -58,6 +58,9 @@ cr.isMac ? 'meta+enter' : 'ctrl+enter'; this.shortcuts_[Command.OPEN_NEW_WINDOW] = 'shift+enter'; this.shortcuts_[Command.OPEN] = cr.isMac ? 'meta+down' : 'enter'; + this.shortcuts_[Command.UNDO] = cr.isMac ? 'meta+z' : 'ctrl+z'; + this.shortcuts_[Command.REDO] = + cr.isMac ? 'meta+shift+z' : 'ctrl+y ctrl+shift+z'; }, detached: function() { @@ -107,6 +110,9 @@ switch (command) { case Command.OPEN: return itemIds.size > 0; + case Command.UNDO: + case Command.REDO: + return true; default: return this.isCommandVisible_(command, itemIds) && this.isCommandEnabled_(command, itemIds); @@ -178,6 +184,12 @@ // TODO(jiaxi): Add toast later. }); break; + case Command.UNDO: + chrome.bookmarkManagerPrivate.undo(); + break; + case Command.REDO: + chrome.bookmarkManagerPrivate.redo(); + break; case Command.OPEN_NEW_TAB: case Command.OPEN_NEW_WINDOW: case Command.OPEN_INCOGNITO:
diff --git a/chrome/browser/resources/md_bookmarks/constants.js b/chrome/browser/resources/md_bookmarks/constants.js index bcbee2b9..e93f0a43 100644 --- a/chrome/browser/resources/md_bookmarks/constants.js +++ b/chrome/browser/resources/md_bookmarks/constants.js
@@ -26,6 +26,8 @@ OPEN_NEW_TAB: 'open-new-tab', OPEN_NEW_WINDOW: 'open-new-window', OPEN_INCOGNITO: 'open-incognito', + UNDO: 'undo', + REDO: 'redo', // OPEN triggers when you double-click an item. OPEN: 'open', };
diff --git a/chrome/browser/spellchecker/spellcheck_message_filter_platform_mac_unittest.cc b/chrome/browser/spellchecker/spellcheck_message_filter_platform_mac_unittest.cc index 1ad7b2b1..e9810e8 100644 --- a/chrome/browser/spellchecker/spellcheck_message_filter_platform_mac_unittest.cc +++ b/chrome/browser/spellchecker/spellcheck_message_filter_platform_mac_unittest.cc
@@ -34,7 +34,7 @@ // local & remote result - must be flagged SPELLING, uses remote suggestion. SpellCheckResult result(SpellCheckResult::SPELLING, 20, 5, local_suggestion); local_results.push_back(result); - result.replacements[0] = remote_suggestion; + result.replacement = remote_suggestion; remote_results.push_back(result); SpellCheckMessageFilterPlatform::CombineResults(&remote_results, @@ -45,7 +45,7 @@ EXPECT_EQ(0, remote_results[0].location); EXPECT_EQ(SpellCheckResult::SPELLING, remote_results[1].decoration); EXPECT_EQ(20, remote_results[1].location); - EXPECT_EQ(remote_suggestion, remote_results[1].replacements[0]); + EXPECT_EQ(remote_suggestion, remote_results[1].replacement); } TEST(SpellCheckMessageFilterPlatformMacTest, TestOverrideThread) {
diff --git a/chrome/browser/spellchecker/spellcheck_message_filter_unittest.cc b/chrome/browser/spellchecker/spellcheck_message_filter_unittest.cc index 10477b8..62d445f9 100644 --- a/chrome/browser/spellchecker/spellcheck_message_filter_unittest.cc +++ b/chrome/browser/spellchecker/spellcheck_message_filter_unittest.cc
@@ -121,7 +121,7 @@ EXPECT_EQ(kDecoration, sent_results[0].decoration); EXPECT_EQ(kLocation, sent_results[0].location); EXPECT_EQ(kLength, sent_results[0].length); - EXPECT_EQ(kReplacement, sent_results[0].replacements[0]); + EXPECT_EQ(kReplacement, sent_results[0].replacement); } TEST(SpellCheckMessageFilterTest, OnTextCheckCompleteTest) {
diff --git a/chrome/browser/spellchecker/spelling_service_client_unittest.cc b/chrome/browser/spellchecker/spelling_service_client_unittest.cc index e87056c..a90ea29 100644 --- a/chrome/browser/spellchecker/spelling_service_client_unittest.cc +++ b/chrome/browser/spellchecker/spelling_service_client_unittest.cc
@@ -160,7 +160,7 @@ base::string16 text(base::UTF8ToUTF16(sanitized_request_text_)); for (std::vector<SpellCheckResult>::const_iterator it = results.begin(); it != results.end(); ++it) { - text.replace(it->location, it->length, it->replacements[0]); + text.replace(it->location, it->length, it->replacement); } EXPECT_EQ(corrected_text_, text); }
diff --git a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.cc b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.cc index 41b4582d..cc99120 100644 --- a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.cc +++ b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller.cc
@@ -273,7 +273,6 @@ } case IDC_BOOKMARK_MANAGER: { - base::RecordAction(UserMetricsAction("ShowBookmarkManager")); if (selection_.size() != 1) chrome::ShowBookmarkManager(browser_); else if (selection_[0]->is_folder())
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc index 78cf00f..ce47b609 100644 --- a/chrome/browser/ui/chrome_pages.cc +++ b/chrome/browser/ui/chrome_pages.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" +#include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/download/download_shelf.h" #include "chrome/browser/extensions/launch_util.h" #include "chrome/browser/profiles/profile.h" @@ -28,11 +29,14 @@ #include "chrome/browser/ui/settings_window_manager.h" #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.h" #include "chrome/browser/ui/webui/options/content_settings_handler.h" #include "chrome/browser/ui/webui/site_settings_helper.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/bookmarks/browser/bookmark_node.h" #include "components/signin/core/browser/signin_header_helper.h" #include "components/signin/core/common/profile_management_switches.h" #include "content/public/browser/web_contents.h" @@ -67,15 +71,12 @@ const char kHashMark[] = "#"; -void OpenBookmarkManagerWithHash(Browser* browser, - const std::string& action, - int64_t node_id) { - base::RecordAction(UserMetricsAction("ShowBookmarkManager")); - base::RecordAction(UserMetricsAction("ShowBookmarks")); - NavigateParams params(GetSingletonTabNavigateParams( - browser, - GURL(kChromeUIBookmarksURL).Resolve(base::StringPrintf( - "/#%s%s", action.c_str(), base::Int64ToString(node_id).c_str())))); +void OpenBookmarkManagerForNode(Browser* browser, int64_t node_id) { + GURL url = GURL(kChromeUIBookmarksURL) + .Resolve(base::StringPrintf( + MdBookmarksUI::IsEnabled() ? "/?id=%s" : "/#%s", + base::Int64ToString(node_id).c_str())); + NavigateParams params(GetSingletonTabNavigateParams(browser, url)); params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE; ShowSingletonTabOverwritingNTP(browser, params); } @@ -185,14 +186,22 @@ void ShowBookmarkManager(Browser* browser) { base::RecordAction(UserMetricsAction("ShowBookmarkManager")); - base::RecordAction(UserMetricsAction("ShowBookmarks")); + if (MdBookmarksUI::IsEnabled()) { + const bookmarks::BookmarkNode* bookmark_bar_node = + BookmarkModelFactory::GetForBrowserContext(browser->profile()) + ->bookmark_bar_node(); + OpenBookmarkManagerForNode(browser, bookmark_bar_node->id()); + return; + } + ShowSingletonTabOverwritingNTP( browser, GetSingletonTabNavigateParams(browser, GURL(kChromeUIBookmarksURL))); } void ShowBookmarkManagerForNode(Browser* browser, int64_t node_id) { - OpenBookmarkManagerWithHash(browser, std::string(), node_id); + base::RecordAction(UserMetricsAction("ShowBookmarkManager")); + OpenBookmarkManagerForNode(browser, node_id); } void ShowHistory(Browser* browser) {
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 4181b412..d341329 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -284,7 +284,7 @@ // Enables the pref service. See https://crbug.com/654988. const base::Feature kPrefService{"PrefService", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; #if defined(OS_CHROMEOS) // The lock screen will be preloaded so it is instantly available when the user
diff --git a/chrome/test/data/webui/md_bookmarks/command_manager_test.js b/chrome/test/data/webui/md_bookmarks/command_manager_test.js index e4d82ea..a862fbd 100644 --- a/chrome/test/data/webui/md_bookmarks/command_manager_test.js +++ b/chrome/test/data/webui/md_bookmarks/command_manager_test.js
@@ -113,6 +113,19 @@ commandManager.assertLastCommand('edit', ['11']); }); + test('undo and redo commands trigger', function() { + var undoModifier = cr.isMac ? 'meta' : 'ctrl'; + var undoKey = 'z'; + var redoModifier = cr.isMac ? ['meta', 'shift'] : 'ctrl' + var redoKey = cr.isMac ? 'z' : 'y'; + + MockInteractions.pressAndReleaseKeyOn(document, '', undoModifier, undoKey); + commandManager.assertLastCommand('undo'); + + MockInteractions.pressAndReleaseKeyOn(document, '', redoModifier, redoKey); + commandManager.assertLastCommand('redo'); + }); + test('does not delete children at same time as ancestor', function() { var lastDelete = null; chrome.bookmarkManagerPrivate.removeTrees = function(idArray) {
diff --git a/chromecast/browser/cast_network_delegate.cc b/chromecast/browser/cast_network_delegate.cc index 3e004a0..3be211f 100644 --- a/chromecast/browser/cast_network_delegate.cc +++ b/chromecast/browser/cast_network_delegate.cc
@@ -18,14 +18,16 @@ CastNetworkDelegate::~CastNetworkDelegate() { } -bool CastNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const { +bool CastNetworkDelegate::OnCanAccessFile( + const net::URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { if (base::CommandLine::ForCurrentProcess()-> HasSwitch(switches::kEnableLocalFileAccesses)) { return true; } - LOG(WARNING) << "Could not access file " << path.value() + LOG(WARNING) << "Could not access file " << original_path.value() << ". All file accesses are forbidden."; return false; }
diff --git a/chromecast/browser/cast_network_delegate.h b/chromecast/browser/cast_network_delegate.h index c573a6c..2a7f08d 100644 --- a/chromecast/browser/cast_network_delegate.h +++ b/chromecast/browser/cast_network_delegate.h
@@ -31,7 +31,8 @@ private: // net::NetworkDelegate implementation: bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; DISALLOW_COPY_AND_ASSIGN(CastNetworkDelegate); };
diff --git a/components/cronet/android/cronet_url_request_context_adapter.cc b/components/cronet/android/cronet_url_request_context_adapter.cc index 9e1ebfe..10c1361 100644 --- a/components/cronet/android/cronet_url_request_context_adapter.cc +++ b/components/cronet/android/cronet_url_request_context_adapter.cc
@@ -394,7 +394,8 @@ } bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override { + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override { return false; }
diff --git a/components/spellcheck/common/BUILD.gn b/components/spellcheck/common/BUILD.gn index c03f2e4..4806ceef 100644 --- a/components/spellcheck/common/BUILD.gn +++ b/components/spellcheck/common/BUILD.gn
@@ -13,7 +13,6 @@ "spellcheck_message_generator.cc", "spellcheck_message_generator.h", "spellcheck_messages.h", - "spellcheck_result.cc", "spellcheck_result.h", "spellcheck_switches.cc", "spellcheck_switches.h",
diff --git a/components/spellcheck/common/spellcheck_messages.h b/components/spellcheck/common/spellcheck_messages.h index a56d772..e8e83a8 100644 --- a/components/spellcheck/common/spellcheck_messages.h +++ b/components/spellcheck/common/spellcheck_messages.h
@@ -23,7 +23,7 @@ IPC_STRUCT_TRAITS_MEMBER(decoration) IPC_STRUCT_TRAITS_MEMBER(location) IPC_STRUCT_TRAITS_MEMBER(length) - IPC_STRUCT_TRAITS_MEMBER(replacements) + IPC_STRUCT_TRAITS_MEMBER(replacement) IPC_STRUCT_TRAITS_END() // Messages sent from the browser to the renderer.
diff --git a/components/spellcheck/common/spellcheck_result.cc b/components/spellcheck/common/spellcheck_result.cc deleted file mode 100644 index ba5e0c9..0000000 --- a/components/spellcheck/common/spellcheck_result.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright (c) 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 "components/spellcheck/common/spellcheck_result.h" -#include <vector> - -SpellCheckResult::SpellCheckResult(Decoration d, - int loc, - int len, - const std::vector<base::string16>& rep) - : decoration(d), location(loc), length(len), replacements(rep) {} - -SpellCheckResult::SpellCheckResult(Decoration d, - int loc, - int len, - const base::string16& rep) - : decoration(d), - location(loc), - length(len), - replacements(std::vector<base::string16>({rep})) {} - -SpellCheckResult::~SpellCheckResult() = default; - -SpellCheckResult::SpellCheckResult(const SpellCheckResult&) = default;
diff --git a/components/spellcheck/common/spellcheck_result.h b/components/spellcheck/common/spellcheck_result.h index 1937a8f..0c4fb45 100644 --- a/components/spellcheck/common/spellcheck_result.h +++ b/components/spellcheck/common/spellcheck_result.h
@@ -6,7 +6,6 @@ #define COMPONENTS_SPELLCHECK_COMMON_SPELLCHECK_RESULT_H_ #include <stdint.h> -#include <vector> #include "base/strings/string16.h" @@ -23,25 +22,16 @@ GRAMMAR = 1 << 2, }; - // Default values are so we have a default constructor for IPC::ReadParam() - explicit SpellCheckResult( - Decoration d = SPELLING, - int loc = 0, - int len = 0, - const std::vector<base::string16>& rep = std::vector<base::string16>()); - - explicit SpellCheckResult(Decoration d, - int loc, - int len, - const base::string16& rep); - - ~SpellCheckResult(); - SpellCheckResult(const SpellCheckResult&); + explicit SpellCheckResult(Decoration d = SPELLING, + int loc = 0, + int len = 0, + const base::string16& rep = base::string16()) + : decoration(d), location(loc), length(len), replacement(rep) {} Decoration decoration; int location; int length; - std::vector<base::string16> replacements; + base::string16 replacement; }; #endif // COMPONENTS_SPELLCHECK_COMMON_SPELLCHECK_RESULT_H_
diff --git a/components/spellcheck/renderer/spellcheck.cc b/components/spellcheck/renderer/spellcheck.cc index e895342f..4ef53a06 100644 --- a/components/spellcheck/renderer/spellcheck.cc +++ b/components/spellcheck/renderer/spellcheck.cc
@@ -473,8 +473,7 @@ const base::string16& misspelled_word = line_text.substr(spellcheck_result.location, spellcheck_result.length); - const std::vector<base::string16>& replacements = - spellcheck_result.replacements; + base::string16 replacement = spellcheck_result.replacement; SpellCheckResult::Decoration decoration = spellcheck_result.decoration; // Ignore words in custom dictionary. @@ -483,20 +482,11 @@ continue; } - std::vector<WebString> replacements_adjusted; - for (base::string16 replacement : replacements) { - // Use the same types of appostrophes as in the mispelled word. - PreserveOriginalApostropheTypes(misspelled_word, &replacement); + // Use the same types of appostrophes as in the mispelled word. + PreserveOriginalApostropheTypes(misspelled_word, &replacement); - // Ignore suggestions that are just changing the apostrophe type - // (straight vs. typographical) - if (replacement == misspelled_word) - continue; - - replacements_adjusted.push_back(WebString::FromUTF16(replacement)); - } - - if (replacements_adjusted.empty()) + // Ignore misspellings due the typographical apostrophe. + if (misspelled_word == replacement) continue; if (filter == USE_NATIVE_CHECKER) { @@ -514,10 +504,10 @@ } } - results.push_back( - WebTextCheckingResult(static_cast<WebTextDecorationType>(decoration), - line_offset + spellcheck_result.location, - spellcheck_result.length, replacements_adjusted)); + results.push_back(WebTextCheckingResult( + static_cast<WebTextDecorationType>(decoration), + line_offset + spellcheck_result.location, spellcheck_result.length, + blink::WebString::FromUTF16(replacement))); } textcheck_results->Assign(results);
diff --git a/components/spellcheck/renderer/spellcheck_provider_test.cc b/components/spellcheck/renderer/spellcheck_provider_test.cc index 88882d2f..ffba9d1 100644 --- a/components/spellcheck/renderer/spellcheck_provider_test.cc +++ b/components/spellcheck/renderer/spellcheck_provider_test.cc
@@ -83,9 +83,8 @@ text_.assign(text); text_check_completions_.Remove(identifier); std::vector<blink::WebTextCheckingResult> results; - results.push_back( - blink::WebTextCheckingResult(blink::kWebTextDecorationTypeSpelling, 0, 5, - std::vector<blink::WebString>({"hello"}))); + results.push_back(blink::WebTextCheckingResult( + blink::kWebTextDecorationTypeSpelling, 0, 5, blink::WebString("hello"))); completion->DidFinishCheckingText(results); last_request_ = text; last_results_ = results;
diff --git a/components/spellcheck/renderer/spellcheck_provider_unittest.cc b/components/spellcheck/renderer/spellcheck_provider_unittest.cc index 02684c0..478fe21 100644 --- a/components/spellcheck/renderer/spellcheck_provider_unittest.cc +++ b/components/spellcheck/renderer/spellcheck_provider_unittest.cc
@@ -29,9 +29,8 @@ blink::WebVector<blink::WebTextCheckingResult> last_results; std::vector<blink::WebTextCheckingResult> results; - results.push_back( - blink::WebTextCheckingResult(blink::kWebTextDecorationTypeSpelling, 5, 3, - std::vector<blink::WebString>({"isq"}))); + results.push_back(blink::WebTextCheckingResult( + blink::kWebTextDecorationTypeSpelling, 5, 3, blink::WebString("isq"))); last_results.Assign(results); provider_.SetLastResults(base::ASCIIToUTF16("This isq a test"), last_results); EXPECT_TRUE(provider_.SatisfyRequestFromCache(
diff --git a/components/spellcheck/renderer/spellcheck_unittest.cc b/components/spellcheck/renderer/spellcheck_unittest.cc index 0fdb7dd9..ef73f2d 100644 --- a/components/spellcheck/renderer/spellcheck_unittest.cc +++ b/components/spellcheck/renderer/spellcheck_unittest.cc
@@ -1201,10 +1201,9 @@ SpellCheckResult::SPELLING, 6, 6, base::WideToUTF16(L"haven" TYPOGRAPHICAL_APOSTROPHE L"t"))); spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 13, 10, - base::WideToUTF16( - L"in" TYPOGRAPHICAL_APOSTROPHE L"n" TYPOGRAPHICAL_APOSTROPHE L"ou" - L"t" TYPOGRAPHICAL_APOSTROPHE L"s"))); + SpellCheckResult::SPELLING, 13, 10, base::WideToUTF16( + L"in" TYPOGRAPHICAL_APOSTROPHE L"n" TYPOGRAPHICAL_APOSTROPHE L"out" + TYPOGRAPHICAL_APOSTROPHE L"s"))); // Replacements that differ only by apostrophe type should be ignored. spellcheck_results.push_back( @@ -1214,66 +1213,26 @@ SpellCheckResult(SpellCheckResult::SPELLING, 29, 4, base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve"))); - // If we have multiple replacements that all differ only by apostrophe type, - // we should ignore this misspelling. - spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 0, 11, - std::vector<base::string16>( - {base::UTF8ToUTF16("Ik've havn'"), - base::WideToUTF16(L"Ik" TYPOGRAPHICAL_APOSTROPHE - "ve havn" TYPOGRAPHICAL_APOSTROPHE)}))); - - // If we have multiple replacements where some only differ by apostrophe type - // and some don't, we should keep this misspelling, but remove the - // replacements that only differ by apostrophe type. - spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 0, 5, - std::vector<base::string16>( - {base::UTF8ToUTF16("I've"), base::UTF8ToUTF16("Ive"), - base::WideToUTF16(L"Ik" TYPOGRAPHICAL_APOSTROPHE "ve")}))); - - // Similar to the previous case except with the apostrophe changing from - // typographical to straight instead of the other direction - spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 6, 6, - std::vector<base::string16>({base::UTF8ToUTF16("havn't"), - base::UTF8ToUTF16("havnt"), - base::UTF8ToUTF16("haven't")}))); - - // If we have multiple replacements, none of which differ only by apostrophe - // type, we should keep this misspelling. - spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 6, 6, - std::vector<base::string16>( - {base::UTF8ToUTF16("have"), base::UTF8ToUTF16("haven't")}))); - blink::WebVector<blink::WebTextCheckingResult> textcheck_results; spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 0, text, spellcheck_results, &textcheck_results); - static std::vector<std::vector<const wchar_t*>> kExpectedReplacements = { - {L"I've"}, - {L"haven" TYPOGRAPHICAL_APOSTROPHE L"t"}, - {L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out's"}, - {L"I've"}, - {L"haven" TYPOGRAPHICAL_APOSTROPHE L"t"}, - {L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out" TYPOGRAPHICAL_APOSTROPHE L"s"}, - {L"I've", L"Ive"}, - {L"havnt", L"haven" TYPOGRAPHICAL_APOSTROPHE "t"}, - {L"have", L"haven" TYPOGRAPHICAL_APOSTROPHE "t"}, + static const wchar_t* kExpectedReplacements[] = { + L"I've", + L"haven" TYPOGRAPHICAL_APOSTROPHE L"t", + L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out's", + L"I've", + L"haven" TYPOGRAPHICAL_APOSTROPHE L"t", + L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out" TYPOGRAPHICAL_APOSTROPHE L"s", }; - ASSERT_EQ(kExpectedReplacements.size(), textcheck_results.size()); - for (size_t i = 0; i < kExpectedReplacements.size(); ++i) { - EXPECT_EQ(kExpectedReplacements[i].size(), - textcheck_results[i].replacements.size()); - for (size_t j = 0; j < kExpectedReplacements[i].size(); ++j) { - EXPECT_EQ(base::WideToUTF16(kExpectedReplacements[i][j]), - textcheck_results[i].replacements[j].Utf16()) - << "i=" << i << "\nj=" << j << "\nactual: \"" - << textcheck_results[i].replacements[j].Utf16() << "\""; - } + ASSERT_EQ(arraysize(kExpectedReplacements), textcheck_results.size()); + for (size_t i = 0; i < arraysize(kExpectedReplacements); ++i) { + EXPECT_EQ(base::WideToUTF16(kExpectedReplacements[i]), + textcheck_results[i].replacement.Utf16()) + << "i=" << i << "\nactual: \"" + << textcheck_results[i].replacement.Utf16() << "\""; } }
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc index 50f13c5..a62913c 100644 --- a/content/browser/permissions/permission_service_impl.cc +++ b/content/browser/permissions/permission_service_impl.cc
@@ -106,44 +106,11 @@ const url::Origin& origin, bool user_gesture, const PermissionStatusCallback& callback) { - // This condition is valid if the call is coming from a ChildThread instead of - // a RenderFrame. Some consumers of the service run in Workers and some in - // Frames. In the context of a Worker, it is not possible to show a - // permission prompt because there is no tab. In the context of a Frame, we - // can. Even if the call comes from a context where it is not possible to show - // any UI, we want to still return something relevant so the current - // permission status is returned. - BrowserContext* browser_context = context_->GetBrowserContext(); - DCHECK(browser_context); - if (!context_->render_frame_host() || - !browser_context->GetPermissionManager()) { - callback.Run(GetPermissionStatus(permission, origin)); - return; - } - - int pending_request_id = - pending_requests_.Add(base::MakeUnique<PendingRequest>( - base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1)); - int id = browser_context->GetPermissionManager()->RequestPermission( - PermissionDescriptorToPermissionType(permission), - context_->render_frame_host(), origin.GetURL(), user_gesture, - base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, - weak_factory_.GetWeakPtr(), pending_request_id)); - - // Check if the request still exists. It might have been removed by the - // callback if it was run synchronously. - PendingRequest* pending_request = pending_requests_.Lookup( - pending_request_id); - if (!pending_request) - return; - pending_request->id = id; -} - -void PermissionServiceImpl::OnRequestPermissionResponse( - int pending_request_id, - PermissionStatus status) { - OnRequestPermissionsResponse(pending_request_id, - std::vector<PermissionStatus>(1, status)); + std::vector<PermissionDescriptorPtr> permissions; + permissions.push_back(std::move(permission)); + RequestPermissions( + std::move(permissions), origin, user_gesture, + base::Bind(&PermissionRequestResponseCallbackWrapper, callback)); } void PermissionServiceImpl::RequestPermissions(
diff --git a/content/browser/permissions/permission_service_impl.h b/content/browser/permissions/permission_service_impl.h index cfce915..9d8430d 100644 --- a/content/browser/permissions/permission_service_impl.h +++ b/content/browser/permissions/permission_service_impl.h
@@ -67,8 +67,6 @@ blink::mojom::PermissionStatus last_known_status, blink::mojom::PermissionObserverPtr observer) override; - void OnRequestPermissionResponse(int pending_request_id, - blink::mojom::PermissionStatus status); void OnRequestPermissionsResponse( int pending_request_id, const std::vector<blink::mojom::PermissionStatus>& result);
diff --git a/content/shell/browser/shell_network_delegate.cc b/content/shell/browser/shell_network_delegate.cc index 9565d26..46252eb 100644 --- a/content/shell/browser/shell_network_delegate.cc +++ b/content/shell/browser/shell_network_delegate.cc
@@ -109,8 +109,10 @@ return rv == net::OK; } -bool ShellNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const { +bool ShellNetworkDelegate::OnCanAccessFile( + const net::URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { return true; }
diff --git a/content/shell/browser/shell_network_delegate.h b/content/shell/browser/shell_network_delegate.h index 1c809751..184bbb9 100644 --- a/content/shell/browser/shell_network_delegate.h +++ b/content/shell/browser/shell_network_delegate.h
@@ -54,7 +54,8 @@ const std::string& cookie_line, net::CookieOptions* options) override; bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; bool OnAreExperimentalCookieFeaturesEnabled() const override; bool OnCancelURLRequestWithPolicyViolatingReferrerHeader( const net::URLRequest& request,
diff --git a/content/shell/browser/shell_permission_manager.cc b/content/shell/browser/shell_permission_manager.cc index 5311d5d..aed1bd3 100644 --- a/content/shell/browser/shell_permission_manager.cc +++ b/content/shell/browser/shell_permission_manager.cc
@@ -47,7 +47,7 @@ bool user_gesture, const base::Callback< void(const std::vector<blink::mojom::PermissionStatus>&)>& callback) { - std::vector<blink::mojom::PermissionStatus> result(permissions.size()); + std::vector<blink::mojom::PermissionStatus> result; for (const auto& permission : permissions) { result.push_back(IsWhitelistedPermissionType(permission) ? blink::mojom::PermissionStatus::GRANTED
diff --git a/content/shell/test_runner/mock_spell_check.cc b/content/shell/test_runner/mock_spell_check.cc index 141dc40..52c7bca 100644 --- a/content/shell/test_runner/mock_spell_check.cc +++ b/content/shell/test_runner/mock_spell_check.cc
@@ -114,12 +114,12 @@ const blink::WebString& text, std::vector<blink::WebTextCheckingResult>* results) { if (text == "Helllo wordl.") { - results->push_back(blink::WebTextCheckingResult( - blink::kWebTextDecorationTypeSpelling, 0, 6, - std::vector<blink::WebString>({"Hello"}))); - results->push_back(blink::WebTextCheckingResult( - blink::kWebTextDecorationTypeSpelling, 7, 5, - std::vector<blink::WebString>({"world"}))); + results->push_back( + blink::WebTextCheckingResult(blink::kWebTextDecorationTypeSpelling, 0, + 6, blink::WebString("Hello"))); + results->push_back( + blink::WebTextCheckingResult(blink::kWebTextDecorationTypeSpelling, 7, + 5, blink::WebString("world"))); return true; } return false;
diff --git a/content/shell/test_runner/spell_check_client.cc b/content/shell/test_runner/spell_check_client.cc index 19ed128..e190811 100644 --- a/content/shell/test_runner/spell_check_client.cc +++ b/content/shell/test_runner/spell_check_client.cc
@@ -114,7 +114,8 @@ &suggestions); results.push_back(blink::WebTextCheckingResult( blink::kWebTextDecorationTypeSpelling, offset + misspelled_position, - misspelled_length, suggestions)); + misspelled_length, + suggestions.IsEmpty() ? blink::WebString() : suggestions[0])); text = text.substr(misspelled_position + misspelled_length); offset += misspelled_position + misspelled_length; }
diff --git a/content/test/data/android/permission_navigation.html b/content/test/data/android/permission_navigation.html new file mode 100644 index 0000000..6a73e3aaa --- /dev/null +++ b/content/test/data/android/permission_navigation.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> + +<script> +function navigate() { + window.location = "about:blank"; +} + +function requestGeolocationPermission() { + navigator.geolocation.getCurrentPosition(function() { }); +} + +function requestNotificationPermission() { + Notification.requestPermission(); +} +</script>
diff --git a/extensions/browser/extension_protocols.cc b/extensions/browser/extension_protocols.cc index c1ea0a9..cc5d704 100644 --- a/extensions/browser/extension_protocols.cc +++ b/extensions/browser/extension_protocols.cc
@@ -284,6 +284,13 @@ request_timer_->Elapsed()); } + bool CanAccessFile(const base::FilePath& original_path, + const base::FilePath& absolute_path) override { + // The access checks for the file are performed before the job is + // created, so we should know that this is safe. + return true; + } + void OnFilePathAndLastModifiedTimeRead(base::FilePath* read_file_path, base::Time* last_modified_time) { file_path_ = *read_file_path;
diff --git a/headless/lib/browser/headless_network_delegate.cc b/headless/lib/browser/headless_network_delegate.cc index f58a566..2cc325f 100644 --- a/headless/lib/browser/headless_network_delegate.cc +++ b/headless/lib/browser/headless_network_delegate.cc
@@ -86,7 +86,8 @@ bool HeadlessNetworkDelegate::OnCanAccessFile( const net::URLRequest& request, - const base::FilePath& path) const { + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { return true; }
diff --git a/headless/lib/browser/headless_network_delegate.h b/headless/lib/browser/headless_network_delegate.h index 5395d38..f2a550ad 100644 --- a/headless/lib/browser/headless_network_delegate.h +++ b/headless/lib/browser/headless_network_delegate.h
@@ -64,7 +64,8 @@ net::CookieOptions* options) override; bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; DISALLOW_COPY_AND_ASSIGN(HeadlessNetworkDelegate); };
diff --git a/ios/chrome/browser/net/ios_chrome_network_delegate.cc b/ios/chrome/browser/net/ios_chrome_network_delegate.cc index 85a4b0d..da8bfda 100644 --- a/ios/chrome/browser/net/ios_chrome_network_delegate.cc +++ b/ios/chrome/browser/net/ios_chrome_network_delegate.cc
@@ -146,7 +146,8 @@ bool IOSChromeNetworkDelegate::OnCanAccessFile( const net::URLRequest& request, - const base::FilePath& path) const { + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { return true; }
diff --git a/ios/chrome/browser/net/ios_chrome_network_delegate.h b/ios/chrome/browser/net/ios_chrome_network_delegate.h index ca3ba85..5521baa 100644 --- a/ios/chrome/browser/net/ios_chrome_network_delegate.h +++ b/ios/chrome/browser/net/ios_chrome_network_delegate.h
@@ -64,7 +64,8 @@ const std::string& cookie_line, net::CookieOptions* options) override; bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; bool OnCanEnablePrivacyMode( const GURL& url, const GURL& first_party_for_cookies) const override;
diff --git a/ios/web/shell/shell_network_delegate.cc b/ios/web/shell/shell_network_delegate.cc index 421aa76..717aef9 100644 --- a/ios/web/shell/shell_network_delegate.cc +++ b/ios/web/shell/shell_network_delegate.cc
@@ -78,8 +78,10 @@ return true; } -bool ShellNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const { +bool ShellNetworkDelegate::OnCanAccessFile( + const net::URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { return true; }
diff --git a/ios/web/shell/shell_network_delegate.h b/ios/web/shell/shell_network_delegate.h index 0929c15..ab7d47d 100644 --- a/ios/web/shell/shell_network_delegate.h +++ b/ios/web/shell/shell_network_delegate.h
@@ -51,7 +51,8 @@ const std::string& cookie_line, net::CookieOptions* options) override; bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; DISALLOW_COPY_AND_ASSIGN(ShellNetworkDelegate); };
diff --git a/ios/web_view/internal/web_view_network_delegate.cc b/ios/web_view/internal/web_view_network_delegate.cc index 761aa7b..d875343 100644 --- a/ios/web_view/internal/web_view_network_delegate.cc +++ b/ios/web_view/internal/web_view_network_delegate.cc
@@ -75,8 +75,10 @@ return true; } -bool WebViewNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const { +bool WebViewNetworkDelegate::OnCanAccessFile( + const net::URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { return true; }
diff --git a/ios/web_view/internal/web_view_network_delegate.h b/ios/web_view/internal/web_view_network_delegate.h index bcc1253..119bca36 100644 --- a/ios/web_view/internal/web_view_network_delegate.h +++ b/ios/web_view/internal/web_view_network_delegate.h
@@ -51,7 +51,8 @@ const std::string& cookie_line, net::CookieOptions* options) override; bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; DISALLOW_COPY_AND_ASSIGN(WebViewNetworkDelegate); };
diff --git a/mojo/public/cpp/system/wait_set.cc b/mojo/public/cpp/system/wait_set.cc index 75ce93e..2081309 100644 --- a/mojo/public/cpp/system/wait_set.cc +++ b/mojo/public/cpp/system/wait_set.cc
@@ -32,6 +32,8 @@ void ShutDown() { // NOTE: This may immediately invoke Notify for every context. watcher_handle_.reset(); + + cancelled_contexts_.clear(); } MojoResult AddEvent(base::WaitableEvent* event) { @@ -93,6 +95,11 @@ scoped_refptr<Context> context; { base::AutoLock lock(lock_); + + // Always clear |cancelled_contexts_| in case it's accumulated any more + // entries since the last time we ran. + cancelled_contexts_.clear(); + auto it = handle_to_context_.find(handle); if (it == handle_to_context_.end()) return MOJO_RESULT_NOT_FOUND; @@ -116,13 +123,6 @@ // to |cancelled_contexts_|. DCHECK(rv == MOJO_RESULT_OK || rv == MOJO_RESULT_NOT_FOUND); - { - // Always clear |cancelled_contexts_| in case it's accumulated any more - // entries since the last time we ran. - base::AutoLock lock(lock_); - cancelled_contexts_.clear(); - } - return rv; }
diff --git a/net/base/directory_lister.cc b/net/base/directory_lister.cc index 51cbd12..e5ca942 100644 --- a/net/base/directory_lister.cc +++ b/net/base/directory_lister.cc
@@ -144,6 +144,7 @@ DirectoryListerData data; data.info = file_enum.GetInfo(); data.path = path; + data.absolute_path = base::MakeAbsoluteFilePath(path); directory_list->push_back(data); /* TODO(brettw) bug 24107: It would be nice to send incremental updates.
diff --git a/net/base/directory_lister.h b/net/base/directory_lister.h index 4491c09..0489341 100644 --- a/net/base/directory_lister.h +++ b/net/base/directory_lister.h
@@ -32,6 +32,7 @@ struct DirectoryListerData { base::FileEnumerator::FileInfo info; base::FilePath path; + base::FilePath absolute_path; }; // Implement this class to receive directory entries.
diff --git a/net/base/layered_network_delegate.cc b/net/base/layered_network_delegate.cc index 41c22c1..4718c4b 100644 --- a/net/base/layered_network_delegate.cc +++ b/net/base/layered_network_delegate.cc
@@ -203,16 +203,19 @@ CookieOptions* options) { } -bool LayeredNetworkDelegate::OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const { - OnCanAccessFileInternal(request, path); - return nested_network_delegate_->CanAccessFile(request, path); +bool LayeredNetworkDelegate::OnCanAccessFile( + const URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { + OnCanAccessFileInternal(request, original_path, absolute_path); + return nested_network_delegate_->CanAccessFile(request, original_path, + absolute_path); } void LayeredNetworkDelegate::OnCanAccessFileInternal( const URLRequest& request, - const base::FilePath& path) const { -} + const base::FilePath& original_path, + const base::FilePath& absolute_path) const {} bool LayeredNetworkDelegate::OnCanEnablePrivacyMode( const GURL& url,
diff --git a/net/base/layered_network_delegate.h b/net/base/layered_network_delegate.h index 562ca0f7..033ae357 100644 --- a/net/base/layered_network_delegate.h +++ b/net/base/layered_network_delegate.h
@@ -78,7 +78,8 @@ const std::string& cookie_line, CookieOptions* options) final; bool OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const final; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const final; bool OnCanEnablePrivacyMode(const GURL& url, const GURL& first_party_for_cookies) const final; bool OnAreExperimentalCookieFeaturesEnabled() const final; @@ -153,8 +154,10 @@ const AuthCallback& callback, AuthCredentials* credentials); - virtual void OnCanAccessFileInternal(const URLRequest& request, - const base::FilePath& path) const; + virtual void OnCanAccessFileInternal( + const URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const; virtual void OnCanEnablePrivacyModeInternal( const GURL& url,
diff --git a/net/base/layered_network_delegate_unittest.cc b/net/base/layered_network_delegate_unittest.cc index b92ee03..3ba85add 100644 --- a/net/base/layered_network_delegate_unittest.cc +++ b/net/base/layered_network_delegate_unittest.cc
@@ -128,7 +128,8 @@ } bool OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const override { + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override { IncrementAndCompareCounter("on_can_access_file_count"); return false; } @@ -205,7 +206,7 @@ OnAuthRequired(request.get(), *auth_challenge, AuthCallback(), NULL)); EXPECT_FALSE(OnCanGetCookies(*request, CookieList())); EXPECT_FALSE(OnCanSetCookie(*request, std::string(), NULL)); - EXPECT_FALSE(OnCanAccessFile(*request, base::FilePath())); + EXPECT_FALSE(OnCanAccessFile(*request, base::FilePath(), base::FilePath())); EXPECT_FALSE(OnCanEnablePrivacyMode(GURL(), GURL())); EXPECT_FALSE(OnCancelURLRequestWithPolicyViolatingReferrerHeader( *request, GURL(), GURL())); @@ -310,8 +311,10 @@ EXPECT_EQ(1, (*counters_)["on_can_set_cookie_count"]); } - void OnCanAccessFileInternal(const URLRequest& request, - const base::FilePath& path) const override { + void OnCanAccessFileInternal( + const URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override { ++(*counters_)["on_can_access_file_count"]; EXPECT_EQ(1, (*counters_)["on_can_access_file_count"]); }
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc index 6344e4d..a40f7d6 100644 --- a/net/base/network_delegate.cc +++ b/net/base/network_delegate.cc
@@ -159,9 +159,10 @@ } bool NetworkDelegate::CanAccessFile(const URLRequest& request, - const base::FilePath& path) const { + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { DCHECK(CalledOnValidThread()); - return OnCanAccessFile(request, path); + return OnCanAccessFile(request, original_path, absolute_path); } bool NetworkDelegate::CanEnablePrivacyMode(
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h index eaa1e30..e13ebed 100644 --- a/net/base/network_delegate.h +++ b/net/base/network_delegate.h
@@ -105,7 +105,8 @@ const std::string& cookie_line, CookieOptions* options); bool CanAccessFile(const URLRequest& request, - const base::FilePath& path) const; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const; bool CanEnablePrivacyMode(const GURL& url, const GURL& first_party_for_cookies) const; @@ -278,10 +279,13 @@ CookieOptions* options) = 0; // Called when a file access is attempted to allow the network delegate to - // allow or block access to the given file path. Returns true if access is - // allowed. + // allow or block access to the given file path, provided in the original + // and absolute forms (i.e. symbolic link is resolved). It's up to + // subclasses of NetworkDelegate to decide which path to use for + // checking. Returns true if access is allowed. virtual bool OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const = 0; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const = 0; // Returns true if the given |url| has to be requested over connection that // is not tracked by the server. Usually is false, unless user privacy
diff --git a/net/base/network_delegate_impl.cc b/net/base/network_delegate_impl.cc index 3ca66c1..323c8bd6 100644 --- a/net/base/network_delegate_impl.cc +++ b/net/base/network_delegate_impl.cc
@@ -92,8 +92,10 @@ return true; } -bool NetworkDelegateImpl::OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const { +bool NetworkDelegateImpl::OnCanAccessFile( + const URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { return false; }
diff --git a/net/base/network_delegate_impl.h b/net/base/network_delegate_impl.h index 16f2d603..0ccaf82d 100644 --- a/net/base/network_delegate_impl.h +++ b/net/base/network_delegate_impl.h
@@ -90,7 +90,8 @@ CookieOptions* options) override; bool OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; bool OnCanEnablePrivacyMode( const GURL& url,
diff --git a/net/proxy/network_delegate_error_observer_unittest.cc b/net/proxy/network_delegate_error_observer_unittest.cc index 4e38b620..d2833aa 100644 --- a/net/proxy/network_delegate_error_observer_unittest.cc +++ b/net/proxy/network_delegate_error_observer_unittest.cc
@@ -73,7 +73,8 @@ return true; } bool OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const override { + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override { return true; }
diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc index a1a7e5e..a57e0de 100644 --- a/net/proxy/proxy_script_fetcher_impl_unittest.cc +++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -203,7 +203,8 @@ } bool OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const override { + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override { return true; }
diff --git a/net/url_request/file_protocol_handler.cc b/net/url_request/file_protocol_handler.cc index ceed930..ff19d16ee 100644 --- a/net/url_request/file_protocol_handler.cc +++ b/net/url_request/file_protocol_handler.cc
@@ -26,12 +26,6 @@ base::FilePath file_path; const bool is_file = FileURLToFilePath(request->url(), &file_path); - // Check file access permissions. - if (!network_delegate || - !network_delegate->CanAccessFile(*request, file_path)) { - return new URLRequestErrorJob(request, network_delegate, ERR_ACCESS_DENIED); - } - // We need to decide whether to create URLRequestFileJob for file access or // URLRequestFileDirJob for directory access. To avoid accessing the // filesystem, we only look at the path string here.
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc index 605ff7e..5937f2a6 100644 --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc
@@ -125,7 +125,8 @@ } bool OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const override { + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override { return true; }
diff --git a/net/url_request/url_request_file_dir_job.cc b/net/url_request/url_request_file_dir_job.cc index 435ccb00..27d7ec7 100644 --- a/net/url_request/url_request_file_dir_job.cc +++ b/net/url_request/url_request_file_dir_job.cc
@@ -6,10 +6,12 @@ #include "base/bind.h" #include "base/compiler_specific.h" +#include "base/files/file_util.h" #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "net/base/directory_listing.h" @@ -37,8 +39,12 @@ weak_factory_(this) {} void URLRequestFileDirJob::StartAsync() { - lister_.Start(); - NotifyHeadersComplete(); + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, + {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::Bind(&base::MakeAbsoluteFilePath, dir_path_), + base::Bind(&URLRequestFileDirJob::DidMakeAbsolutePath, + weak_factory_.GetWeakPtr())); } void URLRequestFileDirJob::Start() { @@ -136,6 +142,18 @@ URLRequestFileDirJob::~URLRequestFileDirJob() {} +void URLRequestFileDirJob::DidMakeAbsolutePath( + const base::FilePath& absolute_path) { + if (network_delegate() && !network_delegate()->CanAccessFile( + *request(), dir_path_, absolute_path)) { + NotifyStartError(URLRequestStatus::FromError(ERR_ACCESS_DENIED)); + return; + } + + lister_.Start(); + NotifyHeadersComplete(); +} + void URLRequestFileDirJob::CompleteRead(Error error) { DCHECK_LE(error, OK); DCHECK_NE(error, ERR_IO_PENDING);
diff --git a/net/url_request/url_request_file_dir_job.h b/net/url_request/url_request_file_dir_job.h index 85209ad..458faac 100644 --- a/net/url_request/url_request_file_dir_job.h +++ b/net/url_request/url_request_file_dir_job.h
@@ -42,7 +42,8 @@ ~URLRequestFileDirJob() override; private: - void CloseLister(); + // Called after the target directory path is resolved to an absolute path. + void DidMakeAbsolutePath(const base::FilePath& absolute_path); // When we have data and a read has been pending, this function // will fill the response buffer and notify the request
diff --git a/net/url_request/url_request_file_job.cc b/net/url_request/url_request_file_job.cc index 4924e02..7d68f087 100644 --- a/net/url_request/url_request_file_job.cc +++ b/net/url_request/url_request_file_job.cc
@@ -196,6 +196,12 @@ return GzipSourceStream::Create(std::move(source), SourceStream::TYPE_GZIP); } +bool URLRequestFileJob::CanAccessFile(const base::FilePath& original_path, + const base::FilePath& absolute_path) { + return !network_delegate() || network_delegate()->CanAccessFile( + *request(), original_path, absolute_path); +} + void URLRequestFileJob::FetchMetaInfo(const base::FilePath& file_path, FileMetaInfo* meta_info) { base::File::Info file_info; @@ -208,6 +214,7 @@ // done in WorkerPool. meta_info->mime_type_result = GetMimeTypeFromFile(file_path, &meta_info->mime_type); + meta_info->absolute_path = base::MakeAbsoluteFilePath(file_path); } void URLRequestFileJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) { @@ -230,6 +237,11 @@ return; } + if (!CanAccessFile(file_path_, meta_info->absolute_path)) { + DidOpen(ERR_ACCESS_DENIED); + return; + } + int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_ASYNC;
diff --git a/net/url_request/url_request_file_job.h b/net/url_request/url_request_file_job.h index ec90767..64638ac 100644 --- a/net/url_request/url_request_file_job.h +++ b/net/url_request/url_request_file_job.h
@@ -72,6 +72,11 @@ base::FilePath file_path_; private: + // This class checks if a path is accessible via file: scheme, with + // NetworkDelegate. Subclasses can disable the check if needed. + virtual bool CanAccessFile(const base::FilePath& original_path, + const base::FilePath& absolute_path); + // Meta information about the file. It's used as a member in the // URLRequestFileJob and also passed between threads because disk access is // necessary to obtain it. @@ -89,6 +94,8 @@ bool file_exists; // Flag showing whether the file name actually refers to a directory. bool is_directory; + // Absolute path of the file (i.e. symbolic link is resolved). + base::FilePath absolute_path; }; // Fetches file info on a background thread.
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 5f7f123..4c602012 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc
@@ -648,8 +648,10 @@ return allow; } -bool TestNetworkDelegate::OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const { +bool TestNetworkDelegate::OnCanAccessFile( + const URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const { return can_access_files_; }
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h index 201f07b..9868bcbb 100644 --- a/net/url_request/url_request_test_util.h +++ b/net/url_request/url_request_test_util.h
@@ -356,7 +356,8 @@ const std::string& cookie_line, CookieOptions* options) override; bool OnCanAccessFile(const URLRequest& request, - const base::FilePath& path) const override; + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override; bool OnAreExperimentalCookieFeaturesEnabled() const override; bool OnCancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request,
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 2d158a04..5d299633 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -835,6 +835,41 @@ TestURLRequestContext default_context_; }; +// This NetworkDelegate is picky about what files are accessible. Only +// whitelisted files are allowed. +class CookieBlockingNetworkDelegate : public TestNetworkDelegate { + public: + CookieBlockingNetworkDelegate(){}; + + // Adds |directory| to the access white list. + void AddToWhitelist(const base::FilePath& directory) { + whitelist_.insert(directory); + } + + private: + // Returns true if |path| matches the white list. + bool OnCanAccessFileInternal(const base::FilePath& path) const { + for (const auto& directory : whitelist_) { + if (directory == path || directory.IsParent(path)) + return true; + } + return false; + } + + // Returns true only if both |original_path| and |absolute_path| match the + // white list. + bool OnCanAccessFile(const URLRequest& request, + const base::FilePath& original_path, + const base::FilePath& absolute_path) const override { + return (OnCanAccessFileInternal(original_path) && + OnCanAccessFileInternal(absolute_path)); + } + + std::set<base::FilePath> whitelist_; + + DISALLOW_COPY_AND_ASSIGN(CookieBlockingNetworkDelegate); +}; + TEST_F(URLRequestTest, AboutBlankTest) { TestDelegate d; { @@ -1083,39 +1118,176 @@ TEST_F(URLRequestTest, AllowFileURLs) { base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + // Get an absolute path since |temp_dir| can contain a symbolic link. As of + // now, Mac and Android bots return a path with a symbolic link. + base::FilePath absolute_temp_dir = + base::MakeAbsoluteFilePath(temp_dir.GetPath()); + base::FilePath test_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &test_file)); + ASSERT_TRUE(base::CreateTemporaryFileInDir(absolute_temp_dir, &test_file)); + // The directory part of the path returned from CreateTemporaryFileInDir() + // can be slightly different from |absolute_temp_dir| on Windows. + // Example: C:\\Users\\CHROME~2 -> C:\\Users\\chrome-bot + // Hence the test should use the directory name of |test_file|, rather than + // |absolute_temp_dir|, for whitelisting. + base::FilePath real_temp_dir = test_file.DirName(); std::string test_data("monkey"); base::WriteFile(test_file, test_data.data(), test_data.size()); GURL test_file_url = FilePathToFileURL(test_file); - { TestDelegate d; - TestNetworkDelegate network_delegate; - network_delegate.set_can_access_files(true); + CookieBlockingNetworkDelegate network_delegate; + network_delegate.AddToWhitelist(real_temp_dir); default_context_.set_network_delegate(&network_delegate); std::unique_ptr<URLRequest> r(default_context_.CreateRequest( test_file_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); r->Start(); base::RunLoop().Run(); + // This should be allowed as the file path is whitelisted. EXPECT_FALSE(d.request_failed()); EXPECT_EQ(test_data, d.data_received()); } { TestDelegate d; - TestNetworkDelegate network_delegate; - network_delegate.set_can_access_files(false); + CookieBlockingNetworkDelegate network_delegate; default_context_.set_network_delegate(&network_delegate); std::unique_ptr<URLRequest> r(default_context_.CreateRequest( test_file_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); r->Start(); base::RunLoop().Run(); + // This should be rejected as the file path is not whitelisted. EXPECT_TRUE(d.request_failed()); EXPECT_EQ("", d.data_received()); + EXPECT_EQ(ERR_ACCESS_DENIED, d.request_status()); } } +#if defined(OS_POSIX) // Bacause of symbolic links. + +TEST_F(URLRequestTest, SymlinksToFiles) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + // Get an absolute path since temp_dir can contain a symbolic link. + base::FilePath absolute_temp_dir = + base::MakeAbsoluteFilePath(temp_dir.GetPath()); + + // Create a good directory (will be whitelisted) and a good file. + base::FilePath good_dir = absolute_temp_dir.AppendASCII("good"); + ASSERT_TRUE(base::CreateDirectory(good_dir)); + base::FilePath good_file; + ASSERT_TRUE(base::CreateTemporaryFileInDir(good_dir, &good_file)); + std::string good_data("good"); + base::WriteFile(good_file, good_data.data(), good_data.size()); + // See the comment in AllowFileURLs() for why this is done. + base::FilePath real_good_dir = good_file.DirName(); + + // Create a bad directory (will not be whitelisted) and a bad file. + base::FilePath bad_dir = absolute_temp_dir.AppendASCII("bad"); + ASSERT_TRUE(base::CreateDirectory(bad_dir)); + base::FilePath bad_file; + ASSERT_TRUE(base::CreateTemporaryFileInDir(bad_dir, &bad_file)); + std::string bad_data("bad"); + base::WriteFile(bad_file, bad_data.data(), bad_data.size()); + + // This symlink will point to the good file. Access to the symlink will be + // allowed as both the symlink and the destination file are in the same + // good directory. + base::FilePath good_symlink = good_dir.AppendASCII("good_symlink"); + ASSERT_TRUE(base::CreateSymbolicLink(good_file, good_symlink)); + GURL good_file_url = FilePathToFileURL(good_symlink); + // This symlink will point to the bad file. Even though the symlink is in + // the good directory, access to the symlink will be rejected since it + // points to the bad file. + base::FilePath bad_symlink = good_dir.AppendASCII("bad_symlink"); + ASSERT_TRUE(base::CreateSymbolicLink(bad_file, bad_symlink)); + GURL bad_file_url = FilePathToFileURL(bad_symlink); + + CookieBlockingNetworkDelegate network_delegate; + network_delegate.AddToWhitelist(real_good_dir); + { + TestDelegate d; + default_context_.set_network_delegate(&network_delegate); + std::unique_ptr<URLRequest> r( + default_context_.CreateRequest(good_file_url, DEFAULT_PRIORITY, &d)); + r->Start(); + base::RunLoop().Run(); + // good_file_url should be allowed. + EXPECT_FALSE(d.request_failed()); + EXPECT_EQ(good_data, d.data_received()); + } + + { + TestDelegate d; + default_context_.set_network_delegate(&network_delegate); + std::unique_ptr<URLRequest> r( + default_context_.CreateRequest(bad_file_url, DEFAULT_PRIORITY, &d)); + r->Start(); + base::RunLoop().Run(); + // bad_file_url should be rejected. + EXPECT_TRUE(d.request_failed()); + EXPECT_EQ("", d.data_received()); + EXPECT_EQ(ERR_ACCESS_DENIED, d.request_status()); + } +} + +TEST_F(URLRequestTest, SymlinksToDirs) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + // Get an absolute path since temp_dir can contain a symbolic link. + base::FilePath absolute_temp_dir = + base::MakeAbsoluteFilePath(temp_dir.GetPath()); + + // Create a good directory (will be whitelisted). + base::FilePath good_dir = absolute_temp_dir.AppendASCII("good"); + ASSERT_TRUE(base::CreateDirectory(good_dir)); + + // Create a bad directory (will not be whitelisted). + base::FilePath bad_dir = absolute_temp_dir.AppendASCII("bad"); + ASSERT_TRUE(base::CreateDirectory(bad_dir)); + + // This symlink will point to the good directory. Access to the symlink + // will be allowed as the symlink is in the good dir that'll be white + // listed. + base::FilePath good_symlink = good_dir.AppendASCII("good_symlink"); + ASSERT_TRUE(base::CreateSymbolicLink(good_dir, good_symlink)); + GURL good_file_url = FilePathToFileURL(good_symlink); + // This symlink will point to the bad directory. Even though the symlink is + // in the good directory, access to the symlink will be rejected since it + // points to the bad directory. + base::FilePath bad_symlink = good_dir.AppendASCII("bad_symlink"); + ASSERT_TRUE(base::CreateSymbolicLink(bad_dir, bad_symlink)); + GURL bad_file_url = FilePathToFileURL(bad_symlink); + + CookieBlockingNetworkDelegate network_delegate; + network_delegate.AddToWhitelist(good_dir); + { + TestDelegate d; + default_context_.set_network_delegate(&network_delegate); + std::unique_ptr<URLRequest> r( + default_context_.CreateRequest(good_file_url, DEFAULT_PRIORITY, &d)); + r->Start(); + base::RunLoop().Run(); + // good_file_url should be allowed. + EXPECT_FALSE(d.request_failed()); + ASSERT_NE(d.data_received().find("good_symlink"), std::string::npos); + } + + { + TestDelegate d; + default_context_.set_network_delegate(&network_delegate); + std::unique_ptr<URLRequest> r( + default_context_.CreateRequest(bad_file_url, DEFAULT_PRIORITY, &d)); + r->Start(); + base::RunLoop().Run(); + // bad_file_url should be rejected. + EXPECT_TRUE(d.request_failed()); + EXPECT_EQ("", d.data_received()); + EXPECT_EQ(ERR_ACCESS_DENIED, d.request_status()); + } +} + +#endif // defined(OS_POSIX) TEST_F(URLRequestTest, FileDirCancelTest) { // Put in mock resource provider. @@ -1167,9 +1339,8 @@ EXPECT_GT(info.size, 0); std::string sentinel_output = GetDirectoryListingEntry( base::string16(sentinel_name, sentinel_name + strlen(sentinel_name)), - std::string(sentinel_name), - false /* is_dir */, - info.size, + std::string(sentinel_name), false /* is_dir */, info.size, + info.last_modified); ASSERT_LT(0, d.bytes_received());
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/unregister-then-register.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/unregister-then-register.https.html index d75904d..6c0a0aec 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/unregister-then-register.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/unregister-then-register.https.html
@@ -56,6 +56,45 @@ 'registration is in use.'); async_test(function(t) { + var scope = 'resources/scope/complete-unregistration-followed-by-' + + 'reloading-controllee-iframe'; + var registration; + var frame; + var service_worker; + service_worker_unregister_and_register(t, worker_url, scope) + .then(function(r) { + registration = r; + return wait_for_state(t, r.installing, 'activated'); + }) + .then(function() { + return with_iframe(scope); + }) + .then(function(f) { + frame = f; + return registration.unregister(); + }) + .then(function() { + return new Promise(function(resolve) { + frame.onload = resolve; + frame.contentWindow.location.reload(); + }); + }) + .then(function() { + var c = frame.contentWindow.navigator.serviceWorker.controller; + assert_equals(c, null, 'a page after unregistration should not be ' + + 'controlled by service worker'); + return navigator.serviceWorker.getRegistration(scope); + }) + .then(function(r) { + assert_equals(r, undefined, 'getRegistration should return ' + + 'undefined after unregistration'); + service_worker_unregister_and_done(t, scope); + }) + .catch(unreached_rejection(t)); +}, 'Reloading the last controlled iframe after unregistration should ensure ' + + 'the deletion of the registration'); + +async_test(function(t) { var scope = 'resources/scope/re-register-does-not-affect-existing-controllee'; var iframe; var registration; @@ -116,8 +155,6 @@ return with_iframe(scope); }) .then(function(frame) { - // FIXME: When crbug.com/400602 is fixed, assert that controller - // equals the original worker. assert_not_equals( frame.contentWindow.navigator.serviceWorker.controller, null, 'document should have a controller');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/update.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/update.https.html index 213b72ac..6717d4d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/update.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/update.https.html
@@ -5,12 +5,14 @@ <script src="resources/testharness-helpers.js"></script> <script src="resources/test-helpers.sub.js"></script> <script> +'use strict'; + promise_test(function(t) { var scope = 'resources/simple.txt'; var worker_url = 'resources/update-worker.py'; var expected_url = normalizeURL(worker_url); var registration; - var iframe; + return service_worker_unregister_and_register(t, worker_url, scope) .then(function(r) { registration = r; @@ -41,13 +43,11 @@ .then(function() { assert_equals(registration.installing, null, 'installing should be null after installing.'); - if (registration.waiting) { - assert_equals(registration.waiting.scriptURL, expected_url, - 'waiting should be set after installing.'); - assert_equals(registration.active.scriptURL, expected_url, - 'active should still exist after installing.'); - return wait_for_state(t, registration.waiting, 'activated'); - } + assert_equals(registration.waiting.scriptURL, expected_url, + 'waiting should be set after installing.'); + assert_equals(registration.active.scriptURL, expected_url, + 'active should still exist after installing.'); + return wait_for_state(t, registration.waiting, 'activated'); }) .then(function() { assert_equals(registration.installing, null, @@ -107,17 +107,15 @@ return with_iframe(scope); }) .then(function(frame) { - iframe = frame; + t.add_cleanup(function() { + frame.remove(); + }); return assert_promise_rejects( Promise.all([registration.unregister(), registration.update()]), new TypeError(), 'Calling update() while the uninstalling flag is set ' + 'should return a promise that rejects with a TypeError.'); - }) - .then(function() { - iframe.remove(); - return t.done(); }); }, 'Update a registration.'); </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/update-served-from-cache.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.update-served-from-cache.html similarity index 88% rename from third_party/WebKit/LayoutTests/http/tests/serviceworker/update-served-from-cache.html rename to third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.update-served-from-cache.html index d6f77e7b..3efd693 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/update-served-from-cache.html +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.update-served-from-cache.html
@@ -1,4 +1,7 @@ <!DOCTYPE html> +<!-- This test is prefixed with `chromium.` because it asserts the behavior of + the HTTP cache. This behavior does not violate any standard but neither is it + required. --> <title>Service Worker: Registration update() served from cache</title> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/reject-install-worker.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/reject-install-worker.js deleted file mode 100644 index 41f07fd..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/reject-install-worker.js +++ /dev/null
@@ -1,3 +0,0 @@ -self.oninstall = function(event) { - event.waitUntil(Promise.reject()); -};
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/unregister-controller-page.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/unregister-controller-page.html deleted file mode 100644 index 18a95ee..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/unregister-controller-page.html +++ /dev/null
@@ -1,16 +0,0 @@ -<!DOCTYPE html> -<script> -function fetch_url(url) { - return new Promise(function(resolve, reject) { - var request = new XMLHttpRequest(); - request.addEventListener('load', function(event) { - if (request.status == 200) - resolve(request.response); - else - reject(Error(request.statusText)); - }); - request.open('GET', url); - request.send(); - }); -} -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/update-worker.php b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/update-worker.php deleted file mode 100644 index 81bdd1bf..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/update-worker.php +++ /dev/null
@@ -1,42 +0,0 @@ -<?php -if(!isset($_COOKIE['mode'])) - $mode = 'init'; // Set mode to 'init' for initial fetch. -else - $mode = $_COOKIE['mode']; // $_COOKIE['mode'] is either 'normal' or 'error'. - -// no-cache itself to ensure the user agent finds a new version for each update. -header("Cache-Control: no-cache, must-revalidate"); -header("Pragma: no-cache"); - -$extra_body = ''; - -if ($mode == 'init') { - // Set a normal mimetype. - // Set cookie value to 'normal' so the next fetch will work in 'normal' mode. - header('Content-Type:application/javascript'); - setcookie('mode', 'normal'); -} else if ($mode == 'normal') { - // Set a normal mimetype. - // Set cookie value to 'error' so the next fetch will work in 'error' mode. - header('Content-Type:application/javascript'); - setcookie('mode', 'error'); -} else if ($mode == 'error') { - // Set a disallowed mimetype. - // Set cookie value to 'syntax-error' so the next fetch will work in 'syntax-error' mode. - header('Content-Type:text/html'); - setcookie('mode', 'syntax-error'); -} else if ($mode == 'syntax-error') { - // Set cookie value to 'throw-install' so the next fetch will work in 'throw-install' mode. - header('Content-Type:application/javascript'); - setcookie('mode', 'throw-install'); - $extra_body = 'badsyntax(isbad;'; -} else if ($mode == 'throw-install') { - // Unset and delete cookie to clean up the test setting. - header('Content-Type:application/javascript'); - unset($_COOKIE['mode']); - setcookie('mode', '', time() - 3600); - $extra_body = "addEventListener('install', function(e) { throw new Error('boom'); });"; -} -// Return a different script for each access. -echo '/* ', microtime(), ' */ ', $extra_body; -?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-controller.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-controller.html deleted file mode 100644 index fc05f77..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-controller.html +++ /dev/null
@@ -1,101 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="resources/test-helpers.js"></script> -<script> -var worker_url = 'resources/simple-intercept-worker.js'; - -async_test(function(t) { - var scope = - 'resources/unregister-controller-page.html?load-before-unregister'; - var frame_window; - var controller; - var registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - frame_window = frame.contentWindow; - controller = frame_window.navigator.serviceWorker.controller; - assert_true(controller instanceof frame_window.ServiceWorker, - 'document should load with a controller'); - return registration.unregister(); - }) - .then(function() { - assert_equals(frame_window.navigator.serviceWorker.controller, - controller, - 'unregistration should not modify controller'); - return frame_window.fetch_url('simple.txt'); - }) - .then(function(response) { - assert_equals(response, 'intercepted by service worker', - 'controller should intercept requests'); - t.done(); - }) - .catch(unreached_rejection(t)); - }, 'Unregister does not affect existing controller'); - -async_test(function(t) { - var scope = - 'resources/unregister-controller-page.html?load-after-unregister'; - var registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return registration.unregister(); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - var frame_window = frame.contentWindow; - assert_equals(frame_window.navigator.serviceWorker.controller, null, - 'document should not have a controller'); - return frame_window.fetch_url('simple.txt'); - }) - .then(function(response) { - assert_equals(response, 'a simple text file\n', - 'requests should not be intercepted'); - t.done(); - }) - .catch(unreached_rejection(t)); - }, 'Unregister prevents control of subsequent navigations'); - -async_test(function(t) { - var scope = - 'resources/scope/no-new-controllee-even-if-registration-is-still-used'; - var registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - return registration.unregister(); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - assert_equals(frame.contentWindow.navigator.serviceWorker.controller, - null, - 'document should not have a controller'); - t.done(); - }) - .catch(unreached_rejection(t)); - }, 'Unregister prevents new controllee even if registration is still in use'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-then-register-new-script.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-then-register-new-script.html deleted file mode 100644 index cc5ee793..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-then-register-new-script.html +++ /dev/null
@@ -1,159 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="resources/test-helpers.js"></script> -<script> -var worker_url = 'resources/empty-worker.js'; - -async_test(function(t) { - var scope = 'resources/scope/unregister-then-register-new-script-that-exists'; - var new_worker_url = worker_url + '?new'; - var iframe; - var registration; - var new_registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - iframe = frame; - return registration.unregister(); - }) - .then(function() { - return navigator.serviceWorker.register(new_worker_url, - { scope: scope }); - }) - .then(function(r) { - new_registration = r; - assert_equals(registration.installing.scriptURL, - normalizeURL(new_worker_url), - 'before activated registration.installing'); - assert_equals(registration.waiting, null, - 'before activated registration.waiting'); - assert_equals(registration.active.scriptURL, normalizeURL(worker_url), - 'before activated registration.active'); - assert_equals(new_registration.installing.scriptURL, - normalizeURL(new_worker_url), - 'before activated new_registration.installing'); - assert_equals(new_registration.waiting, null, - 'before activated new_registration.waiting'); - assert_equals(new_registration.active.scriptURL, - normalizeURL(worker_url), - 'before activated new_registration.active'); - iframe.remove(); - return wait_for_state(t, registration.installing, 'activated'); - }) - .then(function() { - assert_equals(new_registration.installing, null, - 'after activated new_registration.installing'); - assert_equals(new_registration.waiting, null, - 'after activated new_registration.waiting'); - assert_equals(new_registration.active.scriptURL, - normalizeURL(new_worker_url), - 'after activated new_registration.active'); - return with_iframe(scope); - }) - .then(function(frame) { - assert_equals( - frame.contentWindow.navigator.serviceWorker.controller.scriptURL, - normalizeURL(new_worker_url), - 'the new worker should control a new document'); - frame.remove(); - return registration.unregister(); - }) - .then(function() { - t.done(); - }) - .catch(unreached_rejection(t)); -}, 'Registering a new script URL while an unregistered registration is in use'); - -async_test(function(t) { - var scope = 'resources/scope/unregister-then-register-new-script-that-404s'; - var iframe; - var registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - iframe = frame; - return registration.unregister(); - }) - .then(function() { - var promise = navigator.serviceWorker.register('this-will-404', - { scope: scope }); - iframe.remove(); - return promise; - }) - .then( - function() { - assert_unreached('register should reject the promise'); - }, - function() { - return with_iframe(scope); - }) - .then(function(frame) { - assert_equals(frame.contentWindow.navigator.serviceWorker.controller, - null, - 'document should not load with a controller'); - frame.remove(); - t.done(); - }) - .catch(unreached_rejection(t)); -}, 'Registering a new script URL that 404s does not resurrect an ' + - 'unregistered registration'); - -async_test(function(t) { - var scope = 'resources/scope/unregister-then-register-reject-install-worker'; - var iframe; - var registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - iframe = frame; - return registration.unregister(); - }) - .then(function() { - var promise = navigator.serviceWorker.register( - 'resources/reject-install-worker.js', { scope: scope }); - iframe.remove(); - return promise; - }) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'redundant'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - assert_equals(frame.contentWindow.navigator.serviceWorker.controller, - null, - 'document should not load with a controller'); - frame.remove(); - return registration.unregister(); - }) - .then(function() { - t.done(); - }) - .catch(unreached_rejection(t)); - }, 'Registering a new script URL that fails to install does not resurrect ' + - 'an unregistered registration'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-then-register.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-then-register.html deleted file mode 100644 index 75db25c..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister-then-register.html +++ /dev/null
@@ -1,167 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="resources/test-helpers.js"></script> -<script> -var worker_url = 'resources/empty-worker.js'; - -async_test(function(t) { - var scope = 'resources/scope/re-register-resolves-to-new-value'; - var iframe; - var registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return registration.unregister(); - }) - .then(function() { - return navigator.serviceWorker.register(worker_url, { scope: scope }); - }) - .then(function(new_registration) { - assert_not_equals(registration, new_registration, - 'register should resolve to a new value'); - service_worker_unregister_and_done(t, scope); - }) - .catch(unreached_rejection(t)); - }, 'Unregister then register resolves to a new value'); - -async_test(function(t) { - var scope = 'resources/scope/re-register-while-old-registration-in-use'; - var registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - return registration.unregister(); - }) - .then(function() { - return navigator.serviceWorker.register(worker_url, { scope: scope }); - }) - .then(function(new_registration) { - assert_equals(registration, new_registration, - 'register should resolve to the same registration'); - service_worker_unregister_and_done(t, scope); - }) - .catch(unreached_rejection(t)); - }, 'Unregister then register resolves to the original value if the ' + - 'registration is in use.'); - -async_test(function(t) { - var scope = 'resources/scope/complete-unregistration-followed-by-' + - 'reloading-controllee-iframe'; - var registration; - var frame; - var service_worker; - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(f) { - frame = f; - return registration.unregister(); - }) - .then(function() { - return new Promise(function(resolve) { - frame.onload = resolve; - frame.contentWindow.location.reload(); - }); - }) - .then(function() { - var c = frame.contentWindow.navigator.serviceWorker.controller; - assert_equals(c, null, 'a page after unregistration should not be ' + - 'controlled by service worker'); - return navigator.serviceWorker.getRegistration(scope); - }) - .then(function(r) { - assert_equals(r, undefined, 'getRegistration should return ' + - 'undefined after unregistration'); - service_worker_unregister_and_done(t, scope); - }) - .catch(unreached_rejection(t)); -}, 'Reloading the last controlled iframe after unregistration should ensure ' + - 'the deletion of the registration'); - -async_test(function(t) { - var scope = 'resources/scope/re-register-does-not-affect-existing-controllee'; - var iframe; - var registration; - var controller; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - iframe = frame; - controller = iframe.contentWindow.navigator.serviceWorker.controller; - return registration.unregister(); - }) - .then(function() { - return navigator.serviceWorker.register(worker_url, { scope: scope }); - }) - .then(function(registration) { - assert_equals(registration.installing, null, - 'installing version is null'); - assert_equals(registration.waiting, null, 'waiting version is null'); - assert_equals( - iframe.contentWindow.navigator.serviceWorker.controller, - controller, - 'the worker from the first registration is the controller'); - service_worker_unregister_and_done(t, scope); - }) - .catch(unreached_rejection(t)); - }, 'Unregister then register does not affect existing controllee'); - -async_test(function(t) { - var scope = 'resources/scope/resurrection'; - var iframe; - var registration; - - service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - iframe = frame; - return registration.unregister(); - }) - .then(function() { - return navigator.serviceWorker.register(worker_url, { scope: scope }); - }) - .then(function() { - iframe.remove(); - return with_iframe(scope); - }) - .then(function(frame) { - // FIXME: When crbug.com/400602 is fixed, assert that controller - // equals the original worker. - assert_not_equals( - frame.contentWindow.navigator.serviceWorker.controller, null, - 'document should have a controller'); - service_worker_unregister_and_done(t, scope); - }) - .catch(unreached_rejection(t)); - }, 'Unregister then register resurrects the registration'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister.html deleted file mode 100644 index 54be479..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/unregister.html +++ /dev/null
@@ -1,40 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="resources/test-helpers.js"></script> -<script> -async_test(function(t) { - var scope = 'resources/scope/unregister-twice'; - var registration; - navigator.serviceWorker.register('resources/empty-worker.js', - {scope: scope}) - .then(function(r) { - registration = r; - return registration.unregister(); - }) - .then(function() { - return registration.unregister(); - }) - .then(function(value) { - assert_equals(value, false, - 'unregistering twice should resolve with false'); - t.done(); - }) - .catch(unreached_rejection(t)); - }, 'Unregister twice'); - -async_test(function(t) { - var scope = 'resources/scope/successful-unregister/'; - navigator.serviceWorker.register('resources/empty-worker.js', - {scope: scope}) - .then(function(registration) { - return registration.unregister(); - }) - .then(function(value) { - assert_equals(value, true, - 'unregistration should resolve with true'); - t.done(); - }) - .catch(unreached_rejection(t)); - }, 'Register then unregister'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/update.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/update.html deleted file mode 100644 index 82db192..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/update.html +++ /dev/null
@@ -1,119 +0,0 @@ -<!DOCTYPE html> -<title>Service Worker: Registration update()</title> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="resources/test-helpers.js"></script> -<script> -promise_test(function(t) { - var scope = 'resources/scope/update'; - var worker_url = 'resources/update-worker.php'; - var expected_url = normalizeURL(worker_url); - var registration; - return service_worker_unregister_and_register(t, worker_url, scope) - .then(function(r) { - registration = r; - return wait_for_state(t, registration.installing, 'activated'); - }) - .then(function() { - assert_equals(registration.installing, null, - 'installing should be null in the initial state.'); - assert_equals(registration.waiting, null, - 'waiting should be null in the initial state.'); - assert_equals(registration.active.scriptURL, expected_url, - 'active should exist in the initial state.'); - - // A new worker (generated by update-worker.php) should be found. - // The returned promise should resolve when a new worker script is - // fetched and starts installing. - return Promise.all([registration.update(), - wait_for_update(t, registration)]); - }) - .then(function() { - assert_equals(registration.installing.scriptURL, expected_url, - 'new installing should be set after update resolves.'); - assert_equals(registration.waiting, null, - 'waiting should still be null after update resolves.'); - assert_equals(registration.active.scriptURL, expected_url, - 'active should still exist after update found.'); - return wait_for_state(t, registration.installing, 'installed'); - }) - .then(function() { - assert_equals(registration.installing, null, - 'installing should be null after installing.'); - assert_equals(registration.waiting.scriptURL, expected_url, - 'waiting should be set after installing.'); - assert_equals(registration.active.scriptURL, expected_url, - 'active should still exist after installing.'); - return wait_for_state(t, registration.waiting, 'activated'); - }) - .then(function() { - assert_equals(registration.installing, null, - 'installing should be null after activated.'); - assert_equals(registration.waiting, null, - 'waiting should be null after activated.'); - assert_equals(registration.active.scriptURL, expected_url, - 'new worker should be promoted to active.'); - }) - .then(function() { - // A new worker(generated by update-worker.php) should be found. - // The returned promise should reject as update-worker.php sets the - // mimetype to a disallowed value for this attempt. - return registration.update(); - }) - .then( - function() { assert_unreached("update() should reject."); }, - function(e) { - assert_throws('SecurityError', function() { throw e; }, - 'Using a disallowed mimetype should make update() ' + - 'promise reject with a SecurityError.'); - assert_equals(registration.active.scriptURL, expected_url, - 'active should still exist after update failure.'); - - // A new worker(generated by update-worker.py) should be found. - // The returned promise should reject as update-worker.py returns - // a worker script with a syntax error. - return registration.update(); - }) - .then( - function() { assert_unreached("update() should reject."); }, - function(e) { - assert_throws({name: 'TypeError'}, function () { throw e; }, - 'A script syntax error should make update() ' + - 'promise reject with a TypeError.'); - assert_equals(registration.active.scriptURL, expected_url, - 'active should still exist after update failure.'); - - // A new worker(generated by update-worker.py) should be found. - // The returned promise should not reject, even though - // update-worker.py returns a worker script that throws in the - // install event handler. - return Promise.all([registration.update(), - wait_for_update(t, registration)]); - }) - .then(function() { - assert_equals(registration.installing.scriptURL, expected_url, - 'installing should be set after update resolves (throw-install).'); - assert_equals(registration.waiting, null, - 'waiting should still be null after update resolves (throw-install).'); - assert_equals(registration.active.scriptURL, expected_url, - 'active should still exist after update found (throw-install).'); - - // We need to hold a client alive so that unregister() below doesn't - // remove the registration before update() has had a chance to look - // at the pending uninstall flag. - return with_iframe(scope); - }) - .then(function(frame) { - return Promise.all([registration.unregister(), - registration.update()]); - }) - .then( - function() { assert_unreached("update() should reject."); }, - function(e) { - assert_throws({name: 'TypeError'}, function () { throw e; }, - 'Calling update() while the uninstalling flag is ' + - 'set should return a promise that rejects with an ' + - 'TypeError.'); - }); - }, 'Update a registration.'); -</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap-expected.txt deleted file mode 100644 index 728c57e..0000000 --- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -This is a testharness.js-based test. -PASS Test that passing null to getComputedStyleMap does not crash -PASS Computed StyleMap.getProperties returns the same list of property names as ComputedStyle -PASS Unsupported but serializable property returns a base CSSStyleValue. -PASS Unsupported and unserializable property returns null. -FAIL get() throws for an invalid property. Test bug: need to pass exception to assert_throws() -PASS has() return false for an unsupported property. -FAIL has() throws for an invalid property. Test bug: need to pass exception to assert_throws() -PASS has() returns true for an unsupported but serializable shorthand property. -PASS has() return false for unsupported and unserializable shorthand properties. -PASS has() returns true for a supported property. -PASS get() returns correct values for an element with display: none. -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap.html b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap.html index 7755f5bf..6e3fbab 100644 --- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap.html +++ b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/computedStylePropertyMap.html
@@ -37,7 +37,7 @@ }, 'Unsupported and unserializable property returns null.'); test(function() { - assert_throws(null, function() { computedStyleMap.get('bananas'); }); + assert_throws(new TypeError(), function() { computedStyleMap.get('bananas'); }); }, 'get() throws for an invalid property.'); test(function() { @@ -45,7 +45,7 @@ }, 'has() return false for an unsupported property.'); test(function() { - assert_throws(null, function() { computedStyleMap.has('bananas'); }); + assert_throws(new TypeError(), function() { computedStyleMap.has('bananas'); }); }, 'has() throws for an invalid property.'); test(function() {
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssCalcLength-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/cssCalcLength-expected.txt deleted file mode 100644 index 995a6f8..0000000 --- a/third_party/WebKit/LayoutTests/typedcssom/cssCalcLength-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -This is a testharness.js-based test. -FAIL Passing invalid arguments to CSSCalcLength throws an exception. Test bug: need to pass exception to assert_throws() -PASS Adding two CSSCalcLengths produces a new CSSCalcLength with the correct value. -PASS Subtracting two CSSCalcLengths produces a new CSSCalcLength with the correct values. -PASS Multiplying a CSSCalcLength produces a new CSSCalcLength with the correct values. -PASS Dividing a CSSCalcLength produces a new CSSCalcLength with the correct values. -PASS Dividing by zero throws a RangeError -PASS cssText produces the correct string -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssMatrixComponent-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/cssMatrixComponent-expected.txt deleted file mode 100644 index d6d0490f..0000000 --- a/third_party/WebKit/LayoutTests/typedcssom/cssMatrixComponent-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS Test that the (a, ... , f) and (m11, ... , m44) attributes for CSSMatrixComponent are correct. -PASS Test that the is2D values for CSSMatrixComponent are correct. -PASS Test that the toString for CSSMatrixComponent is correct. -FAIL Test that invalid number of arguments for CSSMatrixComponent throws an exception. Test bug: need to pass exception to assert_throws() -PASS Test that asMatrix has all the same properties as the original CSSMatrixComponent. -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssMatrixComponent.html b/third_party/WebKit/LayoutTests/typedcssom/cssMatrixComponent.html index 0c7a5183..0669296 100644 --- a/third_party/WebKit/LayoutTests/typedcssom/cssMatrixComponent.html +++ b/third_party/WebKit/LayoutTests/typedcssom/cssMatrixComponent.html
@@ -57,11 +57,11 @@ }, "Test that the toString for CSSMatrixComponent is correct."); test(function() { - assert_throws(null, function() { new CSSMatrixComponent() }); - assert_throws(null, function() { new CSSMatrixComponent(0) }); - assert_throws(null, function() { new CSSMatrixComponent("string") }); - assert_throws(null, function() { new CSSMatrixComponent(None) }); - assert_throws(null, function() { new CSSMatrixComponent(undefined) }); + assert_throws(new TypeError(), function() { new CSSMatrixComponent() }); + assert_throws(new TypeError(), function() { new CSSMatrixComponent(0) }); + assert_throws(new TypeError(), function() { new CSSMatrixComponent("string") }); + assert_throws(new TypeError(), function() { new CSSMatrixComponent(null) }); + assert_throws(new TypeError(), function() { new CSSMatrixComponent(undefined) }); }, "Test that invalid number of arguments for CSSMatrixComponent throws an exception."); test(function() {
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssScale-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/cssScale-expected.txt deleted file mode 100644 index 6d863576..0000000 --- a/third_party/WebKit/LayoutTests/typedcssom/cssScale-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -This is a testharness.js-based test. -PASS Test that the (x, y, z) values for CSSScale are correct. -PASS Test that the is2D values for CSSScale is correct. -PASS Test that the toString for CSSScale is correct. -FAIL Test that invalid number of arguments for CSSScale throws an exception. Test bug: need to pass exception to assert_throws() -FAIL Test that invalid input throws an exception. Test bug: need to pass exception to assert_throws() -PASS Test that asMatrix is constructed correctly for CSSScale. -PASS Test that x, y, z are mutable attributes. -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssScale.html b/third_party/WebKit/LayoutTests/typedcssom/cssScale.html index d67fd22..01075f0 100644 --- a/third_party/WebKit/LayoutTests/typedcssom/cssScale.html +++ b/third_party/WebKit/LayoutTests/typedcssom/cssScale.html
@@ -42,35 +42,35 @@ }, "Test that the toString for CSSScale is correct."); test(function() { - assert_throws(null, () => { new CSSScale(); }); - assert_throws(null, () => { new CSSScale(1); }); + assert_throws(new TypeError(), () => { new CSSScale(); }); + assert_throws(new TypeError(), () => { new CSSScale(1); }); }, "Test that invalid number of arguments for CSSScale throws an exception."); test(function() { - assert_throws(null, () => { new CSSScale(NaN, 0); }); - assert_throws(null, () => { new CSSScale(0, NaN); }); - assert_throws(null, () => { new CSSScale(NaN, NaN); }); - assert_throws(null, () => { new CSSScale(Infinity, 0); }); - assert_throws(null, () => { new CSSScale(-Infinity, 0); }); - assert_throws(null, () => { new CSSScale("hello", 0); }); - assert_throws(null, () => { new CSSScale(0, "world"); }); - assert_throws(null, () => { new CSSScale(undefined, 0); }); - assert_throws(null, () => { new CSSScale({}, {}); }); + assert_throws(new TypeError(), () => { new CSSScale(NaN, 0); }); + assert_throws(new TypeError(), () => { new CSSScale(0, NaN); }); + assert_throws(new TypeError(), () => { new CSSScale(NaN, NaN); }); + assert_throws(new TypeError(), () => { new CSSScale(Infinity, 0); }); + assert_throws(new TypeError(), () => { new CSSScale(-Infinity, 0); }); + assert_throws(new TypeError(), () => { new CSSScale("hello", 0); }); + assert_throws(new TypeError(), () => { new CSSScale(0, "world"); }); + assert_throws(new TypeError(), () => { new CSSScale(undefined, 0); }); + assert_throws(new TypeError(), () => { new CSSScale({}, {}); }); - assert_throws(null, () => { new CSSScale("hello", 0, 0); }); - assert_throws(null, () => { new CSSScale(0, NaN, 0); }); - assert_throws(null, () => { new CSSScale(0, Infinity, 0); }); - assert_throws(null, () => { new CSSScale(0, 0, NaN); }); - assert_throws(null, () => { new CSSScale(0, 0, Infinity); }); - assert_throws(null, () => { new CSSScale(0, 0, -Infinity); }); - assert_throws(null, () => { new CSSScale(0, 0, undefined); }); - assert_throws(null, () => { new CSSScale(undefined, undefined, 0); }); - assert_throws(null, () => { new CSSScale(NaN, undefined, 0); }); - assert_throws(null, () => { new CSSScale(NaN, 0, NaN); }); - assert_throws(null, () => { new CSSScale(0, "hello", "world"); }); - assert_throws(null, () => { new CSSScale(0, {}, {}); }); - assert_throws(null, () => { new CSSScale({}, {}, {}); }); - assert_throws(null, () => { new CSSScale(NaN, NaN, NaN); }); + assert_throws(new TypeError(), () => { new CSSScale("hello", 0, 0); }); + assert_throws(new TypeError(), () => { new CSSScale(0, NaN, 0); }); + assert_throws(new TypeError(), () => { new CSSScale(0, Infinity, 0); }); + assert_throws(new TypeError(), () => { new CSSScale(0, 0, NaN); }); + assert_throws(new TypeError(), () => { new CSSScale(0, 0, Infinity); }); + assert_throws(new TypeError(), () => { new CSSScale(0, 0, -Infinity); }); + assert_throws(new TypeError(), () => { new CSSScale(0, 0, undefined); }); + assert_throws(new TypeError(), () => { new CSSScale(undefined, undefined, 0); }); + assert_throws(new TypeError(), () => { new CSSScale(NaN, undefined, 0); }); + assert_throws(new TypeError(), () => { new CSSScale(NaN, 0, NaN); }); + assert_throws(new TypeError(), () => { new CSSScale(0, "hello", "world"); }); + assert_throws(new TypeError(), () => { new CSSScale(0, {}, {}); }); + assert_throws(new TypeError(), () => { new CSSScale({}, {}, {}); }); + assert_throws(new TypeError(), () => { new CSSScale(NaN, NaN, NaN); }); }, "Test that invalid input throws an exception."); test(function() {
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssSimpleLength-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/cssSimpleLength-expected.txt deleted file mode 100644 index f29ca88..0000000 --- a/third_party/WebKit/LayoutTests/typedcssom/cssSimpleLength-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -This is a testharness.js-based test. -PASS CSSSimpleLengths are immutable -PASS Each unit type is returned according to the spec -PASS Adding CSSSimpleLengths with the same unit produces a new CSSSimpleLength with the correct value. -PASS Adding CSSSimpleLengths with different units produces a calc length with the correct values. -PASS Subtracting CSSSimpleLengths with the same unit produces a new CSSSimpleLength with the correct value. -PASS Subtracting CSSSimpleLengths with different units produces a calc length with the correct values. -PASS Multiplying a CSSSimpleLength produces a new CSSSimpleLength with the correct value. -PASS Dividing a CSSSimpleLength produces a new CSSSimpleLength with the correct value. -PASS Dividing by zero throws a RangeError -PASS cssText is generated correctly for each unit type. -FAIL Invalid input throws an exception. Test bug: need to pass exception to assert_throws() -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/PerformanceTests/Editing/move-down-with-hidden-elements.html b/third_party/WebKit/PerformanceTests/DOM/move-down-with-hidden-elements.html similarity index 100% rename from third_party/WebKit/PerformanceTests/Editing/move-down-with-hidden-elements.html rename to third_party/WebKit/PerformanceTests/DOM/move-down-with-hidden-elements.html
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 e126ba0..50dc4e57 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
@@ -120,7 +120,7 @@ """ def __init__(self, field_role, name_for_methods, property_name, type_name, wrapper_pointer_name, - field_template, field_group, size, default_value, has_custom_compare_and_copy, + field_template, field_group, size, default_value, custom_copy, custom_compare, getter_method_name, setter_method_name, initial_method_name, **kwargs): """Creates a new field.""" self.name = class_member_name(name_for_methods) @@ -133,7 +133,8 @@ 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 + self.custom_copy = custom_copy + self.custom_compare = custom_compare # Field role: one of these must be true self.is_property = field_role == 'property' @@ -298,7 +299,8 @@ field_group=property_['field_group'], size=size, default_value=default_value, - has_custom_compare_and_copy=property_['has_custom_compare_and_copy'], + custom_copy=property_['custom_copy'], + custom_compare=property_['custom_compare'], getter_method_name=property_['getter'], setter_method_name=property_['setter'], initial_method_name=property_['initial'], @@ -321,7 +323,8 @@ field_group=property_['field_group'], size=1, default_value='true', - has_custom_compare_and_copy=False, + custom_copy=False, + custom_compare=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)), @@ -410,8 +413,9 @@ css_properties = [value for value in self._properties.values() if not value['longhands']] for property_ in css_properties: - # All CSS properties that are generated do not have custom comparison and copy logic. - property_['has_custom_compare_and_copy'] = False + # All CSS properties from CSSProperties.json5 do not have custom comparison and copy logic. + property_['custom_copy'] = False + property_['custom_compare'] = False # Read extra fields using the parameter specification from the CSS properties file. extra_fields = json5_generator.Json5File.load_from_files(
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 123c699..8ff8877 100644 --- a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl +++ b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl
@@ -121,7 +121,6 @@ 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/build/scripts/templates/fields/field.tmpl b/third_party/WebKit/Source/build/scripts/templates/fields/field.tmpl index 1538c97..74fcdeb 100644 --- a/third_party/WebKit/Source/build/scripts/templates/fields/field.tmpl +++ b/third_party/WebKit/Source/build/scripts/templates/fields/field.tmpl
@@ -78,28 +78,28 @@ {% for subgroup in group.subgroups %} {# If every field in this subgroup is to be compared, we can compare the group pointer instead. #} - {% if subgroup.all_fields|reject("in", fields_to_compare)|list|length == 0 -%} + {% if subgroup.all_fields|rejectattr("custom_compare")|reject("in", fields_to_compare)|list|length == 0 -%} {{subgroup.member_name}} == o.{{subgroup.member_name}} && {# Otherwise, we would have to recursively generate comparison operations on fields in the subgroup. #} - {% elif subgroup.fields|select("in", fields_to_compare)|list|length > 0 -%} + {% elif subgroup.fields|rejectattr("custom_compare")|select("in", fields_to_compare)|list|length > 0 -%} {{fieldwise_compare(subgroup, fields_to_compare)}} {% endif %} {% endfor %} -{% for field in group.fields|select("in", fields_to_compare) -%} +{% for field in group.fields|rejectattr("custom_compare")|select("in", fields_to_compare) -%} {{compare(field.wrapper_pointer_name, getter_expression(field), "o")}} && {% endfor %} {% endmacro %} {% macro fieldwise_copy(group, fields_to_copy) %} {% for subgroup in group.subgroups %} - {% if subgroup.all_fields|reject("in", fields_to_copy)|list|length == 0 -%} + {% if subgroup.all_fields|rejectattr("custom_copy")|reject("in", fields_to_copy)|list|length == 0 -%} {{subgroup.member_name}} = other.{{subgroup.member_name}}; - {% elif subgroup.fields|select("in", fields_to_copy)|list|length > 0 -%} + {% elif subgroup.fields|rejectattr("custom_copy")|select("in", fields_to_copy)|list|length > 0 -%} {{fieldwise_copy(subgroup, fields_to_copy)}} {% endif %} {% endfor %} -{% for field in group.fields|select("in", fields_to_copy) -%} +{% for field in group.fields|rejectattr("custom_copy")|select("in", fields_to_copy) -%} {{setter_expression(field)}} = other.{{getter_expression(field)}}; {% endfor %} {% endmacro %}
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationEnvironment.h b/third_party/WebKit/Source/core/animation/CSSInterpolationEnvironment.h new file mode 100644 index 0000000..27e3caf49 --- /dev/null +++ b/third_party/WebKit/Source/core/animation/CSSInterpolationEnvironment.h
@@ -0,0 +1,54 @@ +// 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 CSSInterpolationEnvironment_h +#define CSSInterpolationEnvironment_h + +#include "core/animation/InterpolationEnvironment.h" +#include "core/css/resolver/StyleResolverState.h" + +namespace blink { + +class ComputedStyle; + +class CSSInterpolationEnvironment : public InterpolationEnvironment { + public: + explicit CSSInterpolationEnvironment(const InterpolationTypesMap& map, + StyleResolverState& state) + : InterpolationEnvironment(map), state_(&state), style_(state.Style()) {} + + explicit CSSInterpolationEnvironment(const InterpolationTypesMap& map, + const ComputedStyle& style) + : InterpolationEnvironment(map), style_(&style) {} + + bool IsCSS() const final { return true; } + + StyleResolverState& GetState() { + DCHECK(state_); + return *state_; + } + const StyleResolverState& GetState() const { + DCHECK(state_); + return *state_; + } + + const ComputedStyle& Style() const { + DCHECK(style_); + return *style_; + } + + private: + StyleResolverState* state_ = nullptr; + const ComputedStyle* style_ = nullptr; +}; + +DEFINE_TYPE_CASTS(CSSInterpolationEnvironment, + InterpolationEnvironment, + value, + value->IsCSS(), + value.IsCSS()); + +} // namespace blink + +#endif // CSSInterpolationEnvironment_h
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp index 70b70b3c..ff48065 100644 --- a/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp
@@ -6,6 +6,7 @@ #include <memory> #include "core/StylePropertyShorthand.h" +#include "core/animation/CSSInterpolationEnvironment.h" #include "core/animation/StringKeyframe.h" #include "core/css/CSSCustomPropertyDeclaration.h" #include "core/css/CSSValue.h" @@ -128,7 +129,8 @@ const InterpolationValue& underlying, ConversionCheckers& conversion_checkers) const { const CSSValue* value = ToCSSPropertySpecificKeyframe(keyframe).Value(); - const StyleResolverState& state = environment.GetState(); + const StyleResolverState& state = + ToCSSInterpolationEnvironment(environment).GetState(); if (!value) return MaybeConvertNeutral(underlying, conversion_checkers); @@ -243,7 +245,8 @@ InterpolationValue CSSInterpolationType::MaybeConvertUnderlyingValue( const InterpolationEnvironment& environment) const { - const ComputedStyle& style = environment.Style(); + const ComputedStyle& style = + ToCSSInterpolationEnvironment(environment).Style(); if (!GetProperty().IsCSSCustomProperty()) { return MaybeConvertStandardPropertyUnderlyingValue(style); } @@ -271,7 +274,8 @@ const InterpolableValue& interpolable_value, const NonInterpolableValue* non_interpolable_value, InterpolationEnvironment& environment) const { - StyleResolverState& state = environment.GetState(); + StyleResolverState& state = + ToCSSInterpolationEnvironment(environment).GetState(); if (GetProperty().IsCSSCustomProperty()) { ApplyCustomPropertyValue(interpolable_value, non_interpolable_value, state);
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSInterpolationType.h index 7e72a40..c2eb7df 100644 --- a/third_party/WebKit/Source/core/animation/CSSInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSInterpolationType.h
@@ -5,13 +5,15 @@ #ifndef CSSInterpolationType_h #define CSSInterpolationType_h -#include "core/animation/InterpolationEnvironment.h" +#include "core/animation/CSSInterpolationEnvironment.h" #include "core/animation/InterpolationType.h" namespace blink { class CSSCustomPropertyDeclaration; +class ComputedStyle; class PropertyRegistration; +class StyleResolverState; class CSSInterpolationType : public InterpolationType { public: @@ -21,7 +23,8 @@ public: bool IsValid(const InterpolationEnvironment& environment, const InterpolationValue& underlying) const final { - return IsValid(environment.GetState(), underlying); + return IsValid(ToCSSInterpolationEnvironment(environment).GetState(), + underlying); } protected:
diff --git a/third_party/WebKit/Source/core/animation/InterpolationEnvironment.h b/third_party/WebKit/Source/core/animation/InterpolationEnvironment.h index 431b1d4..0af68d3 100644 --- a/third_party/WebKit/Source/core/animation/InterpolationEnvironment.h +++ b/third_party/WebKit/Source/core/animation/InterpolationEnvironment.h
@@ -6,77 +6,28 @@ #define InterpolationEnvironment_h #include "core/animation/InterpolationTypesMap.h" -#include "core/css/resolver/StyleResolverState.h" -#include "platform/heap/Handle.h" #include "platform/wtf/Allocator.h" namespace blink { -class ComputedStyle; -class SVGPropertyBase; -class SVGElement; - class InterpolationEnvironment { STACK_ALLOCATED(); - public: - explicit InterpolationEnvironment(const InterpolationTypesMap& map, - StyleResolverState& state) - : interpolation_types_map_(map), state_(&state), style_(state.Style()) {} - - explicit InterpolationEnvironment(const InterpolationTypesMap& map, - const ComputedStyle& style) - : interpolation_types_map_(map), style_(&style) {} - - explicit InterpolationEnvironment(const InterpolationTypesMap& map, - SVGElement& svg_element, - const SVGPropertyBase& svg_base_value) - : interpolation_types_map_(map), - svg_element_(&svg_element), - svg_base_value_(&svg_base_value) {} + virtual bool IsCSS() const { return false; } + virtual bool IsSVG() const { return false; } const InterpolationTypesMap& GetInterpolationTypesMap() const { return interpolation_types_map_; } - StyleResolverState& GetState() { - DCHECK(state_); - return *state_; - } - const StyleResolverState& GetState() const { - DCHECK(state_); - return *state_; - } + protected: + virtual ~InterpolationEnvironment() {} - const ComputedStyle& Style() const { - DCHECK(style_); - return *style_; - } - - SVGElement& SvgElement() { - DCHECK(svg_element_); - return *svg_element_; - } - const SVGElement& SvgElement() const { - DCHECK(svg_element_); - return *svg_element_; - } - - const SVGPropertyBase& SvgBaseValue() const { - DCHECK(svg_base_value_); - return *svg_base_value_; - } + explicit InterpolationEnvironment(const InterpolationTypesMap& map) + : interpolation_types_map_(map) {} private: const InterpolationTypesMap& interpolation_types_map_; - - // CSSInterpolationType environment - StyleResolverState* state_ = nullptr; - const ComputedStyle* style_ = nullptr; - - // SVGInterpolationType environment - Member<SVGElement> svg_element_ = nullptr; - Member<const SVGPropertyBase> svg_base_value_ = nullptr; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp b/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp index 9a3569e5..29a96ef 100644 --- a/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp +++ b/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp
@@ -4,10 +4,10 @@ #include "core/animation/InvalidatableInterpolation.h" -#include "core/animation/InterpolationEnvironment.h" +#include <memory> +#include "core/animation/CSSInterpolationEnvironment.h" #include "core/animation/StringKeyframe.h" #include "core/css/resolver/StyleResolverState.h" -#include <memory> namespace blink { @@ -198,7 +198,9 @@ InterpolationEnvironment& environment) const { if (!property_.IsCSSProperty() && !property_.IsPresentationAttribute()) return; - if (!environment.GetState().ParentStyle()) + StyleResolverState& state = + ToCSSInterpolationEnvironment(environment).GetState(); + if (!state.ParentStyle()) return; const CSSValue* start_value = ToCSSPropertySpecificKeyframe(*start_keyframe_).Value(); @@ -206,7 +208,7 @@ ToCSSPropertySpecificKeyframe(*end_keyframe_).Value(); if ((start_value && start_value->IsInheritedValue()) || (end_value && end_value->IsInheritedValue())) { - environment.GetState().ParentStyle()->SetHasExplicitlyInheritedProperties(); + state.ParentStyle()->SetHasExplicitlyInheritedProperties(); } }
diff --git a/third_party/WebKit/Source/core/animation/SVGInterpolationEnvironment.h b/third_party/WebKit/Source/core/animation/SVGInterpolationEnvironment.h new file mode 100644 index 0000000..e373a7d8 --- /dev/null +++ b/third_party/WebKit/Source/core/animation/SVGInterpolationEnvironment.h
@@ -0,0 +1,54 @@ +// 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 SVGInterpolationEnvironment_h +#define SVGInterpolationEnvironment_h + +#include "core/animation/InterpolationEnvironment.h" +#include "platform/wtf/Assertions.h" + +namespace blink { + +class SVGPropertyBase; +class SVGElement; + +class SVGInterpolationEnvironment : public InterpolationEnvironment { + public: + explicit SVGInterpolationEnvironment(const InterpolationTypesMap& map, + SVGElement& svg_element, + const SVGPropertyBase& svg_base_value) + : InterpolationEnvironment(map), + svg_element_(&svg_element), + svg_base_value_(&svg_base_value) {} + + bool IsSVG() const final { return true; } + + SVGElement& SvgElement() { + DCHECK(svg_element_); + return *svg_element_; + } + const SVGElement& SvgElement() const { + DCHECK(svg_element_); + return *svg_element_; + } + + const SVGPropertyBase& SvgBaseValue() const { + DCHECK(svg_base_value_); + return *svg_base_value_; + } + + private: + Member<SVGElement> svg_element_ = nullptr; + Member<const SVGPropertyBase> svg_base_value_ = nullptr; +}; + +DEFINE_TYPE_CASTS(SVGInterpolationEnvironment, + InterpolationEnvironment, + value, + value->IsSVG(), + value.IsSVG()); + +} // namespace blink + +#endif // SVGInterpolationEnvironment_h
diff --git a/third_party/WebKit/Source/core/animation/SVGInterpolationType.cpp b/third_party/WebKit/Source/core/animation/SVGInterpolationType.cpp index ad5415f..2fe4100 100644 --- a/third_party/WebKit/Source/core/animation/SVGInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/SVGInterpolationType.cpp
@@ -4,7 +4,7 @@ #include "core/animation/SVGInterpolationType.h" -#include "core/animation/InterpolationEnvironment.h" +#include "core/animation/SVGInterpolationEnvironment.h" #include "core/animation/StringKeyframe.h" #include "core/svg/SVGElement.h" #include "core/svg/properties/SVGProperty.h" @@ -19,22 +19,28 @@ if (keyframe.IsNeutral()) return MaybeConvertNeutral(underlying, conversion_checkers); - SVGPropertyBase* svg_value = environment.SvgBaseValue().CloneForAnimation( - ToSVGPropertySpecificKeyframe(keyframe).Value()); + SVGPropertyBase* svg_value = + ToSVGInterpolationEnvironment(environment) + .SvgBaseValue() + .CloneForAnimation(ToSVGPropertySpecificKeyframe(keyframe).Value()); return MaybeConvertSVGValue(*svg_value); } InterpolationValue SVGInterpolationType::MaybeConvertUnderlyingValue( const InterpolationEnvironment& environment) const { - return MaybeConvertSVGValue(environment.SvgBaseValue()); + return MaybeConvertSVGValue( + ToSVGInterpolationEnvironment(environment).SvgBaseValue()); } void SVGInterpolationType::Apply( const InterpolableValue& interpolable_value, const NonInterpolableValue* non_interpolable_value, InterpolationEnvironment& environment) const { - environment.SvgElement().SetWebAnimatedAttribute( - Attribute(), AppliedSVGValue(interpolable_value, non_interpolable_value)); + ToSVGInterpolationEnvironment(environment) + .SvgElement() + .SetWebAnimatedAttribute( + Attribute(), + AppliedSVGValue(interpolable_value, non_interpolable_value)); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/SVGLengthInterpolationType.cpp b/third_party/WebKit/Source/core/animation/SVGLengthInterpolationType.cpp index f1224eb..cffb3a6 100644 --- a/third_party/WebKit/Source/core/animation/SVGLengthInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/SVGLengthInterpolationType.cpp
@@ -4,13 +4,13 @@ #include "core/animation/SVGLengthInterpolationType.h" -#include "core/animation/InterpolationEnvironment.h" +#include <memory> +#include "core/animation/SVGInterpolationEnvironment.h" #include "core/animation/StringKeyframe.h" #include "core/css/CSSHelper.h" #include "core/svg/SVGElement.h" #include "core/svg/SVGLength.h" #include "core/svg/SVGLengthContext.h" -#include <memory> namespace blink { @@ -115,7 +115,7 @@ const InterpolableValue& interpolable_value, const NonInterpolableValue* non_interpolable_value, InterpolationEnvironment& environment) const { - SVGElement& element = environment.SvgElement(); + SVGElement& element = ToSVGInterpolationEnvironment(environment).SvgElement(); SVGLengthContext length_context(&element); element.SetWebAnimatedAttribute( Attribute(),
diff --git a/third_party/WebKit/Source/core/animation/SVGLengthListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/SVGLengthListInterpolationType.cpp index eff8136..65a3228 100644 --- a/third_party/WebKit/Source/core/animation/SVGLengthListInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/SVGLengthListInterpolationType.cpp
@@ -4,11 +4,11 @@ #include "core/animation/SVGLengthListInterpolationType.h" -#include "core/animation/InterpolationEnvironment.h" +#include <memory> +#include "core/animation/SVGInterpolationEnvironment.h" #include "core/animation/SVGLengthInterpolationType.h" #include "core/animation/UnderlyingLengthChecker.h" #include "core/svg/SVGLengthList.h" -#include <memory> namespace blink { @@ -85,7 +85,7 @@ const InterpolableValue& interpolable_value, const NonInterpolableValue* non_interpolable_value, InterpolationEnvironment& environment) const { - SVGElement& element = environment.SvgElement(); + SVGElement& element = ToSVGInterpolationEnvironment(environment).SvgElement(); SVGLengthContext length_context(&element); SVGLengthList* result = SVGLengthList::Create(unit_mode_);
diff --git a/third_party/WebKit/Source/core/animation/SVGTransformListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/SVGTransformListInterpolationType.cpp index 086ba10..c3a09d9 100644 --- a/third_party/WebKit/Source/core/animation/SVGTransformListInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/SVGTransformListInterpolationType.cpp
@@ -6,8 +6,8 @@ #include <memory> #include "core/animation/InterpolableValue.h" -#include "core/animation/InterpolationEnvironment.h" #include "core/animation/NonInterpolableValue.h" +#include "core/animation/SVGInterpolationEnvironment.h" #include "core/animation/StringKeyframe.h" #include "core/svg/SVGTransform.h" #include "core/svg/SVGTransformList.h" @@ -252,8 +252,10 @@ } if (!keyframe.IsNeutral()) { - SVGPropertyBase* svg_value = environment.SvgBaseValue().CloneForAnimation( - ToSVGPropertySpecificKeyframe(keyframe).Value()); + SVGPropertyBase* svg_value = + ToSVGInterpolationEnvironment(environment) + .SvgBaseValue() + .CloneForAnimation(ToSVGPropertySpecificKeyframe(keyframe).Value()); InterpolationValue value = MaybeConvertSVGValue(*svg_value); if (!value) return nullptr;
diff --git a/third_party/WebKit/Source/core/animation/TransitionInterpolation.cpp b/third_party/WebKit/Source/core/animation/TransitionInterpolation.cpp index 1b5f803d..b2f0a6d 100644 --- a/third_party/WebKit/Source/core/animation/TransitionInterpolation.cpp +++ b/third_party/WebKit/Source/core/animation/TransitionInterpolation.cpp
@@ -47,7 +47,7 @@ void TransitionInterpolation::Apply(StyleResolverState& state) const { CSSInterpolationTypesMap map(state.GetDocument().GetPropertyRegistry()); - InterpolationEnvironment environment(map, state); + CSSInterpolationEnvironment environment(map, state); type_.Apply(CurrentInterpolableValue(), CurrentNonInterpolableValue(), environment); }
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp b/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp index 6a536ab43..f3a6055 100644 --- a/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp +++ b/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
@@ -683,8 +683,8 @@ } CSSInterpolationTypesMap map(registry); - InterpolationEnvironment old_environment(map, state.old_style); - InterpolationEnvironment new_environment(map, state.style); + CSSInterpolationEnvironment old_environment(map, state.old_style); + CSSInterpolationEnvironment new_environment(map, state.style); InterpolationValue start = nullptr; InterpolationValue end = nullptr; const InterpolationType* transition_type = nullptr;
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 b/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 index 0c8a386..cd899447 100644 --- a/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 +++ b/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5
@@ -3,9 +3,15 @@ // generate, but are not CSS properties. parameters: { - // If the field has_custom_compare_and_copy, then it does not appear in - // ComputedStyle::operator== and ComputedStyle::CopyNonInheritedFromCached. - has_custom_compare_and_copy: { + // If true, we do not include this field in ComputedStyleBase::InheritFrom + // and ComputedStyleBase::CopyNonInheritedFromCached. + custom_copy: { + default: false, + }, + + // If true, we do not include this field in ComputedStyleBase::InheritedEqual + // and ComputedStyleBase::NonInheritedEqual. + custom_compare: { default: false, }, @@ -20,7 +26,8 @@ name: "IsLink", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, { name: "BorderLeftColorIsCurrentColor", @@ -67,59 +74,66 @@ default_value: "not-inside-link", keywords: ["not-inside-link", "inside-unvisited-link", "inside-visited-link"], inherited: true, - has_custom_compare_and_copy: true, }, // Style can not be shared. { name: "Unique", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, // Whether this style is affected by these pseudo-classes. { name: "AffectedByFocus", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, { name: "AffectedByFocusWithin", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, { name: "AffectedByHover", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, { name: "AffectedByActive", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, { name: "AffectedByDrag", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, // A non-inherited property references a variable or @apply is used { name: "HasVariableReferenceFromNonInheritedProperty", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, // Explicitly inherits a non-inherited property { name: "HasExplicitlyInheritedProperties", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, // These are set if we used viewport or rem units when resolving a length. // TODO(shend): HasViewportUnits should be a monotonic_flag. @@ -128,13 +142,13 @@ field_template: "primitive", default_value: "false", type_name: "bool", - has_custom_compare_and_copy: true, + custom_compare: true, }, { name: "HasRemUnits", field_template: "monotonic_flag", default_value: "false", - has_custom_compare_and_copy: true, + custom_compare: true, }, // These properties only have generated storage, and their methods are handwritten in ComputedStyle. // TODO(shend): Remove these fields and delete the 'storage_only' template. @@ -144,7 +158,8 @@ field_size: 1, default_value: "false", type_name: "bool", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, { name: "StyleType", @@ -152,7 +167,8 @@ field_size: 6, default_value: "0", type_name: "PseudoId", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, { name: "PseudoBits", @@ -160,7 +176,8 @@ field_size: 8, default_value: "kPseudoIdNone", type_name: "PseudoId", - has_custom_compare_and_copy: true, + custom_copy: true, + custom_compare: true, }, // True if 'underline solid' is the only text decoration on this element. { @@ -170,7 +187,6 @@ default_value: "false", type_name: "bool", inherited: true, - has_custom_compare_and_copy: true, }, // TODO(shend): vertical align is actually a CSS property, but since we don't support union fields // which can be either a keyword or Length, this is specified in this file for now. Remove this
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp index 40edfb05..27323df 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -35,9 +35,9 @@ #include "core/MediaTypeNames.h" #include "core/StylePropertyShorthand.h" #include "core/animation/AnimationTimeline.h" +#include "core/animation/CSSInterpolationEnvironment.h" #include "core/animation/CSSInterpolationTypesMap.h" #include "core/animation/ElementAnimations.h" -#include "core/animation/InterpolationEnvironment.h" #include "core/animation/InvalidatableInterpolation.h" #include "core/animation/KeyframeEffect.h" #include "core/animation/LegacyStyleInterpolation.h" @@ -1234,7 +1234,7 @@ const Interpolation& interpolation = *entry.value.front(); if (interpolation.IsInvalidatableInterpolation()) { CSSInterpolationTypesMap map(state.GetDocument().GetPropertyRegistry()); - InterpolationEnvironment environment(map, state); + CSSInterpolationEnvironment environment(map, state); InvalidatableInterpolation::ApplyStack(entry.value, environment); } else if (interpolation.IsTransitionInterpolation()) { ToTransitionInterpolation(interpolation).Apply(state);
diff --git a/third_party/WebKit/Source/core/dom/AXObject.cpp b/third_party/WebKit/Source/core/dom/AXObject.cpp new file mode 100644 index 0000000..54224a18 --- /dev/null +++ b/third_party/WebKit/Source/core/dom/AXObject.cpp
@@ -0,0 +1,99 @@ +// 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/dom/AXObject.h" + +#include "core/HTMLElementTypeHelpers.h" +#include "core/dom/Element.h" +#include "core/dom/Node.h" +#include "platform/wtf/HashSet.h" +#include "platform/wtf/text/StringHash.h" +#include "platform/wtf/text/WTFString.h" + +namespace blink { + +namespace { + +typedef HashSet<String, CaseFoldingHash> ARIAWidgetSet; + +const char* g_aria_widgets[] = { + // From http://www.w3.org/TR/wai-aria/roles#widget_roles + "alert", "alertdialog", "button", "checkbox", "dialog", "gridcell", "link", + "log", "marquee", "menuitem", "menuitemcheckbox", "menuitemradio", "option", + "progressbar", "radio", "scrollbar", "slider", "spinbutton", "status", + "tab", "tabpanel", "textbox", "timer", "tooltip", "treeitem", + // Composite user interface widgets. + // This list is also from the w3.org site referenced above. + "combobox", "grid", "listbox", "menu", "menubar", "radiogroup", "tablist", + "tree", "treegrid"}; + +static ARIAWidgetSet* CreateARIARoleWidgetSet() { + ARIAWidgetSet* widget_set = new HashSet<String, CaseFoldingHash>(); + for (size_t i = 0; i < WTF_ARRAY_LENGTH(g_aria_widgets); ++i) + widget_set->insert(String(g_aria_widgets[i])); + return widget_set; +} + +bool IncludesARIAWidgetRole(const String& role) { + static const HashSet<String, CaseFoldingHash>* role_set = + CreateARIARoleWidgetSet(); + + Vector<String> role_vector; + role.Split(' ', role_vector); + for (const auto& child : role_vector) { + if (role_set->Contains(child)) + return true; + } + return false; +} + +const char* g_aria_interactive_widget_attributes[] = { + // These attributes implicitly indicate the given widget is interactive. + // From http://www.w3.org/TR/wai-aria/states_and_properties#attrs_widgets + // clang-format off + "aria-activedescendant", + "aria-checked", + "aria-controls", + "aria-disabled", // If it's disabled, it can be made interactive. + "aria-expanded", + "aria-haspopup", + "aria-multiselectable", + "aria-pressed", + "aria-required", + "aria-selected" + // clang-format on +}; + +bool HasInteractiveARIAAttribute(const Element& element) { + for (size_t i = 0; i < WTF_ARRAY_LENGTH(g_aria_interactive_widget_attributes); + ++i) { + const char* attribute = g_aria_interactive_widget_attributes[i]; + if (element.hasAttribute(attribute)) { + return true; + } + } + return false; +} + +} // namespace + +bool AXObject::IsInsideFocusableElementOrARIAWidget(const Node& node) { + const Node* cur_node = &node; + do { + if (cur_node->IsElementNode()) { + const Element* element = ToElement(cur_node); + if (element->IsFocusable()) + return true; + String role = element->getAttribute("role"); + if (!role.IsEmpty() && IncludesARIAWidgetRole(role)) + return true; + if (HasInteractiveARIAAttribute(*element)) + return true; + } + cur_node = cur_node->parentNode(); + } while (cur_node && !isHTMLBodyElement(node)); + return false; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/AXObject.h b/third_party/WebKit/Source/core/dom/AXObject.h index 4acb8a5..ae51855 100644 --- a/third_party/WebKit/Source/core/dom/AXObject.h +++ b/third_party/WebKit/Source/core/dom/AXObject.h
@@ -9,6 +9,8 @@ namespace blink { +class Node; + enum AccessibilityRole { kUnknownRole = 0, // Not mapped in platform APIs, generally indicates a bug kAbbrRole, // No mapping to ARIA role. @@ -284,7 +286,11 @@ // TODO(sashab): Add pure virtual methods to this class to remove dependencies // on AXObjectImpl from outside of modules/. -class CORE_EXPORT AXObject {}; +class CORE_EXPORT AXObject { + public: + // Static helper functions. + static bool IsInsideFocusableElementOrARIAWidget(const Node&); +}; } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/BUILD.gn b/third_party/WebKit/Source/core/dom/BUILD.gn index ce8315d..4a34c98 100644 --- a/third_party/WebKit/Source/core/dom/BUILD.gn +++ b/third_party/WebKit/Source/core/dom/BUILD.gn
@@ -8,6 +8,7 @@ split_count = 5 sources = [ + "AXObject.cpp", "AXObject.h", "AXObjectCache.cpp", "AXObjectCache.h",
diff --git a/third_party/WebKit/Source/core/dom/DOMTokenList.cpp b/third_party/WebKit/Source/core/dom/DOMTokenList.cpp index c11a6ff..b68b08c 100644 --- a/third_party/WebKit/Source/core/dom/DOMTokenList.cpp +++ b/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
@@ -96,9 +96,7 @@ if (!ValidateTokens(tokens, exception_state)) return; - // TODO(tkent): Add a member function for AutoReset + setValue. - AutoReset<bool> updating(&is_in_update_step_, true); - setValue(AddTokens(tokens)); + AddTokens(tokens); } void DOMTokenList::remove(const AtomicString& token, @@ -120,9 +118,7 @@ // See https://github.com/whatwg/dom/issues/462 if (value().IsNull()) return; - // TODO(tkent): Add a member function for AutoReset + setValue. - AutoReset<bool> updating(&is_in_update_step_, true); - setValue(RemoveTokens(tokens)); + RemoveTokens(tokens); } bool DOMTokenList::toggle(const AtomicString& token, @@ -160,55 +156,38 @@ void DOMTokenList::AddInternal(const AtomicString& token) { if (ContainsInternal(token)) return; - // TODO(tkent): Add a member function for AutoReset + setValue. - AutoReset<bool> updating(&is_in_update_step_, true); - setValue(AddToken(token)); + Vector<String> tokens; + tokens.push_back(token.GetString()); + AddTokens(tokens); } void DOMTokenList::RemoveInternal(const AtomicString& token) { - // Check using contains first since it uses AtomicString comparisons instead - // of character by character testing. + // Check using contains first to skip unnecessary reserialization. if (!ContainsInternal(token)) return; - // TODO(tkent): Add a member function for AutoReset + setValue. - AutoReset<bool> updating(&is_in_update_step_, true); - setValue(RemoveToken(token)); -} - -AtomicString DOMTokenList::AddToken(const AtomicString& token) { Vector<String> tokens; tokens.push_back(token.GetString()); - return AddTokens(tokens); + RemoveTokens(tokens); } // https://dom.spec.whatwg.org/#dom-domtokenlist-add -// This returns an AtomicString because it is always passed as argument to -// setValue() and setValue() takes an AtomicString in argument. -AtomicString DOMTokenList::AddTokens(const Vector<String>& tokens) { +void DOMTokenList::AddTokens(const Vector<String>& tokens) { SpaceSplitString& token_set = MutableSet(); // 2. For each token in tokens, append token to context object’s token set. for (const auto& token : tokens) token_set.Add(AtomicString(token)); // 3. Run the update steps. - return SerializeSet(token_set); -} - -AtomicString DOMTokenList::RemoveToken(const AtomicString& token) { - Vector<String> tokens; - tokens.push_back(token.GetString()); - return RemoveTokens(tokens); + UpdateWithTokenSet(token_set); } // https://dom.spec.whatwg.org/#dom-domtokenlist-remove -// This returns an AtomicString because it is always passed as argument to -// setValue() and setValue() takes an AtomicString in argument. -AtomicString DOMTokenList::RemoveTokens(const Vector<String>& tokens) { +void DOMTokenList::RemoveTokens(const Vector<String>& tokens) { SpaceSplitString& token_set = MutableSet(); // 2. For each token in tokens, remove token from context object’s token set. for (const auto& token : tokens) token_set.Remove(AtomicString(token)); // 3. Run the update steps. - return SerializeSet(token_set); + UpdateWithTokenSet(token_set); } // https://dom.spec.whatwg.org/#concept-ordered-set-serializer @@ -230,6 +209,12 @@ return builder.ToAtomicString(); } +// https://dom.spec.whatwg.org/#concept-dtl-update +void DOMTokenList::UpdateWithTokenSet(const SpaceSplitString& token_set) { + AutoReset<bool> updating(&is_in_update_step_, true); + setValue(SerializeSet(token_set)); +} + void DOMTokenList::setValue(const AtomicString& value) { if (observer_) observer_->ValueWasSet(value);
diff --git a/third_party/WebKit/Source/core/dom/DOMTokenList.h b/third_party/WebKit/Source/core/dom/DOMTokenList.h index 3f351f5..d5e5377 100644 --- a/third_party/WebKit/Source/core/dom/DOMTokenList.h +++ b/third_party/WebKit/Source/core/dom/DOMTokenList.h
@@ -96,14 +96,14 @@ bool ValidateToken(const String&, ExceptionState&) const; bool ValidateTokens(const Vector<String>&, ExceptionState&) const; virtual bool ValidateTokenValue(const AtomicString&, ExceptionState&) const; - AtomicString AddToken(const AtomicString&); - AtomicString AddTokens(const Vector<String>&); - AtomicString RemoveToken(const AtomicString&); - AtomicString RemoveTokens(const Vector<String>&); + void AddTokens(const Vector<String>&); + void RemoveTokens(const Vector<String>&); virtual SpaceSplitString& MutableSet() { return tokens_; } - static AtomicString SerializeSet(const SpaceSplitString&); private: + void UpdateWithTokenSet(const SpaceSplitString&); + static AtomicString SerializeSet(const SpaceSplitString&); + SpaceSplitString tokens_; AtomicString value_; WeakMember<DOMTokenListObserver> observer_;
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.h b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.h index 0b90abc..fbe2926 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.h +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.h
@@ -44,7 +44,7 @@ class TextCheckerClient; // TODO(xiaochengh): Move this class to dedicated files. -class CORE_EXPORT SpellCheckRequest final : public TextCheckingRequest { +class SpellCheckRequest final : public TextCheckingRequest { public: static SpellCheckRequest* Create(const EphemeralRange& checking_range, int request_number);
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp index d08c0004..fadc5589 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -537,7 +537,7 @@ DocumentMarker::MarkerType type, int location, int length, - const Vector<String>& descriptions) { + const String& description) { DCHECK(type == DocumentMarker::kSpelling || type == DocumentMarker::kGrammar) << type; DCHECK_GT(length, 0); @@ -549,13 +549,6 @@ if (!SpellChecker::IsSpellCheckingEnabledAt(range_to_mark.EndPosition())) return; - String description; - for (size_t i = 0; i < descriptions.size(); ++i) { - if (i != 0) - description.append('\n'); - description.append(descriptions[i]); - } - if (type == DocumentMarker::kSpelling) { document->Markers().AddSpellingMarker(range_to_mark.StartPosition(), range_to_mark.EndPosition(), @@ -651,7 +644,7 @@ continue; AddMarker(GetFrame().GetDocument(), paragraph.CheckingRange(), DocumentMarker::kSpelling, result_location, result_length, - result.replacements); + result.replacement); continue; case kTextDecorationTypeGrammar: @@ -667,7 +660,7 @@ continue; AddMarker(GetFrame().GetDocument(), paragraph.CheckingRange(), DocumentMarker::kGrammar, result_location + detail.location, - detail.length, result.replacements); + detail.length, result.replacement); } continue; }
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp index e4539ef6..3e393d9 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp
@@ -5,8 +5,6 @@ #include "core/editing/spellcheck/SpellChecker.h" #include "core/editing/Editor.h" -#include "core/editing/markers/DocumentMarkerController.h" -#include "core/editing/spellcheck/SpellCheckRequester.h" #include "core/editing/spellcheck/SpellCheckTestBase.h" #include "core/frame/LocalFrame.h" #include "core/frame/LocalFrameView.h" @@ -84,33 +82,4 @@ EXPECT_EQ(start_count, LayoutCount()); } -TEST_F(SpellCheckerTest, MarkAndReplaceForHandlesMultipleReplacements) { - SetBodyContent( - "<div contenteditable>" - "spllchck" - "</div>"); - Element* div = GetDocument().QuerySelector("div"); - Node* text = div->firstChild(); - EphemeralRange range_to_check = - EphemeralRange(Position(text, 0), Position(text, 8)); - - SpellCheckRequest* request = SpellCheckRequest::Create(range_to_check, 0); - - TextCheckingResult result; - result.decoration = TextDecorationType::kTextDecorationTypeSpelling; - result.location = 0; - result.length = 8; - result.replacements = Vector<String>({"spellcheck", "spillchuck"}); - - GetDocument().GetFrame()->GetSpellChecker().MarkAndReplaceFor( - request, Vector<TextCheckingResult>({result})); - - ASSERT_EQ(1u, GetDocument().Markers().Markers().size()); - - // The Spelling marker's description should be a newline-separated list of the - // suggested replacements - EXPECT_EQ("spellcheck\nspillchuck", - GetDocument().Markers().Markers()[0]->Description()); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/exported/BUILD.gn b/third_party/WebKit/Source/core/exported/BUILD.gn index 9231089..088f61d 100644 --- a/third_party/WebKit/Source/core/exported/BUILD.gn +++ b/third_party/WebKit/Source/core/exported/BUILD.gn
@@ -27,6 +27,8 @@ "WebHistoryItem.cpp", "WebImageCache.cpp", "WebImageDecoder.cpp", + "WebInputMethodControllerImpl.cpp", + "WebInputMethodControllerImpl.h", "WebMemoryStatistics.cpp", "WebPerformance.cpp", "WebPluginContainerBase.cpp",
diff --git a/third_party/WebKit/Source/web/WebInputMethodControllerImpl.cpp b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.cpp similarity index 93% rename from third_party/WebKit/Source/web/WebInputMethodControllerImpl.cpp rename to third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.cpp index 773c854..d071271 100644 --- a/third_party/WebKit/Source/web/WebInputMethodControllerImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.cpp
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "web/WebInputMethodControllerImpl.h" +#include "core/exported/WebInputMethodControllerImpl.h" #include "core/InputTypeNames.h" #include "core/dom/DocumentUserGestureToken.h" @@ -15,29 +15,22 @@ #include "core/editing/PlainTextRange.h" #include "core/exported/WebPluginContainerBase.h" #include "core/frame/LocalFrame.h" +#include "core/frame/WebLocalFrameBase.h" #include "core/page/FocusController.h" #include "core/page/Page.h" #include "platform/UserGestureIndicator.h" #include "public/platform/WebString.h" #include "public/web/WebPlugin.h" #include "public/web/WebRange.h" -#include "web/WebLocalFrameImpl.h" namespace blink { WebInputMethodControllerImpl::WebInputMethodControllerImpl( - WebLocalFrameImpl& web_frame) + WebLocalFrameBase& web_frame) : web_frame_(&web_frame) {} WebInputMethodControllerImpl::~WebInputMethodControllerImpl() {} -// static -WebInputMethodControllerImpl* WebInputMethodControllerImpl::FromFrame( - LocalFrame* frame) { - WebLocalFrameImpl* web_frame_impl = WebLocalFrameImpl::FromFrame(frame); - return web_frame_impl ? web_frame_impl->GetInputMethodController() : nullptr; -} - DEFINE_TRACE(WebInputMethodControllerImpl) { visitor->Trace(web_frame_); }
diff --git a/third_party/WebKit/Source/web/WebInputMethodControllerImpl.h b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h similarity index 85% rename from third_party/WebKit/Source/web/WebInputMethodControllerImpl.h rename to third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h index 4ecd0c8..944e919e 100644 --- a/third_party/WebKit/Source/web/WebInputMethodControllerImpl.h +++ b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h
@@ -5,6 +5,7 @@ #ifndef WebInputMethodControllerImpl_h #define WebInputMethodControllerImpl_h +#include "core/CoreExport.h" #include "platform/heap/Handle.h" #include "platform/wtf/Allocator.h" #include "public/web/WebCompositionUnderline.h" @@ -14,21 +15,20 @@ class InputMethodController; class LocalFrame; -class WebLocalFrameImpl; +class WebLocalFrameBase; class WebPlugin; class WebRange; class WebString; -class WebInputMethodControllerImpl : public WebInputMethodController { +class CORE_EXPORT WebInputMethodControllerImpl + : public NON_EXPORTED_BASE(WebInputMethodController) { WTF_MAKE_NONCOPYABLE(WebInputMethodControllerImpl); DISALLOW_NEW(); public: - explicit WebInputMethodControllerImpl(WebLocalFrameImpl& web_frame); + explicit WebInputMethodControllerImpl(WebLocalFrameBase& web_frame); ~WebInputMethodControllerImpl() override; - static WebInputMethodControllerImpl* FromFrame(LocalFrame*); - // WebInputMethodController overrides. bool SetComposition(const WebString& text, const WebVector<WebCompositionUnderline>& underlines, @@ -51,7 +51,7 @@ InputMethodController& GetInputMethodController() const; WebPlugin* FocusedPluginIfInputMethodSupported() const; - const Member<WebLocalFrameImpl> web_frame_; + const Member<WebLocalFrameBase> web_frame_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/exported/WebViewBase.h b/third_party/WebKit/Source/core/exported/WebViewBase.h index ed45829..2f9129c1 100644 --- a/third_party/WebKit/Source/core/exported/WebViewBase.h +++ b/third_party/WebKit/Source/core/exported/WebViewBase.h
@@ -33,7 +33,7 @@ class PagePopupClient; class PageScaleConstraintsSet; class WebInputEvent; -class WebInputMethodControllerImpl; +class WebInputMethodController; class WebKeyboardEvent; class WebLayer; class WebLocalFrameBase; @@ -171,7 +171,7 @@ // corresponding to the focused frame. It will return nullptr if there is no // focused frame, or if there is one but it belongs to a different local // root. - virtual WebInputMethodControllerImpl* GetActiveWebInputMethodController() + virtual WebInputMethodController* GetActiveWebInputMethodController() const = 0; virtual void ScheduleAnimationForWidget() = 0; virtual CompositorWorkerProxyClient* CreateCompositorWorkerProxyClient() = 0;
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index 6d34f7a..b23deae 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -340,10 +340,6 @@ // bunch of stuff other than real style data. // See comments for each skipped flag below. - // These are not generated in ComputedStyleBase - SetHasViewportUnits(other.HasViewportUnits()); - SetHasRemUnitsInternal(other.HasRemUnits()); - // Correctly set during selector matching: // m_styleType // m_pseudoBits
diff --git a/third_party/WebKit/Source/core/svg/SVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGElement.cpp index 7b4e56a..d3bc529 100644 --- a/third_party/WebKit/Source/core/svg/SVGElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGElement.cpp
@@ -31,8 +31,8 @@ #include "core/animation/DocumentAnimations.h" #include "core/animation/EffectStack.h" #include "core/animation/ElementAnimations.h" -#include "core/animation/InterpolationEnvironment.h" #include "core/animation/InvalidatableInterpolation.h" +#include "core/animation/SVGInterpolationEnvironment.h" #include "core/animation/SVGInterpolationTypesMap.h" #include "core/css/resolver/StyleResolver.h" #include "core/dom/Document.h" @@ -214,7 +214,7 @@ for (auto& entry : active_interpolations_map) { const QualifiedName& attribute = entry.key.SvgAttribute(); SVGInterpolationTypesMap map; - InterpolationEnvironment environment( + SVGInterpolationEnvironment environment( map, *this, PropertyFromAttribute(attribute)->BaseValueBase()); InvalidatableInterpolation::ApplyStack(entry.value, environment); }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectImpl.cpp b/third_party/WebKit/Source/modules/accessibility/AXObjectImpl.cpp index cdc1ec6..bef8d97b 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObjectImpl.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObjectImpl.cpp
@@ -58,7 +58,6 @@ namespace { typedef HashMap<String, AccessibilityRole, CaseFoldingHash> ARIARoleMap; -typedef HashSet<String, CaseFoldingHash> ARIAWidgetSet; struct RoleEntry { const char* aria_role; @@ -315,32 +314,6 @@ return internal_role_name_vector; } -const char* g_aria_widgets[] = { - // From http://www.w3.org/TR/wai-aria/roles#widget_roles - "alert", "alertdialog", "button", "checkbox", "dialog", "gridcell", "link", - "log", "marquee", "menuitem", "menuitemcheckbox", "menuitemradio", "option", - "progressbar", "radio", "scrollbar", "slider", "spinbutton", "status", - "tab", "tabpanel", "textbox", "timer", "tooltip", "treeitem", - // Composite user interface widgets. - // This list is also from the w3.org site referenced above. - "combobox", "grid", "listbox", "menu", "menubar", "radiogroup", "tablist", - "tree", "treegrid"}; - -static ARIAWidgetSet* CreateARIARoleWidgetSet() { - ARIAWidgetSet* widget_set = new HashSet<String, CaseFoldingHash>(); - for (size_t i = 0; i < WTF_ARRAY_LENGTH(g_aria_widgets); ++i) - widget_set->insert(String(g_aria_widgets[i])); - return widget_set; -} - -const char* g_aria_interactive_widget_attributes[] = { - // These attributes implicitly indicate the given widget is interactive. - // From http://www.w3.org/TR/wai-aria/states_and_properties#attrs_widgets - "aria-activedescendant", "aria-checked", "aria-controls", - "aria-disabled", // If it's disabled, it can be made interactive. - "aria-expanded", "aria-haspopup", "aria-multiselectable", - "aria-pressed", "aria-required", "aria-selected"}; - HTMLDialogElement* GetActiveDialogElement(Node* node) { return node->GetDocument().ActiveModalDialog(); } @@ -1907,48 +1880,6 @@ return role; } -bool AXObjectImpl::IsInsideFocusableElementOrARIAWidget(const Node& node) { - const Node* cur_node = &node; - do { - if (cur_node->IsElementNode()) { - const Element* element = ToElement(cur_node); - if (element->IsFocusable()) - return true; - String role = element->getAttribute("role"); - if (!role.IsEmpty() && AXObjectImpl::IncludesARIAWidgetRole(role)) - return true; - if (HasInteractiveARIAAttribute(*element)) - return true; - } - cur_node = cur_node->parentNode(); - } while (cur_node && !isHTMLBodyElement(node)); - return false; -} - -bool AXObjectImpl::HasInteractiveARIAAttribute(const Element& element) { - for (size_t i = 0; i < WTF_ARRAY_LENGTH(g_aria_interactive_widget_attributes); - ++i) { - const char* attribute = g_aria_interactive_widget_attributes[i]; - if (element.hasAttribute(attribute)) { - return true; - } - } - return false; -} - -bool AXObjectImpl::IncludesARIAWidgetRole(const String& role) { - static const HashSet<String, CaseFoldingHash>* role_set = - CreateARIARoleWidgetSet(); - - Vector<String> role_vector; - role.Split(' ', role_vector); - for (const auto& child : role_vector) { - if (role_set->Contains(child)) - return true; - } - return false; -} - bool AXObjectImpl::NameFromContents(bool recursive) const { // ARIA 1.1, section 5.2.7.5. bool result = false;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectImpl.h b/third_party/WebKit/Source/modules/accessibility/AXObjectImpl.h index 0e818af..9eb5526 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObjectImpl.h +++ b/third_party/WebKit/Source/modules/accessibility/AXObjectImpl.h
@@ -810,7 +810,6 @@ static AccessibilityRole AriaRoleToWebCoreRole(const String&); static const AtomicString& RoleName(AccessibilityRole); static const AtomicString& InternalRoleName(AccessibilityRole); - static bool IsInsideFocusableElementOrARIAWidget(const Node&); protected: AXID id_; @@ -886,8 +885,6 @@ private: static bool IsNativeInputInMixedState(const Node*); - static bool IncludesARIAWidgetRole(const String&); - static bool HasInteractiveARIAAttribute(const Element&); static unsigned number_of_live_ax_objects_; };
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectTest.cpp b/third_party/WebKit/Source/modules/accessibility/AXObjectTest.cpp index 416a8d3..7a71cb0 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObjectTest.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObjectTest.cpp
@@ -48,25 +48,25 @@ GetDocument().documentElement()->setInnerHTML(test_content); GetDocument().UpdateStyleAndLayout(); Element* root(GetDocument().documentElement()); - EXPECT_FALSE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_FALSE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("plain"))); - EXPECT_TRUE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_TRUE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("button"))); - EXPECT_TRUE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_TRUE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("button-parent"))); - EXPECT_TRUE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_TRUE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("button-caps"))); - EXPECT_TRUE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_TRUE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("button-second"))); - EXPECT_FALSE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_FALSE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("aria-bogus"))); - EXPECT_TRUE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_TRUE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("aria-selected"))); - EXPECT_TRUE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_TRUE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("haspopup"))); - EXPECT_TRUE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_TRUE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("focusable"))); - EXPECT_TRUE(AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + EXPECT_TRUE(AXObject::IsInsideFocusableElementOrARIAWidget( *root->getElementById("focusable-parent"))); }
diff --git a/third_party/WebKit/Source/platform/text/TextChecking.h b/third_party/WebKit/Source/platform/text/TextChecking.h index 949f076..042dd22 100644 --- a/third_party/WebKit/Source/platform/text/TextChecking.h +++ b/third_party/WebKit/Source/platform/text/TextChecking.h
@@ -53,7 +53,7 @@ int location; int length; Vector<GrammarDetail> details; - Vector<String> replacements; + String replacement; }; const int kUnrequestedTextCheckingSequence = -1; @@ -73,7 +73,7 @@ String text_; }; -class PLATFORM_EXPORT TextCheckingRequest +class TextCheckingRequest : public GarbageCollectedFinalized<TextCheckingRequest> { public: virtual ~TextCheckingRequest() {}
diff --git a/third_party/WebKit/Source/web/BUILD.gn b/third_party/WebKit/Source/web/BUILD.gn index 82e4383..aee8f6fb 100644 --- a/third_party/WebKit/Source/web/BUILD.gn +++ b/third_party/WebKit/Source/web/BUILD.gn
@@ -147,8 +147,6 @@ "WebIDBKeyRange.cpp", "WebInputElement.cpp", "WebInputEvent.cpp", - "WebInputMethodControllerImpl.cpp", - "WebInputMethodControllerImpl.h", "WebKit.cpp", "WebLabelElement.cpp", "WebLanguageDetectionDetails.cpp",
diff --git a/third_party/WebKit/Source/web/TextFinder.cpp b/third_party/WebKit/Source/web/TextFinder.cpp index cfbcf88..3dbb69231 100644 --- a/third_party/WebKit/Source/web/TextFinder.cpp +++ b/third_party/WebKit/Source/web/TextFinder.cpp
@@ -125,10 +125,10 @@ // If the user has selected something since the last Find operation we want // to start from there. Otherwise, we start searching from where the last Find // operation left off (either a Find or a FindNext operation). - VisibleSelection selection(OwnerFrame() - .GetFrame() - ->Selection() - .ComputeVisibleSelectionInDOMTreeDeprecated()); + // TODO(editing-dev): The use of VisibleSelection should be audited. See + // crbug.com/657237 for details. + VisibleSelection selection( + OwnerFrame().GetFrame()->Selection().ComputeVisibleSelectionInDOMTree()); bool active_selection = !selection.IsNone(); if (active_selection) { active_match_ = CreateRange(FirstEphemeralRangeOf(selection));
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp index ce41639..e3806f2d 100644 --- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp +++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -72,7 +72,6 @@ #include "web/CompositorMutatorImpl.h" #include "web/CompositorWorkerProxyClientImpl.h" #include "web/WebDevToolsAgentImpl.h" -#include "web/WebInputMethodControllerImpl.h" #include "web/WebPagePopupImpl.h" #include "web/WebRemoteFrameImpl.h" #include "web/WebViewFrameWidget.h" @@ -459,9 +458,11 @@ local_root_->GetFrameView()->SetBaseBackgroundColor(BaseBackgroundColor()); } -WebInputMethodControllerImpl* +WebInputMethodController* WebFrameWidgetImpl::GetActiveWebInputMethodController() const { - return WebInputMethodControllerImpl::FromFrame(FocusedLocalFrameInWidget()); + WebLocalFrameBase* local_frame = + WebLocalFrameBase::FromFrame(FocusedLocalFrameInWidget()); + return local_frame ? local_frame->GetInputMethodController() : nullptr; } void WebFrameWidgetImpl::ScheduleAnimation() {
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h index 83184da..0c64adb3 100644 --- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h +++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
@@ -44,7 +44,6 @@ #include "public/web/WebInputMethodController.h" #include "web/CompositorMutatorImpl.h" #include "web/PageWidgetDelegate.h" -#include "web/WebInputMethodControllerImpl.h" namespace blink { @@ -119,8 +118,7 @@ void SetBaseBackgroundColorOverride(WebColor) override; void ClearBaseBackgroundColorOverride() override; void SetBaseBackgroundColor(WebColor) override; - WebInputMethodControllerImpl* GetActiveWebInputMethodController() - const override; + WebInputMethodController* GetActiveWebInputMethodController() const override; Frame* FocusedCoreFrame() const;
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp index edb2409..47f9078 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -2543,7 +2543,7 @@ ->ToSingleThreadTaskRunner(); } -WebInputMethodControllerImpl* WebLocalFrameImpl::GetInputMethodController() { +WebInputMethodController* WebLocalFrameImpl::GetInputMethodController() { return &input_method_controller_; }
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h index 708bd0b..05374d85 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -32,6 +32,7 @@ #define WebLocalFrameImpl_h #include "core/editing/VisiblePosition.h" +#include "core/exported/WebInputMethodControllerImpl.h" #include "core/frame/ContentSettingsClient.h" #include "core/frame/LocalFrame.h" #include "core/frame/WebFrameWidgetBase.h" @@ -45,7 +46,6 @@ #include "web/LocalFrameClientImpl.h" #include "web/UserMediaClientImpl.h" #include "web/WebExport.h" -#include "web/WebInputMethodControllerImpl.h" #include <memory> @@ -312,7 +312,7 @@ base::SingleThreadTaskRunner* TimerTaskRunner() override; base::SingleThreadTaskRunner* LoadingTaskRunner() override; base::SingleThreadTaskRunner* UnthrottledTaskRunner() override; - WebInputMethodControllerImpl* GetInputMethodController() override; + WebInputMethodController* GetInputMethodController() override; void ExtractSmartClipData(WebRect rect_in_viewport, WebString& clip_text,
diff --git a/third_party/WebKit/Source/web/WebNode.cpp b/third_party/WebKit/Source/web/WebNode.cpp index 198f0ce..ba78476 100644 --- a/third_party/WebKit/Source/web/WebNode.cpp +++ b/third_party/WebKit/Source/web/WebNode.cpp
@@ -31,6 +31,7 @@ #include "public/web/WebNode.h" #include "bindings/core/v8/ExceptionState.h" +#include "core/dom/AXObject.h" #include "core/dom/AXObjectCacheBase.h" #include "core/dom/Document.h" #include "core/dom/Element.h" @@ -47,7 +48,6 @@ #include "core/html/HTMLElement.h" #include "core/layout/LayoutObject.h" #include "core/layout/LayoutPart.h" -#include "modules/accessibility/AXObjectImpl.h" #include "platform/wtf/PtrUtil.h" #include "public/platform/WebString.h" #include "public/web/WebAXObject.h" @@ -127,7 +127,7 @@ } bool WebNode::IsInsideFocusableElementOrARIAWidget() const { - return AXObjectImpl::IsInsideFocusableElementOrARIAWidget( + return AXObject::IsInsideFocusableElementOrARIAWidget( *this->ConstUnwrap<Node>()); }
diff --git a/third_party/WebKit/Source/web/WebTextCheckingResult.cpp b/third_party/WebKit/Source/web/WebTextCheckingResult.cpp index bf18da76..fa6ff49a 100644 --- a/third_party/WebKit/Source/web/WebTextCheckingResult.cpp +++ b/third_party/WebKit/Source/web/WebTextCheckingResult.cpp
@@ -39,18 +39,12 @@ result.decoration = static_cast<TextDecorationType>(decoration); result.location = location; result.length = length; - - Vector<String> replacements_vec; - for (const WebString& replacement : replacements) { - replacements_vec.push_back(replacement); - } - result.replacements = replacements_vec; - + result.replacement = replacement; if (result.decoration == kTextDecorationTypeGrammar) { GrammarDetail detail; detail.location = 0; detail.length = length; - detail.user_description = replacements.empty() ? "" : replacements[0]; + detail.user_description = replacement; result.details.push_back(detail); }
diff --git a/third_party/WebKit/Source/web/WebViewFrameWidget.cpp b/third_party/WebKit/Source/web/WebViewFrameWidget.cpp index 29cf1d8..1cf162e 100644 --- a/third_party/WebKit/Source/web/WebViewFrameWidget.cpp +++ b/third_party/WebKit/Source/web/WebViewFrameWidget.cpp
@@ -7,7 +7,6 @@ #include "core/exported/WebViewBase.h" #include "core/frame/WebLocalFrameBase.h" #include "core/layout/HitTestResult.h" -#include "web/WebInputMethodControllerImpl.h" namespace blink { @@ -211,7 +210,7 @@ return web_view_->MainFrameImpl(); } -WebInputMethodControllerImpl* +WebInputMethodController* WebViewFrameWidget::GetActiveWebInputMethodController() const { return web_view_->GetActiveWebInputMethodController(); }
diff --git a/third_party/WebKit/Source/web/WebViewFrameWidget.h b/third_party/WebKit/Source/web/WebViewFrameWidget.h index 93410d7..3df2833ba 100644 --- a/third_party/WebKit/Source/web/WebViewFrameWidget.h +++ b/third_party/WebKit/Source/web/WebViewFrameWidget.h
@@ -10,7 +10,6 @@ #include "platform/heap/Handle.h" #include "platform/wtf/Noncopyable.h" #include "platform/wtf/RefPtr.h" -#include "web/WebInputMethodControllerImpl.h" namespace blink { @@ -92,8 +91,7 @@ void ClearBaseBackgroundColorOverride() override; void SetBaseBackgroundColor(WebColor) override; WebLocalFrameBase* LocalRoot() const override; - WebInputMethodControllerImpl* GetActiveWebInputMethodController() - const override; + WebInputMethodController* GetActiveWebInputMethodController() const override; // WebFrameWidgetBase overrides: bool ForSubframe() const override { return false; }
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index 2ab59d9..633c2cb 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -172,7 +172,6 @@ #include "web/PrerendererClientImpl.h" #include "web/StorageQuotaClientImpl.h" #include "web/WebDevToolsAgentImpl.h" -#include "web/WebInputMethodControllerImpl.h" #include "web/WebRemoteFrameImpl.h" #include "web/WebSettingsImpl.h" @@ -3514,9 +3513,11 @@ CancelPagePopup(); } -WebInputMethodControllerImpl* WebViewImpl::GetActiveWebInputMethodController() +WebInputMethodController* WebViewImpl::GetActiveWebInputMethodController() const { - return WebInputMethodControllerImpl::FromFrame(FocusedLocalFrameInWidget()); + WebLocalFrameBase* local_frame = + WebLocalFrameBase::FromFrame(FocusedLocalFrameInWidget()); + return local_frame ? local_frame->GetInputMethodController() : nullptr; } Color WebViewImpl::BaseBackgroundColor() const {
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h index 116282d..b3cfc49 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.h +++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -85,7 +85,7 @@ class WebActiveGestureAnimation; class WebDevToolsAgentImpl; class WebElement; -class WebInputMethodControllerImpl; +class WebInputMethodController; class WebLayerTreeView; class WebLocalFrame; class WebLocalFrameBase; @@ -504,7 +504,7 @@ // corresponding to the focused frame. It will return nullptr if there is no // focused frame, or if the there is one but it belongs to a different local // root. - WebInputMethodControllerImpl* GetActiveWebInputMethodController() const; + WebInputMethodController* GetActiveWebInputMethodController() const; void SetLastHiddenPagePopup(WebPagePopupImpl* page_popup) override { last_hidden_page_popup_ = page_popup;
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index 87e8e69..9aa8819c 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -6600,9 +6600,9 @@ Vector<WebTextCheckingResult> results; const int kMisspellingStartOffset = 1; const int kMisspellingLength = 8; - results.push_back(WebTextCheckingResult( - kWebTextDecorationTypeSpelling, kMisspellingStartOffset, - kMisspellingLength, WebVector<WebString>())); + results.push_back(WebTextCheckingResult(kWebTextDecorationTypeSpelling, + kMisspellingStartOffset, + kMisspellingLength, WebString())); completion->DidFinishCheckingText(results); } int NumberOfTimesChecked() const { return number_of_times_checked_; }
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index dad995b..b602ec0 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -108,7 +108,6 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" #include "web/DevToolsEmulator.h" -#include "web/WebInputMethodControllerImpl.h" #include "web/WebSettingsImpl.h" #include "web/tests/FrameTestHelpers.h"
diff --git a/third_party/WebKit/public/web/WebTextCheckingResult.h b/third_party/WebKit/public/web/WebTextCheckingResult.h index b63cae74..4eb36d8 100644 --- a/third_party/WebKit/public/web/WebTextCheckingResult.h +++ b/third_party/WebKit/public/web/WebTextCheckingResult.h
@@ -31,10 +31,9 @@ #ifndef WebTextCheckingResult_h #define WebTextCheckingResult_h -#include "WebTextDecorationType.h" #include "public/platform/WebCommon.h" #include "public/platform/WebString.h" -#include "public/platform/WebVector.h" +#include "WebTextDecorationType.h" namespace blink { @@ -45,15 +44,14 @@ WebTextCheckingResult() : decoration(kWebTextDecorationTypeSpelling), location(0), length(0) {} - WebTextCheckingResult( - WebTextDecorationType decoration, - int location, - int length, - const WebVector<WebString>& replacements = WebVector<WebString>()) + WebTextCheckingResult(WebTextDecorationType decoration, + int location, + int length, + const WebString& replacement = WebString()) : decoration(decoration), location(location), length(length), - replacements(replacements) {} + replacement(replacement) {} #if BLINK_IMPLEMENTATION operator TextCheckingResult() const; @@ -62,7 +60,7 @@ WebTextDecorationType decoration; int location; int length; - WebVector<WebString> replacements; + WebString replacement; }; } // namespace blink
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index bf752704..8ebcddc 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -14812,6 +14812,7 @@ <action name="ShowBookmarks"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> + <obsolete>Duplicate of ShowBookmarkManager.</obsolete> </action> <action name="ShowBookmarksBar">
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc index 54cb37b3..5fdf772 100644 --- a/ui/message_center/views/notification_view.cc +++ b/ui/message_center/views/notification_view.cc
@@ -346,6 +346,11 @@ return views::GetNativeHandCursor(); } +void NotificationView::OnMouseMoved(const ui::MouseEvent& event) { + MessageView::OnMouseMoved(event); + UpdateControlButtonsVisibility(); +} + void NotificationView::OnMouseEntered(const ui::MouseEvent& event) { MessageView::OnMouseEntered(event); UpdateControlButtonsVisibility();
diff --git a/ui/message_center/views/notification_view.h b/ui/message_center/views/notification_view.h index 57398c5..7fa691a 100644 --- a/ui/message_center/views/notification_view.h +++ b/ui/message_center/views/notification_view.h
@@ -46,6 +46,7 @@ void OnFocus() override; void ScrollRectToVisible(const gfx::Rect& rect) override; gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override; + void OnMouseMoved(const ui::MouseEvent& event) override; void OnMouseEntered(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override;