diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index edbf9e0..6c414b5 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1538,6 +1538,7 @@ "//gin:gin_features", "//google_apis", "//gpu/config", + "//ipc", "//media", "//media:media_features", "//media/midi",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index fabc19c..fb8fbf2 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1080,9 +1080,6 @@ "1", switches::kScrollEndEffect, "0")}, - {"enable-icon-ntp", IDS_FLAGS_ICON_NTP_NAME, IDS_FLAGS_ICON_NTP_DESCRIPTION, - kOsAll, ENABLE_DISABLE_VALUE_TYPE(switches::kEnableIconNtp, - switches::kDisableIconNtp)}, {"enable-touch-drag-drop", IDS_FLAGS_TOUCH_DRAG_DROP_NAME, IDS_FLAGS_TOUCH_DRAG_DROP_DESCRIPTION, kOsWin | kOsCrOS, ENABLE_DISABLE_VALUE_TYPE(switches::kEnableTouchDragDrop,
diff --git a/chrome/browser/chromeos/arc/PRESUBMIT.py b/chrome/browser/chromeos/arc/PRESUBMIT.py new file mode 100644 index 0000000..43ec8845 --- /dev/null +++ b/chrome/browser/chromeos/arc/PRESUBMIT.py
@@ -0,0 +1,6 @@ +# 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. + +def CheckChangeOnUpload(input_api, output_api): + return input_api.canned_checks.CheckChangeLintsClean(input_api, output_api)
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc index 21a1e42..925f9cdf 100644 --- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc +++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc
@@ -156,12 +156,12 @@ } class ExtensionSignedInDevicesTest : public ExtensionApiUnittest { - public: - void SetUp() override { - ExtensionApiUnittest::SetUp(); - - ProfileSyncServiceFactory::GetInstance()->SetTestingFactory( - profile(), CreateProfileSyncServiceMock); + private: + TestingProfile* CreateProfile() override { + TestingProfile::Builder builder; + builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(), + CreateProfileSyncServiceMock); + return builder.Build().release(); } };
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js index b4dbd5c..41b0fae 100644 --- a/chrome/browser/resources/options/browser_options.js +++ b/chrome/browser/resources/options/browser_options.js
@@ -860,13 +860,9 @@ return; var isArcEnabled = !e.value.value; - var androidAppSettings = $('android-apps-settings'); - if (androidAppSettings != null) - androidAppSettings.hidden = isArcEnabled; - - var talkbackSettingsButton = $('talkback-settings-button'); - if (talkbackSettingsButton != null) - talkbackSettingsButton.hidden = isArcEnabled; + $('android-apps-settings').hidden = isArcEnabled; + $('talkback-settings-button').hidden = isArcEnabled; + $('stylus-find-more-link').hidden = isArcEnabled; }); $('android-apps-settings-link').addEventListener('click', function(e) {
diff --git a/chrome/browser/resources/options/chromeos/stylus_overlay.html b/chrome/browser/resources/options/chromeos/stylus_overlay.html index ade2323..bc955bbe 100644 --- a/chrome/browser/resources/options/chromeos/stylus_overlay.html +++ b/chrome/browser/resources/options/chromeos/stylus_overlay.html
@@ -32,10 +32,8 @@ </div> </div> <div class="settings-row"> - <!-- TODO(jdufault): Real webstore link --> - <a is="action-link" i18n-content="stylusFindMoreApps" target="_blank" - id='stylus-find-more-link' - href="https://play.google.com/store/apps/collection/promotion_30023cb_stylus_apps"></a> + <a is="action-link" i18n-content="stylusFindMoreApps" + id='stylus-find-more-link'></a> </div> </div>
diff --git a/chrome/browser/resources/options/chromeos/stylus_overlay.js b/chrome/browser/resources/options/chromeos/stylus_overlay.js index 9462dc2..9fa277fa 100644 --- a/chrome/browser/resources/options/chromeos/stylus_overlay.js +++ b/chrome/browser/resources/options/chromeos/stylus_overlay.js
@@ -57,6 +57,12 @@ $('stylus-note-taking-app-select') .addEventListener( 'change', this.handleNoteTakingAppSelected_.bind(this)); + + var stylusAppsUrl = "https://play.google.com/store/apps/collection/" + + "promotion_30023cb_stylus_apps"; + $('stylus-find-more-link').onclick = function(event) { + chrome.send('showPlayStoreApps', [stylusAppsUrl]); + }; }, /** @override */
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc index 2f4c318..20c4e173 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -240,6 +240,17 @@ event_flags); } +bool LaunchPlayStoreWithUrl(const std::string& url) { + arc::mojom::IntentHelperInstance* instance = + GET_INTENT_HELPER_INSTANCE(HandleUrl); + if (!instance) { + VLOG(1) << "Cannot find a mojo instance, ARC is unreachable"; + return false; + } + instance->HandleUrl(url, kPlayStorePackage); + return true; +} + bool LaunchApp(content::BrowserContext* context, const std::string& app_id, int event_flags) {
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.h b/chrome/browser/ui/app_list/arc/arc_app_utils.h index e60f40f5..475fc7f3 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_utils.h +++ b/chrome/browser/ui/app_list/arc/arc_app_utils.h
@@ -38,6 +38,9 @@ bool LaunchAndroidSettingsApp(content::BrowserContext* context, int event_flags); +// Launch Play Store app. +bool LaunchPlayStoreWithUrl(const std::string& url); + // Launch an app with given layout and let the system decides how big and where // to place it. bool LaunchApp(content::BrowserContext* context,
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index a30bfaf..5b9b1d4 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -885,6 +885,10 @@ base::Bind(&BrowserOptionsHandler::ShowAndroidAppsSettings, base::Unretained(this))); web_ui()->RegisterMessageCallback( + "showPlayStoreApps", + base::Bind(&BrowserOptionsHandler::ShowPlayStoreApps, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( "showAccessibilityTalkBackSettings", base::Bind(&BrowserOptionsHandler::ShowAccessibilityTalkBackSettings, base::Unretained(this))); @@ -2041,6 +2045,18 @@ arc::LaunchAndroidSettingsApp(profile, flags); } +void BrowserOptionsHandler::ShowPlayStoreApps(const base::ListValue* args) { + std::string apps_url; + args->GetString(0, &apps_url); + Profile* profile = Profile::FromWebUI(web_ui()); + if (!arc::IsArcAllowedForProfile(profile)) { + VLOG(1) << "ARC is not enabled for this profile"; + return; + } + + arc::LaunchPlayStoreWithUrl(apps_url); +} + void BrowserOptionsHandler::ShowAccessibilityTalkBackSettings( const base::ListValue *args) { Profile* profile = Profile::FromWebUI(web_ui());
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.h b/chrome/browser/ui/webui/options/browser_options_handler.h index e84a212..37ba5f6 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.h +++ b/chrome/browser/ui/webui/options/browser_options_handler.h
@@ -341,6 +341,9 @@ // Called to show Android apps settings. void ShowAndroidAppsSettings(const base::ListValue* args); + // Called to show apps based on a url for the Play Store. + void ShowPlayStoreApps(const base::ListValue* args); + // Called to show TalkBack settings. void ShowAccessibilityTalkBackSettings(const base::ListValue *args); #endif
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index 72d0b6b..5cd4a6e2 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -6,12 +6,12 @@ #include <stddef.h> #include <stdint.h> +#include <string> +#include <vector> -#include "base/command_line.h" #include "base/i18n/rtl.h" #include "base/json/string_escape.h" #include "base/macros.h" -#include "base/metrics/field_trial.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -31,7 +31,6 @@ #include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/resource/resource_bundle.h" -#include "ui/base/ui_base_switches.h" #include "ui/base/window_open_disposition.h" #include "ui/events/keycodes/keyboard_codes.h" #include "url/gurl.h" @@ -70,21 +69,6 @@ return base::string16(reinterpret_cast<const base::char16*>(*s), s.length()); } -// Returns whether icon NTP is enabled by experiment. -// TODO(huangs): Remove all 3 copies of this routine once Icon NTP launches. -bool IsIconNTPEnabled() { - // Note: It's important to query the field trial state first, to ensure that - // UMA reports the correct group. - const std::string group_name = base::FieldTrialList::FindFullName("IconNTP"); - using base::CommandLine; - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableIconNtp)) - return false; - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableIconNtp)) - return true; - - return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE); -} - // Converts string16 to V8 String. v8::Local<v8::String> UTF16ToV8String(v8::Isolate* isolate, const base::string16& s) { @@ -189,18 +173,6 @@ obj->Set(v8::String::NewFromUtf8(isolate, "tileSource"), v8::Integer::New(isolate, static_cast<int>(mv_item.source))); - - if (IsIconNTPEnabled()) { - // Update website http://www.chromium.org/embeddedsearch when we make this - // permanent. - // Large icon size is 48px * window.devicePixelRatio. This is easier to set - // from JS, where IsIconNTPEnabled() is not available. So we add stubs - // here, and let JS fill in details. - obj->Set(v8::String::NewFromUtf8(isolate, "largeIconUrl"), - v8::String::NewFromUtf8(isolate, "chrome-search://large-icon/")); - obj->Set(v8::String::NewFromUtf8(isolate, "fallbackIconUrl"), - v8::String::NewFromUtf8(isolate, "chrome-search://fallback-icon/")); - } obj->Set(v8::String::NewFromUtf8(isolate, "title"), UTF16ToV8String(isolate, title)); obj->Set(v8::String::NewFromUtf8(isolate, "domain"),
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 26ba839..730545c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3773,6 +3773,7 @@ [ "../browser/download/download_request_infobar_delegate_unittest.cc" ] deps += [ "//device/battery:mojo_bindings", + "//ipc", "//third_party/libaddressinput", ] } @@ -4384,7 +4385,10 @@ "../utility/cloud_print/pwg_encoder_unittest.cc", ] - deps += [ "//printing:test_support" ] + deps += [ + "//ipc", + "//printing:test_support", + ] } if (enable_media_router) {
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index f4c66341..3f660b4 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -49,6 +49,7 @@ "//content/public/utility", "//courgette:courgette_lib", "//extensions/features", + "//ipc", "//media", "//net:net_with_v8", "//printing/features",
diff --git a/chromecast/app/BUILD.gn b/chromecast/app/BUILD.gn index cf2b992..8de02c8 100644 --- a/chromecast/app/BUILD.gn +++ b/chromecast/app/BUILD.gn
@@ -68,6 +68,7 @@ "//base/test:test_support", "//chromecast/base", "//content/test:test_support", + "//ipc", "//mojo/edk/embedder:headers", ] }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 34556d25..c49043cd 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -9248.0.0 \ No newline at end of file +9266.0.0 \ No newline at end of file
diff --git a/components/arc/PRESUBMIT.py b/components/arc/PRESUBMIT.py new file mode 100644 index 0000000..43ec8845 --- /dev/null +++ b/components/arc/PRESUBMIT.py
@@ -0,0 +1,6 @@ +# 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. + +def CheckChangeOnUpload(input_api, output_api): + return input_api.canned_checks.CheckChangeLintsClean(input_api, output_api)
diff --git a/components/favicon/core/favicon_driver_impl.cc b/components/favicon/core/favicon_driver_impl.cc index 8539b03..2aecafd3 100644 --- a/components/favicon/core/favicon_driver_impl.cc +++ b/components/favicon/core/favicon_driver_impl.cc
@@ -4,9 +4,7 @@ #include "components/favicon/core/favicon_driver_impl.h" -#include "base/command_line.h" #include "base/logging.h" -#include "base/metrics/field_trial.h" #include "base/strings/string_util.h" #include "build/build_config.h" #include "components/bookmarks/browser/bookmark_model.h" @@ -14,26 +12,10 @@ #include "components/favicon/core/favicon_handler.h" #include "components/favicon/core/favicon_service.h" #include "components/history/core/browser/history_service.h" -#include "ui/base/ui_base_switches.h" namespace favicon { namespace { -// Returns whether icon NTP is enabled by experiment. -// TODO(huangs): Remove all 3 copies of this routine once Icon NTP launches. -bool IsIconNTPEnabled() { - // Note: It's important to query the field trial state first, to ensure that - // UMA reports the correct group. - const std::string group_name = base::FieldTrialList::FindFullName("IconNTP"); - using base::CommandLine; - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableIconNtp)) - return false; - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableIconNtp)) - return true; - - return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE); -} - #if defined(OS_ANDROID) || defined(OS_IOS) const bool kEnableTouchIcon = true; #else @@ -52,7 +34,7 @@ favicon_service_, this, kEnableTouchIcon ? FaviconDriverObserver::NON_TOUCH_LARGEST : FaviconDriverObserver::NON_TOUCH_16_DIP)); - if (kEnableTouchIcon || IsIconNTPEnabled()) { + if (kEnableTouchIcon) { touch_icon_handler_.reset(new FaviconHandler( favicon_service_, this, FaviconDriverObserver::TOUCH_LARGEST)); }
diff --git a/components/gcm_driver/gcm_account_tracker.cc b/components/gcm_driver/gcm_account_tracker.cc index 56808d94..f3be5ff4d 100644 --- a/components/gcm_driver/gcm_account_tracker.cc +++ b/components/gcm_driver/gcm_account_tracker.cc
@@ -308,8 +308,11 @@ void GCMAccountTracker::DeleteTokenRequest( const OAuth2TokenService::Request* request) { - ScopedVector<OAuth2TokenService::Request>::iterator iter = std::find( - pending_token_requests_.begin(), pending_token_requests_.end(), request); + auto iter = std::find_if( + pending_token_requests_.begin(), pending_token_requests_.end(), + [request](const std::unique_ptr<OAuth2TokenService::Request>& r) { + return request == r.get(); + }); if (iter != pending_token_requests_.end()) pending_token_requests_.erase(iter); } @@ -341,7 +344,7 @@ std::unique_ptr<OAuth2TokenService::Request> request = GetTokenService()->StartRequest(account_iter->first, scopes, this); - pending_token_requests_.push_back(request.release()); + pending_token_requests_.push_back(std::move(request)); account_iter->second.state = GETTING_TOKEN; }
diff --git a/components/gcm_driver/gcm_account_tracker.h b/components/gcm_driver/gcm_account_tracker.h index 5535014..ec72cde 100644 --- a/components/gcm_driver/gcm_account_tracker.h +++ b/components/gcm_driver/gcm_account_tracker.h
@@ -8,10 +8,11 @@ #include <stddef.h> #include <map> +#include <memory> #include <string> +#include <vector> #include "base/macros.h" -#include "base/memory/scoped_vector.h" #include "components/gcm_driver/gcm_client.h" #include "components/gcm_driver/gcm_connection_observer.h" #include "google_apis/gaia/account_tracker.h" @@ -154,7 +155,8 @@ // Indicates whether shutdown has been called. bool shutdown_called_; - ScopedVector<OAuth2TokenService::Request> pending_token_requests_; + std::vector<std::unique_ptr<OAuth2TokenService::Request>> + pending_token_requests_; // Creates weak pointers used to postpone reporting tokens. See // ScheduleReportTokens.
diff --git a/components/nacl/common/BUILD.gn b/components/nacl/common/BUILD.gn index de3d469..8859d08 100644 --- a/components/nacl/common/BUILD.gn +++ b/components/nacl/common/BUILD.gn
@@ -36,7 +36,6 @@ "//base:base_static", "//content/public/common:service_names", "//ipc", - "//ipc:mojom", "//mojo/edk/system", "//services/service_manager/public/cpp", ]
diff --git a/content/app/BUILD.gn b/content/app/BUILD.gn index cdd9410..21d91f9 100644 --- a/content/app/BUILD.gn +++ b/content/app/BUILD.gn
@@ -126,7 +126,10 @@ } configs += extra_configs - deps = content_app_deps + [ ":$runner_target_name" ] + deps = content_app_deps + [ + ":$runner_target_name", + "//ipc", + ] forward_variables_from(invoker, [ "defines",
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d42b36b6..73d3316 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -86,7 +86,6 @@ "//gpu/command_buffer/client:gles2_interface", "//gpu/ipc/host", "//ipc", - "//ipc:mojom", "//media", "//media/capture", "//media/capture/mojo:image_capture",
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index a2f19a9f..6f88159 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <limits> +#include <set> #include <utility> #include <vector> @@ -1722,7 +1723,6 @@ switches::kDisableGpuVsync, switches::kDisableLowResTiling, switches::kDisableHistogramCustomizer, - switches::kDisableIconNtp, switches::kDisableLCDText, switches::kDisableLocalStorage, switches::kDisableLogging, @@ -1759,7 +1759,6 @@ switches::kEnableGpuClientTracing, switches::kEnableGpuMemoryBufferVideoFrames, switches::kEnableGPUServiceLogging, - switches::kEnableIconNtp, switches::kEnableLowResTiling, switches::kEnableMediaSuspend, switches::kEnableInbandTextTracks,
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn index d72cd20..2d7522cc 100644 --- a/content/child/BUILD.gn +++ b/content/child/BUILD.gn
@@ -233,7 +233,6 @@ "//crypto:platform", "//gpu/command_buffer/client", "//ipc", - "//ipc:mojom", "//media", "//mojo/common", "//mojo/edk/system",
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index 1d70521d..9bc53f5 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc
@@ -914,8 +914,7 @@ } bool WebURLLoaderImpl::Context::CanHandleDataURLRequestLocally() const { - GURL url = request_.url(); - if (!url.SchemeIs(url::kDataScheme)) + if (!request_.url().protocolIs(url::kDataScheme)) return false; // The fast paths for data URL, Start() and HandleDataURL(), don't support
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 2e169434..7a76a91d 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -372,7 +372,6 @@ "//gpu/ipc/common", "//gpu/skia_bindings", "//ipc", - "//ipc:mojom", "//media", "//media:shared_memory_support", "//media/base/ipc", @@ -620,6 +619,9 @@ "//url/mojo:url_mojom_origin", ] + overridden_deps = [ "//ipc:mojom" ] + component_deps = [ "//ipc" ] + export_class_attribute = "CONTENT_EXPORT" export_define = "CONTENT_IMPLEMENTATION=1" export_header = "content/common/content_export.h"
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h index 6a3ab90..29f5965 100644 --- a/content/public/test/test_utils.h +++ b/content/public/test/test_utils.h
@@ -100,7 +100,7 @@ // GetDeferredQuitTaskForRunLoop directly. // If you found a case where base::RunLoop is inconvenient or can not be used at // all, please post details in a comment on https://crbug.com/668707. -class MessageLoopRunner : public base::RefCounted<MessageLoopRunner> { +class MessageLoopRunner : public base::RefCountedThreadSafe<MessageLoopRunner> { public: enum class QuitMode { // Message loop stops after finishing the current task. @@ -129,7 +129,7 @@ bool loop_running() const { return loop_running_; } private: - friend class base::RefCounted<MessageLoopRunner>; + friend class base::RefCountedThreadSafe<MessageLoopRunner>; ~MessageLoopRunner(); QuitMode quit_mode_;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 7ecd0bec..e9432902 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -263,7 +263,6 @@ "mojo/blink_interface_registry_impl.h", "mojo/interface_provider_js_wrapper.cc", "mojo/interface_provider_js_wrapper.h", - "mojo/thread_safe_associated_interface_ptr_provider.h", "mojo_bindings_controller.cc", "mojo_bindings_controller.h", "mojo_context_state.cc",
diff --git a/content/renderer/mojo/thread_safe_associated_interface_ptr_provider.h b/content/renderer/mojo/thread_safe_associated_interface_ptr_provider.h deleted file mode 100644 index 87dd2ab..0000000 --- a/content/renderer/mojo/thread_safe_associated_interface_ptr_provider.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_MOJO_THREAD_SAFE_ASSOCIATED_INTERFACE_PTR_PROVIDER_H_ -#define CONTENT_RENDERER_MOJO_THREAD_SAFE_ASSOCIATED_INTERFACE_PTR_PROVIDER_H_ - -#include "base/bind.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "ipc/ipc_channel_proxy.h" -#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" - -namespace content { - -// This class provides a way to create ThreadSafeAssociatedInterfacePtr's from -// the main thread that can be used right away (even though the backing -// AssociatedInterfacePtr is created on the IO thread and the channel may not be -// connected yet). -class ThreadSafeAssociatedInterfacePtrProvider { - public: - // Note that this does not take ownership of |channel_proxy|. It's the - // caller responsibility to ensure |channel_proxy| outlives this object. - explicit ThreadSafeAssociatedInterfacePtrProvider( - IPC::ChannelProxy* channel_proxy) - : channel_proxy_(channel_proxy) {} - - template <typename Interface> - scoped_refptr<mojo::ThreadSafeAssociatedInterfacePtr<Interface>> - CreateInterfacePtr() { - scoped_refptr<mojo::ThreadSafeAssociatedInterfacePtr<Interface>> ptr = - mojo::ThreadSafeAssociatedInterfacePtr<Interface>::CreateUnbound( - channel_proxy_->ipc_task_runner()); - channel_proxy_->RetrieveAssociatedInterfaceOnIOThread<Interface>(base::Bind( - &ThreadSafeAssociatedInterfacePtrProvider::BindInterfacePtr<Interface>, - ptr)); - return ptr; - } - - private: - template <typename Interface> - static void BindInterfacePtr( - const scoped_refptr<mojo::ThreadSafeAssociatedInterfacePtr<Interface>>& - ptr, - mojo::AssociatedInterfacePtr<Interface> interface_ptr) { - bool success = ptr->Bind(std::move(interface_ptr)); - DCHECK(success); - } - - IPC::ChannelProxy* channel_proxy_; - - DISALLOW_COPY_AND_ASSIGN(ThreadSafeAssociatedInterfacePtrProvider); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MOJO_THREAD_SAFE_ASSOCIATED_INTERFACE_PTR_PROVIDER_H_ \ No newline at end of file
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index acb26cb2..56d9e1a 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -109,7 +109,6 @@ #include "content/renderer/media/render_media_client.h" #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" #include "content/renderer/media/video_capture_impl_manager.h" -#include "content/renderer/mojo/thread_safe_associated_interface_ptr_provider.h" #include "content/renderer/net_info_helper.h" #include "content/renderer/p2p/socket_dispatcher.h" #include "content/renderer/render_frame_proxy.h" @@ -630,11 +629,8 @@ gpu_ = ui::Gpu::Create(GetRemoteInterfaces(), GetIOTaskRunner()); } - thread_safe_associated_interface_ptr_provider_ = - base::MakeUnique<ThreadSafeAssociatedInterfacePtrProvider>(channel()); - thread_safe_render_message_filter_ = - thread_safe_associated_interface_ptr_provider_ - ->CreateInterfacePtr<mojom::RenderMessageFilter>(); + channel()->GetThreadSafeRemoteAssociatedInterface( + &thread_safe_render_message_filter_); shared_bitmap_manager_.reset( new ChildSharedBitmapManager(thread_safe_render_message_filter_)); @@ -2218,36 +2214,18 @@ } void RenderThreadImpl::OnMemoryStateChange(base::MemoryState state) { - // TODO(hajimehoshi): Adjust the size of this memory usage according to - // |state|. RenderThreadImpl doesn't have a feature to limit memory usage at - // present. if (blink_platform_impl_) { blink::WebMemoryCoordinator::onMemoryStateChange( static_cast<blink::MemoryState>(state)); } - switch (state) { - case base::MemoryState::NORMAL: - break; - case base::MemoryState::THROTTLED: - // TODO(bashi): Figure out what kind of strategy is suitable on - // THROTTLED state. crbug.com/674815 -#if defined(OS_ANDROID) - OnTrimMemoryImmediately(); -#else - OnSyncMemoryPressure( - base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE); -#endif - ReleaseFreeMemory(); - break; - case base::MemoryState::SUSPENDED: - OnTrimMemoryImmediately(); - ReleaseFreeMemory(); - ClearMemory(); - break; - case base::MemoryState::UNKNOWN: - NOTREACHED(); - break; - } +} + +void RenderThreadImpl::OnPurgeMemory() { + OnTrimMemoryImmediately(); + ReleaseFreeMemory(); + ClearMemory(); + if (blink_platform_impl_) + blink::WebMemoryCoordinator::onPurgeMemory(); } void RenderThreadImpl::ClearMemory() {
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 3924b340..22870b37 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -129,7 +129,6 @@ class RendererBlinkPlatformImpl; class RendererGpuVideoAcceleratorFactories; class ResourceDispatchThrottler; -class ThreadSafeAssociatedInterfacePtrProvider; class VideoCaptureImplManager; #if defined(OS_ANDROID) @@ -526,6 +525,7 @@ // base::MemoryCoordinatorClient implementation: void OnMemoryStateChange(base::MemoryState state) override; + void OnPurgeMemory() override; void ClearMemory(); @@ -626,8 +626,6 @@ // Used on the render thread. std::unique_ptr<VideoCaptureImplManager> vc_manager_; - std::unique_ptr<ThreadSafeAssociatedInterfacePtrProvider> - thread_safe_associated_interface_ptr_provider_; std::unique_ptr<ChildSharedBitmapManager> shared_bitmap_manager_;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 4c72abf..d39cc9c 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -719,7 +719,7 @@ "//gin", "//gpu", "//gpu/ipc/host", - "//ipc:mojom", + "//ipc", "//ipc:test_support", "//media", "//media:test_support",
diff --git a/extensions/renderer/api_binding.cc b/extensions/renderer/api_binding.cc index d34ebdc..6056346 100644 --- a/extensions/renderer/api_binding.cc +++ b/extensions/renderer/api_binding.cc
@@ -20,6 +20,7 @@ #include "extensions/renderer/v8_helpers.h" #include "gin/arguments.h" #include "gin/per_context_data.h" +#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" namespace extensions { @@ -335,8 +336,8 @@ isolate, callback, context, callback_args); request->has_callback = true; } - // TODO(devlin): Query and curry user gestures around. - request->has_user_gesture = false; + request->has_user_gesture = + blink::WebUserGestureIndicator::isProcessingUserGestureThreadSafe(); request->arguments = std::move(converted_arguments); request->method_name = name;
diff --git a/extensions/renderer/api_binding_unittest.cc b/extensions/renderer/api_binding_unittest.cc index e8b4fff..389d6ec 100644 --- a/extensions/renderer/api_binding_unittest.cc +++ b/extensions/renderer/api_binding_unittest.cc
@@ -17,6 +17,7 @@ #include "gin/converter.h" #include "gin/public/context_holder.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/web/WebScopedUserGesture.h" #include "v8/include/v8.h" namespace extensions { @@ -126,8 +127,7 @@ public: void OnFunctionCall(std::unique_ptr<APIBinding::Request> request, v8::Local<v8::Context> context) { - arguments_ = std::move(request->arguments); - had_callback_ = request->has_callback; + last_request_ = std::move(request); } protected: @@ -206,7 +206,11 @@ expected_error); } - bool HandlerWasInvoked() const { return arguments_ != nullptr; } + bool HandlerWasInvoked() const { return last_request_ != nullptr; } + const APIBinding::Request* last_request() const { + return last_request_.get(); + } + void reset_last_request() { last_request_.reset(); } APIBinding* binding() { return binding_.get(); } APIEventHandler* event_handler() { return event_handler_.get(); } APIRequestHandler* request_handler() { return request_handler_.get(); } @@ -221,8 +225,7 @@ bool expect_callback, const std::string& expected_error); - std::unique_ptr<base::ListValue> arguments_; - bool had_callback_ = false; + std::unique_ptr<APIBinding::Request> last_request_; std::unique_ptr<APIBinding> binding_; std::unique_ptr<APIEventHandler> event_handler_; std::unique_ptr<APIRequestHandler> request_handler_; @@ -243,7 +246,7 @@ const std::string& expected_json_arguments, bool expect_callback, const std::string& expected_error) { - EXPECT_FALSE(arguments_); + EXPECT_FALSE(last_request_); std::string wrapped_script_source = base::StringPrintf("(function(obj) { %s })", script_source.c_str()); @@ -255,16 +258,16 @@ if (should_pass) { RunFunction(func, context, 1, argv); - ASSERT_TRUE(arguments_) << script_source; - EXPECT_EQ(expected_json_arguments, ValueToString(*arguments_)); - EXPECT_EQ(expect_callback, had_callback_) << script_source; + ASSERT_TRUE(last_request_) << script_source; + EXPECT_EQ(expected_json_arguments, + ValueToString(*last_request_->arguments)); + EXPECT_EQ(expect_callback, last_request_->has_callback) << script_source; } else { RunFunctionAndExpectError(func, context, 1, argv, expected_error); - EXPECT_FALSE(arguments_); + EXPECT_FALSE(last_request_); } - arguments_.reset(); - had_callback_ = false; + last_request_.reset(); } TEST_F(APIBindingUnittest, TestEmptyAPI) { @@ -985,4 +988,33 @@ "['foo',42]", false); } +// Test that user gestures are properly recorded when calling APIs. +TEST_F(APIBindingUnittest, TestUserGestures) { + SetFunctions(kFunctions); + InitializeBinding(); + + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = ContextLocal(); + + v8::Local<v8::Object> binding_object = binding()->CreateInstance( + context, isolate(), event_handler(), base::Bind(&AllowAllAPIs)); + + v8::Local<v8::Function> function = + FunctionFromString(context, "(function(obj) { obj.oneString('foo');})"); + ASSERT_FALSE(function.IsEmpty()); + + v8::Local<v8::Value> argv[] = {binding_object}; + RunFunction(function, context, arraysize(argv), argv); + ASSERT_TRUE(last_request()); + EXPECT_FALSE(last_request()->has_user_gesture); + reset_last_request(); + + blink::WebScopedUserGesture user_gesture(nullptr); + RunFunction(function, context, arraysize(argv), argv); + ASSERT_TRUE(last_request()); + EXPECT_TRUE(last_request()->has_user_gesture); + + reset_last_request(); +} + } // namespace extensions
diff --git a/extensions/renderer/api_request_handler.cc b/extensions/renderer/api_request_handler.cc index 5319aa0..ef360c87 100644 --- a/extensions/renderer/api_request_handler.cc +++ b/extensions/renderer/api_request_handler.cc
@@ -9,6 +9,8 @@ #include "base/memory/ptr_util.h" #include "base/values.h" #include "content/public/child/v8_value_converter.h" +#include "third_party/WebKit/public/web/WebScopedUserGesture.h" +#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" namespace extensions { @@ -17,7 +19,11 @@ v8::Local<v8::Function> callback, v8::Local<v8::Context> context, const std::vector<v8::Local<v8::Value>>& local_callback_args) - : isolate(isolate), context(isolate, context), callback(isolate, callback) { + : isolate(isolate), + context(isolate, context), + callback(isolate, callback), + user_gesture_token( + blink::WebUserGestureIndicator::currentUserGestureToken()) { if (!local_callback_args.empty()) { callback_arguments.reserve(local_callback_args.size()); for (const auto& arg : local_callback_args) @@ -74,6 +80,7 @@ for (const auto& arg : response_args) args.push_back(converter->ToV8Value(arg.get(), context)); + blink::WebScopedUserGesture user_gesture(pending_request.user_gesture_token); // args.size() is converted to int, but args is controlled by chrome and is // never close to std::numeric_limits<int>::max. call_js_.Run(pending_request.callback.Get(isolate), context, args.size(),
diff --git a/extensions/renderer/api_request_handler.h b/extensions/renderer/api_request_handler.h index f5ce48f..9d3c8e9 100644 --- a/extensions/renderer/api_request_handler.h +++ b/extensions/renderer/api_request_handler.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "third_party/WebKit/public/web/WebUserGestureToken.h" #include "v8/include/v8.h" namespace base { @@ -63,6 +64,7 @@ v8::Global<v8::Context> context; v8::Global<v8::Function> callback; std::vector<v8::Global<v8::Value>> callback_arguments; + blink::WebUserGestureToken user_gesture_token; }; // The next available request identifier.
diff --git a/extensions/renderer/api_request_handler_unittest.cc b/extensions/renderer/api_request_handler_unittest.cc index 3bff9eaa..164edea 100644 --- a/extensions/renderer/api_request_handler_unittest.cc +++ b/extensions/renderer/api_request_handler_unittest.cc
@@ -3,14 +3,18 @@ // found in the LICENSE file. #include "base/bind.h" +#include "base/optional.h" #include "base/values.h" #include "extensions/renderer/api_binding_test.h" #include "extensions/renderer/api_binding_test_util.h" #include "extensions/renderer/api_request_handler.h" #include "gin/converter.h" +#include "gin/function_template.h" #include "gin/public/context_holder.h" #include "gin/public/isolate_holder.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/WebKit/public/web/WebScopedUserGesture.h" +#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" namespace extensions { @@ -192,4 +196,56 @@ EXPECT_TRUE(request_handler.GetPendingRequestIdsForTesting().empty()); } +// Test user gestures being curried around for API requests. +TEST_F(APIRequestHandlerTest, UserGestureTest) { + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = ContextLocal(); + + APIRequestHandler request_handler( + base::Bind(&APIRequestHandlerTest::RunJS, base::Unretained(this))); + + auto callback = [](base::Optional<bool>* ran_with_user_gesture) { + *ran_with_user_gesture = + blink::WebUserGestureIndicator::isProcessingUserGestureThreadSafe(); + }; + + // Set up a callback to be used with the request so we can check if a user + // gesture was active. + base::Optional<bool> ran_with_user_gesture; + v8::Local<v8::FunctionTemplate> function_template = + gin::CreateFunctionTemplate(isolate(), + base::Bind(callback, &ran_with_user_gesture)); + v8::Local<v8::Function> v8_callback = + function_template->GetFunction(context).ToLocalChecked(); + + // Try first without a user gesture. + int request_id = request_handler.AddPendingRequest(isolate(), v8_callback, + context, ArgumentList()); + request_handler.CompleteRequest(request_id, *ListValueFromString("[]")); + + ASSERT_TRUE(ran_with_user_gesture); + EXPECT_FALSE(*ran_with_user_gesture); + ran_with_user_gesture.reset(); + + // Next try calling with a user gesture. Since a gesture will be active at the + // time of the call, it should also be active during the callback. + { + blink::WebScopedUserGesture user_gesture(nullptr); + EXPECT_TRUE( + blink::WebUserGestureIndicator::isProcessingUserGestureThreadSafe()); + request_id = request_handler.AddPendingRequest(isolate(), v8_callback, + context, ArgumentList()); + } + EXPECT_FALSE( + blink::WebUserGestureIndicator::isProcessingUserGestureThreadSafe()); + + request_handler.CompleteRequest(request_id, *ListValueFromString("[]")); + ASSERT_TRUE(ran_with_user_gesture); + EXPECT_TRUE(*ran_with_user_gesture); + // Sanity check - after the callback ran, there shouldn't be an active + // gesture. + EXPECT_FALSE( + blink::WebUserGestureIndicator::isProcessingUserGestureThreadSafe()); +} + } // namespace extensions
diff --git a/ios/chrome/browser/ui/alert_coordinator/BUILD.gn b/ios/chrome/browser/ui/alert_coordinator/BUILD.gn index 8094e9c..7a7ff731 100644 --- a/ios/chrome/browser/ui/alert_coordinator/BUILD.gn +++ b/ios/chrome/browser/ui/alert_coordinator/BUILD.gn
@@ -67,6 +67,7 @@ } source_set("eg_tests") { + configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ "alert_coordinator_egtest.mm",
diff --git a/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_egtest.mm b/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_egtest.mm index 02a8360..f881234 100644 --- a/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_egtest.mm +++ b/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_egtest.mm
@@ -6,13 +6,16 @@ #import <UIKit/UIKit.h> #import <XCTest/XCTest.h> -#import "base/mac/scoped_nsobject.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/testing/earl_grey/disabled_test_macros.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { NSString* kTitle = @"Foo Title"; } // namespace @@ -39,16 +42,16 @@ UIViewController* topViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController]; - base::scoped_nsobject<AlertCoordinator> alertCoordinator( + AlertCoordinator* alertCoordinator = [[AlertCoordinator alloc] initWithBaseViewController:topViewController title:kTitle - message:nil]); + message:nil]; [alertCoordinator start]; GREYAssertTrue([self isPresentingAlert], @"An alert should be presented"); - alertCoordinator.reset(); + alertCoordinator = nil; GREYAssertFalse([self isPresentingAlert], @"The alert should be removed"); } @@ -64,10 +67,10 @@ UIViewController* topViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController]; - base::scoped_nsobject<AlertCoordinator> alertCoordinator( + AlertCoordinator* alertCoordinator = [[AlertCoordinator alloc] initWithBaseViewController:topViewController title:kTitle - message:nil]); + message:nil]; __block BOOL blockCalled = NO;
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn index 07b878a..16959fb 100644 --- a/ipc/BUILD.gn +++ b/ipc/BUILD.gn
@@ -98,12 +98,12 @@ defines = [ "IPC_IMPLEMENTATION" ] public_deps = [ + ":mojom", ":param_traits", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", ] deps = [ - ":mojom", "//base", ] @@ -122,6 +122,9 @@ sources = [ "ipc.mojom", ] + export_class_attribute = "IPC_EXPORT" + export_define = "IPC_IMPLEMENTATION" + export_header = "ipc/ipc_export.h" } mojom("test_interfaces") { @@ -180,7 +183,6 @@ deps = [ ":ipc", - ":mojom", ":run_all_unittests", ":test_interfaces", ":test_support",
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h index 1c0a89d..4a201441 100644 --- a/ipc/ipc_channel.h +++ b/ipc/ipc_channel.h
@@ -18,6 +18,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "ipc/ipc.mojom.h" #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sender.h" @@ -25,6 +26,7 @@ #include "mojo/public/cpp/bindings/associated_interface_ptr.h" #include "mojo/public/cpp/bindings/associated_interface_request.h" #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" +#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" #if defined(OS_POSIX) #include <sys/types.h> @@ -94,6 +96,11 @@ // with this Channel. Must be safe to call from any thread. virtual mojo::AssociatedGroup* GetAssociatedGroup() = 0; + // Returns a ThreadSafeForwarded for this channel which can be used to + // safely send mojom::Channel requests from arbitrary threads. + virtual std::unique_ptr<mojo::ThreadSafeForwarder<mojom::Channel>> + CreateThreadSafeChannel() = 0; + // Adds an interface factory to this channel for interface |name|. Must be // safe to call from any thread. virtual void AddGenericAssociatedInterface(
diff --git a/ipc/ipc_channel_mojo.cc b/ipc/ipc_channel_mojo.cc index 4189b9c0..3d5e855 100644 --- a/ipc/ipc_channel_mojo.cc +++ b/ipc/ipc_channel_mojo.cc
@@ -274,25 +274,49 @@ Mode mode, Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) - : pipe_(handle.get()), listener_(listener), weak_factory_(this) { - // Create MojoBootstrap after all members are set as it touches - // ChannelMojo from a different thread. - bootstrap_ = - MojoBootstrap::Create(std::move(handle), mode, this, ipc_task_runner); + : task_runner_(ipc_task_runner), + pipe_(handle.get()), + listener_(listener), + weak_factory_(this) { + bootstrap_ = MojoBootstrap::Create(std::move(handle), mode, ipc_task_runner); +} + +void ChannelMojo::ForwardMessageFromThreadSafePtr(mojo::Message message) { + DCHECK(task_runner_->RunsTasksOnCurrentThread()); + if (!message_reader_) + return; + message_reader_->sender().internal_state()->ForwardMessage( + std::move(message)); +} + +void ChannelMojo::ForwardMessageWithResponderFromThreadSafePtr( + mojo::Message message, + std::unique_ptr<mojo::MessageReceiver> responder) { + DCHECK(task_runner_->RunsTasksOnCurrentThread()); + if (!message_reader_) + return; + message_reader_->sender().internal_state()->ForwardMessageWithResponder( + std::move(message), std::move(responder)); } ChannelMojo::~ChannelMojo() { + DCHECK(task_runner_->RunsTasksOnCurrentThread()); Close(); } bool ChannelMojo::Connect() { + DCHECK(task_runner_->RunsTasksOnCurrentThread()); + WillConnect(); - DCHECK(!task_runner_); - task_runner_ = base::ThreadTaskRunnerHandle::Get(); - DCHECK(!message_reader_); + mojom::ChannelAssociatedPtr sender; + mojom::ChannelAssociatedRequest receiver; + bootstrap_->Connect(&sender, &receiver); - bootstrap_->Connect(); + DCHECK(!message_reader_); + sender->SetPeerPid(GetSelfPID()); + message_reader_.reset(new internal::MessagePipeReader( + pipe_, std::move(sender), std::move(receiver), this)); return true; } @@ -321,14 +345,6 @@ associated_interfaces_.clear(); } -// MojoBootstrap::Delegate implementation -void ChannelMojo::OnPipesAvailable(mojom::ChannelAssociatedPtr sender, - mojom::ChannelAssociatedRequest receiver) { - sender->SetPeerPid(GetSelfPID()); - message_reader_.reset(new internal::MessagePipeReader( - pipe_, std::move(sender), std::move(receiver), this)); -} - void ChannelMojo::OnPipeError() { DCHECK(task_runner_); if (task_runner_->RunsTasksOnCurrentThread()) { @@ -377,6 +393,15 @@ Channel::AssociatedInterfaceSupport* ChannelMojo::GetAssociatedInterfaceSupport() { return this; } +std::unique_ptr<mojo::ThreadSafeForwarder<mojom::Channel>> +ChannelMojo::CreateThreadSafeChannel() { + return base::MakeUnique<mojo::ThreadSafeForwarder<mojom::Channel>>( + task_runner_, base::Bind(&ChannelMojo::ForwardMessageFromThreadSafePtr, + weak_factory_.GetWeakPtr()), + base::Bind(&ChannelMojo::ForwardMessageWithResponderFromThreadSafePtr, + weak_factory_.GetWeakPtr())); +} + void ChannelMojo::OnPeerPidReceived(int32_t peer_pid) { listener_->OnChannelConnected(peer_pid); }
diff --git a/ipc/ipc_channel_mojo.h b/ipc/ipc_channel_mojo.h index 215b198..d2d6880f 100644 --- a/ipc/ipc_channel_mojo.h +++ b/ipc/ipc_channel_mojo.h
@@ -21,11 +21,13 @@ #include "base/task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "ipc/ipc.mojom.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_channel_factory.h" #include "ipc/ipc_export.h" #include "ipc/ipc_message_pipe_reader.h" #include "ipc/ipc_mojo_bootstrap.h" +#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" #include "mojo/public/cpp/system/core.h" namespace IPC { @@ -42,7 +44,6 @@ class IPC_EXPORT ChannelMojo : public Channel, public Channel::AssociatedInterfaceSupport, - public NON_EXPORTED_BASE(MojoBootstrap::Delegate), public NON_EXPORTED_BASE(internal::MessagePipeReader::Delegate) { public: // Creates a ChannelMojo. @@ -84,10 +85,6 @@ Message* message, base::Optional<std::vector<mojom::SerializedHandlePtr>>* handles); - // MojoBootstrapDelegate implementation - void OnPipesAvailable(mojom::ChannelAssociatedPtr sender, - mojom::ChannelAssociatedRequest receiver) override; - // MessagePipeReader::Delegate void OnPeerPidReceived(int32_t peer_pid) override; void OnMessageReceived(const Message& message) override; @@ -103,8 +100,15 @@ Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner); + void ForwardMessageFromThreadSafePtr(mojo::Message message); + void ForwardMessageWithResponderFromThreadSafePtr( + mojo::Message message, + std::unique_ptr<mojo::MessageReceiver> responder); + // Channel::AssociatedInterfaceSupport: mojo::AssociatedGroup* GetAssociatedGroup() override; + std::unique_ptr<mojo::ThreadSafeForwarder<mojom::Channel>> + CreateThreadSafeChannel() override; void AddGenericAssociatedInterface( const std::string& name, const GenericAssociatedInterfaceFactory& factory) override; @@ -113,7 +117,7 @@ mojo::ScopedInterfaceEndpointHandle handle) override; // A TaskRunner which runs tasks on the ChannelMojo's owning thread. - scoped_refptr<base::TaskRunner> task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; const mojo::MessagePipeHandle pipe_; std::unique_ptr<MojoBootstrap> bootstrap_;
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index 91e8236..6759c49 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc
@@ -68,6 +68,7 @@ channel_->GetAssociatedInterfaceSupport(); if (support) { associated_group_ = *support->GetAssociatedGroup(); + thread_safe_channel_ = support->CreateThreadSafeChannel(); base::AutoLock l(pending_filters_lock_); for (auto& entry : pending_io_thread_interfaces_) @@ -398,19 +399,6 @@ base::Passed(base::WrapUnique(message)))); } -// Called on the IPC::Channel thread -void ChannelProxy::Context::GetRemoteAssociatedInterface( - const std::string& name, - mojo::ScopedInterfaceEndpointHandle handle) { - if (!channel_) - return; - Channel::AssociatedInterfaceSupport* associated_interface_support = - channel_->GetAssociatedInterfaceSupport(); - DCHECK(associated_interface_support); - associated_interface_support->GetGenericRemoteAssociatedInterface( - name, std::move(handle)); -} - //----------------------------------------------------------------------------- // static @@ -580,14 +568,14 @@ const std::string& name, mojo::ScopedInterfaceEndpointHandle handle) { DCHECK(did_init_); - context_->ipc_task_runner()->PostTask( - FROM_HERE, base::Bind(&Context::GetRemoteAssociatedInterface, - context_, name, base::Passed(&handle))); + mojom::GenericInterfaceAssociatedRequest request; + request.Bind(std::move(handle)); + context()->thread_safe_channel().GetAssociatedInterface(name, + std::move(request)); } void ChannelProxy::ClearIPCTaskRunner() { DCHECK(CalledOnValidThread()); - context()->ClearIPCTaskRunner(); }
diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h index bda83bb18..cde6a896 100644 --- a/ipc/ipc_channel_proxy.h +++ b/ipc/ipc_channel_proxy.h
@@ -22,8 +22,10 @@ #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" #include "mojo/public/cpp/bindings/associated_group.h" +#include "mojo/public/cpp/bindings/associated_interface_ptr.h" #include "mojo/public/cpp/bindings/associated_interface_request.h" #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" +#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" namespace base { class SingleThreadTaskRunner; @@ -209,17 +211,22 @@ } #endif + // Creates a ThreadSafeAssociatedInterfacePtr for |Interface|. This object + // may be used to send messages on the interface from any thread and those + // messages will remain ordered with respect to other messages sent on the + // same thread over other ThreadSafeAssociatedInterfacePtrs associated with + // the same Channel. template <typename Interface> - using AssociatedInterfaceRetrievedCallback = - base::Callback<void(mojo::AssociatedInterfacePtr<Interface>)>; - // Creates an AssociatedInterfacePtr to |Interface| on the IO thread and - // passes it to |callback|, also invoked on the IO thread. - template <typename Interface> - void RetrieveAssociatedInterfaceOnIOThread( - const AssociatedInterfaceRetrievedCallback<Interface>& callback) { - context_->ipc_task_runner()->PostTask( - FROM_HERE, base::Bind(&Context::RetrieveAssociatedInterface<Interface>, - context_, callback)); + void GetThreadSafeRemoteAssociatedInterface( + scoped_refptr<mojo::ThreadSafeAssociatedInterfacePtr<Interface>>* + out_ptr) { + mojo::AssociatedInterfacePtrInfo<Interface> ptr_info; + mojo::AssociatedInterfaceRequest<Interface> request; + GetAssociatedGroup()->CreateAssociatedInterface( + mojo::AssociatedGroup::WILL_PASS_REQUEST, &ptr_info, &request); + GetGenericRemoteAssociatedInterface(Interface::Name_, request.PassHandle()); + *out_ptr = mojo::ThreadSafeAssociatedInterfacePtr<Interface>::Create( + std::move(ptr_info), ipc_task_runner()); } base::SingleThreadTaskRunner* ipc_task_runner() const { @@ -251,11 +258,6 @@ // Sends |message| from appropriate thread. void Send(Message* message); - // Requests a remote associated interface on the IPC thread. - void GetRemoteAssociatedInterface( - const std::string& name, - mojo::ScopedInterfaceEndpointHandle handle); - protected: friend class base::RefCountedThreadSafe<Context>; ~Context() override; @@ -299,14 +301,6 @@ void OnSendMessage(std::unique_ptr<Message> message_ptr); void OnAddFilter(); void OnRemoveFilter(MessageFilter* filter); - template <typename Interface> - void RetrieveAssociatedInterface( - const AssociatedInterfaceRetrievedCallback<Interface>& callback) { - mojo::AssociatedInterfacePtr<Interface> interface_ptr; - channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface( - &interface_ptr); - callback.Run(std::move(interface_ptr)); - } // Methods called on the listener thread. void AddFilter(MessageFilter* filter); @@ -320,6 +314,9 @@ void ClearChannel(); mojo::AssociatedGroup* associated_group() { return &associated_group_; } + mojom::Channel& thread_safe_channel() { + return thread_safe_channel_->proxy(); + } void AddGenericAssociatedInterfaceForIOThread( const std::string& name, @@ -360,6 +357,11 @@ mojo::AssociatedGroup associated_group_; + // A thread-safe mojom::Channel interface we use to make remote interface + // requests from the proxy thread. + std::unique_ptr<mojo::ThreadSafeForwarder<mojom::Channel>> + thread_safe_channel_; + // Holds associated interface binders added by // AddGenericAssociatedInterfaceForIOThread until the underlying channel has // been initialized.
diff --git a/ipc/ipc_message_pipe_reader.h b/ipc/ipc_message_pipe_reader.h index 686982a9..b441960 100644 --- a/ipc/ipc_message_pipe_reader.h +++ b/ipc/ipc_message_pipe_reader.h
@@ -84,7 +84,7 @@ void GetRemoteInterface(const std::string& name, mojo::ScopedInterfaceEndpointHandle handle); - mojom::Channel* sender() const { return sender_.get(); } + mojom::ChannelAssociatedPtr& sender() { return sender_; } protected: void OnPipeClosed();
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc index 68454ae..5e6f5459a 100644 --- a/ipc/ipc_mojo_bootstrap.cc +++ b/ipc/ipc_mojo_bootstrap.cc
@@ -885,11 +885,8 @@ public: MojoBootstrapImpl( mojo::ScopedMessagePipeHandle handle, - Delegate* delegate, const scoped_refptr<ChannelAssociatedGroupController> controller) - : controller_(controller), - handle_(std::move(handle)), - delegate_(delegate) { + : controller_(controller), handle_(std::move(handle)) { associated_group_ = controller_->CreateAssociatedGroup(); } @@ -898,15 +895,10 @@ } private: - // MojoBootstrap: - void Connect() override { + void Connect(mojom::ChannelAssociatedPtr* sender, + mojom::ChannelAssociatedRequest* receiver) override { controller_->Bind(std::move(handle_)); - - IPC::mojom::ChannelAssociatedPtr sender; - IPC::mojom::ChannelAssociatedRequest receiver; - controller_->CreateChannelEndpoints(&sender, &receiver); - - delegate_->OnPipesAvailable(std::move(sender), std::move(receiver)); + controller_->CreateChannelEndpoints(sender, receiver); } void Pause() override { @@ -928,7 +920,6 @@ scoped_refptr<ChannelAssociatedGroupController> controller_; mojo::ScopedMessagePipeHandle handle_; - Delegate* delegate_; std::unique_ptr<mojo::AssociatedGroup> associated_group_; DISALLOW_COPY_AND_ASSIGN(MojoBootstrapImpl); @@ -940,12 +931,10 @@ std::unique_ptr<MojoBootstrap> MojoBootstrap::Create( mojo::ScopedMessagePipeHandle handle, Channel::Mode mode, - Delegate* delegate, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { return base::MakeUnique<MojoBootstrapImpl>( - std::move(handle), delegate, - new ChannelAssociatedGroupController(mode == Channel::MODE_SERVER, - ipc_task_runner)); + std::move(handle), new ChannelAssociatedGroupController( + mode == Channel::MODE_SERVER, ipc_task_runner)); } } // namespace IPC
diff --git a/ipc/ipc_mojo_bootstrap.h b/ipc/ipc_mojo_bootstrap.h index 5188cd0..cb4bcdc 100644 --- a/ipc/ipc_mojo_bootstrap.h +++ b/ipc/ipc_mojo_bootstrap.h
@@ -31,14 +31,6 @@ // UI thread as Channel::Create() can be. class IPC_EXPORT MojoBootstrap { public: - class Delegate { - public: - virtual ~Delegate() {} - - virtual void OnPipesAvailable(mojom::ChannelAssociatedPtr sender, - mojom::ChannelAssociatedRequest receiver) = 0; - }; - virtual ~MojoBootstrap() {} // Create the MojoBootstrap instance, using |handle| as the message pipe, in @@ -46,11 +38,11 @@ static std::unique_ptr<MojoBootstrap> Create( mojo::ScopedMessagePipeHandle handle, Channel::Mode mode, - Delegate* delegate, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner); // Start the handshake over the underlying message pipe. - virtual void Connect() = 0; + virtual void Connect(mojom::ChannelAssociatedPtr* sender, + mojom::ChannelAssociatedRequest* receiver) = 0; // Stop transmitting messages and start queueing them instead. virtual void Pause() = 0;
diff --git a/ipc/ipc_mojo_bootstrap_unittest.cc b/ipc/ipc_mojo_bootstrap_unittest.cc index b036faca..c6cde3e 100644 --- a/ipc/ipc_mojo_bootstrap_unittest.cc +++ b/ipc/ipc_mojo_bootstrap_unittest.cc
@@ -18,6 +18,7 @@ #include "mojo/edk/embedder/embedder.h" #include "mojo/edk/test/mojo_test_base.h" #include "mojo/edk/test/multiprocess_test_helper.h" +#include "mojo/public/cpp/bindings/associated_binding.h" #if defined(OS_POSIX) #include "base/file_descriptor_posix.h" @@ -25,47 +26,62 @@ namespace { +constexpr int32_t kTestServerPid = 42; +constexpr int32_t kTestClientPid = 4242; + +class PeerPidReceiver : public IPC::mojom::Channel { + public: + PeerPidReceiver(IPC::mojom::ChannelAssociatedRequest request, + const base::Closure& on_peer_pid_set) + : binding_(this, std::move(request)), on_peer_pid_set_(on_peer_pid_set) {} + ~PeerPidReceiver() override {} + + // mojom::Channel: + void SetPeerPid(int32_t pid) override { + peer_pid_ = pid; + on_peer_pid_set_.Run(); + } + + void Receive(const std::vector<uint8_t>& data, + base::Optional<std::vector<IPC::mojom::SerializedHandlePtr>> + handles) override {} + + void GetAssociatedInterface( + const std::string& name, + IPC::mojom::GenericInterfaceAssociatedRequest request) override {} + + int32_t peer_pid() const { return peer_pid_; } + + private: + mojo::AssociatedBinding<IPC::mojom::Channel> binding_; + const base::Closure on_peer_pid_set_; + int32_t peer_pid_ = -1; + + DISALLOW_COPY_AND_ASSIGN(PeerPidReceiver); +}; + class IPCMojoBootstrapTest : public testing::Test { protected: mojo::edk::test::MultiprocessTestHelper helper_; }; -class TestingDelegate : public IPC::MojoBootstrap::Delegate { - public: - explicit TestingDelegate(const base::Closure& quit_callback) - : passed_(false), quit_callback_(quit_callback) {} - - void OnPipesAvailable( - IPC::mojom::ChannelAssociatedPtr sender, - IPC::mojom::ChannelAssociatedRequest receiver) override; - - bool passed() const { return passed_; } - - private: - bool passed_; - const base::Closure quit_callback_; -}; - -void TestingDelegate::OnPipesAvailable( - IPC::mojom::ChannelAssociatedPtr sender, - IPC::mojom::ChannelAssociatedRequest receiver) { - passed_ = true; - quit_callback_.Run(); -} - TEST_F(IPCMojoBootstrapTest, Connect) { base::MessageLoop message_loop; - base::RunLoop run_loop; - TestingDelegate delegate(run_loop.QuitClosure()); std::unique_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create( helper_.StartChild("IPCMojoBootstrapTestClient"), - IPC::Channel::MODE_SERVER, &delegate, - base::ThreadTaskRunnerHandle::Get()); + IPC::Channel::MODE_SERVER, base::ThreadTaskRunnerHandle::Get()); - bootstrap->Connect(); + IPC::mojom::ChannelAssociatedPtr sender; + IPC::mojom::ChannelAssociatedRequest receiver; + bootstrap->Connect(&sender, &receiver); + sender->SetPeerPid(kTestServerPid); + + base::RunLoop run_loop; + PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure()); run_loop.Run(); - EXPECT_TRUE(delegate.passed()); + EXPECT_EQ(kTestClientPid, impl.peer_pid()); + EXPECT_TRUE(helper_.WaitForChildTestShutdown()); } @@ -74,18 +90,22 @@ IPCMojoBootstrapTestClientTestChildMain, ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { base::MessageLoop message_loop; - base::RunLoop run_loop; - TestingDelegate delegate(run_loop.QuitClosure()); std::unique_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create( std::move(mojo::edk::test::MultiprocessTestHelper::primordial_pipe), - IPC::Channel::MODE_CLIENT, &delegate, - base::ThreadTaskRunnerHandle::Get()); + IPC::Channel::MODE_CLIENT, base::ThreadTaskRunnerHandle::Get()); - bootstrap->Connect(); + IPC::mojom::ChannelAssociatedPtr sender; + IPC::mojom::ChannelAssociatedRequest receiver; + bootstrap->Connect(&sender, &receiver); + sender->SetPeerPid(kTestClientPid); + base::RunLoop run_loop; + PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure()); run_loop.Run(); - return delegate.passed() ? 0 : 1; + EXPECT_EQ(kTestServerPid, impl.peer_pid()); + + return 0; } } // namespace
diff --git a/mojo/public/cpp/bindings/associated_interface_ptr.h b/mojo/public/cpp/bindings/associated_interface_ptr.h index 42cb9dc6..f44da8f 100644 --- a/mojo/public/cpp/bindings/associated_interface_ptr.h +++ b/mojo/public/cpp/bindings/associated_interface_ptr.h
@@ -31,6 +31,9 @@ template <typename Interface> class AssociatedInterfacePtr { public: + using InterfaceType = Interface; + using PtrInfoType = AssociatedInterfacePtrInfo<Interface>; + // Constructs an unbound AssociatedInterfacePtr. AssociatedInterfacePtr() {} AssociatedInterfacePtr(decltype(nullptr)) {}
diff --git a/mojo/public/cpp/bindings/interface_ptr.h b/mojo/public/cpp/bindings/interface_ptr.h index 4db5e674..9d9a5a5 100644 --- a/mojo/public/cpp/bindings/interface_ptr.h +++ b/mojo/public/cpp/bindings/interface_ptr.h
@@ -40,6 +40,9 @@ template <typename Interface> class InterfacePtr { public: + using InterfaceType = Interface; + using PtrInfoType = InterfacePtrInfo<Interface>; + // Constructs an unbound InterfacePtr. InterfacePtr() {} InterfacePtr(decltype(nullptr)) {}
diff --git a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc index 12482d1..56c1e87 100644 --- a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc +++ b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
@@ -1055,50 +1055,53 @@ struct ForwarderTestContext { IntegerSenderConnectionPtr connection_ptr; std::unique_ptr<IntegerSenderConnectionImpl> interface_impl; + IntegerSenderAssociatedRequest sender_request; }; -TEST_F(AssociatedInterfaceTest, BindLaterThreadSafeAssociatedInterfacePtr) { +TEST_F(AssociatedInterfaceTest, + ThreadSafeAssociatedInterfacePtrWithTaskRunner) { // Start the thread from where we'll bind the interface pointer. base::Thread other_thread("service test thread"); other_thread.Start(); const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner = other_thread.message_loop()->task_runner(); - ForwarderTestContext* context = new ForwarderTestContext(); - base::WaitableEvent echo_called_event( + ForwarderTestContext* context = new ForwarderTestContext(); + IntegerSenderAssociatedPtrInfo sender_info; + base::WaitableEvent sender_info_bound_event( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); + auto setup = [](base::WaitableEvent* sender_info_bound_event, + IntegerSenderAssociatedPtrInfo* sender_info, + ForwarderTestContext* context) { + context->interface_impl = base::MakeUnique<IntegerSenderConnectionImpl>( + MakeRequest(&context->connection_ptr)); - // Create a ThreadSafeAssociatedPtr that we'll bind from a different thread. + IntegerSenderAssociatedPtr sender; + IntegerSenderAssociatedRequest sender_request = + MakeRequest(&sender, context->connection_ptr.associated_group()); + *sender_info = sender.PassInterface(); + + context->connection_ptr->GetSender(std::move(sender_request)); + + // Unblock the main thread as soon as |sender_info| is set. + sender_info_bound_event->Signal(); + }; + other_thread_task_runner->PostTask( + FROM_HERE, + base::Bind(setup, &sender_info_bound_event, &sender_info, context)); + sender_info_bound_event.Wait(); + + // Create a ThreadSafeAssociatedPtr that binds on the background thread and is + // associated with |connection_ptr| there. scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr = - ThreadSafeIntegerSenderAssociatedPtr::CreateUnbound( - other_thread_task_runner); + ThreadSafeIntegerSenderAssociatedPtr::Create(std::move(sender_info), + other_thread_task_runner); - base::RunLoop bind_run_loop; - auto run_method = base::Bind( - [](base::WaitableEvent* echo_called_event, - const scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr>& - thread_safe_ptr, - ForwarderTestContext* context) { - // Wait for echo to be called on the main thread so the interface method - // call happens before the bind. - echo_called_event->Wait(); - - // We are on the background thread, create the interface ptr. - context->interface_impl = - base::MakeUnique<IntegerSenderConnectionImpl>( - MakeRequest(&(context->connection_ptr))); - IntegerSenderAssociatedPtr sender; - context->connection_ptr->GetSender( - MakeRequest(&sender, context->connection_ptr.associated_group())); - thread_safe_ptr->Bind(std::move(sender)); - }, - &echo_called_event, thread_safe_ptr, context); - - other_thread_task_runner->PostTask(FROM_HERE, run_method); - + // Issue a call on the thread-safe ptr immediately. Note that this may happen + // before the interface is bound on the background thread, and that must be + // OK. { - // Now we can call methods on the interface from the main thread. auto echo_callback = base::Bind([](const base::Closure& quit_closure, int32_t result) { EXPECT_EQ(123, result); @@ -1108,9 +1111,6 @@ (*thread_safe_ptr) ->Echo(123, base::Bind(echo_callback, run_loop.QuitClosure())); - // Let the bind happen on the background thread. - echo_called_event.Signal(); - // Block until the method callback is called. run_loop.Run(); }
diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc index 4849c61..fb602f5 100644 --- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc +++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
@@ -853,16 +853,20 @@ run_loop.Run(); } -TEST_F(InterfacePtrTest, BindLaterThreadSafeInterfacePointer) { +TEST_F(InterfacePtrTest, ThreadSafeInterfacePointerWithTaskRunner) { // Create and start the thread from where we'll bind the interface pointer. base::Thread other_thread("service test thread"); other_thread.Start(); const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner = other_thread.message_loop()->task_runner(); + math::CalculatorPtr ptr; + math::CalculatorRequest request(&ptr); + // Create a ThreadSafeInterfacePtr that we'll bind from a different thread. scoped_refptr<math::ThreadSafeCalculatorPtr> thread_safe_ptr = - math::ThreadSafeCalculatorPtr::CreateUnbound(other_thread_task_runner); + math::ThreadSafeCalculatorPtr::Create(ptr.PassInterface(), + other_thread_task_runner); ASSERT_TRUE(thread_safe_ptr); MathCalculatorImpl* math_calc_impl = nullptr; @@ -872,15 +876,15 @@ [](const scoped_refptr<base::TaskRunner>& main_task_runner, const base::Closure& quit_closure, const scoped_refptr<math::ThreadSafeCalculatorPtr>& thread_safe_ptr, + math::CalculatorRequest request, MathCalculatorImpl** math_calc_impl) { math::CalculatorPtr ptr; // In real life, the implementation would have a legitimate owner. - *math_calc_impl = new MathCalculatorImpl(MakeRequest(&ptr)); - thread_safe_ptr->Bind(std::move(ptr)); + *math_calc_impl = new MathCalculatorImpl(std::move(request)); main_task_runner->PostTask(FROM_HERE, quit_closure); }, base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(), - thread_safe_ptr, &math_calc_impl); + thread_safe_ptr, base::Passed(&request), &math_calc_impl); other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method); run_loop.Run(); }
diff --git a/mojo/public/cpp/bindings/thread_safe_interface_ptr.h b/mojo/public/cpp/bindings/thread_safe_interface_ptr.h index 605bddda1..f475c1f 100644 --- a/mojo/public/cpp/bindings/thread_safe_interface_ptr.h +++ b/mojo/public/cpp/bindings/thread_safe_interface_ptr.h
@@ -18,134 +18,55 @@ namespace mojo { -struct ThreadSafeInterfacePtrDeleter; - -// ThreadSafeInterfacePtr and ThreadSafeAssociatedInterfacePtr are versions of -// InterfacePtr and AssociatedInterfacePtr that let callers invoke -// interface methods from any threads. Callbacks are received on the thread that -// performed the interface call. -// -// To create a ThreadSafeInterfacePtr/ThreadSafeAssociatedInterfacePtr, first -// create a regular InterfacePtr/AssociatedInterfacePtr that -// you then provide to ThreadSafeInterfacePtr/AssociatedInterfacePtr::Create. -// You can then call methods on the -// ThreadSafeInterfacePtr/AssociatedInterfacePtr instance from any thread. -// -// Ex for ThreadSafeInterfacePtr: -// frob::FrobinatorPtr frobinator; -// frob::FrobinatorImpl impl(MakeRequest(&frobinator)); -// scoped_refptr<frob::ThreadSafeFrobinatorPtr> thread_safe_frobinator = -// frob::ThreadSafeFrobinatorPtr::Create(std::move(frobinator)); -// (*thread_safe_frobinator)->FrobinateToTheMax(); -// -// An alternate way is to create the ThreadSafeInterfacePtr unbound (not -// associated with an InterfacePtr) and call Bind() at a later time when the -// InterfacePtr becomes available. Note that you shouldn't call any interface -// methods on the ThreadSafeInterfacePtr before it is bound. - -template <typename Interface, template <typename> class InterfacePtrType> -class ThreadSafeInterfacePtrBase - : public MessageReceiverWithResponder, - public base::RefCountedThreadSafe< - ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>, - ThreadSafeInterfacePtrDeleter> { +// Instances of this class may be used from any thread to serialize |Interface| +// messages and forward them elsewhere. In general you should use one of the +// ThreadSafeInterfacePtrBase helper aliases defined below, but this type may be +// useful if you need/want to manually manage the lifetime of the underlying +// proxy object which will be used to ultimately send messages. +template <typename Interface> +class ThreadSafeForwarder : public MessageReceiverWithResponder { public: using ProxyType = typename Interface::Proxy_; + using ForwardMessageCallback = base::Callback<void(Message)>; + using ForwardMessageWithResponderCallback = + base::Callback<void(Message, std::unique_ptr<MessageReceiver>)>; - static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> - Create(InterfacePtrType<Interface> interface_ptr) { - scoped_refptr<ThreadSafeInterfacePtrBase> ptr( - new ThreadSafeInterfacePtrBase()); - return ptr->Bind(std::move(interface_ptr)) ? ptr : nullptr; - } + // Constructs a ThreadSafeForwarder through which Messages are forwarded to + // |forward| or |forward_with_responder| by posting to |task_runner|. + // + // Any message sent through this forwarding interface will dispatch its reply, + // if any, back to the thread which called the corresponding interface method. + ThreadSafeForwarder( + const scoped_refptr<base::SequencedTaskRunner>& task_runner, + const ForwardMessageCallback& forward, + const ForwardMessageWithResponderCallback& forward_with_responder) + : proxy_(this), + task_runner_(task_runner), + forward_(forward), + forward_with_responder_(forward_with_responder) {} - // Creates a ThreadSafeInterfacePtrBase with no associated InterfacePtr. - // Call Bind() with the InterfacePtr once available, which must be called on - // the |bind_task_runner|. - // Providing the TaskRunner here allows you to post a task to - // |bind_task_runner| to do the bind and then immediately start calling - // methods on the returned interface. - static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> - CreateUnbound( - const scoped_refptr<base::SingleThreadTaskRunner>& bind_task_runner) { - scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> ptr = - new ThreadSafeInterfacePtrBase(); - ptr->interface_ptr_task_runner_ = bind_task_runner; - return ptr; - } + ~ThreadSafeForwarder() override {} - // Binds a ThreadSafeInterfacePtrBase previously created with CreateUnbound(). - // This must be called on the thread that |interface_ptr| should be used. - // If created with CreateUnbound() that thread should be the same as the one - // provided at creation time. - bool Bind(InterfacePtrType<Interface> interface_ptr) { - DCHECK(!interface_ptr_task_runner_ || - interface_ptr_task_runner_ == base::ThreadTaskRunnerHandle::Get()); - if (!interface_ptr.is_bound()) { - LOG(ERROR) << "Attempting to bind a ThreadSafe[Associated]InterfacePtr " - "from an unbound InterfacePtr."; - return false; - } - interface_ptr_ = std::move(interface_ptr); - interface_ptr_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - return true; - } - - ~ThreadSafeInterfacePtrBase() override {} - - Interface* get() { return &proxy_; } - Interface* operator->() { return get(); } - Interface& operator*() { return *get(); } + ProxyType& proxy() { return proxy_; } private: - friend class base::RefCountedThreadSafe< - ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>; - friend struct ThreadSafeInterfacePtrDeleter; - - ThreadSafeInterfacePtrBase() : proxy_(this), weak_ptr_factory_(this) {} - - void DeleteOnCorrectThread() const { - if (interface_ptr_task_runner_ && - !interface_ptr_task_runner_->BelongsToCurrentThread() && - interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) { - return; - } - delete this; - } - // MessageReceiverWithResponder implementation: bool Accept(Message* message) override { - interface_ptr_task_runner_->PostTask( - FROM_HERE, - base::Bind(&ThreadSafeInterfacePtrBase::AcceptOnInterfacePtrThread, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(*message)))); + task_runner_->PostTask(FROM_HERE, + base::Bind(forward_, base::Passed(message))); return true; } bool AcceptWithResponder(Message* message, - MessageReceiver* responder) override { - auto forward_responder = base::MakeUnique<ForwardToCallingThread>( - base::WrapUnique(responder)); - interface_ptr_task_runner_->PostTask( - FROM_HERE, base::Bind(&ThreadSafeInterfacePtrBase:: - AcceptWithResponderOnInterfacePtrThread, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(*message)), - base::Passed(std::move(forward_responder)))); + MessageReceiver* response_receiver) override { + auto responder = base::MakeUnique<ForwardToCallingThread>( + base::WrapUnique(response_receiver)); + task_runner_->PostTask( + FROM_HERE, base::Bind(forward_with_responder_, base::Passed(message), + base::Passed(&responder))); return true; } - void AcceptOnInterfacePtrThread(Message message) { - interface_ptr_.internal_state()->ForwardMessage(std::move(message)); - } - void AcceptWithResponderOnInterfacePtrThread( - Message message, - std::unique_ptr<MessageReceiver> responder) { - interface_ptr_.internal_state()->ForwardMessageWithResponder( - std::move(message), std::move(responder)); - } - class ForwardToCallingThread : public MessageReceiver { public: explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder) @@ -175,28 +96,143 @@ scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; }; - scoped_refptr<base::SingleThreadTaskRunner> interface_ptr_task_runner_; ProxyType proxy_; - InterfacePtrType<Interface> interface_ptr_; - base::WeakPtrFactory<ThreadSafeInterfacePtrBase> weak_ptr_factory_; + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + const ForwardMessageCallback forward_; + const ForwardMessageWithResponderCallback forward_with_responder_; + + DISALLOW_COPY_AND_ASSIGN(ThreadSafeForwarder); }; -struct ThreadSafeInterfacePtrDeleter { - template <typename Interface, template <typename> class InterfacePtrType> - static void Destruct( - const ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>* - interface_ptr) { - interface_ptr->DeleteOnCorrectThread(); +template <typename InterfacePtrType> +class ThreadSafeInterfacePtrBase + : public base::RefCountedThreadSafe< + ThreadSafeInterfacePtrBase<InterfacePtrType>> { + public: + using InterfaceType = typename InterfacePtrType::InterfaceType; + using PtrInfoType = typename InterfacePtrType::PtrInfoType; + + explicit ThreadSafeInterfacePtrBase( + std::unique_ptr<ThreadSafeForwarder<InterfaceType>> forwarder) + : forwarder_(std::move(forwarder)) {} + + // Creates a ThreadSafeInterfacePtrBase wrapping an underlying non-thread-safe + // InterfacePtrType which is bound to the calling thread. All messages sent + // via this thread-safe proxy will internally be sent by first posting to this + // (the calling) thread's TaskRunner. + static scoped_refptr<ThreadSafeInterfacePtrBase> Create( + InterfacePtrType interface_ptr) { + scoped_refptr<PtrWrapper> wrapper = + new PtrWrapper(std::move(interface_ptr)); + return new ThreadSafeInterfacePtrBase(wrapper->CreateForwarder()); } + + // Creates a ThreadSafeInterfacePtrBase which binds the underlying + // non-thread-safe InterfacePtrType on the specified TaskRunner. All messages + // sent via this thread-safe proxy will internally be sent by first posting to + // that TaskRunner. + static scoped_refptr<ThreadSafeInterfacePtrBase> Create( + PtrInfoType ptr_info, + const scoped_refptr<base::SingleThreadTaskRunner>& bind_task_runner) { + scoped_refptr<PtrWrapper> wrapper = new PtrWrapper(bind_task_runner); + wrapper->BindOnTaskRunner(std::move(ptr_info)); + return new ThreadSafeInterfacePtrBase(wrapper->CreateForwarder()); + } + + InterfaceType* get() { return &forwarder_->proxy(); } + InterfaceType* operator->() { return get(); } + InterfaceType& operator*() { return *get(); } + + private: + friend class base::RefCountedThreadSafe< + ThreadSafeInterfacePtrBase<InterfacePtrType>>; + + struct PtrWrapperDeleter; + + // Helper class which owns an |InterfacePtrType| instance on an appropriate + // thread. This is kept alive as long its bound within some + // ThreadSafeForwarder's callbacks. + class PtrWrapper + : public base::RefCountedThreadSafe<PtrWrapper, PtrWrapperDeleter> { + public: + explicit PtrWrapper(InterfacePtrType ptr) + : PtrWrapper(base::ThreadTaskRunnerHandle::Get()) { + ptr_ = std::move(ptr); + } + + explicit PtrWrapper( + const scoped_refptr<base::SequencedTaskRunner>& task_runner) + : task_runner_(task_runner) {} + + void BindOnTaskRunner(PtrInfoType ptr_info) { + task_runner_->PostTask(FROM_HERE, base::Bind(&PtrWrapper::Bind, this, + base::Passed(&ptr_info))); + } + + std::unique_ptr<ThreadSafeForwarder<InterfaceType>> CreateForwarder() { + return base::MakeUnique<ThreadSafeForwarder<InterfaceType>>( + task_runner_, base::Bind(&PtrWrapper::Accept, this), + base::Bind(&PtrWrapper::AcceptWithResponder, this)); + } + + private: + friend struct PtrWrapperDeleter; + + ~PtrWrapper() {} + + void Bind(PtrInfoType ptr_info) { + DCHECK(task_runner_->RunsTasksOnCurrentThread()); + ptr_.Bind(std::move(ptr_info)); + } + + void Accept(Message message) { + ptr_.internal_state()->ForwardMessage(std::move(message)); + } + + void AcceptWithResponder(Message message, + std::unique_ptr<MessageReceiver> responder) { + ptr_.internal_state()->ForwardMessageWithResponder(std::move(message), + std::move(responder)); + } + + void DeleteOnCorrectThread() const { + if (!task_runner_->RunsTasksOnCurrentThread()) { + // NOTE: This is only called when there are no more references to + // |this|, so binding it unretained is both safe and necessary. + task_runner_->PostTask(FROM_HERE, + base::Bind(&PtrWrapper::DeleteOnCorrectThread, + base::Unretained(this))); + } else { + delete this; + } + } + + InterfacePtrType ptr_; + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + + DISALLOW_COPY_AND_ASSIGN(PtrWrapper); + }; + + struct PtrWrapperDeleter { + static void Destruct(const PtrWrapper* interface_ptr) { + interface_ptr->DeleteOnCorrectThread(); + } + }; + + ~ThreadSafeInterfacePtrBase() {} + + const std::unique_ptr<ThreadSafeForwarder<InterfaceType>> forwarder_; + + DISALLOW_COPY_AND_ASSIGN(ThreadSafeInterfacePtrBase); }; template <typename Interface> using ThreadSafeAssociatedInterfacePtr = - ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>; + ThreadSafeInterfacePtrBase<AssociatedInterfacePtr<Interface>>; template <typename Interface> using ThreadSafeInterfacePtr = - ThreadSafeInterfacePtrBase<Interface, InterfacePtr>; + ThreadSafeInterfacePtrBase<InterfacePtr<Interface>>; } // namespace mojo
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn index db787d6..95457d7d 100644 --- a/remoting/host/BUILD.gn +++ b/remoting/host/BUILD.gn
@@ -725,6 +725,7 @@ "//base", "//base:i18n", "//components/policy/core/common", + "//ipc", "//net", "//remoting/base", "//remoting/host",
diff --git a/remoting/host/security_key/BUILD.gn b/remoting/host/security_key/BUILD.gn index ff462ab..422dd84 100644 --- a/remoting/host/security_key/BUILD.gn +++ b/remoting/host/security_key/BUILD.gn
@@ -36,6 +36,7 @@ ] deps = [ + "//ipc", "//mojo/edk/system", "//remoting/proto", "//third_party/webrtc/modules/desktop_capture", @@ -112,6 +113,7 @@ ] deps = [ + "//ipc", "//remoting/proto", "//testing/gtest", ]
diff --git a/remoting/host/win/BUILD.gn b/remoting/host/win/BUILD.gn index 3248a04..4d864c65 100644 --- a/remoting/host/win/BUILD.gn +++ b/remoting/host/win/BUILD.gn
@@ -152,6 +152,7 @@ ] deps = [ + "//ipc", "//remoting/host", "//remoting/host:test_support", "//remoting/host/it2me:common",
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index f006541..5391046 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -942,18 +942,6 @@ ] } ], - "IconNTP": [ - { - "platforms": [ - "win" - ], - "experiments": [ - { - "name": "Default" - } - ] - } - ], "ImportantSitesInCBD": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations index d18c531c..4a3a9cb 100644 --- a/third_party/WebKit/LayoutTests/W3CImportExpectations +++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -285,7 +285,8 @@ ## Owners: phoglund@chromium.org # external/wpt/mediacapture-streams [ Pass ] external/wpt/microdata [ Skip ] -external/wpt/mixed-content [ Skip ] +## Owners: mkwst@chromium.org +# external/wpt/mixed-content [ Pass ] ## Owners: sunjian@chromium.org,panicker@chromium.org external/wpt/navigation-timing [ Pass ] external/wpt/notifications [ Skip ] @@ -303,11 +304,10 @@ external/wpt/proximity [ Skip ] ## Owners: rob.buis@samsung.com # external/wpt/quirks-mode [ Skip ] -## Owners: mkwst@chromium.org -# http://crbug.com/360762: Requires HTTPS server with python. -external/wpt/referrer-policy [ Skip ] ## Owners: avayvod@chromium.org,mlamouri@chromium.org # external/wpt/remote-playback [ Pass ] +## Owners: jochen@chromium.org,estark@chromium.org +# external/wpt/referrer-policy [ Pass ] external/wpt/resource-timing [ Skip ] ## Owners: jsbell@chromium.org # external/wpt/resources [ Pass ] @@ -332,8 +332,8 @@ # external/wpt/shadow-dom [ Pass ] ## Owners: domenic@chromium.org,ricea@chromium.org,tyoshino@chromium.org external/wpt/streams [ Pass ] -## Owners: jww@chromium.org -external/wpt/subresource-integrity [ Skip ] +## Owners: mkwst@chromium.org,jochen@chromium.org +# external/wpt/subresource-integrity [ Pass ] ## Owners: foolip@chromium.org # external/wpt/svg [ Pass ] external/wpt/svg/import [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/relayout-nested-float-after-line.html b/third_party/WebKit/LayoutTests/fast/block/float/relayout-nested-float-after-line.html new file mode 100644 index 0000000..396d127 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/block/float/relayout-nested-float-after-line.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<p>The word "BONZER" should be adjacent to the hotpink square.</p> +<div style="position:relative; overflow:hidden;"> + + <div style="float:left; width:100%; height:1px;"></div> + <div style="float:left; width:100%;"> + <div id="innerFloat" style="float:left; width:666px; height:20px; background:hotpink;"></div> + <span id="targetSpan">BONZER<br></span> + </div> +</div> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script> +test(() => { + document.body.offsetTop; + innerFloat.style.width = "20px"; + assert_equals(targetSpan.offsetLeft, 20); +}, "Resize inner float next to line"); +</script>
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp index 051c4551..2108dc9 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp
@@ -801,13 +801,6 @@ isolate(), transferables->offscreenCanvases, exceptionState); } -// static -String ScriptValueSerializer::serializeWTFString(const String& data) { - SerializedScriptValueWriter valueWriter; - valueWriter.writeWebCoreString(data); - return valueWriter.takeWireString(); -} - ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerialize( v8::Local<v8::Value> value, StateBase* next) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.h b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.h index 7e8a59fa..03ca5c5 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.h
@@ -233,8 +233,6 @@ Transferables*, ExceptionState&); - static String serializeWTFString(const String&); - protected: class StateBase { USING_FAST_MALLOC(StateBase);
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp index a9edce8..986d3f3c 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp
@@ -70,11 +70,6 @@ isolate, value, transferables, blobInfo, exception); } -PassRefPtr<SerializedScriptValue> SerializedScriptValue::serialize( - const String& str) { - return create(ScriptValueSerializer::serializeWTFString(str)); -} - PassRefPtr<SerializedScriptValue> SerializedScriptValue::serializeAndSwallowExceptions( v8::Isolate* isolate,
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h index 85f0f0dd..7799d5bd 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h
@@ -79,7 +79,6 @@ Transferables*, WebBlobInfoArray*, ExceptionState&); - static PassRefPtr<SerializedScriptValue> serialize(const String&); static PassRefPtr<SerializedScriptValue> serializeAndSwallowExceptions( v8::Isolate*, v8::Local<v8::Value>);
diff --git a/third_party/WebKit/Source/build/scripts/json5_generator.py b/third_party/WebKit/Source/build/scripts/json5_generator.py index 5b7184b..4c7a63d 100644 --- a/third_party/WebKit/Source/build/scripts/json5_generator.py +++ b/third_party/WebKit/Source/build/scripts/json5_generator.py
@@ -152,11 +152,7 @@ return entry if "name" not in item: raise Exception("Missing name in item: %s" % item) - if not self.parameters: - entry.update(item) - return entry entry["name"] = item.pop("name") - # Validate parameters if it's specified. for key, value in item.items(): if key not in self.parameters: raise Exception(
diff --git a/third_party/WebKit/Source/build/scripts/make_element_factory.py b/third_party/WebKit/Source/build/scripts/make_element_factory.py index 68606172..5e9af05 100755 --- a/third_party/WebKit/Source/build/scripts/make_element_factory.py +++ b/third_party/WebKit/Source/build/scripts/make_element_factory.py
@@ -30,7 +30,7 @@ import sys from collections import defaultdict -import json5_generator +import in_generator import template_expander import name_utilities @@ -38,23 +38,23 @@ class MakeElementFactoryWriter(MakeQualifiedNamesWriter): - default_parameters = { - 'JSInterfaceName': {}, - 'Conditional': {}, - 'constructorNeedsCreatedByParser': {}, - 'interfaceName': {}, - 'noConstructor': {}, - 'noTypeHelpers': {}, - 'runtimeEnabled': {}, - } - default_metadata = dict(MakeQualifiedNamesWriter.default_metadata, **{ + defaults = dict(MakeQualifiedNamesWriter.default_parameters, **{ + 'JSInterfaceName': None, + 'Conditional': None, + 'constructorNeedsCreatedByParser': None, + 'interfaceName': None, + 'noConstructor': None, + 'noTypeHelpers': None, + 'runtimeEnabled': None, + }) + default_parameters = dict(MakeQualifiedNamesWriter.default_parameters, **{ 'fallbackInterfaceName': '', 'fallbackJSInterfaceName': '', }) filters = MakeQualifiedNamesWriter.filters - def __init__(self, json5_file_paths): - super(MakeElementFactoryWriter, self).__init__(json5_file_paths) + def __init__(self, in_file_paths): + super(MakeElementFactoryWriter, self).__init__(in_file_paths) # FIXME: When we start using these element factories, we'll want to # remove the "new" prefix and also have our base class generate @@ -64,8 +64,8 @@ (self.namespace + 'ElementFactory.cpp'): self.generate_factory_implementation, }) - fallback_interface = self.tags_json5_file.metadata['fallbackInterfaceName'].strip('"') - fallback_js_interface = self.tags_json5_file.metadata['fallbackJSInterfaceName'].strip('"') or fallback_interface + fallback_interface = self.tags_in_file.parameters['fallbackInterfaceName'].strip('"') + fallback_js_interface = self.tags_in_file.parameters['fallbackJSInterfaceName'].strip('"') or fallback_interface interface_counts = defaultdict(int) tags = self._template_context['tags'] @@ -114,4 +114,4 @@ if __name__ == "__main__": - json5_generator.Maker(MakeElementFactoryWriter).main() + in_generator.Maker(MakeElementFactoryWriter).main(sys.argv)
diff --git a/third_party/WebKit/Source/build/scripts/make_element_lookup_trie.py b/third_party/WebKit/Source/build/scripts/make_element_lookup_trie.py index 89b0d36b..5663f300 100755 --- a/third_party/WebKit/Source/build/scripts/make_element_lookup_trie.py +++ b/third_party/WebKit/Source/build/scripts/make_element_lookup_trie.py
@@ -29,21 +29,21 @@ import sys -import json5_generator +import in_generator import trie_builder import template_expander -class ElementLookupTrieWriter(json5_generator.Writer): +class ElementLookupTrieWriter(in_generator.Writer): # FIXME: Inherit all these from somewhere. - default_parameters = { - 'JSInterfaceName': {}, - 'constructorNeedsCreatedByParser': {}, - 'interfaceName': {}, - 'noConstructor': {}, - 'runtimeEnabled': {}, + defaults = { + 'JSInterfaceName': None, + 'constructorNeedsCreatedByParser': None, + 'interfaceName': None, + 'noConstructor': None, + 'runtimeEnabled': None, } - default_metadata = { + default_parameters = { 'attrsNullNamespace': None, 'export': '', 'fallbackInterfaceName': '', @@ -53,12 +53,12 @@ 'namespaceURI': '', } - def __init__(self, json5_file_paths): - super(ElementLookupTrieWriter, self).__init__(json5_file_paths) + def __init__(self, in_file_paths): + super(ElementLookupTrieWriter, self).__init__(in_file_paths) self._tags = {} - for entry in self.json5_file.name_dictionaries: + for entry in self.in_file.name_dictionaries: self._tags[entry['name']] = entry['name'] - self._namespace = self.json5_file.metadata['namespace'].strip('"') + self._namespace = self.in_file.parameters['namespace'].strip('"') self._outputs = { (self._namespace + 'ElementLookupTrie.h'): self.generate_header, (self._namespace + 'ElementLookupTrie.cpp'): self.generate_implementation, @@ -79,4 +79,4 @@ if __name__ == '__main__': - json5_generator.Maker(ElementLookupTrieWriter).main() + in_generator.Maker(ElementLookupTrieWriter).main(sys.argv)
diff --git a/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py b/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py index 035bf730..c6b4063 100755 --- a/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py +++ b/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py
@@ -7,27 +7,31 @@ from collections import defaultdict import hasher -import json5_generator +import in_generator import name_utilities import template_expander +from in_file import InFile + def _symbol(tag): + # FIXME: Remove this special case for the ugly x-webkit-foo attributes. + if tag['name'].startswith('-webkit-'): + return tag['name'].replace('-', '_')[1:] return name_utilities.cpp_name(tag).replace('-', '_') - -class MakeElementTypeHelpersWriter(json5_generator.Writer): - default_parameters = { - 'Conditional': {}, - 'ImplementedAs': {}, - 'JSInterfaceName': {}, - 'constructorNeedsCreatedByParser': {}, - 'interfaceName': {}, - 'noConstructor': {}, - 'noTypeHelpers': {}, - 'runtimeEnabled': {}, +class MakeElementTypeHelpersWriter(in_generator.Writer): + defaults = { + 'Conditional': None, + 'ImplementedAs': None, + 'JSInterfaceName': None, + 'constructorNeedsCreatedByParser': None, + 'interfaceName': None, + 'noConstructor': None, + 'noTypeHelpers': None, + 'runtimeEnabled': None, } - default_metadata = { + default_parameters = { 'attrsNullNamespace': None, 'export': '', 'fallbackInterfaceName': '', @@ -41,11 +45,11 @@ 'symbol': _symbol, } - def __init__(self, json5_file_path): - super(MakeElementTypeHelpersWriter, self).__init__(json5_file_path) + def __init__(self, in_file_path): + super(MakeElementTypeHelpersWriter, self).__init__(in_file_path) - self.namespace = self.json5_file.metadata['namespace'].strip('"') - self.fallback_interface = self.json5_file.metadata['fallbackInterfaceName'].strip('"') + self.namespace = self.in_file.parameters['namespace'].strip('"') + self.fallbackInterface = self.in_file.parameters['fallbackInterfaceName'].strip('"') assert self.namespace, 'A namespace is required.' @@ -56,7 +60,7 @@ self._template_context = { 'namespace': self.namespace, - 'tags': self.json5_file.name_dictionaries, + 'tags': self.in_file.name_dictionaries, 'elements': set(), } @@ -69,7 +73,7 @@ elements.add(tag['interface']) for tag in tags: - tag['multipleTagNames'] = (interface_counts[tag['interface']] > 1 or tag['interface'] == self.fallback_interface) + tag['multipleTagNames'] = (interface_counts[tag['interface']] > 1 or tag['interface'] == self.fallbackInterface) @template_expander.use_jinja("ElementTypeHelpers.h.tmpl", filters=filters) def generate_helper_header(self): @@ -93,4 +97,4 @@ return '%s%sElement' % (self.namespace, name) if __name__ == "__main__": - json5_generator.Maker(MakeElementTypeHelpersWriter).main() + in_generator.Maker(MakeElementTypeHelpersWriter).main(sys.argv)
diff --git a/third_party/WebKit/Source/build/scripts/make_qualified_names.py b/third_party/WebKit/Source/build/scripts/make_qualified_names.py index b9b5ff5..a7d9d1a7 100755 --- a/third_party/WebKit/Source/build/scripts/make_qualified_names.py +++ b/third_party/WebKit/Source/build/scripts/make_qualified_names.py
@@ -30,20 +30,24 @@ import sys import hasher -import json5_generator +import in_generator import name_utilities import template_expander -from json5_generator import Json5File +from in_file import InFile def _symbol(entry): + # FIXME: Remove this special case for the ugly x-webkit-foo attributes. + if entry['name'].startswith('x-webkit-'): + return entry['name'].replace('-', '')[1:] return entry['name'].replace('-', '_') -class MakeQualifiedNamesWriter(json5_generator.Writer): - default_parameters = {} - default_metadata = { +class MakeQualifiedNamesWriter(in_generator.Writer): + defaults = { + } + default_parameters = { 'attrsNullNamespace': None, 'export': '', 'namespace': '', @@ -56,44 +60,43 @@ 'to_macro_style': name_utilities.to_macro_style, } - def __init__(self, json5_file_paths): + def __init__(self, in_file_paths): super(MakeQualifiedNamesWriter, self).__init__(None) - assert len(json5_file_paths) <= 2, 'MakeQualifiedNamesWriter requires at most 2 in files, got %d.' % len(json5_file_paths) + assert len(in_file_paths) <= 2, 'MakeQualifiedNamesWriter requires at most 2 in files, got %d.' % len(in_file_paths) - if len(json5_file_paths) == 2: - self.tags_json5_file = Json5File.load_from_files( - [json5_file_paths.pop(0)], self.default_metadata, self.default_parameters) + if len(in_file_paths) == 2: + self.tags_in_file = InFile.load_from_files([in_file_paths.pop(0)], self.defaults, self.valid_values, self.default_parameters) else: - self.tags_json5_file = None + self.tags_in_file = None - self.attrs_json5_file = Json5File.load_from_files([json5_file_paths.pop()], self.default_metadata, self.default_parameters) + self.attrs_in_file = InFile.load_from_files([in_file_paths.pop()], self.defaults, self.valid_values, self.default_parameters) - self.namespace = self._metadata('namespace') + self.namespace = self._parameter('namespace') - namespace_prefix = self._metadata('namespacePrefix') or self.namespace.lower() - namespace_uri = self._metadata('namespaceURI') + namespace_prefix = self._parameter('namespacePrefix') or self.namespace.lower() + namespace_uri = self._parameter('namespaceURI') - use_namespace_for_attrs = self.attrs_json5_file.metadata['attrsNullNamespace'] is None + use_namespace_for_attrs = self.attrs_in_file.parameters['attrsNullNamespace'] is None self._outputs = { (self.namespace + "Names.h"): self.generate_header, (self.namespace + "Names.cpp"): self.generate_implementation, } self._template_context = { - 'attrs': self.attrs_json5_file.name_dictionaries, - 'export': self._metadata('export'), + 'attrs': self.attrs_in_file.name_dictionaries, + 'export': self._parameter('export'), 'namespace': self.namespace, 'namespace_prefix': namespace_prefix, 'namespace_uri': namespace_uri, - 'tags': self.tags_json5_file.name_dictionaries if self.tags_json5_file else [], + 'tags': self.tags_in_file.name_dictionaries if self.tags_in_file else [], 'use_namespace_for_attrs': use_namespace_for_attrs, } - def _metadata(self, name): - metadata = self.attrs_json5_file.metadata[name].strip('"') - if self.tags_json5_file: - assert metadata == self.tags_json5_file.metadata[name].strip('"'), 'Both files must have the same %s.' % name - return metadata + def _parameter(self, name): + parameter = self.attrs_in_file.parameters[name].strip('"') + if self.tags_in_file: + assert parameter == self.tags_in_file.parameters[name].strip('"'), 'Both in files must have the same %s.' % name + return parameter @template_expander.use_jinja('MakeQualifiedNames.h.tmpl', filters=filters) def generate_header(self): @@ -104,5 +107,5 @@ return self._template_context -if __name__ == "__majson5__": - json5_generator.Maker(MakeQualifiedNamesWriter).main() +if __name__ == "__main__": + in_generator.Maker(MakeQualifiedNamesWriter).main(sys.argv)
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index 02b4257..1b8461c1 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -510,8 +510,8 @@ script = "../build/scripts/make_element_factory.py" in_files = [ - "html/HTMLTagNames.json5", - "html/HTMLAttributeNames.json5", + "html/HTMLTagNames.in", + "html/HTMLAttributeNames.in", ] other_inputs = make_element_factory_files outputs = [ @@ -525,7 +525,7 @@ process_in_files("make_core_generated_html_element_type_helpers") { script = "../build/scripts/make_element_type_helpers.py" - in_files = [ "html/HTMLTagNames.json5" ] + in_files = [ "html/HTMLTagNames.in" ] other_inputs = make_element_type_helpers_files outputs = [ "$blink_core_output_dir/HTMLElementTypeHelpers.cpp", @@ -537,8 +537,8 @@ script = "../build/scripts/make_element_factory.py" in_files = [ - "svg/SVGTagNames.json5", - "svg/SVGAttributeNames.json5", + "svg/SVGTagNames.in", + "svg/SVGAttributeNames.in", ] other_inputs = make_element_factory_files outputs = [ @@ -552,7 +552,7 @@ process_in_files("make_core_generated_svg_element_type_helpers") { script = "../build/scripts/make_element_type_helpers.py" - in_files = [ "svg/SVGTagNames.json5" ] + in_files = [ "svg/SVGTagNames.in" ] other_inputs = make_element_type_helpers_files outputs = [ "$blink_core_output_dir/SVGElementTypeHelpers.h", @@ -644,8 +644,8 @@ make_qualified_names("make_core_generated_math_ml_names") { in_files = [ - "html/parser/MathMLTagNames.json5", - "html/parser/MathMLAttributeNames.json5", + "html/parser/MathMLTagNames.in", + "html/parser/MathMLAttributeNames.in", ] outputs = [ "$blink_core_output_dir/MathMLNames.cpp", @@ -654,7 +654,7 @@ } make_qualified_names("make_core_generated_xlink_names") { - in_files = [ "svg/xlinkattrs.json5" ] + in_files = [ "svg/xlinkattrs.in" ] outputs = [ "$blink_core_output_dir/XLinkNames.cpp", "$blink_core_output_dir/XLinkNames.h", @@ -662,7 +662,7 @@ } make_qualified_names("make_core_generated_xml_ns_names") { - in_files = [ "xml/xmlnsattrs.json5" ] + in_files = [ "xml/xmlnsattrs.in" ] outputs = [ "$blink_core_output_dir/XMLNSNames.cpp", "$blink_core_output_dir/XMLNSNames.h", @@ -670,7 +670,7 @@ } make_qualified_names("make_core_generated_xml_names") { - in_files = [ "xml/xmlattrs.json5" ] + in_files = [ "xml/xmlattrs.in" ] outputs = [ "$blink_core_output_dir/XMLNames.cpp", "$blink_core_output_dir/XMLNames.h", @@ -774,7 +774,7 @@ visibility = [ ":*" ] script = "../build/scripts/make_element_lookup_trie.py" - input_file = "html/HTMLTagNames.json5" + input_file = "html/HTMLTagNames.in" inputs = make_trie_helpers_files + [ input_file, "../build/scripts/templates/ElementLookupTrie.cpp.tmpl",
diff --git a/third_party/WebKit/Source/core/editing/BUILD.gn b/third_party/WebKit/Source/core/editing/BUILD.gn index b3441fd..0449e43 100644 --- a/third_party/WebKit/Source/core/editing/BUILD.gn +++ b/third_party/WebKit/Source/core/editing/BUILD.gn
@@ -20,6 +20,8 @@ "EditingStrategy.cpp", "EditingStrategy.h", "EditingStyle.cpp", + "EditingStyleUtilities.cpp", + "EditingStyleUtilities.h", "EditingUtilities.cpp", "EditingUtilities.h", "Editor.cpp",
diff --git a/third_party/WebKit/Source/core/editing/EditingStyle.h b/third_party/WebKit/Source/core/editing/EditingStyle.h index 336512a..12bdc3f6 100644 --- a/third_party/WebKit/Source/core/editing/EditingStyle.h +++ b/third_party/WebKit/Source/core/editing/EditingStyle.h
@@ -148,6 +148,9 @@ void mergeInlineStyleOfElement(HTMLElement*, CSSPropertyOverrideMode, PropertiesToInclude = AllProperties); + void mergeInlineAndImplicitStyleOfElement(Element*, + CSSPropertyOverrideMode, + PropertiesToInclude); static EditingStyle* wrappingStyleForAnnotatedSerialization( ContainerNode* context); static EditingStyle* wrappingStyleForSerialization(ContainerNode* context); @@ -162,6 +165,8 @@ float fontSizeDelta() const { return m_fontSizeDelta; } bool hasFontSizeDelta() const { return m_fontSizeDelta != NoFontDelta; } + void setProperty(CSSPropertyID, const String& value, bool important = false); + static EditingStyle* styleAtSelectionStart( const VisibleSelection&, bool shouldUseBackgroundColorInEffect = false, @@ -185,7 +190,6 @@ EditingStyle(CSSPropertyID, const String& value); void init(Node*, PropertiesToInclude); void removeInheritedColorsIfNeeded(const ComputedStyle*); - void setProperty(CSSPropertyID, const String& value, bool important = false); void replaceFontSizeByKeywordIfPossible(const ComputedStyle*, CSSComputedStyleDeclaration*); void extractFontSizeDelta(); @@ -195,9 +199,6 @@ HTMLElement*, EditingStyle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const; - void mergeInlineAndImplicitStyleOfElement(Element*, - CSSPropertyOverrideMode, - PropertiesToInclude); void mergeStyle(const StylePropertySet*, CSSPropertyOverrideMode); Member<MutableStylePropertySet> m_mutableStyle;
diff --git a/third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp index 1df94712..cdb69e51 100644 --- a/third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp +++ b/third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp
@@ -24,761 +24,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "core/editing/EditingStyle.h" +#include "EditingStyleUtilities.h" -#include "bindings/core/v8/ExceptionState.h" -#include "core/HTMLNames.h" #include "core/css/CSSColorValue.h" #include "core/css/CSSComputedStyleDeclaration.h" #include "core/css/CSSIdentifierValue.h" -#include "core/css/CSSPrimitiveValue.h" -#include "core/css/CSSPrimitiveValueMappings.h" -#include "core/css/CSSPropertyMetadata.h" -#include "core/css/CSSRuleList.h" -#include "core/css/CSSStyleRule.h" -#include "core/css/CSSValueList.h" -#include "core/css/FontSize.h" #include "core/css/StylePropertySet.h" -#include "core/css/StyleRule.h" #include "core/css/parser/CSSParser.h" -#include "core/css/resolver/StyleResolver.h" -#include "core/dom/Document.h" -#include "core/dom/Element.h" -#include "core/dom/Node.h" -#include "core/dom/NodeComputedStyle.h" -#include "core/dom/NodeTraversal.h" -#include "core/dom/QualifiedName.h" +#include "core/editing/EditingStyle.h" #include "core/editing/EditingUtilities.h" -#include "core/editing/Editor.h" -#include "core/editing/FrameSelection.h" -#include "core/editing/Position.h" -#include "core/editing/commands/ApplyStyleCommand.h" -#include "core/editing/serializers/HTMLInterchange.h" -#include "core/frame/LocalFrame.h" -#include "core/html/HTMLFontElement.h" -#include "core/html/HTMLSpanElement.h" -#include "core/layout/LayoutBox.h" -#include "core/layout/LayoutObject.h" -#include "core/style/ComputedStyle.h" -#include "wtf/StdLibExtras.h" namespace blink { -static const CSSPropertyID& textDecorationPropertyForEditing() { - static const CSSPropertyID property = - RuntimeEnabledFeatures::css3TextDecorationsEnabled() - ? CSSPropertyTextDecorationLine - : CSSPropertyTextDecoration; - return property; -} - -// Editing style properties must be preserved during editing operation. -// e.g. when a user inserts a new paragraph, all properties listed here must be -// copied to the new paragraph. -// NOTE: Use either allEditingProperties() or inheritableEditingProperties() to -// respect runtime enabling of properties. -static const CSSPropertyID staticEditingProperties[] = { - CSSPropertyBackgroundColor, CSSPropertyColor, CSSPropertyFontFamily, - CSSPropertyFontSize, CSSPropertyFontStyle, CSSPropertyFontVariantLigatures, - CSSPropertyFontVariantCaps, CSSPropertyFontWeight, CSSPropertyLetterSpacing, - CSSPropertyOrphans, CSSPropertyTextAlign, - // FIXME: CSSPropertyTextDecoration needs to be removed when CSS3 Text - // Decoration feature is no longer experimental. - CSSPropertyTextDecoration, CSSPropertyTextDecorationLine, - CSSPropertyTextIndent, CSSPropertyTextTransform, CSSPropertyWhiteSpace, - CSSPropertyWidows, CSSPropertyWordSpacing, - CSSPropertyWebkitTextDecorationsInEffect, CSSPropertyWebkitTextFillColor, - CSSPropertyWebkitTextStrokeColor, CSSPropertyWebkitTextStrokeWidth, - CSSPropertyCaretColor}; - -enum EditingPropertiesType { - OnlyInheritableEditingProperties, - AllEditingProperties -}; - -static const Vector<CSSPropertyID>& allEditingProperties() { - DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ()); - if (properties.isEmpty()) { - CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector( - staticEditingProperties, WTF_ARRAY_LENGTH(staticEditingProperties), - properties); - if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) - properties.remove(properties.find(CSSPropertyTextDecoration)); - } - return properties; -} - -static const Vector<CSSPropertyID>& inheritableEditingProperties() { - DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ()); - if (properties.isEmpty()) { - CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector( - staticEditingProperties, WTF_ARRAY_LENGTH(staticEditingProperties), - properties); - for (size_t index = 0; index < properties.size();) { - if (!CSSPropertyMetadata::isInheritedProperty(properties[index])) { - properties.remove(index); - continue; - } - ++index; - } - } - return properties; -} - -template <class StyleDeclarationType> -static MutableStylePropertySet* copyEditingProperties( - StyleDeclarationType* style, - EditingPropertiesType type = OnlyInheritableEditingProperties) { - if (type == AllEditingProperties) - return style->copyPropertiesInSet(allEditingProperties()); - return style->copyPropertiesInSet(inheritableEditingProperties()); -} - -static inline bool isEditingProperty(int id) { - return allEditingProperties().contains(static_cast<CSSPropertyID>(id)); -} - -static MutableStylePropertySet* editingStyleFromComputedStyle( - CSSComputedStyleDeclaration* style, - EditingPropertiesType type = OnlyInheritableEditingProperties) { - if (!style) - return MutableStylePropertySet::create(HTMLQuirksMode); - return copyEditingProperties(style, type); -} - -static CSSComputedStyleDeclaration* ensureComputedStyle( - const Position& position) { - Element* elem = associatedElementOf(position); - if (!elem) - return nullptr; - return CSSComputedStyleDeclaration::create(elem); -} - -static MutableStylePropertySet* getPropertiesNotIn( - StylePropertySet* styleWithRedundantProperties, - CSSStyleDeclaration* baseStyle); -enum LegacyFontSizeMode { - AlwaysUseLegacyFontSize, - UseLegacyFontSizeOnlyIfPixelValuesMatch -}; -static int legacyFontSizeFromCSSValue(Document*, - const CSSValue*, - bool, - LegacyFontSizeMode); -static bool isTransparentColorValue(const CSSValue*); -static bool hasTransparentBackgroundColor(CSSStyleDeclaration*); -static bool hasTransparentBackgroundColor(StylePropertySet*); -static const CSSValue* backgroundColorValueInEffect(Node*); -static bool hasAncestorVerticalAlignStyle(Node&, CSSValueID); - -class HTMLElementEquivalent : public GarbageCollected<HTMLElementEquivalent> { - public: - static HTMLElementEquivalent* create(CSSPropertyID propertyID, - CSSValueID primitiveValue, - const HTMLQualifiedName& tagName) { - return new HTMLElementEquivalent(propertyID, primitiveValue, tagName); - } - - virtual bool matches(const Element* element) const { - return !m_tagName || element->hasTagName(*m_tagName); - } - virtual bool hasAttribute() const { return false; } - virtual bool propertyExistsInStyle(const StylePropertySet* style) const { - return style->getPropertyCSSValue(m_propertyID); - } - virtual bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const; - virtual void addToStyle(Element*, EditingStyle*) const; - - DEFINE_INLINE_VIRTUAL_TRACE() { visitor->trace(m_identifierValue); } - - protected: - HTMLElementEquivalent(CSSPropertyID); - HTMLElementEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName); - HTMLElementEquivalent(CSSPropertyID, - CSSValueID primitiveValue, - const HTMLQualifiedName& tagName); - const CSSPropertyID m_propertyID; - const Member<CSSIdentifierValue> m_identifierValue; - // We can store a pointer because HTML tag names are const global. - const HTMLQualifiedName* m_tagName; -}; - -HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id) - : m_propertyID(id), m_tagName(0) {} - -HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, - const HTMLQualifiedName& tagName) - : m_propertyID(id), m_tagName(&tagName) {} - -HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, - CSSValueID valueID, - const HTMLQualifiedName& tagName) - : m_propertyID(id), - m_identifierValue(CSSIdentifierValue::create(valueID)), - m_tagName(&tagName) { - DCHECK_NE(valueID, CSSValueInvalid); -} - -bool HTMLElementEquivalent::valueIsPresentInStyle( - HTMLElement* element, - StylePropertySet* style) const { - const CSSValue* value = style->getPropertyCSSValue(m_propertyID); - return matches(element) && value && value->isIdentifierValue() && - toCSSIdentifierValue(value)->getValueID() == - m_identifierValue->getValueID(); -} - -void HTMLElementEquivalent::addToStyle(Element*, EditingStyle* style) const { - style->setProperty(m_propertyID, m_identifierValue->cssText()); -} - -class HTMLTextDecorationEquivalent final : public HTMLElementEquivalent { - public: - static HTMLElementEquivalent* create(CSSValueID primitiveValue, - const HTMLQualifiedName& tagName) { - return new HTMLTextDecorationEquivalent(primitiveValue, tagName); - } - bool propertyExistsInStyle(const StylePropertySet*) const override; - bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const override; - - DEFINE_INLINE_VIRTUAL_TRACE() { HTMLElementEquivalent::trace(visitor); } - - private: - HTMLTextDecorationEquivalent(CSSValueID primitiveValue, - const HTMLQualifiedName& tagName); -}; - -HTMLTextDecorationEquivalent::HTMLTextDecorationEquivalent( - CSSValueID primitiveValue, - const HTMLQualifiedName& tagName) - : HTMLElementEquivalent(textDecorationPropertyForEditing(), - primitiveValue, - tagName) -// m_propertyID is used in HTMLElementEquivalent::addToStyle -{} - -bool HTMLTextDecorationEquivalent::propertyExistsInStyle( - const StylePropertySet* style) const { - return style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect) || - style->getPropertyCSSValue(textDecorationPropertyForEditing()); -} - -bool HTMLTextDecorationEquivalent::valueIsPresentInStyle( - HTMLElement* element, - StylePropertySet* style) const { - const CSSValue* styleValue = - style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect); - if (!styleValue) - styleValue = style->getPropertyCSSValue(textDecorationPropertyForEditing()); - return matches(element) && styleValue && styleValue->isValueList() && - toCSSValueList(styleValue)->hasValue(*m_identifierValue); -} - -class HTMLAttributeEquivalent : public HTMLElementEquivalent { - public: - static HTMLAttributeEquivalent* create(CSSPropertyID propertyID, - const HTMLQualifiedName& tagName, - const QualifiedName& attrName) { - return new HTMLAttributeEquivalent(propertyID, tagName, attrName); - } - static HTMLAttributeEquivalent* create(CSSPropertyID propertyID, - const QualifiedName& attrName) { - return new HTMLAttributeEquivalent(propertyID, attrName); - } - - bool matches(const Element* element) const override { - return HTMLElementEquivalent::matches(element) && - element->hasAttribute(m_attrName); - } - bool hasAttribute() const override { return true; } - bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const override; - void addToStyle(Element*, EditingStyle*) const override; - virtual const CSSValue* attributeValueAsCSSValue(Element*) const; - inline const QualifiedName& attributeName() const { return m_attrName; } - - DEFINE_INLINE_VIRTUAL_TRACE() { HTMLElementEquivalent::trace(visitor); } - - protected: - HTMLAttributeEquivalent(CSSPropertyID, - const HTMLQualifiedName& tagName, - const QualifiedName& attrName); - HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& attrName); - // We can store a reference because HTML attribute names are const global. - const QualifiedName& m_attrName; -}; - -HTMLAttributeEquivalent::HTMLAttributeEquivalent( - CSSPropertyID id, - const HTMLQualifiedName& tagName, - const QualifiedName& attrName) - : HTMLElementEquivalent(id, tagName), m_attrName(attrName) {} - -HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, - const QualifiedName& attrName) - : HTMLElementEquivalent(id), m_attrName(attrName) {} - -bool HTMLAttributeEquivalent::valueIsPresentInStyle( - HTMLElement* element, - StylePropertySet* style) const { - const CSSValue* value = attributeValueAsCSSValue(element); - const CSSValue* styleValue = style->getPropertyCSSValue(m_propertyID); - - return compareCSSValuePtr(value, styleValue); -} - -void HTMLAttributeEquivalent::addToStyle(Element* element, - EditingStyle* style) const { - if (const CSSValue* value = attributeValueAsCSSValue(element)) - style->setProperty(m_propertyID, value->cssText()); -} - -const CSSValue* HTMLAttributeEquivalent::attributeValueAsCSSValue( - Element* element) const { - DCHECK(element); - const AtomicString& value = element->getAttribute(m_attrName); - if (value.isNull()) - return nullptr; - - MutableStylePropertySet* dummyStyle = nullptr; - dummyStyle = MutableStylePropertySet::create(HTMLQuirksMode); - dummyStyle->setProperty(m_propertyID, value); - return dummyStyle->getPropertyCSSValue(m_propertyID); -} - -class HTMLFontSizeEquivalent final : public HTMLAttributeEquivalent { - public: - static HTMLFontSizeEquivalent* create() { - return new HTMLFontSizeEquivalent(); - } - const CSSValue* attributeValueAsCSSValue(Element*) const override; - - DEFINE_INLINE_VIRTUAL_TRACE() { HTMLAttributeEquivalent::trace(visitor); } - - private: - HTMLFontSizeEquivalent(); -}; - -HTMLFontSizeEquivalent::HTMLFontSizeEquivalent() - : HTMLAttributeEquivalent(CSSPropertyFontSize, - HTMLNames::fontTag, - HTMLNames::sizeAttr) {} - -const CSSValue* HTMLFontSizeEquivalent::attributeValueAsCSSValue( - Element* element) const { - DCHECK(element); - const AtomicString& value = element->getAttribute(m_attrName); - if (value.isNull()) - return nullptr; - CSSValueID size; - if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size)) - return nullptr; - return CSSIdentifierValue::create(size); -} - -float EditingStyle::NoFontDelta = 0.0f; - -EditingStyle::EditingStyle(ContainerNode* node, - PropertiesToInclude propertiesToInclude) { - init(node, propertiesToInclude); -} - -EditingStyle::EditingStyle(const Position& position, - PropertiesToInclude propertiesToInclude) { - init(position.anchorNode(), propertiesToInclude); -} - -EditingStyle::EditingStyle(const StylePropertySet* style) - : m_mutableStyle(style ? style->mutableCopy() : nullptr) { - extractFontSizeDelta(); -} - -EditingStyle::EditingStyle(CSSPropertyID propertyID, const String& value) - : m_mutableStyle(nullptr) { - setProperty(propertyID, value); - m_isVerticalAlign = propertyID == CSSPropertyVerticalAlign && - (value == "sub" || value == "super"); -} - -static Color cssValueToColor(const CSSValue* colorValue) { - if (!colorValue || - (!colorValue->isColorValue() && !colorValue->isPrimitiveValue() && - !colorValue->isIdentifierValue())) - return Color::transparent; - - if (colorValue->isColorValue()) - return toCSSColorValue(colorValue)->value(); - - Color color = 0; - // FIXME: Why ignore the return value? - CSSParser::parseColor(color, colorValue->cssText()); - return color; -} - -static inline Color getFontColor(CSSStyleDeclaration* style) { - return cssValueToColor(style->getPropertyCSSValueInternal(CSSPropertyColor)); -} - -static inline Color getFontColor(StylePropertySet* style) { - return cssValueToColor(style->getPropertyCSSValue(CSSPropertyColor)); -} - -static inline Color getBackgroundColor(CSSStyleDeclaration* style) { - return cssValueToColor( - style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor)); -} - -static inline Color getBackgroundColor(StylePropertySet* style) { - return cssValueToColor( - style->getPropertyCSSValue(CSSPropertyBackgroundColor)); -} - -static inline Color backgroundColorInEffect(Node* node) { - return cssValueToColor(backgroundColorValueInEffect(node)); -} - -static int textAlignResolvingStartAndEnd(int textAlign, int direction) { - switch (textAlign) { - case CSSValueCenter: - case CSSValueWebkitCenter: - return CSSValueCenter; - case CSSValueJustify: - return CSSValueJustify; - case CSSValueLeft: - case CSSValueWebkitLeft: - return CSSValueLeft; - case CSSValueRight: - case CSSValueWebkitRight: - return CSSValueRight; - case CSSValueStart: - return direction != CSSValueRtl ? CSSValueLeft : CSSValueRight; - case CSSValueEnd: - return direction == CSSValueRtl ? CSSValueRight : CSSValueLeft; - } - return CSSValueInvalid; -} - -template <typename T> -static int textAlignResolvingStartAndEnd(T* style) { - return textAlignResolvingStartAndEnd( - getIdentifierValue(style, CSSPropertyTextAlign), - getIdentifierValue(style, CSSPropertyDirection)); -} - -void EditingStyle::init(Node* node, PropertiesToInclude propertiesToInclude) { - if (isTabHTMLSpanElementTextNode(node)) - node = tabSpanElement(node)->parentNode(); - else if (isTabHTMLSpanElement(node)) - node = node->parentNode(); - - CSSComputedStyleDeclaration* computedStyleAtPosition = - CSSComputedStyleDeclaration::create(node); - m_mutableStyle = - propertiesToInclude == AllProperties && computedStyleAtPosition - ? computedStyleAtPosition->copyProperties() - : editingStyleFromComputedStyle(computedStyleAtPosition); - - if (propertiesToInclude == EditingPropertiesInEffect) { - if (const CSSValue* value = backgroundColorValueInEffect(node)) - m_mutableStyle->setProperty(CSSPropertyBackgroundColor, value->cssText()); - if (const CSSValue* value = computedStyleAtPosition->getPropertyCSSValue( - CSSPropertyWebkitTextDecorationsInEffect)) - m_mutableStyle->setProperty(CSSPropertyTextDecoration, value->cssText()); - } - - if (node && node->ensureComputedStyle()) { - const ComputedStyle* computedStyle = node->ensureComputedStyle(); - removeInheritedColorsIfNeeded(computedStyle); - replaceFontSizeByKeywordIfPossible(computedStyle, computedStyleAtPosition); - } - - m_isMonospaceFont = computedStyleAtPosition->isMonospaceFont(); - extractFontSizeDelta(); -} - -void EditingStyle::removeInheritedColorsIfNeeded( - const ComputedStyle* computedStyle) { - // If a node's text fill color is currentColor, then its children use - // their font-color as their text fill color (they don't - // inherit it). Likewise for stroke color. - // Similar thing happens for caret-color if it's auto or currentColor. - if (computedStyle->textFillColor().isCurrentColor()) - m_mutableStyle->removeProperty(CSSPropertyWebkitTextFillColor); - if (computedStyle->textStrokeColor().isCurrentColor()) - m_mutableStyle->removeProperty(CSSPropertyWebkitTextStrokeColor); - if (computedStyle->caretColor().isAutoColor() || - computedStyle->caretColor().isCurrentColor()) - m_mutableStyle->removeProperty(CSSPropertyCaretColor); -} - -void EditingStyle::setProperty(CSSPropertyID propertyID, - const String& value, - bool important) { - if (!m_mutableStyle) - m_mutableStyle = MutableStylePropertySet::create(HTMLQuirksMode); - - m_mutableStyle->setProperty(propertyID, value, important); -} - -void EditingStyle::replaceFontSizeByKeywordIfPossible( - const ComputedStyle* computedStyle, - CSSComputedStyleDeclaration* cssComputedStyle) { - DCHECK(computedStyle); - if (computedStyle->getFontDescription().keywordSize()) { - m_mutableStyle->setProperty( - CSSPropertyFontSize, - cssComputedStyle->getFontSizeCSSValuePreferringKeyword()->cssText()); - } -} - -void EditingStyle::extractFontSizeDelta() { - if (!m_mutableStyle) - return; - - if (m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize)) { - // Explicit font size overrides any delta. - m_mutableStyle->removeProperty(CSSPropertyWebkitFontSizeDelta); - return; - } - - // Get the adjustment amount out of the style. - const CSSValue* value = - m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitFontSizeDelta); - if (!value || !value->isPrimitiveValue()) - return; - - const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); - - // Only PX handled now. If we handle more types in the future, perhaps - // a switch statement here would be more appropriate. - if (!primitiveValue->isPx()) - return; - - m_fontSizeDelta = primitiveValue->getFloatValue(); - m_mutableStyle->removeProperty(CSSPropertyWebkitFontSizeDelta); -} - -bool EditingStyle::isEmpty() const { - return (!m_mutableStyle || m_mutableStyle->isEmpty()) && - m_fontSizeDelta == NoFontDelta; -} - -bool EditingStyle::textDirection(WritingDirection& writingDirection) const { - if (!m_mutableStyle) - return false; - - const CSSValue* unicodeBidi = - m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi); - if (!unicodeBidi || !unicodeBidi->isIdentifierValue()) - return false; - - CSSValueID unicodeBidiValue = toCSSIdentifierValue(unicodeBidi)->getValueID(); - if (isEmbedOrIsolate(unicodeBidiValue)) { - const CSSValue* direction = - m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection); - if (!direction || !direction->isIdentifierValue()) - return false; - - writingDirection = - toCSSIdentifierValue(direction)->getValueID() == CSSValueLtr - ? LeftToRightWritingDirection - : RightToLeftWritingDirection; - - return true; - } - - if (unicodeBidiValue == CSSValueNormal) { - writingDirection = NaturalWritingDirection; - return true; - } - - return false; -} - -void EditingStyle::overrideWithStyle(const StylePropertySet* style) { - if (!style || style->isEmpty()) - return; - if (!m_mutableStyle) - m_mutableStyle = MutableStylePropertySet::create(HTMLQuirksMode); - m_mutableStyle->mergeAndOverrideOnConflict(style); - extractFontSizeDelta(); -} - -void EditingStyle::clear() { - m_mutableStyle.clear(); - m_isMonospaceFont = false; - m_fontSizeDelta = NoFontDelta; -} - -EditingStyle* EditingStyle::copy() const { - EditingStyle* copy = EditingStyle::create(); - if (m_mutableStyle) - copy->m_mutableStyle = m_mutableStyle->mutableCopy(); - copy->m_isMonospaceFont = m_isMonospaceFont; - copy->m_fontSizeDelta = m_fontSizeDelta; - return copy; -} - -// This is the list of CSS properties that apply specially to block-level -// elements. -static const CSSPropertyID staticBlockProperties[] = { - CSSPropertyBreakAfter, - CSSPropertyBreakBefore, - CSSPropertyBreakInside, - CSSPropertyOrphans, - CSSPropertyOverflow, // This can be also be applied to replaced elements - CSSPropertyColumnCount, - CSSPropertyColumnGap, - CSSPropertyColumnRuleColor, - CSSPropertyColumnRuleStyle, - CSSPropertyColumnRuleWidth, - CSSPropertyWebkitColumnBreakBefore, - CSSPropertyWebkitColumnBreakAfter, - CSSPropertyWebkitColumnBreakInside, - CSSPropertyColumnWidth, - CSSPropertyPageBreakAfter, - CSSPropertyPageBreakBefore, - CSSPropertyPageBreakInside, - CSSPropertyTextAlign, - CSSPropertyTextAlignLast, - CSSPropertyTextIndent, - CSSPropertyTextJustify, - CSSPropertyWidows}; - -static const Vector<CSSPropertyID>& blockPropertiesVector() { - DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ()); - if (properties.isEmpty()) { - CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector( - staticBlockProperties, WTF_ARRAY_LENGTH(staticBlockProperties), - properties); - } - return properties; -} - -EditingStyle* EditingStyle::extractAndRemoveBlockProperties() { - EditingStyle* blockProperties = EditingStyle::create(); - if (!m_mutableStyle) - return blockProperties; - - blockProperties->m_mutableStyle = - m_mutableStyle->copyPropertiesInSet(blockPropertiesVector()); - removeBlockProperties(); - - return blockProperties; -} - -EditingStyle* EditingStyle::extractAndRemoveTextDirection() { - EditingStyle* textDirection = EditingStyle::create(); - textDirection->m_mutableStyle = - MutableStylePropertySet::create(HTMLQuirksMode); - textDirection->m_mutableStyle->setProperty( - CSSPropertyUnicodeBidi, CSSValueIsolate, - m_mutableStyle->propertyIsImportant(CSSPropertyUnicodeBidi)); - textDirection->m_mutableStyle->setProperty( - CSSPropertyDirection, - m_mutableStyle->getPropertyValue(CSSPropertyDirection), - m_mutableStyle->propertyIsImportant(CSSPropertyDirection)); - - m_mutableStyle->removeProperty(CSSPropertyUnicodeBidi); - m_mutableStyle->removeProperty(CSSPropertyDirection); - - return textDirection; -} - -void EditingStyle::removeBlockProperties() { - if (!m_mutableStyle) - return; - - m_mutableStyle->removePropertiesInSet(blockPropertiesVector().data(), - blockPropertiesVector().size()); -} - -void EditingStyle::removeStyleAddedByElement(Element* element) { - if (!element || !element->parentNode()) - return; - MutableStylePropertySet* parentStyle = editingStyleFromComputedStyle( - CSSComputedStyleDeclaration::create(element->parentNode()), - AllEditingProperties); - MutableStylePropertySet* nodeStyle = editingStyleFromComputedStyle( - CSSComputedStyleDeclaration::create(element), AllEditingProperties); - nodeStyle->removeEquivalentProperties(parentStyle); - m_mutableStyle->removeEquivalentProperties(nodeStyle); -} - -void EditingStyle::removeStyleConflictingWithStyleOfElement(Element* element) { - if (!element || !element->parentNode() || !m_mutableStyle) - return; - - MutableStylePropertySet* parentStyle = editingStyleFromComputedStyle( - CSSComputedStyleDeclaration::create(element->parentNode()), - AllEditingProperties); - MutableStylePropertySet* nodeStyle = editingStyleFromComputedStyle( - CSSComputedStyleDeclaration::create(element), AllEditingProperties); - nodeStyle->removeEquivalentProperties(parentStyle); - - unsigned propertyCount = nodeStyle->propertyCount(); - for (unsigned i = 0; i < propertyCount; ++i) - m_mutableStyle->removeProperty(nodeStyle->propertyAt(i).id()); -} - -void EditingStyle::collapseTextDecorationProperties() { - if (!m_mutableStyle) - return; - - const CSSValue* textDecorationsInEffect = m_mutableStyle->getPropertyCSSValue( - CSSPropertyWebkitTextDecorationsInEffect); - if (!textDecorationsInEffect) - return; - - if (textDecorationsInEffect->isValueList()) { - m_mutableStyle->setProperty(textDecorationPropertyForEditing(), - textDecorationsInEffect->cssText(), - m_mutableStyle->propertyIsImportant( - textDecorationPropertyForEditing())); - } else { - m_mutableStyle->removeProperty(textDecorationPropertyForEditing()); - } - m_mutableStyle->removeProperty(CSSPropertyWebkitTextDecorationsInEffect); -} - -// CSS properties that create a visual difference only when applied to text. -static const CSSPropertyID textOnlyProperties[] = { - // FIXME: CSSPropertyTextDecoration needs to be removed when CSS3 Text - // Decoration feature is no longer experimental. - CSSPropertyTextDecoration, - CSSPropertyTextDecorationLine, - CSSPropertyWebkitTextDecorationsInEffect, - CSSPropertyFontStyle, - CSSPropertyFontWeight, - CSSPropertyColor, -}; - -TriState EditingStyle::triStateOfStyle(EditingStyle* style) const { - if (!style || !style->m_mutableStyle) - return FalseTriState; - return triStateOfStyle(style->m_mutableStyle->ensureCSSStyleDeclaration(), - DoNotIgnoreTextOnlyProperties); -} - -TriState EditingStyle::triStateOfStyle( - CSSStyleDeclaration* styleToCompare, - ShouldIgnoreTextOnlyProperties shouldIgnoreTextOnlyProperties) const { - MutableStylePropertySet* difference = - getPropertiesNotIn(m_mutableStyle.get(), styleToCompare); - - if (shouldIgnoreTextOnlyProperties == IgnoreTextOnlyProperties) { - difference->removePropertiesInSet(textOnlyProperties, - WTF_ARRAY_LENGTH(textOnlyProperties)); - } - - if (difference->isEmpty()) - return TrueTriState; - if (difference->propertyCount() == m_mutableStyle->propertyCount()) - return FalseTriState; - - return MixedTriState; -} - -static bool hasAncestorVerticalAlignStyle(Node& node, CSSValueID value) { +bool EditingStyleUtilities::hasAncestorVerticalAlignStyle(Node& node, + CSSValueID value) { for (Node& runner : NodeTraversal::inclusiveAncestorsOf(node)) { CSSComputedStyleDeclaration* ancestorStyle = CSSComputedStyleDeclaration::create(&runner); @@ -788,476 +47,7 @@ return false; } -TriState EditingStyle::triStateOfStyle( - const VisibleSelection& selection) const { - if (selection.isNone()) - return FalseTriState; - - if (selection.isCaret()) - return triStateOfStyle(EditingStyle::styleAtSelectionStart(selection)); - - TriState state = FalseTriState; - bool nodeIsStart = true; - for (Node& node : NodeTraversal::startsAt(*selection.start().anchorNode())) { - if (node.layoutObject() && hasEditableStyle(node)) { - CSSComputedStyleDeclaration* nodeStyle = - CSSComputedStyleDeclaration::create(&node); - if (nodeStyle) { - // If the selected element has <sub> or <sup> ancestor element, apply - // the corresponding style(vertical-align) to it so that - // document.queryCommandState() works with the style. See bug - // http://crbug.com/582225. - if (m_isVerticalAlign && - getIdentifierValue(nodeStyle, CSSPropertyVerticalAlign) == - CSSValueBaseline) { - const CSSIdentifierValue* verticalAlign = toCSSIdentifierValue( - m_mutableStyle->getPropertyCSSValue(CSSPropertyVerticalAlign)); - if (hasAncestorVerticalAlignStyle(node, - verticalAlign->getValueID())) { - node.mutableComputedStyle()->setVerticalAlign( - verticalAlign->convertTo<EVerticalAlign>()); - } - } - - // Pass EditingStyle::DoNotIgnoreTextOnlyProperties without checking if - // node.isTextNode() because the node can be an element node. See bug - // http://crbug.com/584939. - TriState nodeState = triStateOfStyle( - nodeStyle, EditingStyle::DoNotIgnoreTextOnlyProperties); - if (nodeIsStart) { - state = nodeState; - nodeIsStart = false; - } else if (state != nodeState && node.isTextNode()) { - state = MixedTriState; - break; - } - } - } - if (&node == selection.end().anchorNode()) - break; - } - - return state; -} - -bool EditingStyle::conflictsWithInlineStyleOfElement( - HTMLElement* element, - EditingStyle* extractedStyle, - Vector<CSSPropertyID>* conflictingProperties) const { - DCHECK(element); - DCHECK(!conflictingProperties || conflictingProperties->isEmpty()); - - const StylePropertySet* inlineStyle = element->inlineStyle(); - if (!m_mutableStyle || !inlineStyle) - return false; - - unsigned propertyCount = m_mutableStyle->propertyCount(); - for (unsigned i = 0; i < propertyCount; ++i) { - CSSPropertyID propertyID = m_mutableStyle->propertyAt(i).id(); - - // We don't override whitespace property of a tab span because that would - // collapse the tab into a space. - if (propertyID == CSSPropertyWhiteSpace && isTabHTMLSpanElement(element)) - continue; - - if (propertyID == CSSPropertyWebkitTextDecorationsInEffect && - inlineStyle->getPropertyCSSValue(textDecorationPropertyForEditing())) { - if (!conflictingProperties) - return true; - conflictingProperties->push_back(CSSPropertyTextDecoration); - // Because text-decoration expands to text-decoration-line when CSS3 - // Text Decoration is enabled, we also state it as conflicting. - if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) - conflictingProperties->push_back(CSSPropertyTextDecorationLine); - if (extractedStyle) { - extractedStyle->setProperty( - textDecorationPropertyForEditing(), - inlineStyle->getPropertyValue(textDecorationPropertyForEditing()), - inlineStyle->propertyIsImportant( - textDecorationPropertyForEditing())); - } - continue; - } - - if (!inlineStyle->getPropertyCSSValue(propertyID)) - continue; - - if (propertyID == CSSPropertyUnicodeBidi && - inlineStyle->getPropertyCSSValue(CSSPropertyDirection)) { - if (!conflictingProperties) - return true; - conflictingProperties->push_back(CSSPropertyDirection); - if (extractedStyle) { - extractedStyle->setProperty( - propertyID, inlineStyle->getPropertyValue(propertyID), - inlineStyle->propertyIsImportant(propertyID)); - } - } - - if (!conflictingProperties) - return true; - - conflictingProperties->push_back(propertyID); - - if (extractedStyle) { - extractedStyle->setProperty(propertyID, - inlineStyle->getPropertyValue(propertyID), - inlineStyle->propertyIsImportant(propertyID)); - } - } - - return conflictingProperties && !conflictingProperties->isEmpty(); -} - -static const HeapVector<Member<HTMLElementEquivalent>>& -htmlElementEquivalents() { - DEFINE_STATIC_LOCAL(HeapVector<Member<HTMLElementEquivalent>>, - HTMLElementEquivalents, - (new HeapVector<Member<HTMLElementEquivalent>>)); - if (!HTMLElementEquivalents.size()) { - HTMLElementEquivalents.push_back(HTMLElementEquivalent::create( - CSSPropertyFontWeight, CSSValueBold, HTMLNames::bTag)); - HTMLElementEquivalents.push_back(HTMLElementEquivalent::create( - CSSPropertyFontWeight, CSSValueBold, HTMLNames::strongTag)); - HTMLElementEquivalents.push_back(HTMLElementEquivalent::create( - CSSPropertyVerticalAlign, CSSValueSub, HTMLNames::subTag)); - HTMLElementEquivalents.push_back(HTMLElementEquivalent::create( - CSSPropertyVerticalAlign, CSSValueSuper, HTMLNames::supTag)); - HTMLElementEquivalents.push_back(HTMLElementEquivalent::create( - CSSPropertyFontStyle, CSSValueItalic, HTMLNames::iTag)); - HTMLElementEquivalents.push_back(HTMLElementEquivalent::create( - CSSPropertyFontStyle, CSSValueItalic, HTMLNames::emTag)); - - HTMLElementEquivalents.push_back(HTMLTextDecorationEquivalent::create( - CSSValueUnderline, HTMLNames::uTag)); - HTMLElementEquivalents.push_back(HTMLTextDecorationEquivalent::create( - CSSValueLineThrough, HTMLNames::sTag)); - HTMLElementEquivalents.push_back(HTMLTextDecorationEquivalent::create( - CSSValueLineThrough, HTMLNames::strikeTag)); - } - - return HTMLElementEquivalents; -} - -bool EditingStyle::conflictsWithImplicitStyleOfElement( - HTMLElement* element, - EditingStyle* extractedStyle, - ShouldExtractMatchingStyle shouldExtractMatchingStyle) const { - if (!m_mutableStyle) - return false; - - const HeapVector<Member<HTMLElementEquivalent>>& HTMLElementEquivalents = - htmlElementEquivalents(); - for (size_t i = 0; i < HTMLElementEquivalents.size(); ++i) { - const HTMLElementEquivalent* equivalent = HTMLElementEquivalents[i].get(); - if (equivalent->matches(element) && - equivalent->propertyExistsInStyle(m_mutableStyle.get()) && - (shouldExtractMatchingStyle == ExtractMatchingStyle || - !equivalent->valueIsPresentInStyle(element, m_mutableStyle.get()))) { - if (extractedStyle) - equivalent->addToStyle(element, extractedStyle); - return true; - } - } - return false; -} - -static const HeapVector<Member<HTMLAttributeEquivalent>>& -htmlAttributeEquivalents() { - DEFINE_STATIC_LOCAL(HeapVector<Member<HTMLAttributeEquivalent>>, - HTMLAttributeEquivalents, - (new HeapVector<Member<HTMLAttributeEquivalent>>)); - if (!HTMLAttributeEquivalents.size()) { - // elementIsStyledSpanOrHTMLEquivalent depends on the fact each - // HTMLAttriuteEquivalent matches exactly one attribute of exactly one - // element except dirAttr. - HTMLAttributeEquivalents.push_back(HTMLAttributeEquivalent::create( - CSSPropertyColor, HTMLNames::fontTag, HTMLNames::colorAttr)); - HTMLAttributeEquivalents.push_back(HTMLAttributeEquivalent::create( - CSSPropertyFontFamily, HTMLNames::fontTag, HTMLNames::faceAttr)); - HTMLAttributeEquivalents.push_back(HTMLFontSizeEquivalent::create()); - - HTMLAttributeEquivalents.push_back(HTMLAttributeEquivalent::create( - CSSPropertyDirection, HTMLNames::dirAttr)); - HTMLAttributeEquivalents.push_back(HTMLAttributeEquivalent::create( - CSSPropertyUnicodeBidi, HTMLNames::dirAttr)); - } - - return HTMLAttributeEquivalents; -} - -bool EditingStyle::conflictsWithImplicitStyleOfAttributes( - HTMLElement* element) const { - DCHECK(element); - if (!m_mutableStyle) - return false; - - const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents = - htmlAttributeEquivalents(); - for (const auto& equivalent : HTMLAttributeEquivalents) { - if (equivalent->matches(element) && - equivalent->propertyExistsInStyle(m_mutableStyle.get()) && - !equivalent->valueIsPresentInStyle(element, m_mutableStyle.get())) - return true; - } - - return false; -} - -bool EditingStyle::extractConflictingImplicitStyleOfAttributes( - HTMLElement* element, - ShouldPreserveWritingDirection shouldPreserveWritingDirection, - EditingStyle* extractedStyle, - Vector<QualifiedName>& conflictingAttributes, - ShouldExtractMatchingStyle shouldExtractMatchingStyle) const { - DCHECK(element); - // HTMLAttributeEquivalent::addToStyle doesn't support unicode-bidi and - // direction properties - if (extractedStyle) - DCHECK_EQ(shouldPreserveWritingDirection, PreserveWritingDirection); - if (!m_mutableStyle) - return false; - - const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents = - htmlAttributeEquivalents(); - bool removed = false; - for (const auto& attribute : HTMLAttributeEquivalents) { - const HTMLAttributeEquivalent* equivalent = attribute.get(); - - // unicode-bidi and direction are pushed down separately so don't push down - // with other styles. - if (shouldPreserveWritingDirection == PreserveWritingDirection && - equivalent->attributeName() == HTMLNames::dirAttr) - continue; - - if (!equivalent->matches(element) || - !equivalent->propertyExistsInStyle(m_mutableStyle.get()) || - (shouldExtractMatchingStyle == DoNotExtractMatchingStyle && - equivalent->valueIsPresentInStyle(element, m_mutableStyle.get()))) - continue; - - if (extractedStyle) - equivalent->addToStyle(element, extractedStyle); - conflictingAttributes.push_back(equivalent->attributeName()); - removed = true; - } - - return removed; -} - -bool EditingStyle::styleIsPresentInComputedStyleOfNode(Node* node) const { - return !m_mutableStyle || - getPropertiesNotIn(m_mutableStyle.get(), - CSSComputedStyleDeclaration::create(node)) - ->isEmpty(); -} - -bool EditingStyle::elementIsStyledSpanOrHTMLEquivalent( - const HTMLElement* element) { - DCHECK(element); - bool elementIsSpanOrElementEquivalent = false; - if (isHTMLSpanElement(*element)) { - elementIsSpanOrElementEquivalent = true; - } else { - const HeapVector<Member<HTMLElementEquivalent>>& HTMLElementEquivalents = - htmlElementEquivalents(); - size_t i; - for (i = 0; i < HTMLElementEquivalents.size(); ++i) { - if (HTMLElementEquivalents[i]->matches(element)) { - elementIsSpanOrElementEquivalent = true; - break; - } - } - } - - AttributeCollection attributes = element->attributes(); - if (attributes.isEmpty()) { - // span, b, etc... without any attributes - return elementIsSpanOrElementEquivalent; - } - - unsigned matchedAttributes = 0; - const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents = - htmlAttributeEquivalents(); - for (const auto& equivalent : HTMLAttributeEquivalents) { - if (equivalent->matches(element) && - equivalent->attributeName() != HTMLNames::dirAttr) - matchedAttributes++; - } - - if (!elementIsSpanOrElementEquivalent && !matchedAttributes) { - // element is not a span, a html element equivalent, or font element. - return false; - } - - if (element->getAttribute(HTMLNames::classAttr) == AppleStyleSpanClass) - matchedAttributes++; - - if (element->hasAttribute(HTMLNames::styleAttr)) { - if (const StylePropertySet* style = element->inlineStyle()) { - unsigned propertyCount = style->propertyCount(); - for (unsigned i = 0; i < propertyCount; ++i) { - if (!isEditingProperty(style->propertyAt(i).id())) - return false; - } - } - matchedAttributes++; - } - - // font with color attribute, span with style attribute, etc... - DCHECK_LE(matchedAttributes, attributes.size()); - return matchedAttributes >= attributes.size(); -} - -void EditingStyle::prepareToApplyAt( - const Position& position, - ShouldPreserveWritingDirection shouldPreserveWritingDirection) { - if (!m_mutableStyle) - return; - - // ReplaceSelectionCommand::handleStyleSpans() requires that this function - // only removes the editing style. If this function was modified in the future - // to delete all redundant properties, then add a boolean value to indicate - // which one of editingStyleAtPosition or computedStyle is called. - EditingStyle* editingStyleAtPosition = - EditingStyle::create(position, EditingPropertiesInEffect); - StylePropertySet* styleAtPosition = - editingStyleAtPosition->m_mutableStyle.get(); - - const CSSValue* unicodeBidi = nullptr; - const CSSValue* direction = nullptr; - if (shouldPreserveWritingDirection == PreserveWritingDirection) { - unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi); - direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection); - } - - m_mutableStyle->removeEquivalentProperties(styleAtPosition); - - if (textAlignResolvingStartAndEnd(m_mutableStyle.get()) == - textAlignResolvingStartAndEnd(styleAtPosition)) - m_mutableStyle->removeProperty(CSSPropertyTextAlign); - - if (getFontColor(m_mutableStyle.get()) == getFontColor(styleAtPosition)) - m_mutableStyle->removeProperty(CSSPropertyColor); - - if (hasTransparentBackgroundColor(m_mutableStyle.get()) || - cssValueToColor( - m_mutableStyle->getPropertyCSSValue(CSSPropertyBackgroundColor)) == - backgroundColorInEffect(position.computeContainerNode())) - m_mutableStyle->removeProperty(CSSPropertyBackgroundColor); - - if (unicodeBidi && unicodeBidi->isIdentifierValue()) { - m_mutableStyle->setProperty( - CSSPropertyUnicodeBidi, - toCSSIdentifierValue(unicodeBidi)->getValueID()); - if (direction && direction->isIdentifierValue()) { - m_mutableStyle->setProperty( - CSSPropertyDirection, toCSSIdentifierValue(direction)->getValueID()); - } - } -} - -void EditingStyle::mergeTypingStyle(Document* document) { - DCHECK(document); - - EditingStyle* typingStyle = document->frame()->selection().typingStyle(); - if (!typingStyle || typingStyle == this) - return; - - mergeStyle(typingStyle->style(), OverrideValues); -} - -void EditingStyle::mergeInlineStyleOfElement( - HTMLElement* element, - CSSPropertyOverrideMode mode, - PropertiesToInclude propertiesToInclude) { - DCHECK(element); - if (!element->inlineStyle()) - return; - - switch (propertiesToInclude) { - case AllProperties: - mergeStyle(element->inlineStyle(), mode); - return; - case OnlyEditingInheritableProperties: - mergeStyle(copyEditingProperties(element->inlineStyle(), - OnlyInheritableEditingProperties), - mode); - return; - case EditingPropertiesInEffect: - mergeStyle( - copyEditingProperties(element->inlineStyle(), AllEditingProperties), - mode); - return; - } -} - -static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl( - const HTMLElementEquivalent* equivalent, - const Element* element, - EditingStyle::CSSPropertyOverrideMode mode, - StylePropertySet* style) { - return equivalent->matches(element) && - (!element->inlineStyle() || - !equivalent->propertyExistsInStyle(element->inlineStyle())) && - (mode == EditingStyle::OverrideValues || - !equivalent->propertyExistsInStyle(style)); -} - -static MutableStylePropertySet* extractEditingProperties( - const StylePropertySet* style, - EditingStyle::PropertiesToInclude propertiesToInclude) { - if (!style) - return nullptr; - - switch (propertiesToInclude) { - case EditingStyle::AllProperties: - case EditingStyle::EditingPropertiesInEffect: - return copyEditingProperties(style, AllEditingProperties); - case EditingStyle::OnlyEditingInheritableProperties: - return copyEditingProperties(style, OnlyInheritableEditingProperties); - } - - NOTREACHED(); - return nullptr; -} - -void EditingStyle::mergeInlineAndImplicitStyleOfElement( - Element* element, - CSSPropertyOverrideMode mode, - PropertiesToInclude propertiesToInclude) { - EditingStyle* styleFromRules = EditingStyle::create(); - styleFromRules->mergeStyleFromRulesForSerialization(element); - - if (element->inlineStyle()) { - styleFromRules->m_mutableStyle->mergeAndOverrideOnConflict( - element->inlineStyle()); - } - - styleFromRules->m_mutableStyle = extractEditingProperties( - styleFromRules->m_mutableStyle.get(), propertiesToInclude); - mergeStyle(styleFromRules->m_mutableStyle.get(), mode); - - const HeapVector<Member<HTMLElementEquivalent>>& elementEquivalents = - htmlElementEquivalents(); - for (const auto& equivalent : elementEquivalents) { - if (elementMatchesAndPropertyIsNotInInlineStyleDecl( - equivalent.get(), element, mode, m_mutableStyle.get())) - equivalent->addToStyle(element, this); - } - - const HeapVector<Member<HTMLAttributeEquivalent>>& attributeEquivalents = - htmlAttributeEquivalents(); - for (const auto& attribute : attributeEquivalents) { - if (attribute->attributeName() == HTMLNames::dirAttr) - continue; // We don't want to include directionality - if (elementMatchesAndPropertyIsNotInInlineStyleDecl( - attribute.get(), element, mode, m_mutableStyle.get())) - attribute->addToStyle(element, this); - } -} - -EditingStyle* EditingStyle::wrappingStyleForAnnotatedSerialization( +EditingStyle* EditingStyleUtilities::wrappingStyleForAnnotatedSerialization( ContainerNode* context) { EditingStyle* wrappingStyle = EditingStyle::create(context, EditingStyle::EditingPropertiesInEffect); @@ -1277,7 +67,7 @@ return wrappingStyle; } -EditingStyle* EditingStyle::wrappingStyleForSerialization( +EditingStyle* EditingStyleUtilities::wrappingStyleForSerialization( ContainerNode* context) { DCHECK(context); EditingStyle* wrappingStyle = EditingStyle::create(); @@ -1297,246 +87,7 @@ return wrappingStyle; } -static const CSSValueList& mergeTextDecorationValues( - const CSSValueList& mergedValue, - const CSSValueList& valueToMerge) { - DEFINE_STATIC_LOCAL(CSSIdentifierValue, underline, - (CSSIdentifierValue::create(CSSValueUnderline))); - DEFINE_STATIC_LOCAL(CSSIdentifierValue, lineThrough, - (CSSIdentifierValue::create(CSSValueLineThrough))); - CSSValueList& result = *mergedValue.copy(); - if (valueToMerge.hasValue(underline) && !mergedValue.hasValue(underline)) - result.append(underline); - - if (valueToMerge.hasValue(lineThrough) && !mergedValue.hasValue(lineThrough)) - result.append(lineThrough); - - return result; -} - -void EditingStyle::mergeStyle(const StylePropertySet* style, - CSSPropertyOverrideMode mode) { - if (!style) - return; - - if (!m_mutableStyle) { - m_mutableStyle = style->mutableCopy(); - return; - } - - unsigned propertyCount = style->propertyCount(); - for (unsigned i = 0; i < propertyCount; ++i) { - StylePropertySet::PropertyReference property = style->propertyAt(i); - const CSSValue* value = m_mutableStyle->getPropertyCSSValue(property.id()); - - // text decorations never override values - if ((property.id() == textDecorationPropertyForEditing() || - property.id() == CSSPropertyWebkitTextDecorationsInEffect) && - property.value().isValueList() && value) { - if (value->isValueList()) { - const CSSValueList& result = mergeTextDecorationValues( - *toCSSValueList(value), toCSSValueList(property.value())); - m_mutableStyle->setProperty(property.id(), result, - property.isImportant()); - continue; - } - // text-decoration: none is equivalent to not having the property - value = nullptr; - } - - if (mode == OverrideValues || (mode == DoNotOverrideValues && !value)) - m_mutableStyle->setProperty(property.toCSSProperty()); - } -} - -static MutableStylePropertySet* styleFromMatchedRulesForElement( - Element* element, - unsigned rulesToInclude) { - MutableStylePropertySet* style = - MutableStylePropertySet::create(HTMLQuirksMode); - StyleRuleList* matchedRules = - element->document().ensureStyleResolver().styleRulesForElement( - element, rulesToInclude); - if (matchedRules) { - for (unsigned i = 0; i < matchedRules->size(); ++i) - style->mergeAndOverrideOnConflict(&matchedRules->at(i)->properties()); - } - return style; -} - -void EditingStyle::mergeStyleFromRules(Element* element) { - MutableStylePropertySet* styleFromMatchedRules = - styleFromMatchedRulesForElement( - element, - StyleResolver::AuthorCSSRules | StyleResolver::CrossOriginCSSRules); - // Styles from the inline style declaration, held in the variable "style", - // take precedence over those from matched rules. - if (m_mutableStyle) - styleFromMatchedRules->mergeAndOverrideOnConflict(m_mutableStyle.get()); - - clear(); - m_mutableStyle = styleFromMatchedRules; -} - -void EditingStyle::mergeStyleFromRulesForSerialization(Element* element) { - mergeStyleFromRules(element); - - // The property value, if it's a percentage, may not reflect the actual - // computed value. - // For example: style="height: 1%; overflow: visible;" in quirksmode - // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot - // copy/paste fidelity problem - CSSComputedStyleDeclaration* computedStyleForElement = - CSSComputedStyleDeclaration::create(element); - MutableStylePropertySet* fromComputedStyle = - MutableStylePropertySet::create(HTMLQuirksMode); - { - unsigned propertyCount = m_mutableStyle->propertyCount(); - for (unsigned i = 0; i < propertyCount; ++i) { - StylePropertySet::PropertyReference property = - m_mutableStyle->propertyAt(i); - const CSSValue& value = property.value(); - if (!value.isPrimitiveValue()) - continue; - if (toCSSPrimitiveValue(value).isPercentage()) { - if (const CSSValue* computedPropertyValue = - computedStyleForElement->getPropertyCSSValue(property.id())) { - fromComputedStyle->addRespectingCascade( - CSSProperty(property.id(), *computedPropertyValue)); - } - } - } - } - m_mutableStyle->mergeAndOverrideOnConflict(fromComputedStyle); -} - -static void removePropertiesInStyle( - MutableStylePropertySet* styleToRemovePropertiesFrom, - StylePropertySet* style) { - unsigned propertyCount = style->propertyCount(); - Vector<CSSPropertyID> propertiesToRemove(propertyCount); - for (unsigned i = 0; i < propertyCount; ++i) - propertiesToRemove[i] = style->propertyAt(i).id(); - - styleToRemovePropertiesFrom->removePropertiesInSet(propertiesToRemove.data(), - propertiesToRemove.size()); -} - -void EditingStyle::removeStyleFromRulesAndContext(Element* element, - ContainerNode* context) { - DCHECK(element); - if (!m_mutableStyle) - return; - - // StyleResolver requires clean style. - DCHECK_GE(element->document().lifecycle().state(), - DocumentLifecycle::StyleClean); - DCHECK(element->document().isActive()); - - // 1. Remove style from matched rules because style remain without repeating - // it in inline style declaration - MutableStylePropertySet* styleFromMatchedRules = - styleFromMatchedRulesForElement(element, - StyleResolver::AllButEmptyCSSRules); - if (styleFromMatchedRules && !styleFromMatchedRules->isEmpty()) { - m_mutableStyle = - getPropertiesNotIn(m_mutableStyle.get(), - styleFromMatchedRules->ensureCSSStyleDeclaration()); - } - - // 2. Remove style present in context and not overriden by matched rules. - EditingStyle* computedStyle = - EditingStyle::create(context, EditingPropertiesInEffect); - if (computedStyle->m_mutableStyle) { - if (!computedStyle->m_mutableStyle->getPropertyCSSValue( - CSSPropertyBackgroundColor)) { - computedStyle->m_mutableStyle->setProperty(CSSPropertyBackgroundColor, - CSSValueTransparent); - } - - removePropertiesInStyle(computedStyle->m_mutableStyle.get(), - styleFromMatchedRules); - m_mutableStyle = getPropertiesNotIn( - m_mutableStyle.get(), - computedStyle->m_mutableStyle->ensureCSSStyleDeclaration()); - } - - // 3. If this element is a span and has display: inline or float: none, remove - // them unless they are overriden by rules. These rules are added by - // serialization code to wrap text nodes. - if (isStyleSpanOrSpanWithOnlyStyleAttribute(element)) { - if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyDisplay) && - getIdentifierValue(m_mutableStyle.get(), CSSPropertyDisplay) == - CSSValueInline) - m_mutableStyle->removeProperty(CSSPropertyDisplay); - if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyFloat) && - getIdentifierValue(m_mutableStyle.get(), CSSPropertyFloat) == - CSSValueNone) - m_mutableStyle->removeProperty(CSSPropertyFloat); - } -} - -void EditingStyle::removePropertiesInElementDefaultStyle(Element* element) { - if (!m_mutableStyle || m_mutableStyle->isEmpty()) - return; - - StylePropertySet* defaultStyle = styleFromMatchedRulesForElement( - element, StyleResolver::UAAndUserCSSRules); - - removePropertiesInStyle(m_mutableStyle.get(), defaultStyle); -} - -void EditingStyle::addAbsolutePositioningFromElement(const Element& element) { - LayoutRect rect = element.boundingBox(); - LayoutObject* layoutObject = element.layoutObject(); - - LayoutUnit x = rect.x(); - LayoutUnit y = rect.y(); - LayoutUnit width = rect.width(); - LayoutUnit height = rect.height(); - if (layoutObject && layoutObject->isBox()) { - LayoutBox* layoutBox = toLayoutBox(layoutObject); - - x -= layoutBox->marginLeft(); - y -= layoutBox->marginTop(); - - m_mutableStyle->setProperty(CSSPropertyBoxSizing, CSSValueBorderBox); - } - - m_mutableStyle->setProperty(CSSPropertyPosition, CSSValueAbsolute); - m_mutableStyle->setProperty( - CSSPropertyLeft, - *CSSPrimitiveValue::create(x, CSSPrimitiveValue::UnitType::Pixels)); - m_mutableStyle->setProperty( - CSSPropertyTop, - *CSSPrimitiveValue::create(y, CSSPrimitiveValue::UnitType::Pixels)); - m_mutableStyle->setProperty( - CSSPropertyWidth, - *CSSPrimitiveValue::create(width, CSSPrimitiveValue::UnitType::Pixels)); - m_mutableStyle->setProperty( - CSSPropertyHeight, - *CSSPrimitiveValue::create(height, CSSPrimitiveValue::UnitType::Pixels)); -} - -void EditingStyle::forceInline() { - if (!m_mutableStyle) - m_mutableStyle = MutableStylePropertySet::create(HTMLQuirksMode); - const bool propertyIsImportant = true; - m_mutableStyle->setProperty(CSSPropertyDisplay, CSSValueInline, - propertyIsImportant); -} - -int EditingStyle::legacyFontSize(Document* document) const { - const CSSValue* cssValue = - m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize); - if (!cssValue || - !(cssValue->isPrimitiveValue() || cssValue->isIdentifierValue())) - return 0; - return legacyFontSizeFromCSSValue(document, cssValue, m_isMonospaceFont, - AlwaysUseLegacyFontSize); -} - -EditingStyle* EditingStyle::styleAtSelectionStart( +EditingStyle* EditingStyleUtilities::styleAtSelectionStart( const VisibleSelection& selection, bool shouldUseBackgroundColorInEffect, MutableStylePropertySet* styleToCheck) { @@ -1585,7 +136,7 @@ if (getIdentifierValue(elementStyle, CSSPropertyVerticalAlign) == CSSValueBaseline && hasAncestorVerticalAlignStyle(*element, valueID)) - style->m_mutableStyle->setProperty(CSSPropertyVerticalAlign, valueID); + style->style()->setProperty(CSSPropertyVerticalAlign, valueID); } // If background color is transparent, traverse parent nodes until we hit a @@ -1593,8 +144,7 @@ // the background color at the start of selection, and find the background // color of the common ancestor. if (shouldUseBackgroundColorInEffect && - (selection.isRange() || - hasTransparentBackgroundColor(style->m_mutableStyle.get()))) { + (selection.isRange() || hasTransparentBackgroundColor(style->style()))) { const EphemeralRange range(selection.toNormalizedEphemeralRange()); if (const CSSValue* value = backgroundColorValueInEffect(Range::commonAncestorContainer( @@ -1614,7 +164,7 @@ valueID == CSSValueIsolateOverride || valueID == CSSValuePlaintext; } -WritingDirection EditingStyle::textDirectionForSelection( +WritingDirection EditingStyleUtilities::textDirectionForSelection( const VisibleSelection& selection, EditingStyle* typingStyle, bool& hasNestedOrMultipleEmbeddings) { @@ -1717,318 +267,7 @@ return foundDirection; } -DEFINE_TRACE(EditingStyle) { - visitor->trace(m_mutableStyle); -} - -static void reconcileTextDecorationProperties(MutableStylePropertySet* style) { - const CSSValue* textDecorationsInEffect = - style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect); - const CSSValue* textDecoration = - style->getPropertyCSSValue(textDecorationPropertyForEditing()); - // "LayoutTests/editing/execCommand/insert-list-and-strikethrough.html" makes - // both |textDecorationsInEffect| and |textDecoration| non-null. - if (textDecorationsInEffect) { - style->setProperty(textDecorationPropertyForEditing(), - textDecorationsInEffect->cssText()); - style->removeProperty(CSSPropertyWebkitTextDecorationsInEffect); - textDecoration = textDecorationsInEffect; - } - - // If text-decoration is set to "none", remove the property because we don't - // want to add redundant "text-decoration: none". - if (textDecoration && !textDecoration->isValueList()) - style->removeProperty(textDecorationPropertyForEditing()); -} - -StyleChange::StyleChange(EditingStyle* style, const Position& position) - : m_applyBold(false), - m_applyItalic(false), - m_applyUnderline(false), - m_applyLineThrough(false), - m_applySubscript(false), - m_applySuperscript(false) { - Document* document = position.document(); - if (!style || !style->style() || !document || !document->frame() || - !associatedElementOf(position)) - return; - - CSSComputedStyleDeclaration* computedStyle = ensureComputedStyle(position); - // FIXME: take care of background-color in effect - MutableStylePropertySet* mutableStyle = - getPropertiesNotIn(style->style(), computedStyle); - DCHECK(mutableStyle); - - reconcileTextDecorationProperties(mutableStyle); - if (!document->frame()->editor().shouldStyleWithCSS()) - extractTextStyles(document, mutableStyle, computedStyle->isMonospaceFont()); - - // Changing the whitespace style in a tab span would collapse the tab into a - // space. - if (isTabHTMLSpanElementTextNode(position.anchorNode()) || - isTabHTMLSpanElement((position.anchorNode()))) - mutableStyle->removeProperty(CSSPropertyWhiteSpace); - - // If unicode-bidi is present in mutableStyle and direction is not, then add - // direction to mutableStyle. - // FIXME: Shouldn't this be done in getPropertiesNotIn? - if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) && - !style->style()->getPropertyCSSValue(CSSPropertyDirection)) { - mutableStyle->setProperty( - CSSPropertyDirection, - style->style()->getPropertyValue(CSSPropertyDirection)); - } - - // Save the result for later - m_cssStyle = mutableStyle->asText().stripWhiteSpace(); -} - -static void setTextDecorationProperty(MutableStylePropertySet* style, - const CSSValueList* newTextDecoration, - CSSPropertyID propertyID) { - if (newTextDecoration->length()) { - style->setProperty(propertyID, newTextDecoration->cssText(), - style->propertyIsImportant(propertyID)); - } else { - // text-decoration: none is redundant since it does not remove any text - // decorations. - style->removeProperty(propertyID); - } -} - -void StyleChange::extractTextStyles(Document* document, - MutableStylePropertySet* style, - bool isMonospaceFont) { - DCHECK(style); - - if (getIdentifierValue(style, CSSPropertyFontWeight) == CSSValueBold) { - style->removeProperty(CSSPropertyFontWeight); - m_applyBold = true; - } - - int fontStyle = getIdentifierValue(style, CSSPropertyFontStyle); - if (fontStyle == CSSValueItalic || fontStyle == CSSValueOblique) { - style->removeProperty(CSSPropertyFontStyle); - m_applyItalic = true; - } - - // Assuming reconcileTextDecorationProperties has been called, there should - // not be -webkit-text-decorations-in-effect - // Furthermore, text-decoration: none has been trimmed so that text-decoration - // property is always a CSSValueList. - const CSSValue* textDecoration = - style->getPropertyCSSValue(textDecorationPropertyForEditing()); - if (textDecoration && textDecoration->isValueList()) { - DEFINE_STATIC_LOCAL(CSSIdentifierValue, underline, - (CSSIdentifierValue::create(CSSValueUnderline))); - DEFINE_STATIC_LOCAL(CSSIdentifierValue, lineThrough, - (CSSIdentifierValue::create(CSSValueLineThrough))); - CSSValueList* newTextDecoration = toCSSValueList(textDecoration)->copy(); - if (newTextDecoration->removeAll(underline)) - m_applyUnderline = true; - if (newTextDecoration->removeAll(lineThrough)) - m_applyLineThrough = true; - - // If trimTextDecorations, delete underline and line-through - setTextDecorationProperty(style, newTextDecoration, - textDecorationPropertyForEditing()); - } - - int verticalAlign = getIdentifierValue(style, CSSPropertyVerticalAlign); - switch (verticalAlign) { - case CSSValueSub: - style->removeProperty(CSSPropertyVerticalAlign); - m_applySubscript = true; - break; - case CSSValueSuper: - style->removeProperty(CSSPropertyVerticalAlign); - m_applySuperscript = true; - break; - } - - if (style->getPropertyCSSValue(CSSPropertyColor)) { - m_applyFontColor = getFontColor(style).serialized(); - style->removeProperty(CSSPropertyColor); - } - - m_applyFontFace = style->getPropertyValue(CSSPropertyFontFamily); - // Remove double quotes for Outlook 2007 compatibility. See - // https://bugs.webkit.org/show_bug.cgi?id=79448 - m_applyFontFace.replace('"', ""); - style->removeProperty(CSSPropertyFontFamily); - - if (const CSSValue* fontSize = - style->getPropertyCSSValue(CSSPropertyFontSize)) { - if (!fontSize->isPrimitiveValue() && !fontSize->isIdentifierValue()) { - // Can't make sense of the number. Put no font size. - style->removeProperty(CSSPropertyFontSize); - } else if (int legacyFontSize = legacyFontSizeFromCSSValue( - document, fontSize, isMonospaceFont, - UseLegacyFontSizeOnlyIfPixelValuesMatch)) { - m_applyFontSize = String::number(legacyFontSize); - style->removeProperty(CSSPropertyFontSize); - } - } -} - -static void diffTextDecorations(MutableStylePropertySet* style, - CSSPropertyID propertyID, - const CSSValue* refTextDecoration) { - const CSSValue* textDecoration = style->getPropertyCSSValue(propertyID); - if (!textDecoration || !textDecoration->isValueList() || !refTextDecoration || - !refTextDecoration->isValueList()) - return; - - CSSValueList* newTextDecoration = toCSSValueList(textDecoration)->copy(); - const CSSValueList* valuesInRefTextDecoration = - toCSSValueList(refTextDecoration); - - for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++) - newTextDecoration->removeAll(valuesInRefTextDecoration->item(i)); - - setTextDecorationProperty(style, newTextDecoration, propertyID); -} - -static bool fontWeightIsBold(const CSSValue* fontWeight) { - if (!fontWeight->isIdentifierValue()) - return false; - - // Because b tag can only bold text, there are only two states in plain html: - // bold and not bold. Collapse all other values to either one of these two - // states for editing purposes. - switch (toCSSIdentifierValue(fontWeight)->getValueID()) { - case CSSValue100: - case CSSValue200: - case CSSValue300: - case CSSValue400: - case CSSValue500: - case CSSValueNormal: - return false; - case CSSValueBold: - case CSSValue600: - case CSSValue700: - case CSSValue800: - case CSSValue900: - return true; - default: - break; - } - - NOTREACHED(); // For CSSValueBolder and CSSValueLighter - return false; -} - -static bool fontWeightNeedsResolving(const CSSValue* fontWeight) { - if (!fontWeight->isIdentifierValue()) - return true; - - const CSSValueID value = toCSSIdentifierValue(fontWeight)->getValueID(); - return value == CSSValueLighter || value == CSSValueBolder; -} - -MutableStylePropertySet* getPropertiesNotIn( - StylePropertySet* styleWithRedundantProperties, - CSSStyleDeclaration* baseStyle) { - DCHECK(styleWithRedundantProperties); - DCHECK(baseStyle); - MutableStylePropertySet* result = styleWithRedundantProperties->mutableCopy(); - - result->removeEquivalentProperties(baseStyle); - - const CSSValue* baseTextDecorationsInEffect = - baseStyle->getPropertyCSSValueInternal( - CSSPropertyWebkitTextDecorationsInEffect); - diffTextDecorations(result, textDecorationPropertyForEditing(), - baseTextDecorationsInEffect); - diffTextDecorations(result, CSSPropertyWebkitTextDecorationsInEffect, - baseTextDecorationsInEffect); - - if (const CSSValue* baseFontWeight = - baseStyle->getPropertyCSSValueInternal(CSSPropertyFontWeight)) { - if (const CSSValue* fontWeight = - result->getPropertyCSSValue(CSSPropertyFontWeight)) { - if (!fontWeightNeedsResolving(fontWeight) && - !fontWeightNeedsResolving(baseFontWeight) && - (fontWeightIsBold(fontWeight) == fontWeightIsBold(baseFontWeight))) - result->removeProperty(CSSPropertyFontWeight); - } - } - - if (baseStyle->getPropertyCSSValueInternal(CSSPropertyColor) && - getFontColor(result) == getFontColor(baseStyle)) - result->removeProperty(CSSPropertyColor); - - if (baseStyle->getPropertyCSSValueInternal(CSSPropertyTextAlign) && - textAlignResolvingStartAndEnd(result) == - textAlignResolvingStartAndEnd(baseStyle)) - result->removeProperty(CSSPropertyTextAlign); - - if (baseStyle->getPropertyCSSValueInternal(CSSPropertyBackgroundColor) && - getBackgroundColor(result) == getBackgroundColor(baseStyle)) - result->removeProperty(CSSPropertyBackgroundColor); - - return result; -} - -CSSValueID getIdentifierValue(StylePropertySet* style, - CSSPropertyID propertyID) { - if (!style) - return CSSValueInvalid; - const CSSValue* value = style->getPropertyCSSValue(propertyID); - if (!value || !value->isIdentifierValue()) - return CSSValueInvalid; - return toCSSIdentifierValue(value)->getValueID(); -} - -CSSValueID getIdentifierValue(CSSStyleDeclaration* style, - CSSPropertyID propertyID) { - if (!style) - return CSSValueInvalid; - const CSSValue* value = style->getPropertyCSSValueInternal(propertyID); - if (!value || !value->isIdentifierValue()) - return CSSValueInvalid; - return toCSSIdentifierValue(value)->getValueID(); -} - -int legacyFontSizeFromCSSValue(Document* document, - const CSSValue* value, - bool isMonospaceFont, - LegacyFontSizeMode mode) { - if (value->isPrimitiveValue()) { - const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(*value); - CSSPrimitiveValue::LengthUnitType lengthType; - if (CSSPrimitiveValue::unitTypeToLengthUnitType( - primitiveValue.typeWithCalcResolved(), lengthType) && - lengthType == CSSPrimitiveValue::UnitTypePixels) { - double conversion = - CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor( - primitiveValue.typeWithCalcResolved()); - int pixelFontSize = - clampTo<int>(primitiveValue.getDoubleValue() * conversion); - int legacyFontSize = - FontSize::legacyFontSize(document, pixelFontSize, isMonospaceFont); - // Use legacy font size only if pixel value matches exactly to that of - // legacy font size. - if (mode == AlwaysUseLegacyFontSize || - FontSize::fontSizeForKeyword(document, legacyFontSize, - isMonospaceFont) == pixelFontSize) - return legacyFontSize; - - return 0; - } - } - - if (value->isIdentifierValue()) { - const CSSIdentifierValue& identifierValue = toCSSIdentifierValue(*value); - if (CSSValueXSmall <= identifierValue.getValueID() && - identifierValue.getValueID() <= CSSValueWebkitXxxLarge) - return identifierValue.getValueID() - CSSValueXSmall + 1; - } - - return 0; -} - -bool isTransparentColorValue(const CSSValue* cssValue) { +bool EditingStyleUtilities::isTransparentColorValue(const CSSValue* cssValue) { if (!cssValue) return true; if (cssValue->isColorValue()) @@ -2038,19 +277,22 @@ return toCSSIdentifierValue(cssValue)->getValueID() == CSSValueTransparent; } -bool hasTransparentBackgroundColor(CSSStyleDeclaration* style) { +bool EditingStyleUtilities::hasTransparentBackgroundColor( + CSSStyleDeclaration* style) { const CSSValue* cssValue = style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor); return isTransparentColorValue(cssValue); } -bool hasTransparentBackgroundColor(StylePropertySet* style) { +bool EditingStyleUtilities::hasTransparentBackgroundColor( + StylePropertySet* style) { const CSSValue* cssValue = style->getPropertyCSSValue(CSSPropertyBackgroundColor); return isTransparentColorValue(cssValue); } -const CSSValue* backgroundColorValueInEffect(Node* node) { +const CSSValue* EditingStyleUtilities::backgroundColorValueInEffect( + Node* node) { for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) { CSSComputedStyleDeclaration* ancestorStyle = CSSComputedStyleDeclaration::create(ancestor);
diff --git a/third_party/WebKit/Source/core/editing/EditingStyleUtilities.h b/third_party/WebKit/Source/core/editing/EditingStyleUtilities.h index 6c8d53a0..0f4e7fa 100644 --- a/third_party/WebKit/Source/core/editing/EditingStyleUtilities.h +++ b/third_party/WebKit/Source/core/editing/EditingStyleUtilities.h
@@ -34,134 +34,24 @@ #include "core/CSSPropertyNames.h" #include "core/CSSValueKeywords.h" -#include "core/CoreExport.h" -#include "core/editing/Position.h" #include "core/editing/VisibleSelection.h" #include "core/editing/WritingDirection.h" -#include "platform/heap/Handle.h" -#include "wtf/Forward.h" -#include "wtf/TriState.h" -#include "wtf/Vector.h" -#include "wtf/text/WTFString.h" namespace blink { class CSSStyleDeclaration; -class CSSComputedStyleDeclaration; -class ContainerNode; -class Document; -class Element; -class HTMLElement; +class EditingStyle; class MutableStylePropertySet; class Node; -class QualifiedName; -class ComputedStyle; class StylePropertySet; -class CORE_EXPORT EditingStyle final : public GarbageCollected<EditingStyle> { +class EditingStyleUtilities { + STATIC_ONLY(EditingStyleUtilities); + public: - enum PropertiesToInclude { - AllProperties, - OnlyEditingInheritableProperties, - EditingPropertiesInEffect - }; - enum ShouldPreserveWritingDirection { - PreserveWritingDirection, - DoNotPreserveWritingDirection - }; - enum ShouldExtractMatchingStyle { - ExtractMatchingStyle, - DoNotExtractMatchingStyle - }; - static float NoFontDelta; - - static EditingStyle* create() { return new EditingStyle(); } - - static EditingStyle* create(ContainerNode* node, - PropertiesToInclude propertiesToInclude = - OnlyEditingInheritableProperties) { - return new EditingStyle(node, propertiesToInclude); - } - - static EditingStyle* create(const Position& position, - PropertiesToInclude propertiesToInclude = - OnlyEditingInheritableProperties) { - return new EditingStyle(position, propertiesToInclude); - } - - static EditingStyle* create(const StylePropertySet* style) { - return new EditingStyle(style); - } - - static EditingStyle* create(CSSPropertyID propertyID, const String& value) { - return new EditingStyle(propertyID, value); - } - - MutableStylePropertySet* style() { return m_mutableStyle.get(); } - bool textDirection(WritingDirection&) const; - bool isEmpty() const; - void overrideWithStyle(const StylePropertySet*); - void clear(); - EditingStyle* copy() const; - EditingStyle* extractAndRemoveBlockProperties(); - EditingStyle* extractAndRemoveTextDirection(); - void removeBlockProperties(); - void removeStyleAddedByElement(Element*); - void removeStyleConflictingWithStyleOfElement(Element*); - void collapseTextDecorationProperties(); - enum ShouldIgnoreTextOnlyProperties { - IgnoreTextOnlyProperties, - DoNotIgnoreTextOnlyProperties - }; - TriState triStateOfStyle(EditingStyle*) const; - TriState triStateOfStyle(const VisibleSelection&) const; - bool conflictsWithInlineStyleOfElement(HTMLElement* element) const { - return conflictsWithInlineStyleOfElement(element, 0, 0); - } - bool conflictsWithInlineStyleOfElement( - HTMLElement* element, - EditingStyle* extractedStyle, - Vector<CSSPropertyID>& conflictingProperties) const { - return conflictsWithInlineStyleOfElement(element, extractedStyle, - &conflictingProperties); - } - bool conflictsWithImplicitStyleOfElement( - HTMLElement*, - EditingStyle* extractedStyle = nullptr, - ShouldExtractMatchingStyle = DoNotExtractMatchingStyle) const; - bool conflictsWithImplicitStyleOfAttributes(HTMLElement*) const; - bool extractConflictingImplicitStyleOfAttributes( - HTMLElement*, - ShouldPreserveWritingDirection, - EditingStyle* extractedStyle, - Vector<QualifiedName>& conflictingAttributes, - ShouldExtractMatchingStyle) const; - bool styleIsPresentInComputedStyleOfNode(Node*) const; - - static bool elementIsStyledSpanOrHTMLEquivalent(const HTMLElement*); - - void prepareToApplyAt( - const Position&, - ShouldPreserveWritingDirection = DoNotPreserveWritingDirection); - void mergeTypingStyle(Document*); - enum CSSPropertyOverrideMode { OverrideValues, DoNotOverrideValues }; - void mergeInlineStyleOfElement(HTMLElement*, - CSSPropertyOverrideMode, - PropertiesToInclude = AllProperties); static EditingStyle* wrappingStyleForAnnotatedSerialization( ContainerNode* context); static EditingStyle* wrappingStyleForSerialization(ContainerNode* context); - void mergeStyleFromRules(Element*); - void mergeStyleFromRulesForSerialization(Element*); - void removeStyleFromRulesAndContext(Element*, ContainerNode* context); - void removePropertiesInElementDefaultStyle(Element*); - void addAbsolutePositioningFromElement(const Element&); - void forceInline(); - int legacyFontSize(Document*) const; - - float fontSizeDelta() const { return m_fontSizeDelta; } - bool hasFontSizeDelta() const { return m_fontSizeDelta != NoFontDelta; } - static EditingStyle* styleAtSelectionStart( const VisibleSelection&, bool shouldUseBackgroundColorInEffect = false, @@ -175,104 +65,13 @@ unicodeBidi == CSSValueWebkitIsolate || unicodeBidi == CSSValueEmbed; } - DECLARE_TRACE(); - - private: - EditingStyle() = default; - EditingStyle(ContainerNode*, PropertiesToInclude); - EditingStyle(const Position&, PropertiesToInclude); - explicit EditingStyle(const StylePropertySet*); - EditingStyle(CSSPropertyID, const String& value); - void init(Node*, PropertiesToInclude); - void removeInheritedColorsIfNeeded(const ComputedStyle*); - void setProperty(CSSPropertyID, const String& value, bool important = false); - void replaceFontSizeByKeywordIfPossible(const ComputedStyle*, - CSSComputedStyleDeclaration*); - void extractFontSizeDelta(); - TriState triStateOfStyle(CSSStyleDeclaration* styleToCompare, - ShouldIgnoreTextOnlyProperties) const; - bool conflictsWithInlineStyleOfElement( - HTMLElement*, - EditingStyle* extractedStyle, - Vector<CSSPropertyID>* conflictingProperties) const; - void mergeInlineAndImplicitStyleOfElement(Element*, - CSSPropertyOverrideMode, - PropertiesToInclude); - void mergeStyle(const StylePropertySet*, CSSPropertyOverrideMode); - - Member<MutableStylePropertySet> m_mutableStyle; - bool m_isMonospaceFont = false; - float m_fontSizeDelta = NoFontDelta; - bool m_isVerticalAlign = false; - - friend class HTMLElementEquivalent; - friend class HTMLAttributeEquivalent; + static bool isTransparentColorValue(const CSSValue*); + static bool hasTransparentBackgroundColor(CSSStyleDeclaration*); + static bool hasTransparentBackgroundColor(StylePropertySet*); + static const CSSValue* backgroundColorValueInEffect(Node*); + static bool hasAncestorVerticalAlignStyle(Node&, CSSValueID); }; -class StyleChange { - DISALLOW_NEW(); - - public: - StyleChange() - : m_applyBold(false), - m_applyItalic(false), - m_applyUnderline(false), - m_applyLineThrough(false), - m_applySubscript(false), - m_applySuperscript(false) {} - - StyleChange(EditingStyle*, const Position&); - - String cssStyle() const { return m_cssStyle; } - bool applyBold() const { return m_applyBold; } - bool applyItalic() const { return m_applyItalic; } - bool applyUnderline() const { return m_applyUnderline; } - bool applyLineThrough() const { return m_applyLineThrough; } - bool applySubscript() const { return m_applySubscript; } - bool applySuperscript() const { return m_applySuperscript; } - bool applyFontColor() const { return m_applyFontColor.length() > 0; } - bool applyFontFace() const { return m_applyFontFace.length() > 0; } - bool applyFontSize() const { return m_applyFontSize.length() > 0; } - - String fontColor() { return m_applyFontColor; } - String fontFace() { return m_applyFontFace; } - String fontSize() { return m_applyFontSize; } - - bool operator==(const StyleChange& other) { - return m_cssStyle == other.m_cssStyle && m_applyBold == other.m_applyBold && - m_applyItalic == other.m_applyItalic && - m_applyUnderline == other.m_applyUnderline && - m_applyLineThrough == other.m_applyLineThrough && - m_applySubscript == other.m_applySubscript && - m_applySuperscript == other.m_applySuperscript && - m_applyFontColor == other.m_applyFontColor && - m_applyFontFace == other.m_applyFontFace && - m_applyFontSize == other.m_applyFontSize; - } - bool operator!=(const StyleChange& other) { return !(*this == other); } - - private: - void extractTextStyles(Document*, - MutableStylePropertySet*, - bool isMonospaceFont); - - String m_cssStyle; - bool m_applyBold; - bool m_applyItalic; - bool m_applyUnderline; - bool m_applyLineThrough; - bool m_applySubscript; - bool m_applySuperscript; - String m_applyFontColor; - String m_applyFontFace; - String m_applyFontSize; -}; - -// FIXME: Remove these functions or make them non-global to discourage using -// CSSStyleDeclaration directly. -CSSValueID getIdentifierValue(CSSStyleDeclaration*, CSSPropertyID); -CSSValueID getIdentifierValue(StylePropertySet*, CSSPropertyID); - } // namespace blink #endif // EditingStyleUtilities_h
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.cpp b/third_party/WebKit/Source/core/events/MessageEvent.cpp index 2f3119c..97ca6f65 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.cpp +++ b/third_party/WebKit/Source/core/events/MessageEvent.cpp
@@ -198,6 +198,28 @@ ->registerMemoryAllocatedWithCurrentScriptContext(); } +void MessageEvent::initMessageEvent(const AtomicString& type, + bool canBubble, + bool cancelable, + const String& data, + const String& origin, + const String& lastEventId, + EventTarget* source, + MessagePortArray* ports) { + if (isBeingDispatched()) + return; + + initEvent(type, canBubble, cancelable); + + m_dataType = DataTypeString; + m_dataAsString = data; + m_origin = origin; + m_lastEventId = lastEventId; + m_source = source; + m_ports = ports; + m_suborigin = ""; +} + const AtomicString& MessageEvent::interfaceName() const { return EventNames::MessageEvent; }
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.h b/third_party/WebKit/Source/core/events/MessageEvent.h index de9700cad..f497a484 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.h +++ b/third_party/WebKit/Source/core/events/MessageEvent.h
@@ -108,6 +108,14 @@ const String& lastEventId, EventTarget* source, MessagePortArray*); + void initMessageEvent(const AtomicString& type, + bool canBubble, + bool cancelable, + const String& data, + const String& origin, + const String& lastEventId, + EventTarget* source, + MessagePortArray*); const String& origin() const { return m_origin; } const String& suborigin() const { return m_suborigin; }
diff --git a/third_party/WebKit/Source/core/html/HTMLAttributeNames.in b/third_party/WebKit/Source/core/html/HTMLAttributeNames.in new file mode 100644 index 0000000..d7670e9 --- /dev/null +++ b/third_party/WebKit/Source/core/html/HTMLAttributeNames.in
@@ -0,0 +1,348 @@ +namespace="HTML" +namespacePrefix="xhtml" +namespaceURI="http://www.w3.org/1999/xhtml" +attrsNullNamespace +export="CORE_EXPORT" + +abbr +accept-charset +accept +accesskey +action +align +alink +allowfullscreen +allowpaymentrequest +alt +archive +aria-activedescendant +aria-atomic +aria-autocomplete +aria-busy +aria-checked +aria-colcount +aria-colindex +aria-colspan +aria-controls +aria-current +aria-describedby +aria-details +aria-disabled +aria-dropeffect +aria-errormessage +aria-expanded +aria-flowto +aria-grabbed +aria-haspopup +aria-help +aria-hidden +aria-invalid +aria-keyshortcuts +aria-label +aria-labeledby +aria-labelledby +aria-level +aria-live +aria-modal +aria-multiline +aria-multiselectable +aria-orientation +aria-owns +aria-placeholder +aria-posinset +aria-pressed +aria-readonly +aria-relevant +aria-required +aria-roledescription +aria-rowcount +aria-rowindex +aria-rowspan +aria-selected +aria-setsize +aria-sort +aria-valuemax +aria-valuemin +aria-valuenow +aria-valuetext +as +async +autocapitalize +autocomplete +autocorrect +autofocus +autoplay +axis +background +behavior +bgcolor +border +bordercolor +capture +cellpadding +cellspacing +char +challenge +charoff +charset +checked +cite +class +classid +clear +code +codebase +codetype +color +cols +colspan +compact +content +contenteditable +contextmenu +controls +coords +crossorigin +csp +data +datetime +declare +default +defer +dir +direction +dirname +disabled +disableremoteplayback +download +draggable +webkitdropzone +enctype +end +event +face +for +form +formaction +formenctype +formmethod +formnovalidate +formtarget +frame +frameborder +headers +height +hidden +high +href +hreflang +hspace +http-equiv +icon +id +incremental +inputmode +integrity +is +ismap +keytype +kind +label +lang +language +leftmargin +link +list +longdesc +loop +low +lowsrc +manifest +marginheight +marginwidth +max +maxlength +mayscript +media +method +min +minlength +multiple +muted +name +nohref +nonce +noresize +noshade +novalidate +nowrap +object +onabort +onanimationstart +onanimationiteration +onanimationend +onauxclick +onbeforecopy +onbeforecut +onbeforepaste +onbeforeunload +onblur +oncancel +oncanplay +oncanplaythrough +onchange +onclick +onclose +oncontextmenu +oncopy +oncuechange +oncut +ondblclick +ondrag +ondragend +ondragenter +ondragleave +ondragover +ondragstart +ondrop +ondurationchange +onemptied +onended +onerror +onfocus +onfocusin +onfocusout +ongotpointercapture +onhashchange +oninput +oninvalid +onkeydown +onkeypress +onkeyup +onlanguagechange +onload +onloadeddata +onloadedmetadata +onloadstart +onlostpointercapture +onmessage +onmousedown +onmouseenter +onmouseleave +onmousemove +onmouseout +onmouseover +onmouseup +onmousewheel +ononline +onoffline +onorientationchange +onpagehide +onpageshow +onpaste +onpause +onplay +onplaying +onpointercancel +onpointerdown +onpointerenter +onpointerleave +onpointermove +onpointerout +onpointerover +onpointerup +onpopstate +onprogress +onratechange +onreset +onresize +onscroll +onsearch +onseeked +onseeking +onselect +onselectstart +onselectionchange +onshow +onstalled +onstorage +onsuspend +onsubmit +ontimeupdate +ontoggle +ontouchstart +ontouchmove +ontouchend +ontouchcancel +ontransitionend +onunload +onvolumechange +onwaiting +onwebkitanimationstart +onwebkitanimationiteration +onwebkitanimationend +onwebkitfullscreenchange +onwebkitfullscreenerror +onwebkittransitionend +onwheel +open +optimum +pattern +permissions +placeholder +ping +poster +preload +pseudo +radiogroup +readonly +referrerpolicy +rel +required +rev +reversed +role +rows +rowspan +rules +sandbox +scheme +scope +scrollamount +scrolldelay +scrolling +select +selected +shape +size +sizes +slot +span +spellcheck +src +srcset +srcdoc +srclang +standby +start +step +style +summary +tabindex +target +text +title +topmargin +translate +truespeed +type +usemap +valign +value +valuetype +version +vlink +vspace +webkitdirectory +width +wrap
diff --git a/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5 b/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5 deleted file mode 100644 index 0ad4d65e..0000000 --- a/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5 +++ /dev/null
@@ -1,354 +0,0 @@ -{ - metadata: { - namespace: "HTML", - namespacePrefix: "xhtml", - namespaceURI: "http://www.w3.org/1999/xhtml", - attrsNullNamespace: true, - export: "CORE_EXPORT", - }, - - data: [ - "abbr", - "accept-charset", - "accept", - "accesskey", - "action", - "align", - "alink", - "allowfullscreen", - "allowpaymentrequest", - "alt", - "archive", - "aria-activedescendant", - "aria-atomic", - "aria-autocomplete", - "aria-busy", - "aria-checked", - "aria-colcount", - "aria-colindex", - "aria-colspan", - "aria-controls", - "aria-current", - "aria-describedby", - "aria-details", - "aria-disabled", - "aria-dropeffect", - "aria-errormessage", - "aria-expanded", - "aria-flowto", - "aria-grabbed", - "aria-haspopup", - "aria-help", - "aria-hidden", - "aria-invalid", - "aria-keyshortcuts", - "aria-label", - "aria-labeledby", - "aria-labelledby", - "aria-level", - "aria-live", - "aria-modal", - "aria-multiline", - "aria-multiselectable", - "aria-orientation", - "aria-owns", - "aria-placeholder", - "aria-posinset", - "aria-pressed", - "aria-readonly", - "aria-relevant", - "aria-required", - "aria-roledescription", - "aria-rowcount", - "aria-rowindex", - "aria-rowspan", - "aria-selected", - "aria-setsize", - "aria-sort", - "aria-valuemax", - "aria-valuemin", - "aria-valuenow", - "aria-valuetext", - "as", - "async", - "autocapitalize", - "autocomplete", - "autocorrect", - "autofocus", - "autoplay", - "axis", - "background", - "behavior", - "bgcolor", - "border", - "bordercolor", - "capture", - "cellpadding", - "cellspacing", - "char", - "challenge", - "charoff", - "charset", - "checked", - "cite", - "class", - "classid", - "clear", - "code", - "codebase", - "codetype", - "color", - "cols", - "colspan", - "compact", - "content", - "contenteditable", - "contextmenu", - "controls", - "coords", - "crossorigin", - "csp", - "data", - "datetime", - "declare", - "default", - "defer", - "dir", - "direction", - "dirname", - "disabled", - "disableremoteplayback", - "download", - "draggable", - "webkitdropzone", - "enctype", - "end", - "event", - "face", - "for", - "form", - "formaction", - "formenctype", - "formmethod", - "formnovalidate", - "formtarget", - "frame", - "frameborder", - "headers", - "height", - "hidden", - "high", - "href", - "hreflang", - "hspace", - "http-equiv", - "icon", - "id", - "incremental", - "inputmode", - "integrity", - "is", - "ismap", - "keytype", - "kind", - "label", - "lang", - "language", - "leftmargin", - "link", - "list", - "longdesc", - "loop", - "low", - "lowsrc", - "manifest", - "marginheight", - "marginwidth", - "max", - "maxlength", - "mayscript", - "media", - "method", - "min", - "minlength", - "multiple", - "muted", - "name", - "nohref", - "nonce", - "noresize", - "noshade", - "novalidate", - "nowrap", - "object", - "onabort", - "onanimationstart", - "onanimationiteration", - "onanimationend", - "onauxclick", - "onbeforecopy", - "onbeforecut", - "onbeforepaste", - "onbeforeunload", - "onblur", - "oncancel", - "oncanplay", - "oncanplaythrough", - "onchange", - "onclick", - "onclose", - "oncontextmenu", - "oncopy", - "oncuechange", - "oncut", - "ondblclick", - "ondrag", - "ondragend", - "ondragenter", - "ondragleave", - "ondragover", - "ondragstart", - "ondrop", - "ondurationchange", - "onemptied", - "onended", - "onerror", - "onfocus", - "onfocusin", - "onfocusout", - "ongotpointercapture", - "onhashchange", - "oninput", - "oninvalid", - "onkeydown", - "onkeypress", - "onkeyup", - "onlanguagechange", - "onload", - "onloadeddata", - "onloadedmetadata", - "onloadstart", - "onlostpointercapture", - "onmessage", - "onmousedown", - "onmouseenter", - "onmouseleave", - "onmousemove", - "onmouseout", - "onmouseover", - "onmouseup", - "onmousewheel", - "ononline", - "onoffline", - "onorientationchange", - "onpagehide", - "onpageshow", - "onpaste", - "onpause", - "onplay", - "onplaying", - "onpointercancel", - "onpointerdown", - "onpointerenter", - "onpointerleave", - "onpointermove", - "onpointerout", - "onpointerover", - "onpointerup", - "onpopstate", - "onprogress", - "onratechange", - "onreset", - "onresize", - "onscroll", - "onsearch", - "onseeked", - "onseeking", - "onselect", - "onselectstart", - "onselectionchange", - "onshow", - "onstalled", - "onstorage", - "onsuspend", - "onsubmit", - "ontimeupdate", - "ontoggle", - "ontouchstart", - "ontouchmove", - "ontouchend", - "ontouchcancel", - "ontransitionend", - "onunload", - "onvolumechange", - "onwaiting", - "onwebkitanimationstart", - "onwebkitanimationiteration", - "onwebkitanimationend", - "onwebkitfullscreenchange", - "onwebkitfullscreenerror", - "onwebkittransitionend", - "onwheel", - "open", - "optimum", - "pattern", - "permissions", - "placeholder", - "ping", - "poster", - "preload", - "pseudo", - "radiogroup", - "readonly", - "referrerpolicy", - "rel", - "required", - "rev", - "reversed", - "role", - "rows", - "rowspan", - "rules", - "sandbox", - "scheme", - "scope", - "scrollamount", - "scrolldelay", - "scrolling", - "select", - "selected", - "shape", - "size", - "sizes", - "slot", - "span", - "spellcheck", - "src", - "srcset", - "srcdoc", - "srclang", - "standby", - "start", - "step", - "style", - "summary", - "tabindex", - "target", - "text", - "title", - "topmargin", - "translate", - "truespeed", - "type", - "usemap", - "valign", - "value", - "valuetype", - "version", - "vlink", - "vspace", - "webkitdirectory", - "width", - "wrap", - ], -}
diff --git a/third_party/WebKit/Source/core/html/HTMLTagNames.in b/third_party/WebKit/Source/core/html/HTMLTagNames.in new file mode 100644 index 0000000..0c8b5137 --- /dev/null +++ b/third_party/WebKit/Source/core/html/HTMLTagNames.in
@@ -0,0 +1,145 @@ +namespace="HTML" +namespacePrefix="xhtml" +namespaceURI="http://www.w3.org/1999/xhtml" +fallbackInterfaceName="HTMLUnknownElement" +export="CORE_EXPORT" + +a interfaceName=HTMLAnchorElement +abbr interfaceName=HTMLElement +acronym interfaceName=HTMLElement +address interfaceName=HTMLElement +applet interfaceName=HTMLUnknownElement +area +article interfaceName=HTMLElement +aside interfaceName=HTMLElement +audio +b interfaceName=HTMLElement +base +basefont interfaceName=HTMLElement +bdi interfaceName=HTMLBDIElement, JSInterfaceName=HTMLElement +bdo interfaceName=HTMLElement +bgsound interfaceName=HTMLUnknownElement +big interfaceName=HTMLElement +blockquote interfaceName=HTMLQuoteElement +body +br interfaceName=HTMLBRElement +button +canvas +caption interfaceName=HTMLTableCaptionElement +center interfaceName=HTMLElement +cite interfaceName=HTMLElement +code interfaceName=HTMLElement +col interfaceName=HTMLTableColElement +colgroup interfaceName=HTMLTableColElement +command interfaceName=HTMLUnknownElement +content interfaceName=HTMLContentElement +datalist interfaceName=HTMLDataListElement +dd interfaceName=HTMLElement +del interfaceName=HTMLModElement +details +dfn interfaceName=HTMLElement +dir interfaceName=HTMLDirectoryElement +dialog +div +dl interfaceName=HTMLDListElement +dt interfaceName=HTMLElement +em interfaceName=HTMLElement +embed constructorNeedsCreatedByParser +fieldset interfaceName=HTMLFieldSetElement +figcaption interfaceName=HTMLElement +figure interfaceName=HTMLElement +font +footer interfaceName=HTMLElement +form +frame +frameset interfaceName=HTMLFrameSetElement +h1 interfaceName=HTMLHeadingElement +h2 interfaceName=HTMLHeadingElement +h3 interfaceName=HTMLHeadingElement +h4 interfaceName=HTMLHeadingElement +h5 interfaceName=HTMLHeadingElement +h6 interfaceName=HTMLHeadingElement +head +header interfaceName=HTMLElement +hgroup interfaceName=HTMLElement +hr interfaceName=HTMLHRElement +html +i interfaceName=HTMLElement +iframe interfaceName=HTMLIFrameElement +image interfaceName=HTMLUnknownElement +img interfaceName=HTMLImageElement, constructorNeedsCreatedByParser +input constructorNeedsCreatedByParser +ins interfaceName=HTMLModElement +kbd interfaceName=HTMLElement +keygen interfaceName=HTMLUnknownElement +label +layer interfaceName=HTMLElement +legend +li interfaceName=HTMLLIElement +link constructorNeedsCreatedByParser +listing interfaceName=HTMLPreElement +main interfaceName=HTMLElement +map +mark interfaceName=HTMLElement +marquee +menu +menuitem interfaceName=HTMLMenuItemElement, runtimeEnabled=contextMenu +meta +meter interfaceName=HTMLMeterElement +nav interfaceName=HTMLElement +nobr interfaceName=HTMLElement +noembed interfaceName=HTMLNoEmbedElement, JSInterfaceName=HTMLElement +noframes interfaceName=HTMLElement +nolayer interfaceName=HTMLElement +object constructorNeedsCreatedByParser +ol interfaceName=HTMLOListElement +optgroup interfaceName=HTMLOptGroupElement +option +output +shadow interfaceName=HTMLShadowElement +p interfaceName=HTMLParagraphElement +param +picture interfaceName=HTMLPictureElement +plaintext interfaceName=HTMLElement +pre +progress interfaceName=HTMLProgressElement +q interfaceName=HTMLQuoteElement +rb interfaceName=HTMLElement +rp interfaceName=HTMLElement +rt interfaceName=HTMLRTElement, JSInterfaceName=HTMLElement +rtc interfaceName=HTMLElement +ruby interfaceName=HTMLRubyElement, JSInterfaceName=HTMLElement +s interfaceName=HTMLElement +samp interfaceName=HTMLElement +script constructorNeedsCreatedByParser +section interfaceName=HTMLElement +select +slot interfaceName=HTMLSlotElement +small interfaceName=HTMLElement +source +span +strike interfaceName=HTMLElement +strong interfaceName=HTMLElement +style constructorNeedsCreatedByParser +sub interfaceName=HTMLElement +summary interfaceName=HTMLSummaryElement, JSInterfaceName=HTMLElement +sup interfaceName=HTMLElement +table +tbody interfaceName=HTMLTableSectionElement +td interfaceName=HTMLTableCellElement +template +textarea interfaceName=HTMLTextAreaElement +tfoot interfaceName=HTMLTableSectionElement +th interfaceName=HTMLTableCellElement +thead interfaceName=HTMLTableSectionElement +title +tr interfaceName=HTMLTableRowElement +track +tt interfaceName=HTMLElement +u interfaceName=HTMLElement +ul interfaceName=HTMLUListElement +var interfaceName=HTMLElement +video +wbr interfaceName=HTMLWBRElement, JSInterfaceName=HTMLElement +xmp interfaceName=HTMLPreElement +noscript interfaceName=HTMLNoScriptElement, JSInterfaceName=HTMLElement
diff --git a/third_party/WebKit/Source/core/html/HTMLTagNames.json5 b/third_party/WebKit/Source/core/html/HTMLTagNames.json5 deleted file mode 100644 index 5d65b245..0000000 --- a/third_party/WebKit/Source/core/html/HTMLTagNames.json5 +++ /dev/null
@@ -1,481 +0,0 @@ -{ - metadata: { - namespace: "HTML", - namespacePrefix: "xhtml", - namespaceURI: "http://www.w3.org/1999/xhtml", - fallbackInterfaceName: "HTMLUnknownElement", - export: "CORE_EXPORT", - }, - - data: [ - { - name: "a", - interfaceName: "HTMLAnchorElement", - }, - { - name: "abbr", - interfaceName: "HTMLElement", - }, - { - name: "acronym", - interfaceName: "HTMLElement", - }, - { - name: "address", - interfaceName: "HTMLElement", - }, - { - name: "applet", - interfaceName: "HTMLUnknownElement", - }, - "area", - { - name: "article", - interfaceName: "HTMLElement", - }, - { - name: "aside", - interfaceName: "HTMLElement", - }, - "audio", - { - name: "b", - interfaceName: "HTMLElement", - }, - "base", - { - name: "basefont", - interfaceName: "HTMLElement", - }, - { - name: "bdi", - JSInterfaceName: "HTMLElement", - interfaceName: "HTMLBDIElement", - }, - { - name: "bdo", - interfaceName: "HTMLElement", - }, - { - name: "bgsound", - interfaceName: "HTMLUnknownElement", - }, - { - name: "big", - interfaceName: "HTMLElement", - }, - { - name: "blockquote", - interfaceName: "HTMLQuoteElement", - }, - "body", - { - name: "br", - interfaceName: "HTMLBRElement", - }, - "button", - "canvas", - { - name: "caption", - interfaceName: "HTMLTableCaptionElement", - }, - { - name: "center", - interfaceName: "HTMLElement", - }, - { - name: "cite", - interfaceName: "HTMLElement", - }, - { - name: "code", - interfaceName: "HTMLElement", - }, - { - name: "col", - interfaceName: "HTMLTableColElement", - }, - { - name: "colgroup", - interfaceName: "HTMLTableColElement", - }, - { - name: "command", - interfaceName: "HTMLUnknownElement", - }, - { - name: "content", - interfaceName: "HTMLContentElement", - }, - { - name: "datalist", - interfaceName: "HTMLDataListElement", - }, - { - name: "dd", - interfaceName: "HTMLElement", - }, - { - name: "del", - interfaceName: "HTMLModElement", - }, - "details", - { - name: "dfn", - interfaceName: "HTMLElement", - }, - { - name: "dir", - interfaceName: "HTMLDirectoryElement", - }, - "dialog", - "div", - { - name: "dl", - interfaceName: "HTMLDListElement", - }, - { - name: "dt", - interfaceName: "HTMLElement", - }, - { - name: "em", - interfaceName: "HTMLElement", - }, - { - name: "embed", - constructorNeedsCreatedByParser: true, - }, - { - name: "fieldset", - interfaceName: "HTMLFieldSetElement", - }, - { - name: "figcaption", - interfaceName: "HTMLElement", - }, - { - name: "figure", - interfaceName: "HTMLElement", - }, - "font", - { - name: "footer", - interfaceName: "HTMLElement", - }, - "form", - "frame", - { - name: "frameset", - interfaceName: "HTMLFrameSetElement", - }, - { - name: "h1", - interfaceName: "HTMLHeadingElement", - }, - { - name: "h2", - interfaceName: "HTMLHeadingElement", - }, - { - name: "h3", - interfaceName: "HTMLHeadingElement", - }, - { - name: "h4", - interfaceName: "HTMLHeadingElement", - }, - { - name: "h5", - interfaceName: "HTMLHeadingElement", - }, - { - name: "h6", - interfaceName: "HTMLHeadingElement", - }, - "head", - { - name: "header", - interfaceName: "HTMLElement", - }, - { - name: "hgroup", - interfaceName: "HTMLElement", - }, - { - name: "hr", - interfaceName: "HTMLHRElement", - }, - "html", - { - name: "i", - interfaceName: "HTMLElement", - }, - { - name: "iframe", - interfaceName: "HTMLIFrameElement", - }, - { - name: "image", - interfaceName: "HTMLUnknownElement", - }, - { - name: "img", - constructorNeedsCreatedByParser: true, - interfaceName: "HTMLImageElement", - }, - { - name: "input", - constructorNeedsCreatedByParser: true, - }, - { - name: "ins", - interfaceName: "HTMLModElement", - }, - { - name: "kbd", - interfaceName: "HTMLElement", - }, - { - name: "keygen", - interfaceName: "HTMLUnknownElement", - }, - "label", - { - name: "layer", - interfaceName: "HTMLElement", - }, - "legend", - { - name: "li", - interfaceName: "HTMLLIElement", - }, - { - name: "link", - constructorNeedsCreatedByParser: true, - }, - { - name: "listing", - interfaceName: "HTMLPreElement", - }, - { - name: "main", - interfaceName: "HTMLElement", - }, - "map", - { - name: "mark", - interfaceName: "HTMLElement", - }, - "marquee", - "menu", - { - name: "menuitem", - interfaceName: "HTMLMenuItemElement", - runtimeEnabled: "contextMenu", - }, - "meta", - { - name: "meter", - interfaceName: "HTMLMeterElement", - }, - { - name: "nav", - interfaceName: "HTMLElement", - }, - { - name: "nobr", - interfaceName: "HTMLElement", - }, - { - name: "noembed", - JSInterfaceName: "HTMLElement", - interfaceName: "HTMLNoEmbedElement", - }, - { - name: "noframes", - interfaceName: "HTMLElement", - }, - { - name: "nolayer", - interfaceName: "HTMLElement", - }, - { - name: "object", - constructorNeedsCreatedByParser: true, - }, - { - name: "ol", - interfaceName: "HTMLOListElement", - }, - { - name: "optgroup", - interfaceName: "HTMLOptGroupElement", - }, - "option", - "output", - { - name: "shadow", - interfaceName: "HTMLShadowElement", - }, - { - name: "p", - interfaceName: "HTMLParagraphElement", - }, - "param", - { - name: "picture", - interfaceName: "HTMLPictureElement", - }, - { - name: "plaintext", - interfaceName: "HTMLElement", - }, - "pre", - { - name: "progress", - interfaceName: "HTMLProgressElement", - }, - { - name: "q", - interfaceName: "HTMLQuoteElement", - }, - { - name: "rb", - interfaceName: "HTMLElement", - }, - { - name: "rp", - interfaceName: "HTMLElement", - }, - { - name: "rt", - JSInterfaceName: "HTMLElement", - interfaceName: "HTMLRTElement", - }, - { - name: "rtc", - interfaceName: "HTMLElement", - }, - { - name: "ruby", - JSInterfaceName: "HTMLElement", - interfaceName: "HTMLRubyElement", - }, - { - name: "s", - interfaceName: "HTMLElement", - }, - { - name: "samp", - interfaceName: "HTMLElement", - }, - { - name: "script", - constructorNeedsCreatedByParser: true, - }, - { - name: "section", - interfaceName: "HTMLElement", - }, - "select", - { - name: "slot", - interfaceName: "HTMLSlotElement", - }, - { - name: "small", - interfaceName: "HTMLElement", - }, - "source", - "span", - { - name: "strike", - interfaceName: "HTMLElement", - }, - { - name: "strong", - interfaceName: "HTMLElement", - }, - { - name: "style", - constructorNeedsCreatedByParser: true, - }, - { - name: "sub", - interfaceName: "HTMLElement", - }, - { - name: "summary", - JSInterfaceName: "HTMLElement", - interfaceName: "HTMLSummaryElement", - }, - { - name: "sup", - interfaceName: "HTMLElement", - }, - "table", - { - name: "tbody", - interfaceName: "HTMLTableSectionElement", - }, - { - name: "td", - interfaceName: "HTMLTableCellElement", - }, - "template", - { - name: "textarea", - interfaceName: "HTMLTextAreaElement", - }, - { - name: "tfoot", - interfaceName: "HTMLTableSectionElement", - }, - { - name: "th", - interfaceName: "HTMLTableCellElement", - }, - { - name: "thead", - interfaceName: "HTMLTableSectionElement", - }, - "title", - { - name: "tr", - interfaceName: "HTMLTableRowElement", - }, - "track", - { - name: "tt", - interfaceName: "HTMLElement", - }, - { - name: "u", - interfaceName: "HTMLElement", - }, - { - name: "ul", - interfaceName: "HTMLUListElement", - }, - { - name: "var", - interfaceName: "HTMLElement", - }, - "video", - { - name: "wbr", - JSInterfaceName: "HTMLElement", - interfaceName: "HTMLWBRElement", - }, - { - name: "xmp", - interfaceName: "HTMLPreElement", - }, - { - name: "noscript", - JSInterfaceName: "HTMLElement", - interfaceName: "HTMLNoScriptElement", - }, - ], -}
diff --git a/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in b/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in new file mode 100644 index 0000000..2277695 --- /dev/null +++ b/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in
@@ -0,0 +1,6 @@ +namespace="MathML" +namespaceURI="http://www.w3.org/1998/Math/MathML" +attrsNullNamespace + +definitionURL +encoding
diff --git a/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.json5 b/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.json5 deleted file mode 100644 index 464ce188..0000000 --- a/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.json5 +++ /dev/null
@@ -1,12 +0,0 @@ -{ - metadata: { - namespace: "MathML", - namespaceURI: "http://www.w3.org/1998/Math/MathML", - attrsNullNamespace: true, - }, - - data: [ - "definitionURL", - "encoding", - ], -}
diff --git a/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in b/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in new file mode 100644 index 0000000..80d830f --- /dev/null +++ b/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in
@@ -0,0 +1,12 @@ +namespace="MathML" +namespaceURI="http://www.w3.org/1998/Math/MathML" + +math +mi +mn +mo +mtext +ms +mglyph +malignmark +annotation-xml
diff --git a/third_party/WebKit/Source/core/html/parser/MathMLTagNames.json5 b/third_party/WebKit/Source/core/html/parser/MathMLTagNames.json5 deleted file mode 100644 index 4326dd7..0000000 --- a/third_party/WebKit/Source/core/html/parser/MathMLTagNames.json5 +++ /dev/null
@@ -1,18 +0,0 @@ -{ - metadata: { - namespace: "MathML", - namespaceURI: "http://www.w3.org/1998/Math/MathML", - }, - - data: [ - "math", - "mi", - "mn", - "mo", - "mtext", - "ms", - "mglyph", - "malignmark", - "annotation-xml", - ], -}
diff --git a/third_party/WebKit/Source/core/layout/line/LineBoxList.cpp b/third_party/WebKit/Source/core/layout/line/LineBoxList.cpp index 77b3069d..29888e5 100644 --- a/third_party/WebKit/Source/core/layout/line/LineBoxList.cpp +++ b/third_party/WebKit/Source/core/layout/line/LineBoxList.cpp
@@ -293,11 +293,13 @@ RootInlineBox* box = nullptr; LineLayoutItem curr = child.previousSibling(); if (child.isFloating() && !curr) { - LineLayoutItem parent = child.parent(); - while (parent && parent.isLayoutInline() && !parent.previousSibling()) - parent = parent.parent(); - if (parent) - curr = parent.previousSibling(); + LineLayoutInline outerInline; + for (LineLayoutItem parent = child.parent(); + parent && parent.isLayoutInline() && !parent.previousSibling(); + parent = parent.parent()) + outerInline = LineLayoutInline(parent); + if (outerInline) + curr = outerInline.previousSibling(); } for (; curr; curr = curr.previousSibling()) {
diff --git a/third_party/WebKit/Source/core/svg/SVGAttributeNames.in b/third_party/WebKit/Source/core/svg/SVGAttributeNames.in new file mode 100644 index 0000000..7952490 --- /dev/null +++ b/third_party/WebKit/Source/core/svg/SVGAttributeNames.in
@@ -0,0 +1,243 @@ +namespace="SVG" +namespaceURI="http://www.w3.org/2000/svg" +attrsNullNamespace +export="CORE_EXPORT" + +accent-height +accumulate +additive +alignment-baseline +alphabetic +amplitude +animate +arabic-form +ascent +attributeName +attributeType +azimuth +baseFrequency +baseline-shift +baseProfile +bbox +begin +bias +buffered-rendering +by +calcMode +cap-height +clip +clip-path +clip-rule +clipPathUnits +color +color-interpolation +color-interpolation-filters +color-rendering +cursor +cx +cy +d +descent +diffuseConstant +direction +display +divisor +dominant-baseline +dur +dx +dy +edgeMode +elevation +end +exponent +fill +fill-opacity +fill-rule +filter +filterUnits +flood-color +flood-opacity +font-family +font-size +font-size-adjust +font-stretch +font-style +font-variant +font-weight +format +from +fx +fy +fr +g1 +g2 +glyph-name +glyphRef +gradientTransform +gradientUnits +hanging +height +horiz-adv-x +horiz-origin-x +horiz-origin-y +href +ideographic +image-rendering +in +in2 +intercept +k +k1 +k2 +k3 +k4 +kernelMatrix +kernelUnitLength +keyPoints +keySplines +keyTimes +lang +lengthAdjust +letter-spacing +lighting-color +limitingConeAngle +local +marker-end +marker-mid +marker-start +markerHeight +markerUnits +markerWidth +mask +mask-type +maskContentUnits +maskUnits +mathematical +max +media +method +min +mode +name +numOctaves +offset +onactivate +onbegin +onend +onfocusin +onfocusout +onrepeat +opacity +operator +order +orient +orientation +origin +overflow +overline-position +overline-thickness +paint-order +panose-1 +path +pathLength +patternContentUnits +patternTransform +patternUnits +pointer-events +points +pointsAtX +pointsAtY +pointsAtZ +preserveAlpha +preserveAspectRatio +primitiveUnits +r +radius +refX +refY +rendering-intent +repeatCount +repeatDur +requiredExtensions +requiredFeatures +restart +result +rotate +rx +ry +scale +seed +shape-rendering +slope +spacing +specularConstant +specularExponent +spreadMethod +startOffset +stdDeviation +stemh +stemv +stitchTiles +stop-color +stop-opacity +strikethrough-position +strikethrough-thickness +stroke +stroke-dasharray +stroke-dashoffset +stroke-linecap +stroke-linejoin +stroke-miterlimit +stroke-opacity +stroke-width +style +surfaceScale +systemLanguage +tableValues +target +targetX +targetY +text-anchor +text-decoration +text-rendering +textLength +title +to +transform +transform-origin +type +u1 +u2 +underline-position +underline-thickness +unicode +unicode-bidi +unicode-range +units-per-em +v-alphabetic +v-hanging +v-ideographic +v-mathematical +values +vector-effect +version +vert-adv-y +vert-origin-x +vert-origin-y +viewBox +visibility +width +widths +word-spacing +writing-mode +x +x-height +x1 +x2 +xChannelSelector +y +y1 +y2 +yChannelSelector +z +zoomAndPan
diff --git a/third_party/WebKit/Source/core/svg/SVGAttributeNames.json5 b/third_party/WebKit/Source/core/svg/SVGAttributeNames.json5 deleted file mode 100644 index 5e5121d3..0000000 --- a/third_party/WebKit/Source/core/svg/SVGAttributeNames.json5 +++ /dev/null
@@ -1,249 +0,0 @@ -{ - metadata: { - namespace: "SVG", - namespaceURI: "http://www.w3.org/2000/svg", - attrsNullNamespace: true, - export: "CORE_EXPORT", - }, - - data: [ - "accent-height", - "accumulate", - "additive", - "alignment-baseline", - "alphabetic", - "amplitude", - "animate", - "arabic-form", - "ascent", - "attributeName", - "attributeType", - "azimuth", - "baseFrequency", - "baseline-shift", - "baseProfile", - "bbox", - "begin", - "bias", - "buffered-rendering", - "by", - "calcMode", - "cap-height", - "clip", - "clip-path", - "clip-rule", - "clipPathUnits", - "color", - "color-interpolation", - "color-interpolation-filters", - "color-rendering", - "cursor", - "cx", - "cy", - "d", - "descent", - "diffuseConstant", - "direction", - "display", - "divisor", - "dominant-baseline", - "dur", - "dx", - "dy", - "edgeMode", - "elevation", - "end", - "exponent", - "fill", - "fill-opacity", - "fill-rule", - "filter", - "filterUnits", - "flood-color", - "flood-opacity", - "font-family", - "font-size", - "font-size-adjust", - "font-stretch", - "font-style", - "font-variant", - "font-weight", - "format", - "from", - "fx", - "fy", - "fr", - "g1", - "g2", - "glyph-name", - "glyphRef", - "gradientTransform", - "gradientUnits", - "hanging", - "height", - "horiz-adv-x", - "horiz-origin-x", - "horiz-origin-y", - "href", - "ideographic", - "image-rendering", - "in", - "in2", - "intercept", - "k", - "k1", - "k2", - "k3", - "k4", - "kernelMatrix", - "kernelUnitLength", - "keyPoints", - "keySplines", - "keyTimes", - "lang", - "lengthAdjust", - "letter-spacing", - "lighting-color", - "limitingConeAngle", - "local", - "marker-end", - "marker-mid", - "marker-start", - "markerHeight", - "markerUnits", - "markerWidth", - "mask", - "mask-type", - "maskContentUnits", - "maskUnits", - "mathematical", - "max", - "media", - "method", - "min", - "mode", - "name", - "numOctaves", - "offset", - "onactivate", - "onbegin", - "onend", - "onfocusin", - "onfocusout", - "onrepeat", - "opacity", - "operator", - "order", - "orient", - "orientation", - "origin", - "overflow", - "overline-position", - "overline-thickness", - "paint-order", - "panose-1", - "path", - "pathLength", - "patternContentUnits", - "patternTransform", - "patternUnits", - "pointer-events", - "points", - "pointsAtX", - "pointsAtY", - "pointsAtZ", - "preserveAlpha", - "preserveAspectRatio", - "primitiveUnits", - "r", - "radius", - "refX", - "refY", - "rendering-intent", - "repeatCount", - "repeatDur", - "requiredExtensions", - "requiredFeatures", - "restart", - "result", - "rotate", - "rx", - "ry", - "scale", - "seed", - "shape-rendering", - "slope", - "spacing", - "specularConstant", - "specularExponent", - "spreadMethod", - "startOffset", - "stdDeviation", - "stemh", - "stemv", - "stitchTiles", - "stop-color", - "stop-opacity", - "strikethrough-position", - "strikethrough-thickness", - "stroke", - "stroke-dasharray", - "stroke-dashoffset", - "stroke-linecap", - "stroke-linejoin", - "stroke-miterlimit", - "stroke-opacity", - "stroke-width", - "style", - "surfaceScale", - "systemLanguage", - "tableValues", - "target", - "targetX", - "targetY", - "text-anchor", - "text-decoration", - "text-rendering", - "textLength", - "title", - "to", - "transform", - "transform-origin", - "type", - "u1", - "u2", - "underline-position", - "underline-thickness", - "unicode", - "unicode-bidi", - "unicode-range", - "units-per-em", - "v-alphabetic", - "v-hanging", - "v-ideographic", - "v-mathematical", - "values", - "vector-effect", - "version", - "vert-adv-y", - "vert-origin-x", - "vert-origin-y", - "viewBox", - "visibility", - "width", - "widths", - "word-spacing", - "writing-mode", - "x", - "x-height", - "x1", - "x2", - "xChannelSelector", - "y", - "y1", - "y2", - "yChannelSelector", - "z", - "zoomAndPan", - ], -}
diff --git a/third_party/WebKit/Source/core/svg/SVGTagNames.in b/third_party/WebKit/Source/core/svg/SVGTagNames.in new file mode 100644 index 0000000..23f5ad8 --- /dev/null +++ b/third_party/WebKit/Source/core/svg/SVGTagNames.in
@@ -0,0 +1,71 @@ +namespace="SVG" +namespaceURI="http://www.w3.org/2000/svg" +fallbackInterfaceName="SVGUnknownElement" +fallbackJSInterfaceName="SVGElement" +export="CORE_EXPORT" + +a +animate runtimeEnabled=smil, noTypeHelpers +animateColor runtimeEnabled=smil, interfaceName=SVGUnknownElement, JSInterfaceName=SVGElement, noConstructor +animateMotion runtimeEnabled=smil +animateTransform runtimeEnabled=smil +set runtimeEnabled=smil +circle +clipPath +defs +desc +discard runtimeEnabled=smil +ellipse +feBlend +feColorMatrix +feComponentTransfer +feComposite +feConvolveMatrix +feDiffuseLighting +feDisplacementMap +feDistantLight +feDropShadow +feFlood +feFuncA +feFuncB +feFuncG +feFuncR +feGaussianBlur +feImage +feMerge +feMergeNode +feMorphology +feOffset +fePointLight +feSpecularLighting +feSpotLight +feTile +feTurbulence +filter +foreignObject +g +image +line +linearGradient +marker +mask +metadata +mpath runtimeEnabled=smil, interfaceName=SVGMPathElement +path +pattern +polygon +polyline +radialGradient +rect +script constructorNeedsCreatedByParser +stop +style constructorNeedsCreatedByParser +svg interfaceName=SVGSVGElement +switch +symbol +text +textPath +title +tspan interfaceName=SVGTSpanElement +use +view
diff --git a/third_party/WebKit/Source/core/svg/SVGTagNames.json5 b/third_party/WebKit/Source/core/svg/SVGTagNames.json5 deleted file mode 100644 index bc54ea7c..0000000 --- a/third_party/WebKit/Source/core/svg/SVGTagNames.json5 +++ /dev/null
@@ -1,115 +0,0 @@ -{ - metadata: { - namespace: "SVG", - namespaceURI: "http://www.w3.org/2000/svg", - fallbackInterfaceName: "SVGUnknownElement", - fallbackJSInterfaceName: "SVGElement", - export: "CORE_EXPORT", - }, - - data: [ - "a", - { - name: "animate", - noTypeHelpers: true, - runtimeEnabled: "smil", - }, - { - name: "animateColor", - JSInterfaceName: "SVGElement", - interfaceName: "SVGUnknownElement", - noConstructor: true, - runtimeEnabled: "smil", - }, - { - name: "animateMotion", - runtimeEnabled: "smil", - }, - { - name: "animateTransform", - runtimeEnabled: "smil", - }, - { - name: "set", - runtimeEnabled: "smil", - }, - "circle", - "clipPath", - "defs", - "desc", - { - name: "discard", - runtimeEnabled: "smil", - }, - "ellipse", - "feBlend", - "feColorMatrix", - "feComponentTransfer", - "feComposite", - "feConvolveMatrix", - "feDiffuseLighting", - "feDisplacementMap", - "feDistantLight", - "feDropShadow", - "feFlood", - "feFuncA", - "feFuncB", - "feFuncG", - "feFuncR", - "feGaussianBlur", - "feImage", - "feMerge", - "feMergeNode", - "feMorphology", - "feOffset", - "fePointLight", - "feSpecularLighting", - "feSpotLight", - "feTile", - "feTurbulence", - "filter", - "foreignObject", - "g", - "image", - "line", - "linearGradient", - "marker", - "mask", - "metadata", - { - name: "mpath", - interfaceName: "SVGMPathElement", - runtimeEnabled: "smil", - }, - "path", - "pattern", - "polygon", - "polyline", - "radialGradient", - "rect", - { - name: "script", - constructorNeedsCreatedByParser: true, - }, - "stop", - { - name: "style", - constructorNeedsCreatedByParser: true, - }, - { - name: "svg", - interfaceName: "SVGSVGElement", - }, - "switch", - "symbol", - "text", - "textPath", - "title", - { - name: "tspan", - interfaceName: "SVGTSpanElement", - }, - "use", - "view", - ], -}
diff --git a/third_party/WebKit/Source/core/svg/xlinkattrs.in b/third_party/WebKit/Source/core/svg/xlinkattrs.in new file mode 100644 index 0000000..e3e0c33 --- /dev/null +++ b/third_party/WebKit/Source/core/svg/xlinkattrs.in
@@ -0,0 +1,11 @@ +namespace="XLink" +namespaceURI="http://www.w3.org/1999/xlink" +export="CORE_EXPORT" + +actuate +arcrole +href +role +show +title +type
diff --git a/third_party/WebKit/Source/core/svg/xlinkattrs.json5 b/third_party/WebKit/Source/core/svg/xlinkattrs.json5 deleted file mode 100644 index 70ac0534..0000000 --- a/third_party/WebKit/Source/core/svg/xlinkattrs.json5 +++ /dev/null
@@ -1,17 +0,0 @@ -{ - metadata: { - namespace: "XLink", - namespaceURI: "http://www.w3.org/1999/xlink", - export: "CORE_EXPORT", - }, - - data: [ - "actuate", - "arcrole", - "href", - "role", - "show", - "title", - "type", - ], -}
diff --git a/third_party/WebKit/Source/core/xml/xmlattrs.in b/third_party/WebKit/Source/core/xml/xmlattrs.in new file mode 100644 index 0000000..ae6ab01 --- /dev/null +++ b/third_party/WebKit/Source/core/xml/xmlattrs.in
@@ -0,0 +1,6 @@ +namespace="XML" +namespacePrefix="xml" +namespaceURI="http://www.w3.org/XML/1998/namespace" + +lang +space
diff --git a/third_party/WebKit/Source/core/xml/xmlattrs.json5 b/third_party/WebKit/Source/core/xml/xmlattrs.json5 deleted file mode 100644 index 6fa47033..0000000 --- a/third_party/WebKit/Source/core/xml/xmlattrs.json5 +++ /dev/null
@@ -1,12 +0,0 @@ -{ - metadata: { - namespace: "XML", - namespacePrefix: "xml", - namespaceURI: "http://www.w3.org/XML/1998/namespace", - }, - - data: [ - "lang", - "space", - ], -}
diff --git a/third_party/WebKit/Source/core/xml/xmlnsattrs.in b/third_party/WebKit/Source/core/xml/xmlnsattrs.in new file mode 100644 index 0000000..7ac415a --- /dev/null +++ b/third_party/WebKit/Source/core/xml/xmlnsattrs.in
@@ -0,0 +1,4 @@ +namespace="XMLNS" +namespaceURI="http://www.w3.org/2000/xmlns/" + +xmlns
diff --git a/third_party/WebKit/Source/core/xml/xmlnsattrs.json5 b/third_party/WebKit/Source/core/xml/xmlnsattrs.json5 deleted file mode 100644 index 81f1684..0000000 --- a/third_party/WebKit/Source/core/xml/xmlnsattrs.json5 +++ /dev/null
@@ -1,10 +0,0 @@ -{ - metadata: { - namespace: "XMLNS", - namespaceURI: "http://www.w3.org/2000/xmlns/", - }, - - data: [ - "xmlns", - ], -}
diff --git a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp index 646b470..742c938 100644 --- a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp +++ b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
@@ -350,9 +350,8 @@ const String& data, const AtomicString& lastEventId) { MessageEvent* e = MessageEvent::create(); - e->initMessageEvent(eventType, false, false, - SerializedScriptValue::serialize(data), - m_eventStreamOrigin, lastEventId, 0, nullptr); + e->initMessageEvent(eventType, false, false, data, m_eventStreamOrigin, + lastEventId, 0, nullptr); InspectorInstrumentation::willDispatchEventSourceEvent( getExecutionContext(), this, eventType, lastEventId, data);
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp index 8c01f6a..f0ed3d8 100644 --- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp +++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
@@ -62,24 +62,24 @@ Sensor::~Sensor() = default; -void Sensor::start(ScriptState* scriptState, ExceptionState& exceptionState) { +void Sensor::start() { if (m_state != Sensor::SensorState::Unconnected && m_state != Sensor::SensorState::Idle && m_state != Sensor::SensorState::Errored) return; initSensorProxyIfNeeded(); - if (!m_sensorProxy) { - exceptionState.throwDOMException( - InvalidStateError, "The Sensor is no longer associated to a frame."); + reportError(InvalidStateError, + "The Sensor is no longer associated to a frame."); return; } + m_lastUpdateTimestamp = WTF::monotonicallyIncreasingTime(); startListening(); } -void Sensor::stop(ScriptState*, ExceptionState& exceptionState) { +void Sensor::stop() { if (m_state == Sensor::SensorState::Unconnected || m_state == Sensor::SensorState::Idle || m_state == Sensor::SensorState::Errored)
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.h b/third_party/WebKit/Source/modules/sensor/Sensor.h index 171e3a32..f7bc333 100644 --- a/third_party/WebKit/Source/modules/sensor/Sensor.h +++ b/third_party/WebKit/Source/modules/sensor/Sensor.h
@@ -35,8 +35,8 @@ ~Sensor() override; - void start(ScriptState*, ExceptionState&); - void stop(ScriptState*, ExceptionState&); + void start(); + void stop(); // EventTarget overrides. const AtomicString& interfaceName() const override {
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.idl b/third_party/WebKit/Source/modules/sensor/Sensor.idl index 56ac99f..daf1e537 100644 --- a/third_party/WebKit/Source/modules/sensor/Sensor.idl +++ b/third_party/WebKit/Source/modules/sensor/Sensor.idl
@@ -21,8 +21,8 @@ readonly attribute SensorState state; [CallWith=ScriptState] readonly attribute DOMHighResTimeStamp? timestamp; - [CallWith=ScriptState, RaisesException, MeasureAs=GenericSensorStart] void start(); - [CallWith=ScriptState, RaisesException, MeasureAs=GenericSensorStop] void stop(); + [MeasureAs=GenericSensorStart] void start(); + [MeasureAs=GenericSensorStop] void stop(); attribute EventHandler onerror; attribute EventHandler onchange;
diff --git a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp index 2e9effb..2d0242d0a 100644 --- a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp +++ b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp
@@ -30,6 +30,7 @@ #include "modules/websockets/DocumentWebSocketChannel.h" +#include <memory> #include "core/dom/DOMArrayBuffer.h" #include "core/dom/Document.h" #include "core/dom/ExecutionContext.h" @@ -45,6 +46,7 @@ #include "modules/websockets/WebSocketChannelClient.h" #include "modules/websockets/WebSocketFrame.h" #include "modules/websockets/WebSocketHandleImpl.h" +#include "platform/WebFrameScheduler.h" #include "platform/loader/fetch/UniqueIdentifier.h" #include "platform/network/NetworkLog.h" #include "platform/network/WebSocketHandshakeRequest.h" @@ -52,7 +54,6 @@ #include "public/platform/InterfaceProvider.h" #include "public/platform/Platform.h" #include "wtf/PtrUtil.h" -#include <memory> namespace blink { @@ -165,6 +166,11 @@ ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); } + if (document()->frame()) { + connection_handle_for_scheduler_ = + document()->frame()->frameScheduler()->onActiveConnectionCreated(); + } + m_url = url; Vector<String> protocols; // Avoid placing an empty token in the Vector when the protocol string is @@ -288,6 +294,8 @@ NETWORK_DVLOG(1) << this << " fail(" << reason << ")"; // m_handle and m_client can be null here. + connection_handle_for_scheduler_.reset(); + InspectorInstrumentation::didReceiveWebSocketFrameError(document(), m_identifier, reason); const String message = "WebSocket connection to '" + m_url.elidedString() + @@ -311,6 +319,7 @@ "data", InspectorWebSocketEvent::data(document(), m_identifier)); InspectorInstrumentation::didCloseWebSocket(document(), m_identifier); } + connection_handle_for_scheduler_.reset(); abortAsyncOperations(); m_handle.reset(); m_client = nullptr; @@ -503,6 +512,8 @@ NETWORK_DVLOG(1) << this << " didFail(" << handle << ", " << String(message) << ")"; + connection_handle_for_scheduler_.reset(); + DCHECK(m_handle); DCHECK_EQ(handle, m_handle.get()); @@ -585,6 +596,8 @@ NETWORK_DVLOG(1) << this << " didClose(" << handle << ", " << wasClean << ", " << code << ", " << String(reason) << ")"; + connection_handle_for_scheduler_.reset(); + DCHECK(m_handle); DCHECK_EQ(handle, m_handle.get());
diff --git a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h index 6e678c9..90eb1f2 100644 --- a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h +++ b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h
@@ -31,6 +31,8 @@ #ifndef DocumentWebSocketChannel_h #define DocumentWebSocketChannel_h +#include <stdint.h> +#include <memory> #include "bindings/core/v8/SourceLocation.h" #include "core/fileapi/Blob.h" #include "core/fileapi/FileError.h" @@ -38,6 +40,7 @@ #include "modules/websockets/WebSocketChannel.h" #include "modules/websockets/WebSocketHandle.h" #include "modules/websockets/WebSocketHandleClient.h" +#include "platform/WebFrameScheduler.h" #include "platform/heap/Handle.h" #include "platform/weborigin/KURL.h" #include "wtf/Deque.h" @@ -46,8 +49,6 @@ #include "wtf/Vector.h" #include "wtf/text/CString.h" #include "wtf/text/WTFString.h" -#include <memory> -#include <stdint.h> namespace blink { @@ -173,6 +174,8 @@ uint64_t m_sendingQuota; uint64_t m_receivedDataSizeForFlowControl; size_t m_sentSizeOfTopMessage; + std::unique_ptr<WebFrameScheduler::ActiveConnectionHandle> + connection_handle_for_scheduler_; std::unique_ptr<SourceLocation> m_locationAtConstruction; RefPtr<WebSocketHandshakeRequest> m_handshakeRequest;
diff --git a/third_party/WebKit/Source/platform/MemoryCoordinator.cpp b/third_party/WebKit/Source/platform/MemoryCoordinator.cpp index b414dbf4..8dd8a65 100644 --- a/third_party/WebKit/Source/platform/MemoryCoordinator.cpp +++ b/third_party/WebKit/Source/platform/MemoryCoordinator.cpp
@@ -74,6 +74,12 @@ WTF::Partitions::decommitFreeableMemory(); } +void MemoryCoordinator::onPurgeMemory() { + // TODO(tasak|bashi): Move code from onMemoryStateChange(). Currently + // onMemoryStateChange() is called when the purge+throttled experiment is + // enabled. +} + void MemoryCoordinator::clearMemory() { // Clear the image cache. // TODO(tasak|bashi): Make ImageDecodingStore and FontCache be
diff --git a/third_party/WebKit/Source/platform/MemoryCoordinator.h b/third_party/WebKit/Source/platform/MemoryCoordinator.h index bb2ab3fa..939c3cec 100644 --- a/third_party/WebKit/Source/platform/MemoryCoordinator.h +++ b/third_party/WebKit/Source/platform/MemoryCoordinator.h
@@ -51,6 +51,8 @@ void onMemoryStateChange(MemoryState); + void onPurgeMemory(); + DECLARE_TRACE(); private:
diff --git a/third_party/WebKit/Source/platform/WebFrameScheduler.h b/third_party/WebKit/Source/platform/WebFrameScheduler.h index 069fedf..0a14a9d9 100644 --- a/third_party/WebKit/Source/platform/WebFrameScheduler.h +++ b/third_party/WebKit/Source/platform/WebFrameScheduler.h
@@ -7,6 +7,8 @@ #include "wtf/RefPtr.h" +#include <memory> + namespace blink { class WebTaskRunner; @@ -16,6 +18,15 @@ public: virtual ~WebFrameScheduler() {} + class ActiveConnectionHandle { + public: + ActiveConnectionHandle() {} + virtual ~ActiveConnectionHandle() {} + + private: + DISALLOW_COPY_AND_ASSIGN(ActiveConnectionHandle); + }; + // The scheduler may throttle tasks associated with offscreen frames. virtual void setFrameVisible(bool) {} @@ -67,6 +78,13 @@ // Tells the scheduler that the first meaningful paint has occured for this // frame. virtual void onFirstMeaningfulPaint() {} + + // Notifies scheduler that this frame has established an active real time + // connection (websocket, webrtc, etc). When connection is closed this handle + // must be destroyed. + virtual std::unique_ptr<ActiveConnectionHandle> onActiveConnectionCreated() { + return nullptr; + }; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/exported/WebMemoryCoordinator.cpp b/third_party/WebKit/Source/platform/exported/WebMemoryCoordinator.cpp index f1ba1a8..e1721072 100644 --- a/third_party/WebKit/Source/platform/exported/WebMemoryCoordinator.cpp +++ b/third_party/WebKit/Source/platform/exported/WebMemoryCoordinator.cpp
@@ -17,4 +17,8 @@ MemoryCoordinator::instance().onMemoryStateChange(state); } +void WebMemoryCoordinator::onPurgeMemory() { + MemoryCoordinator::instance().onPurgeMemory(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc index 027e3b7..b14a019 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -28,6 +28,18 @@ } // namespace +WebFrameSchedulerImpl::ActiveConnectionHandleImpl::ActiveConnectionHandleImpl( + WebFrameSchedulerImpl* frame_scheduler) + : frame_scheduler_(frame_scheduler->AsWeakPtr()) { + frame_scheduler->didOpenActiveConnection(); +} + +WebFrameSchedulerImpl::ActiveConnectionHandleImpl:: + ~ActiveConnectionHandleImpl() { + if (frame_scheduler_) + frame_scheduler_->didCloseActiveConnection(); +} + WebFrameSchedulerImpl::WebFrameSchedulerImpl( RendererSchedulerImpl* renderer_scheduler, WebViewSchedulerImpl* parent_web_view_scheduler, @@ -38,9 +50,13 @@ frame_visible_(true), page_throttled_(true), frame_suspended_(false), - cross_origin_(false) {} + cross_origin_(false), + active_connection_count_(0), + weak_factory_(this) {} WebFrameSchedulerImpl::~WebFrameSchedulerImpl() { + weak_factory_.InvalidateWeakPtrs(); + if (loading_task_queue_) { loading_task_queue_->UnregisterTaskQueue(); loading_task_queue_->SetBlameContext(nullptr); @@ -57,8 +73,12 @@ unthrottled_task_queue_->SetBlameContext(nullptr); } - if (parent_web_view_scheduler_) + if (parent_web_view_scheduler_) { parent_web_view_scheduler_->Unregister(this); + + if (active_connection_count_) + parent_web_view_scheduler_->OnConnectionUpdated(); + } } void WebFrameSchedulerImpl::DetachFromWebViewScheduler() { @@ -167,6 +187,19 @@ parent_web_view_scheduler_->DidStopLoading(identifier); } +void WebFrameSchedulerImpl::didOpenActiveConnection() { + ++active_connection_count_; + if (parent_web_view_scheduler_) + parent_web_view_scheduler_->OnConnectionUpdated(); +} + +void WebFrameSchedulerImpl::didCloseActiveConnection() { + DCHECK_GT(active_connection_count_, 0); + --active_connection_count_; + if (parent_web_view_scheduler_) + parent_web_view_scheduler_->OnConnectionUpdated(); +} + void WebFrameSchedulerImpl::setDocumentParsingInBackground( bool background_parser_active) { if (background_parser_active) @@ -224,6 +257,12 @@ renderer_scheduler_->OnFirstMeaningfulPaint(); } +std::unique_ptr<WebFrameScheduler::ActiveConnectionHandle> +WebFrameSchedulerImpl::onActiveConnectionCreated() { + return base::MakeUnique<WebFrameSchedulerImpl::ActiveConnectionHandleImpl>( + this); +} + bool WebFrameSchedulerImpl::ShouldThrottleTimers() const { if (page_throttled_) return true; @@ -244,5 +283,9 @@ } } +base::WeakPtr<WebFrameSchedulerImpl> WebFrameSchedulerImpl::AsWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + } // namespace scheduler } // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h index 141ea7cb..9111528d 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h
@@ -9,10 +9,11 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/trace_event/trace_event.h" #include "platform/WebFrameScheduler.h" -#include "public/platform/scheduler/base/task_queue.h" #include "public/platform/WebCommon.h" +#include "public/platform/scheduler/base/task_queue.h" namespace base { namespace trace_event { @@ -50,18 +51,37 @@ void didStopLoading(unsigned long identifier) override; void setDocumentParsingInBackground(bool background_parser_active) override; void onFirstMeaningfulPaint() override; + std::unique_ptr<ActiveConnectionHandle> onActiveConnectionCreated() override; void AsValueInto(base::trace_event::TracedValue* state) const; + bool has_active_connection() const { return active_connection_count_; } + private: friend class WebViewSchedulerImpl; + class ActiveConnectionHandleImpl : public ActiveConnectionHandle { + public: + ActiveConnectionHandleImpl(WebFrameSchedulerImpl* frame_scheduler); + ~ActiveConnectionHandleImpl() override; + + private: + base::WeakPtr<WebFrameSchedulerImpl> frame_scheduler_; + + DISALLOW_COPY_AND_ASSIGN(ActiveConnectionHandleImpl); + }; + void DetachFromWebViewScheduler(); void RemoveTimerQueueFromBackgroundTimeBudgetPool(); void ApplyPolicyToTimerQueue(); bool ShouldThrottleTimers() const; void UpdateTimerThrottling(bool was_throttled); + void didOpenActiveConnection(); + void didCloseActiveConnection(); + + base::WeakPtr<WebFrameSchedulerImpl> AsWeakPtr(); + scoped_refptr<TaskQueue> loading_task_queue_; scoped_refptr<TaskQueue> timer_task_queue_; scoped_refptr<TaskQueue> unthrottled_task_queue_; @@ -77,6 +97,9 @@ bool page_throttled_; bool frame_suspended_; bool cross_origin_; + int active_connection_count_; + + base::WeakPtrFactory<WebFrameSchedulerImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(WebFrameSchedulerImpl); };
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc index a5ccc87b..d14a7f7 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc
@@ -108,6 +108,7 @@ virtual_time_(false), is_audio_playing_(false), reported_background_throttling_since_navigation_(false), + has_active_connection_(false), background_time_budget_pool_(nullptr), settings_(settings) { renderer_scheduler->AddWebViewScheduler(this); @@ -238,6 +239,10 @@ renderer_scheduler_->OnAudioStateChanged(); } +bool WebViewSchedulerImpl::hasActiveConnectionForTest() const { + return has_active_connection_; +} + void WebViewSchedulerImpl::ApplyVirtualTimePolicy() { if (virtual_time_policy_ != VirtualTimePolicy::DETERMINISTIC_LOADING) { return; @@ -255,6 +260,18 @@ return is_audio_playing_; } +void WebViewSchedulerImpl::OnConnectionUpdated() { + bool has_active_connection = false; + for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { + has_active_connection |= frame_scheduler->has_active_connection(); + } + + if (has_active_connection_ != has_active_connection) { + has_active_connection_ = has_active_connection; + UpdateBackgroundThrottlingState(); + } +} + void WebViewSchedulerImpl::AsValueInto( base::trace_event::TracedValue* state) const { state->SetDouble("pending_loads", pending_loads_.size()); @@ -335,10 +352,7 @@ for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { frame_scheduler->setPageThrottled(true); } - if (background_time_budget_pool_) { - LazyNow lazy_now(renderer_scheduler_->tick_clock()); - background_time_budget_pool_->EnableThrottling(&lazy_now); - } + UpdateBackgroundBudgetPoolThrottlingState(); } void WebViewSchedulerImpl::UpdateBackgroundThrottlingState() { @@ -349,15 +363,29 @@ for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { frame_scheduler->setPageThrottled(false); } - if (background_time_budget_pool_) { - LazyNow lazy_now(renderer_scheduler_->tick_clock()); - background_time_budget_pool_->DisableThrottling(&lazy_now); - } + UpdateBackgroundBudgetPoolThrottlingState(); } else { - // TODO(altimin): Consider moving this logic into PumpThrottledTasks. - renderer_scheduler_->ControlTaskRunner()->PostDelayedTask( - FROM_HERE, delayed_background_throttling_enabler_.callback(), - kBackgroundThrottlingGracePeriod); + if (has_active_connection_) { + // If connection is active, update state immediately to stop throttling. + UpdateBackgroundBudgetPoolThrottlingState(); + } else { + // TODO(altimin): Consider moving this logic into PumpThrottledTasks. + renderer_scheduler_->ControlTaskRunner()->PostDelayedTask( + FROM_HERE, delayed_background_throttling_enabler_.callback(), + kBackgroundThrottlingGracePeriod); + } + } +} + +void WebViewSchedulerImpl::UpdateBackgroundBudgetPoolThrottlingState() { + if (!background_time_budget_pool_) + return; + + LazyNow lazy_now(renderer_scheduler_->tick_clock()); + if (page_visible_ || has_active_connection_) { + background_time_budget_pool_->DisableThrottling(&lazy_now); + } else { + background_time_budget_pool_->EnableThrottling(&lazy_now); } }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.h index 423100f..d762a11 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.h
@@ -47,6 +47,7 @@ bool virtualTimeAllowedToAdvance() const override; void setVirtualTimePolicy(VirtualTimePolicy virtual_time_policy) override; void audioStateChanged(bool is_audio_playing) override; + bool hasActiveConnectionForTest() const override; // Virtual for testing. virtual void ReportIntervention(const std::string& message); @@ -63,6 +64,8 @@ bool IsAudioPlaying() const; + void OnConnectionUpdated(); + void AsValueInto(base::trace_event::TracedValue* state) const; private: @@ -83,6 +86,11 @@ // call to enable it after a grace period. void UpdateBackgroundThrottlingState(); + // As a part of UpdateBackgroundThrottlingState set correct + // background_time_budget_pool_ state depending on page visibility and + // number of active connections. + void UpdateBackgroundBudgetPoolThrottlingState(); + void EnableBackgroundThrottling(); std::set<WebFrameSchedulerImpl*> frame_schedulers_; @@ -99,6 +107,7 @@ bool virtual_time_; bool is_audio_playing_; bool reported_background_throttling_since_navigation_; + bool has_active_connection_; TaskQueueThrottler::TimeBudgetPool* background_time_budget_pool_; // Not owned. CancelableClosureHolder delayed_background_throttling_enabler_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc index 5f3ccdb..61961b6 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
@@ -685,5 +685,105 @@ base::TimeTicks() + base::TimeDelta::FromSeconds(26))); } +TEST_F(WebViewSchedulerImplTest, OpenWebSocketExemptsFromBudgetThrottling) { + ScopedExpensiveBackgroundTimerThrottlingForTest + budget_background_throttling_enabler(true); + + std::vector<base::TimeTicks> run_times; + FakeWebViewSchedulerSettings web_view_scheduler_settings; + std::unique_ptr<WebViewSchedulerImpl> web_view_scheduler( + new WebViewSchedulerImpl(nullptr, &web_view_scheduler_settings, + scheduler_.get(), false)); + + std::unique_ptr<WebFrameSchedulerImpl> web_frame_scheduler1 = + web_view_scheduler->createWebFrameSchedulerImpl(nullptr); + std::unique_ptr<WebFrameSchedulerImpl> web_frame_scheduler2 = + web_view_scheduler->createWebFrameSchedulerImpl(nullptr); + + web_view_scheduler->setPageVisible(false); + + // Wait for 20s to avoid initial throttling delay. + mock_task_runner_->RunUntilTime(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(20500)); + + for (size_t i = 0; i < 3; ++i) { + web_frame_scheduler1->timerTaskRunner()->postDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), 1); + } + + mock_task_runner_->RunUntilTime(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(55500)); + + // Check that tasks are throttled. + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(21), + base::TimeTicks() + base::TimeDelta::FromSeconds(26), + base::TimeTicks() + base::TimeDelta::FromSeconds(51))); + run_times.clear(); + + std::unique_ptr<WebFrameScheduler::ActiveConnectionHandle> + websocket_connection = web_frame_scheduler1->onActiveConnectionCreated(); + + for (size_t i = 0; i < 3; ++i) { + web_frame_scheduler1->timerTaskRunner()->postDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), 1); + } + + mock_task_runner_->RunUntilTime(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(58500)); + + // Check that the timer task queue from the first frame is aligned, + // but not throttled. + EXPECT_THAT( + run_times, + ElementsAre( + base::TimeTicks() + base::TimeDelta::FromMilliseconds(56000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(56250), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(56500))); + run_times.clear(); + + for (size_t i = 0; i < 3; ++i) { + web_frame_scheduler2->timerTaskRunner()->postDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), 1); + } + + mock_task_runner_->RunUntilTime(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(59500)); + + // Check that the second frame scheduler becomes unthrottled. + EXPECT_THAT( + run_times, + ElementsAre( + base::TimeTicks() + base::TimeDelta::FromMilliseconds(59000), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(59250), + base::TimeTicks() + base::TimeDelta::FromMilliseconds(59500))); + run_times.clear(); + + websocket_connection.reset(); + + // Wait for 10s to enable throttling back. + mock_task_runner_->RunUntilTime(base::TimeTicks() + + base::TimeDelta::FromMilliseconds(70500)); + + for (size_t i = 0; i < 3; ++i) { + web_frame_scheduler1->timerTaskRunner()->postDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), 1); + } + + mock_task_runner_->RunUntilIdle(); + + // WebSocket is closed, budget-based throttling now applies. + EXPECT_THAT( + run_times, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(84), + base::TimeTicks() + base::TimeDelta::FromSeconds(109), + base::TimeTicks() + base::TimeDelta::FromSeconds(134))); +} + } // namespace scheduler } // namespace blink
diff --git a/third_party/WebKit/Source/web/BUILD.gn b/third_party/WebKit/Source/web/BUILD.gn index 18cc77e..93bf8b9 100644 --- a/third_party/WebKit/Source/web/BUILD.gn +++ b/third_party/WebKit/Source/web/BUILD.gn
@@ -327,6 +327,7 @@ # FIXME: Move the tests from web/tests/ to appropriate places. # crbug.com/353585 + "tests/ActiveConnectionThrottlingTest.cpp", "tests/ActivityLoggerTest.cpp", "tests/BrowserControlsTest.cpp", "tests/ChromeClientImplTest.cpp",
diff --git a/third_party/WebKit/Source/web/tests/ActiveConnectionThrottlingTest.cpp b/third_party/WebKit/Source/web/tests/ActiveConnectionThrottlingTest.cpp new file mode 100644 index 0000000..96488cd --- /dev/null +++ b/third_party/WebKit/Source/web/tests/ActiveConnectionThrottlingTest.cpp
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code if governed by a BSD-style license that can be +// found in LICENSE file. + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebViewScheduler.h" +#include "web/WebViewImpl.h" +#include "web/tests/sim/SimRequest.h" +#include "web/tests/sim/SimTest.h" + +using testing::_; + +namespace blink { + +class ActiveConnectionThrottlingTest : public SimTest {}; + +TEST_F(ActiveConnectionThrottlingTest, WebSocketStopsThrottling) { + SimRequest mainResource("https://example.com/", "text/html"); + + loadURL("https://example.com/"); + + EXPECT_FALSE(webView().scheduler()->hasActiveConnectionForTest()); + + mainResource.complete( + "(<script>" + " var socket = new WebSocket(\"ws://www.example.com/websocket\");" + "</script>)"); + + EXPECT_TRUE(webView().scheduler()->hasActiveConnectionForTest()); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index a9b73309..7f22058 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -38,6 +38,7 @@ #include "SkCanvas.h" #include "bindings/core/v8/SerializedScriptValueFactory.h" #include "bindings/core/v8/V8Node.h" +#include "bindings/core/v8/serialization/V8ScriptValueSerializer.h" #include "core/clipboard/DataTransfer.h" #include "core/css/StyleSheetContents.h" #include "core/css/resolver/StyleResolver.h" @@ -990,6 +991,21 @@ EXPECT_EQ(std::string::npos, content.find("Message 2.")); } +namespace { + +RefPtr<SerializedScriptValue> serializeString(const StringView& message, + ScriptState* scriptState) { + // This is inefficient, but avoids duplicating serialization logic for the + // sake of this test. + NonThrowableExceptionState exceptionState; + ScriptState::Scope scope(scriptState); + V8ScriptValueSerializer serializer(scriptState); + return serializer.serialize(v8String(scriptState->isolate(), message), + nullptr, exceptionState); +} + +} // namespace + TEST_P(ParameterizedWebFrameTest, PostMessageThenDetach) { FrameTestHelpers::WebViewHelper webViewHelper; webViewHelper.initializeAndLoad("about:blank"); @@ -997,10 +1013,11 @@ LocalFrame* frame = toLocalFrame(webViewHelper.webView()->page()->mainFrame()); NonThrowableExceptionState exceptionState; + RefPtr<SerializedScriptValue> message = + serializeString("message", ScriptState::forMainWorld(frame)); MessagePortArray messagePorts; - frame->domWindow()->postMessage(SerializedScriptValue::serialize("message"), - messagePorts, "*", frame->domWindow(), - exceptionState); + frame->domWindow()->postMessage(message, messagePorts, "*", + frame->domWindow(), exceptionState); webViewHelper.reset(); EXPECT_FALSE(exceptionState.hadException());
diff --git a/third_party/WebKit/public/platform/WebMemoryCoordinator.h b/third_party/WebKit/public/platform/WebMemoryCoordinator.h index 04f70a7..7b3588d 100644 --- a/third_party/WebKit/public/platform/WebMemoryCoordinator.h +++ b/third_party/WebKit/public/platform/WebMemoryCoordinator.h
@@ -19,6 +19,8 @@ BLINK_PLATFORM_EXPORT static void onMemoryPressure(WebMemoryPressureLevel); BLINK_PLATFORM_EXPORT static void onMemoryStateChange(MemoryState); + + BLINK_PLATFORM_EXPORT static void onPurgeMemory(); }; } // namespace blink
diff --git a/third_party/WebKit/public/platform/WebViewScheduler.h b/third_party/WebKit/public/platform/WebViewScheduler.h index 55f6184..77e003ee 100644 --- a/third_party/WebKit/public/platform/WebViewScheduler.h +++ b/third_party/WebKit/public/platform/WebViewScheduler.h
@@ -79,6 +79,8 @@ virtual void setVirtualTimePolicy(VirtualTimePolicy) = 0; virtual void audioStateChanged(bool isAudioPlaying) = 0; + + virtual bool hasActiveConnectionForTest() const = 0; }; } // namespace blink
diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc index 2544b1a5..ae808387 100644 --- a/ui/base/ui_base_switches.cc +++ b/ui/base/ui_base_switches.cc
@@ -34,18 +34,12 @@ // Disables use of DWM composition for top level windows. const char kDisableDwmComposition[] = "disable-dwm-composition"; -// Disables large icons on the New Tab page. -const char kDisableIconNtp[] = "disable-icon-ntp"; - // Disables touch adjustment. const char kDisableTouchAdjustment[] = "disable-touch-adjustment"; // Disables touch event based drag and drop. const char kDisableTouchDragDrop[] = "disable-touch-drag-drop"; -// Enables large icons on the New Tab page. -const char kEnableIconNtp[] = "enable-icon-ntp"; - // Enables touch event based drag and drop. const char kEnableTouchDragDrop[] = "enable-touch-drag-drop";
diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h index 353c9358..eb581ac 100644 --- a/ui/base/ui_base_switches.h +++ b/ui/base/ui_base_switches.h
@@ -26,10 +26,8 @@ #endif UI_BASE_EXPORT extern const char kDisableDwmComposition[]; -UI_BASE_EXPORT extern const char kDisableIconNtp[]; UI_BASE_EXPORT extern const char kDisableTouchAdjustment[]; UI_BASE_EXPORT extern const char kDisableTouchDragDrop[]; -UI_BASE_EXPORT extern const char kEnableIconNtp[]; UI_BASE_EXPORT extern const char kEnableTouchDragDrop[]; UI_BASE_EXPORT extern const char kLang[]; UI_BASE_EXPORT extern const char kMaterialDesignInkDropAnimationSpeed[];
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html index 74ef004..2ed13112 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html +++ b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html
@@ -13,10 +13,11 @@ } </style> <template> - <iron-icon id="indicator" tabindex=0 + <iron-icon id="indicator" tabindex=0 aria-describedby="tooltip" hidden$="[[!isIndicatorVisible(indicatorType)]]" icon="[[getPolicyIndicatorIcon(indicatorType)]]"></iron-icon> - <paper-tooltip for="indicator" position="top" fit-to-visible-bounds> + <paper-tooltip id="tooltip" for="indicator" position="top" + fit-to-visible-bounds> [[getTooltip_(indicatorType, pref)]] </paper-tooltip> </template>