diff --git a/DEPS b/DEPS index c6f930a..1296d791 100644 --- a/DEPS +++ b/DEPS
@@ -43,7 +43,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '7dc32c84c10ce2592e3e346a6deb312810cc8751', + 'v8_revision': '7135a7399d0cc195b02b2ea8c4315a5727a8c849', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -131,7 +131,7 @@ Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '8f91ea3a7e0413df3312204058da856058a8099b', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'e466f6ac8f60bb9697af4a91c6911c6fc4aec95f', 'src/third_party/libexif/sources': Var('chromium_git') + '/chromium/deps/libexif/sources.git' + '@' + '045b7fb9aa6d9b7f1954db248caf5eefe917476d', @@ -275,7 +275,7 @@ 'src/third_party/catapult': Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' + - 'cb78598b63fc3b6b4767a6b81f68ef7d05a27c3d', + 'dd5b026ac253edbcdb3be08a12eef1d03b796b35', 'src/third_party/openh264/src': Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
diff --git a/chrome/browser/safe_browsing/local_database_manager.cc b/chrome/browser/safe_browsing/local_database_manager.cc index 38395ff..6a02287 100644 --- a/chrome/browser/safe_browsing/local_database_manager.cc +++ b/chrome/browser/safe_browsing/local_database_manager.cc
@@ -34,6 +34,7 @@ #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing_db/util.h" +#include "components/safe_browsing_db/v4_get_hash_protocol_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "url/url_constants.h" @@ -270,8 +271,16 @@ } LocalSafeBrowsingDatabaseManager::LocalSafeBrowsingDatabaseManager( - const scoped_refptr<SafeBrowsingService>& service) - : sb_service_(service), + const scoped_refptr<SafeBrowsingService>& service) : + LocalSafeBrowsingDatabaseManager(service, NULL, V4GetHashProtocolConfig()) { +} + +LocalSafeBrowsingDatabaseManager::LocalSafeBrowsingDatabaseManager( + const scoped_refptr<SafeBrowsingService>& service, + net::URLRequestContextGetter* request_context_getter, + const V4GetHashProtocolConfig& config) + : SafeBrowsingDatabaseManager(request_context_getter, config), + sb_service_(service), database_(NULL), enabled_(false), enable_download_protection_(false),
diff --git a/chrome/browser/safe_browsing/local_database_manager.h b/chrome/browser/safe_browsing/local_database_manager.h index c1635034..6c543ad 100644 --- a/chrome/browser/safe_browsing/local_database_manager.h +++ b/chrome/browser/safe_browsing/local_database_manager.h
@@ -41,6 +41,7 @@ class SafeBrowsingDatabase; class ClientSideDetectionService; class DownloadProtectionService; +struct V4GetHashProtocolConfig; // Implemetation that manages a local database on disk. // @@ -100,10 +101,16 @@ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingCheck); }; - // Creates the safe browsing service. Need to initialize before using. + // Use this constructor for testing only. explicit LocalSafeBrowsingDatabaseManager( const scoped_refptr<SafeBrowsingService>& service); + // Creates the safe browsing service. Need to initialize before using. + LocalSafeBrowsingDatabaseManager( + const scoped_refptr<SafeBrowsingService>& service, + net::URLRequestContextGetter* request_context_getter, + const V4GetHashProtocolConfig& config); + // // SafeBrowsingDatabaseManager overrides //
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index 67f3f2fe..18b315a 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/safe_browsing/download_protection_service.h" #include "chrome/browser/safe_browsing/ping_manager.h" #include "chrome/browser/safe_browsing/protocol_manager.h" +#include "chrome/browser/safe_browsing/protocol_manager_helper.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" @@ -40,10 +41,12 @@ #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing_db/database_manager.h" +#include "components/safe_browsing_db/v4_get_hash_protocol_manager.h" #include "components/user_prefs/tracked/tracked_preference_validation_delegate.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/cookie_store_factory.h" #include "content/public/browser/notification_service.h" +#include "google_apis/google_api_keys.h" #include "net/cookies/cookie_store.h" #include "net/extras/sqlite/cookie_crypto_delegate.h" #include "net/url_request/url_request_context.h" @@ -399,10 +402,11 @@ } SafeBrowsingDatabaseManager* SafeBrowsingService::CreateDatabaseManager() { + V4GetHashProtocolConfig config = GetV4GetHashProtocolConfig(); #if defined(SAFE_BROWSING_DB_LOCAL) - return new LocalSafeBrowsingDatabaseManager(this); + return new LocalSafeBrowsingDatabaseManager(this, NULL, config); #elif defined(SAFE_BROWSING_DB_REMOTE) - return new RemoteSafeBrowsingDatabaseManager(); + return new RemoteSafeBrowsingDatabaseManager(NULL, config); #else return NULL; #endif @@ -428,27 +432,8 @@ SafeBrowsingProtocolConfig SafeBrowsingService::GetProtocolConfig() const { SafeBrowsingProtocolConfig config; - // On Windows, get the safe browsing client name from the browser - // distribution classes in installer util. These classes don't yet have - // an analog on non-Windows builds so just keep the name specified here. -#if defined(OS_WIN) - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); - config.client_name = dist->GetSafeBrowsingName(); -#else -#if defined(GOOGLE_CHROME_BUILD) - config.client_name = "googlechrome"; -#else - config.client_name = "chromium"; -#endif + config.client_name = GetProtocolConfigClientName(); - // Mark client string to allow server to differentiate mobile. -#if defined(OS_ANDROID) - config.client_name.append("-a"); -#elif defined(OS_IOS) - config.client_name.append("-i"); -#endif - -#endif // defined(OS_WIN) base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); config.disable_auto_update = cmdline->HasSwitch(switches::kSbDisableAutoUpdate) || @@ -461,6 +446,43 @@ return config; } +V4GetHashProtocolConfig +SafeBrowsingService::GetV4GetHashProtocolConfig() const { + V4GetHashProtocolConfig config; + config.client_name = GetProtocolConfigClientName(); + config.version = SafeBrowsingProtocolManagerHelper::Version(); + config.key_param = google_apis::GetAPIKey();; + + return config; +} + +std::string SafeBrowsingService::GetProtocolConfigClientName() const { + std::string client_name; + // On Windows, get the safe browsing client name from the browser + // distribution classes in installer util. These classes don't yet have + // an analog on non-Windows builds so just keep the name specified here. +#if defined(OS_WIN) + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + client_name = dist->GetSafeBrowsingName(); +#else +#if defined(GOOGLE_CHROME_BUILD) + client_name = "googlechrome"; +#else + client_name = "chromium"; +#endif + + // Mark client string to allow server to differentiate mobile. +#if defined(OS_ANDROID) + client_name.append("-a"); +#elif defined(OS_IOS) + client_name.append("-i"); +#endif + +#endif // defined(OS_WIN) + + return client_name; +} + // Any tests that create a DatabaseManager that isn't derived from // LocalSafeBrowsingDatabaseManager should override this to return NULL. SafeBrowsingProtocolManagerDelegate*
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h index ec8d59c..3c3435d 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.h +++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -58,6 +58,7 @@ class SafeBrowsingServiceFactory; class SafeBrowsingUIManager; class SafeBrowsingURLRequestContextGetter; +struct V4GetHashProtocolConfig; #if defined(FULL_SAFE_BROWSING) class IncidentReportingService; @@ -103,6 +104,12 @@ // Create a protocol config struct. virtual SafeBrowsingProtocolConfig GetProtocolConfig() const; + // Create a v4 protocol config struct. + virtual V4GetHashProtocolConfig GetV4GetHashProtocolConfig() const; + + // Returns the client_name field for both V3 and V4 protocol manager configs. + std::string GetProtocolConfigClientName() const; + // Get current enabled status. Must be called on IO thread. bool enabled() const { DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 5b209b30..6de8be6 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -162,7 +162,8 @@ } void Surface::Attach(Buffer* buffer) { - TRACE_EVENT1("exo", "Surface::Attach", "buffer", buffer->AsTracedValue()); + TRACE_EVENT1("exo", "Surface::Attach", "buffer", + buffer ? buffer->GetSize().ToString() : "null"); has_pending_contents_ = true; pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>();
diff --git a/components/safe_browsing_db/BUILD.gn b/components/safe_browsing_db/BUILD.gn index ad32884..5a58fe2 100644 --- a/components/safe_browsing_db/BUILD.gn +++ b/components/safe_browsing_db/BUILD.gn
@@ -49,9 +49,12 @@ ] deps = [ ":hit_report", + ":proto", ":util", + ":v4_get_hash_protocol_manager", "//base:base", "//content/public/common", + "//net", "//url:url", ] } @@ -100,7 +103,9 @@ ] deps = [ ":database_manager", + ":proto", ":safe_browsing_api_handler", + ":v4_get_hash_protocol_manager", "//base:base", "//components/variations", "//content/public/browser",
diff --git a/components/safe_browsing_db/database_manager.cc b/components/safe_browsing_db/database_manager.cc index b818722dd..6412cf0a 100644 --- a/components/safe_browsing_db/database_manager.cc +++ b/components/safe_browsing_db/database_manager.cc
@@ -4,10 +4,29 @@ #include "components/safe_browsing_db/database_manager.h" +#include "components/safe_browsing_db/v4_get_hash_protocol_manager.h" +#include "net/url_request/url_request_context_getter.h" #include "url/gurl.h" namespace safe_browsing { +SafeBrowsingDatabaseManager::SafeBrowsingDatabaseManager() + : SafeBrowsingDatabaseManager(NULL, V4GetHashProtocolConfig()) { +} + +SafeBrowsingDatabaseManager::SafeBrowsingDatabaseManager( + net::URLRequestContextGetter* request_context_getter, + const V4GetHashProtocolConfig& config) { + // Instantiate a V4GetHashProtocolManager. + if (request_context_getter) { + v4_get_hash_protocol_manager_.reset(V4GetHashProtocolManager::Create( + request_context_getter, config)); + } +} + +SafeBrowsingDatabaseManager::~SafeBrowsingDatabaseManager() { +} + void SafeBrowsingDatabaseManager::CheckApiBlacklistUrl(const GURL& url, Client* client) { // TODO(kcarattini): Implement this.
diff --git a/components/safe_browsing_db/database_manager.h b/components/safe_browsing_db/database_manager.h index fd8a276f..6ee8cbd 100644 --- a/components/safe_browsing_db/database_manager.h +++ b/components/safe_browsing_db/database_manager.h
@@ -20,8 +20,15 @@ #include "content/public/common/resource_type.h" #include "url/gurl.h" +namespace net { +class URLRequestContextGetter; +} // namespace net + namespace safe_browsing { +struct V4GetHashProtocolConfig; +class V4GetHashProtocolManager; + // Base class to either the locally-managed or a remotely-managed database. class SafeBrowsingDatabaseManager : public base::RefCountedThreadSafe<SafeBrowsingDatabaseManager> { @@ -162,9 +169,19 @@ virtual void StopOnIOThread(bool shutdown) = 0; protected: - virtual ~SafeBrowsingDatabaseManager() {} + // Use this constructor for testing only. + SafeBrowsingDatabaseManager(); + + // Constructs the database manager. + SafeBrowsingDatabaseManager( + net::URLRequestContextGetter* request_context_getter, + const V4GetHashProtocolConfig& config); + + virtual ~SafeBrowsingDatabaseManager(); friend class base::RefCountedThreadSafe<SafeBrowsingDatabaseManager>; + + std::unique_ptr<V4GetHashProtocolManager> v4_get_hash_protocol_manager_; }; // class SafeBrowsingDatabaseManager } // namespace safe_browsing
diff --git a/components/safe_browsing_db/remote_database_manager.cc b/components/safe_browsing_db/remote_database_manager.cc index e699b305..adcb0be 100644 --- a/components/safe_browsing_db/remote_database_manager.cc +++ b/components/safe_browsing_db/remote_database_manager.cc
@@ -11,6 +11,7 @@ #include "base/strings/string_split.h" #include "base/timer/elapsed_timer.h" #include "components/safe_browsing_db/safe_browsing_api_handler.h" +#include "components/safe_browsing_db/v4_get_hash_protocol_manager.h" #include "components/variations/variations_associated_data.h" #include "content/public/browser/browser_thread.h" @@ -93,7 +94,14 @@ // TODO(nparker): Add more tests for this class RemoteSafeBrowsingDatabaseManager::RemoteSafeBrowsingDatabaseManager() - : enabled_(false) { + : RemoteSafeBrowsingDatabaseManager(NULL, V4GetHashProtocolConfig()) { +} + +RemoteSafeBrowsingDatabaseManager::RemoteSafeBrowsingDatabaseManager( + net::URLRequestContextGetter* request_context_getter, + const V4GetHashProtocolConfig& config) + : SafeBrowsingDatabaseManager(request_context_getter, config), + enabled_(false) { // Decide which resource types to check. These two are the minimum. resource_types_to_check_.insert(content::RESOURCE_TYPE_MAIN_FRAME); resource_types_to_check_.insert(content::RESOURCE_TYPE_SUB_FRAME);
diff --git a/components/safe_browsing_db/remote_database_manager.h b/components/safe_browsing_db/remote_database_manager.h index 6b2c764..143902c 100644 --- a/components/safe_browsing_db/remote_database_manager.h +++ b/components/safe_browsing_db/remote_database_manager.h
@@ -18,15 +18,26 @@ #include "components/safe_browsing_db/database_manager.h" #include "url/gurl.h" +namespace net { +class URLRequestContextGetter; +} + namespace safe_browsing { +struct V4GetHashProtocolConfig; + // An implementation that proxies requests to a service outside of Chromium. // Does not manage a local database. class RemoteSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { public: + // Use this constructor for testing only. + RemoteSafeBrowsingDatabaseManager(); + // Construct RemoteSafeBrowsingDatabaseManager. // Must be initialized by calling StartOnIOThread() before using. - RemoteSafeBrowsingDatabaseManager(); + RemoteSafeBrowsingDatabaseManager( + net::URLRequestContextGetter* request_context_getter, + const V4GetHashProtocolConfig& config); // // SafeBrowsingDatabaseManager implementation
diff --git a/content/renderer/mojo/service_registry_js_wrapper.cc b/content/renderer/mojo/service_registry_js_wrapper.cc index e45decc3..14f4dc3 100644 --- a/content/renderer/mojo/service_registry_js_wrapper.cc +++ b/content/renderer/mojo/service_registry_js_wrapper.cc
@@ -10,33 +10,10 @@ #include "content/common/mojo/service_registry_impl.h" #include "content/public/common/service_registry.h" #include "mojo/edk/js/handle.h" -#include "v8/include/v8.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" namespace content { -namespace { - -struct JsFactoryDeleter { - inline void operator()(v8::Persistent<v8::Function>* ptr) const { - ptr->Reset(); - delete ptr; - } -}; - -using ScopedJsFactory = - scoped_ptr<v8::Persistent<v8::Function>, JsFactoryDeleter>; - -void CallJsFactory(ScopedJsFactory factory, - mojo::ScopedMessagePipeHandle pipe) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - v8::Local<v8::Value> argv[] = { - gin::ConvertToV8(isolate, mojo::Handle(pipe.release().value())) - }; - factory->Get(isolate)->Call(v8::Undefined(isolate), 1, argv); -} - -} // namespace - gin::WrapperInfo ServiceRegistryJsWrapper::kWrapperInfo = { gin::kEmbedderNativeGin}; const char ServiceRegistryJsWrapper::kModuleName[] = @@ -48,10 +25,12 @@ // static gin::Handle<ServiceRegistryJsWrapper> ServiceRegistryJsWrapper::Create( v8::Isolate* isolate, + v8::Handle<v8::Context> context, ServiceRegistry* service_registry) { return gin::CreateHandle( isolate, new ServiceRegistryJsWrapper( + isolate, context, static_cast<ServiceRegistryImpl*>(service_registry)->GetWeakPtr())); } @@ -80,16 +59,45 @@ static_cast<ServiceRegistryImpl*>(service_registry_.get()); if (!registry) return; - ScopedJsFactory factory( - new v8::Persistent<v8::Function>(v8::Isolate::GetCurrent(), - service_factory)); + ScopedJsFactory factory(v8::Isolate::GetCurrent(), service_factory); registry->AddServiceOverrideForTesting( - service_name, base::Bind(&CallJsFactory, base::Passed(&factory))); + service_name, base::Bind(&ServiceRegistryJsWrapper::CallJsFactory, + weak_factory_.GetWeakPtr(), factory)); } ServiceRegistryJsWrapper::ServiceRegistryJsWrapper( + v8::Isolate* isolate, + v8::Handle<v8::Context> context, base::WeakPtr<ServiceRegistry> service_registry) - : service_registry_(service_registry) { + : isolate_(isolate), + context_(isolate, context), + service_registry_(service_registry), + weak_factory_(this) { + context_.SetWeak(this, &ServiceRegistryJsWrapper::ClearContext, + v8::WeakCallbackType::kParameter); +} + +void ServiceRegistryJsWrapper::CallJsFactory( + const ScopedJsFactory& factory, + mojo::ScopedMessagePipeHandle pipe) { + if (context_.IsEmpty()) + return; + + v8::HandleScope handle_scope(isolate_); + v8::Handle<v8::Context> context = context_.Get(isolate_); + v8::Context::Scope context_scope(context); + v8::Local<v8::Value> argv[] = { + gin::ConvertToV8(isolate_, mojo::Handle(pipe.release().value()))}; + blink::WebLocalFrame::frameForContext(context) + ->callFunctionEvenIfScriptDisabled(factory.Get(isolate_), + v8::Undefined(isolate_), 1, argv); +} + +// static +void ServiceRegistryJsWrapper::ClearContext( + const v8::WeakCallbackInfo<ServiceRegistryJsWrapper>& data) { + ServiceRegistryJsWrapper* service_registry = data.GetParameter(); + service_registry->context_.Reset(); } } // namespace content
diff --git a/content/renderer/mojo/service_registry_js_wrapper.h b/content/renderer/mojo/service_registry_js_wrapper.h index 543d214..8fe8a3eb 100644 --- a/content/renderer/mojo/service_registry_js_wrapper.h +++ b/content/renderer/mojo/service_registry_js_wrapper.h
@@ -12,11 +12,8 @@ #include "gin/handle.h" #include "gin/object_template_builder.h" #include "gin/wrappable.h" -#include "mojo/public/cpp/system/handle.h" - -namespace v8 { -class Isolate; -} +#include "mojo/public/cpp/system/message_pipe.h" +#include "v8/include/v8.h" namespace content { @@ -30,6 +27,7 @@ ~ServiceRegistryJsWrapper() override; static gin::Handle<ServiceRegistryJsWrapper> Create( v8::Isolate* isolate, + v8::Handle<v8::Context> context, ServiceRegistry* service_registry); // gin::Wrappable<ServiceRegistryJsWrapper> overrides. @@ -45,11 +43,25 @@ static const char kModuleName[]; private: - explicit ServiceRegistryJsWrapper( - base::WeakPtr<ServiceRegistry> service_registry); + using ScopedJsFactory = + v8::Persistent<v8::Function, v8::CopyablePersistentTraits<v8::Function>>; + ServiceRegistryJsWrapper(v8::Isolate* isolate, + v8::Handle<v8::Context> context, + base::WeakPtr<ServiceRegistry> service_registry); + + void CallJsFactory(const ScopedJsFactory& factory, + mojo::ScopedMessagePipeHandle pipe); + + static void ClearContext( + const v8::WeakCallbackInfo<ServiceRegistryJsWrapper>& data); + + v8::Isolate* isolate_; + v8::Global<v8::Context> context_; base::WeakPtr<ServiceRegistry> service_registry_; + base::WeakPtrFactory<ServiceRegistryJsWrapper> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(ServiceRegistryJsWrapper); };
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 1ef1619..a906c38 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2382,9 +2382,9 @@ registry->AddBuiltinModule(isolate, mojo::edk::js::Support::kModuleName, mojo::edk::js::Support::GetModule(isolate)); registry->AddBuiltinModule( - isolate, - ServiceRegistryJsWrapper::kModuleName, - ServiceRegistryJsWrapper::Create(isolate, &service_registry_).ToV8()); + isolate, ServiceRegistryJsWrapper::kModuleName, + ServiceRegistryJsWrapper::Create(isolate, context, &service_registry_) + .ToV8()); } void RenderFrameImpl::AddMessageToConsole(ConsoleMessageLevel level,
diff --git a/ipc/unix_domain_socket_util.cc b/ipc/unix_domain_socket_util.cc index 86367998..6e06fe7 100644 --- a/ipc/unix_domain_socket_util.cc +++ b/ipc/unix_domain_socket_util.cc
@@ -24,37 +24,24 @@ namespace { -// Returns fd (>= 0) on success, -1 on failure. If successful, fills in +// Returns true on success, false otherwise. If successful, fills in // |unix_addr| with the appropriate data for the socket, and sets // |unix_addr_len| to the length of the data therein. -int MakeUnixAddrForPath(const std::string& socket_name, - struct sockaddr_un* unix_addr, - size_t* unix_addr_len) { +bool MakeUnixAddrForPath(const std::string& socket_name, + struct sockaddr_un* unix_addr, + size_t* unix_addr_len) { DCHECK(unix_addr); DCHECK(unix_addr_len); if (socket_name.length() == 0) { LOG(ERROR) << "Empty socket name provided for unix socket address."; - return -1; + return false; } // We reject socket_name.length() == kMaxSocketNameLength to make room for // the NUL terminator at the end of the string. if (socket_name.length() >= kMaxSocketNameLength) { LOG(ERROR) << "Socket name too long: " << socket_name; - return -1; - } - - // Create socket. - base::ScopedFD fd(socket(AF_UNIX, SOCK_STREAM, 0)); - if (!fd.is_valid()) { - PLOG(ERROR) << "socket"; - return -1; - } - - // Make socket non-blocking - if (!base::SetNonBlocking(fd.get())) { - PLOG(ERROR) << "base::SetNonBlocking() failed " << fd.get(); - return -1; + return false; } // Create unix_addr structure. @@ -63,7 +50,25 @@ strncpy(unix_addr->sun_path, socket_name.c_str(), kMaxSocketNameLength); *unix_addr_len = offsetof(struct sockaddr_un, sun_path) + socket_name.length(); - return fd.release(); + return true; +} + +// Returns a valid socket on success. +base::ScopedFD CreateUnixDomainSocket() { + // Create socket. + base::ScopedFD fd(socket(AF_UNIX, SOCK_STREAM, 0)); + if (!fd.is_valid()) { + PLOG(ERROR) << "Failed to create AF_UNIX socket."; + return base::ScopedFD(); + } + + // Make socket non-blocking. + if (!base::SetNonBlocking(fd.get())) { + PLOG(ERROR) << "base::SetNonBlocking() failed " << fd.get(); + return base::ScopedFD(); + } + + return fd; } bool IsRecoverableError() { @@ -80,8 +85,9 @@ const std::string socket_name = socket_path.value(); struct sockaddr_un unix_addr; size_t unix_addr_len; - base::ScopedFD fd( - MakeUnixAddrForPath(socket_name, &unix_addr, &unix_addr_len)); + if (!MakeUnixAddrForPath(socket_name, &unix_addr, &unix_addr_len)) + return false; + base::ScopedFD fd(CreateUnixDomainSocket()); if (!fd.is_valid()) return false; @@ -122,8 +128,9 @@ struct sockaddr_un unix_addr; size_t unix_addr_len; - base::ScopedFD fd( - MakeUnixAddrForPath(socket_path.value(), &unix_addr, &unix_addr_len)); + if (!MakeUnixAddrForPath(socket_path.value(), &unix_addr, &unix_addr_len)) + return false; + base::ScopedFD fd(CreateUnixDomainSocket()); if (!fd.is_valid()) return false;
diff --git a/mojo/edk/embedder/embedder.cc b/mojo/edk/embedder/embedder.cc index 1feadda..62702af 100644 --- a/mojo/edk/embedder/embedder.cc +++ b/mojo/edk/embedder/embedder.cc
@@ -87,6 +87,15 @@ shared_memory_handle, num_bytes, read_only, mojo_wrapper_handle); } +MojoResult PassSharedMemoryHandle( + MojoHandle mojo_handle, + base::SharedMemoryHandle* shared_memory_handle, + size_t* num_bytes, + bool* read_only) { + return internal::g_core->PassSharedMemoryHandle( + mojo_handle, shared_memory_handle, num_bytes, read_only); +} + void InitIPCSupport(ProcessDelegate* process_delegate, scoped_refptr<base::TaskRunner> io_thread_task_runner) { CHECK(internal::g_core);
diff --git a/mojo/edk/embedder/embedder.h b/mojo/edk/embedder/embedder.h index e34ef5c..95b3b21 100644 --- a/mojo/edk/embedder/embedder.h +++ b/mojo/edk/embedder/embedder.h
@@ -94,6 +94,21 @@ bool read_only, MojoHandle* mojo_wrapper_handle); +// Retrieves the underlying |SharedMemoryHandle| from a shared buffer +// |MojoHandle| and closes the handle. If successful, |num_bytes| will contain +// the size of the shared memory buffer and |read_only| will contain whether the +// buffer handle is read-only. Both |num_bytes| and |read_only| may be null. +// Note: The value of |shared_memory_handle| may be +// base::SharedMemory::NULLHandle(), even if this function returns success. +// Callers should perform appropriate checks. +// TODO(crbug.com/556587): Support read-only handles. Currently, |read_only| +// will always return |false|. +MOJO_SYSTEM_IMPL_EXPORT MojoResult +PassSharedMemoryHandle(MojoHandle mojo_handle, + base::SharedMemoryHandle* shared_memory_handle, + size_t* num_bytes, + bool* read_only); + // Initialialization/shutdown for interprocess communication (IPC) ------------- // |InitIPCSupport()| sets up the subsystem for interprocess communication,
diff --git a/mojo/edk/embedder/embedder_unittest.cc b/mojo/edk/embedder/embedder_unittest.cc index 1a36378..9b96c1f5 100644 --- a/mojo/edk/embedder/embedder_unittest.cc +++ b/mojo/edk/embedder/embedder_unittest.cc
@@ -362,8 +362,19 @@ memcpy(buffer, kByeWorld, sizeof(kByeWorld)); WriteMessage(client_mp, "bye"); - // 5. Close |sb1|. - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(sb1)); + // 5. Extract the shared memory handle and ensure we can map it and read the + // contents. + base::SharedMemoryHandle shm_handle; + ASSERT_EQ(MOJO_RESULT_OK, + PassSharedMemoryHandle(sb1, &shm_handle, nullptr, nullptr)); + base::SharedMemory shared_memory(shm_handle, false); + ASSERT_TRUE(shared_memory.Map(123)); + EXPECT_NE(buffer, shared_memory.memory()); + EXPECT_EQ(kByeWorld, std::string(static_cast<char*>(shared_memory.memory()))); + + // 6. Close |sb1|. Should fail because |PassSharedMemoryHandle()| should have + // closed the handle. + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(sb1)); } // TODO(vtl): Test immediate write & close.
diff --git a/mojo/edk/embedder/platform_shared_buffer.cc b/mojo/edk/embedder/platform_shared_buffer.cc index 9dce8d5..bbcf15d4 100644 --- a/mojo/edk/embedder/platform_shared_buffer.cc +++ b/mojo/edk/embedder/platform_shared_buffer.cc
@@ -152,6 +152,13 @@ return handle; } +base::SharedMemoryHandle PlatformSharedBuffer::DuplicateSharedMemoryHandle() { + DCHECK(shared_memory_); + + base::AutoLock locker(lock_); + return base::SharedMemory::DuplicateHandle(shared_memory_->handle()); +} + PlatformSharedBuffer::PlatformSharedBuffer(size_t num_bytes) : num_bytes_(num_bytes) {}
diff --git a/mojo/edk/embedder/platform_shared_buffer.h b/mojo/edk/embedder/platform_shared_buffer.h index 623fb9e3..5494122 100644 --- a/mojo/edk/embedder/platform_shared_buffer.h +++ b/mojo/edk/embedder/platform_shared_buffer.h
@@ -74,6 +74,9 @@ // TODO(vtl): On POSIX, we'll need two FDs to support sharing read-only. ScopedPlatformHandle DuplicatePlatformHandle(); + // Duplicates the underlying shared memory handle and passes it to the caller. + base::SharedMemoryHandle DuplicateSharedMemoryHandle(); + // Passes the underlying platform handle to the caller. This should only be // called if there's a unique reference to this object (owned by the caller). // After calling this, this object should no longer be used, but should only
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc index 11892be2..69c918c 100644 --- a/mojo/edk/system/core.cc +++ b/mojo/edk/system/core.cc
@@ -163,6 +163,48 @@ return MOJO_RESULT_OK; } +MojoResult Core::PassSharedMemoryHandle( + MojoHandle mojo_handle, + base::SharedMemoryHandle* shared_memory_handle, + size_t* num_bytes, + bool* read_only) { + if (!shared_memory_handle) + return MOJO_RESULT_INVALID_ARGUMENT; + + scoped_refptr<Dispatcher> dispatcher; + MojoResult result = MOJO_RESULT_OK; + { + base::AutoLock lock(handles_lock_); + // Get the dispatcher and check it before removing it from the handle table + // to ensure that the dispatcher is of the correct type. This ensures we + // don't close and remove the wrong type of dispatcher. + dispatcher = handles_.GetDispatcher(mojo_handle); + if (!dispatcher || dispatcher->GetType() != Dispatcher::Type::SHARED_BUFFER) + return MOJO_RESULT_INVALID_ARGUMENT; + + result = handles_.GetAndRemoveDispatcher(mojo_handle, &dispatcher); + if (result != MOJO_RESULT_OK) + return result; + } + + SharedBufferDispatcher* shm_dispatcher = + static_cast<SharedBufferDispatcher*>(dispatcher.get()); + scoped_refptr<PlatformSharedBuffer> platform_shared_buffer = + shm_dispatcher->PassPlatformSharedBuffer(); + + if (!platform_shared_buffer) + return MOJO_RESULT_INVALID_ARGUMENT; + + if (num_bytes) + *num_bytes = platform_shared_buffer->GetNumBytes(); + if (read_only) + *read_only = false; + *shared_memory_handle = platform_shared_buffer->DuplicateSharedMemoryHandle(); + + shm_dispatcher->Close(); + return result; +} + void Core::RequestShutdown(const base::Closure& callback) { base::Closure on_shutdown; if (base::ThreadTaskRunnerHandle::IsSet()) {
diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h index 938726a..e2a22b0 100644 --- a/mojo/edk/system/core.h +++ b/mojo/edk/system/core.h
@@ -88,6 +88,12 @@ bool read_only, MojoHandle* mojo_wrapper_handle); + MojoResult PassSharedMemoryHandle( + MojoHandle mojo_handle, + base::SharedMemoryHandle* shared_memory_handle, + size_t* num_bytes, + bool* read_only); + // Requests that the EDK tear itself down. |callback| will be called once // the shutdown process is complete. Note that |callback| is always called // asynchronously on the calling thread if said thread is running a message
diff --git a/mojo/edk/system/shared_buffer_dispatcher.cc b/mojo/edk/system/shared_buffer_dispatcher.cc index 1484166..1805a92 100644 --- a/mojo/edk/system/shared_buffer_dispatcher.cc +++ b/mojo/edk/system/shared_buffer_dispatcher.cc
@@ -139,13 +139,24 @@ return CreateInternal(std::move(shared_buffer)); } +scoped_refptr<PlatformSharedBuffer> +SharedBufferDispatcher::PassPlatformSharedBuffer() { + base::AutoLock lock(lock_); + if (!shared_buffer_ || in_transit_) + return nullptr; + + scoped_refptr<PlatformSharedBuffer> retval = shared_buffer_; + shared_buffer_ = nullptr; + return retval; +} + Dispatcher::Type SharedBufferDispatcher::GetType() const { return Type::SHARED_BUFFER; } MojoResult SharedBufferDispatcher::Close() { base::AutoLock lock(lock_); - if (!shared_buffer_ || in_transit_) + if (in_transit_) return MOJO_RESULT_INVALID_ARGUMENT; shared_buffer_ = nullptr;
diff --git a/mojo/edk/system/shared_buffer_dispatcher.h b/mojo/edk/system/shared_buffer_dispatcher.h index 011a43a..a8d5bcda 100644 --- a/mojo/edk/system/shared_buffer_dispatcher.h +++ b/mojo/edk/system/shared_buffer_dispatcher.h
@@ -61,6 +61,10 @@ PlatformHandle* platform_handles, size_t num_platform_handles); + // Passes the underlying platform shared buffer. This dispatcher must be + // closed after calling this function. + scoped_refptr<PlatformSharedBuffer> PassPlatformSharedBuffer(); + // Dispatcher: Type GetType() const override; MojoResult Close() override;
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/css3-gradient-parsing-expected.txt b/third_party/WebKit/LayoutTests/fast/gradients/css3-gradient-parsing-expected.txt index fd9b1cf..82406f37 100644 --- a/third_party/WebKit/LayoutTests/fast/gradients/css3-gradient-parsing-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/gradients/css3-gradient-parsing-expected.txt
@@ -27,18 +27,18 @@ PASS testGradient("background-image: -webkit-radial-gradient(white, black)", "background-image") is "-webkit-radial-gradient(center, white, black)" -PASS testGradient("background-image: -webkit-radial-gradient(bottom right, white, black)", "background-image") is "-webkit-radial-gradient(100% 100%, white, black)" +PASS testGradient("background-image: -webkit-radial-gradient(bottom right, white, black)", "background-image") is "-webkit-radial-gradient(right bottom, white, black)" PASS testGradient("background-image: -webkit-radial-gradient(cover, white, black)", "background-image") is "-webkit-radial-gradient(center, ellipse cover, white, black)" PASS testGradient("background-image: -webkit-radial-gradient(circle, white, black)", "background-image") is "-webkit-radial-gradient(center, circle cover, white, black)" PASS testGradient("background-image: -webkit-radial-gradient(circle contain, white, black)", "background-image") is "-webkit-radial-gradient(center, circle contain, white, black)" -PASS testGradient("background-image: -webkit-radial-gradient(top, circle contain, white, black)", "background-image") is "-webkit-radial-gradient(50% 0%, circle contain, white, black)" -PASS testGradient("background-image: -webkit-radial-gradient(top left, circle contain, white, black)", "background-image") is "-webkit-radial-gradient(0% 0%, circle contain, white, black)" +PASS testGradient("background-image: -webkit-radial-gradient(top, circle contain, white, black)", "background-image") is "-webkit-radial-gradient(center top, circle contain, white, black)" +PASS testGradient("background-image: -webkit-radial-gradient(top left, circle contain, white, black)", "background-image") is "-webkit-radial-gradient(left top, circle contain, white, black)" PASS testGradient("background-image: -webkit-radial-gradient(10px 20%, circle contain, white, black)", "background-image") is "-webkit-radial-gradient(10px 20%, circle contain, white, black)" PASS testGradient("background-image: -webkit-radial-gradient(10px, 20%, circle contain, white, black)", "background-image") is "none" PASS testGradient("background-image: -webkit-radial-gradient(circle 10px 20%, circle contain, white, black)", "background-image") is "none" PASS testGradient("background-image: -webkit-radial-gradient(circle 10px, circle contain, white, black)", "background-image") is "none" PASS testGradient("background-image: -webkit-radial-gradient(center, 10px, white, black)", "background-image") is "none" -PASS testGradient("background-image: -webkit-radial-gradient(center, 10px 10px, white, black)", "background-image") is "-webkit-radial-gradient(50% 50%, 10px 10px, white, black)" +PASS testGradient("background-image: -webkit-radial-gradient(center, 10px 10px, white, black)", "background-image") is "-webkit-radial-gradient(center center, 10px 10px, white, black)" PASS testGradient("background-image: -webkit-radial-gradient(ellipse farthest-corner, white, black)", "background-image") is "-webkit-radial-gradient(center, ellipse farthest-corner, white, black)" PASS testGradient("background-image: -webkit-radial-gradient(circle closest-side, white, black)", "background-image") is "-webkit-radial-gradient(center, circle closest-side, white, black)" -webkit-repeating-radial-gradient
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/css3-gradient-parsing.html b/third_party/WebKit/LayoutTests/fast/gradients/css3-gradient-parsing.html index d89fa56..d13c8ca 100644 --- a/third_party/WebKit/LayoutTests/fast/gradients/css3-gradient-parsing.html +++ b/third_party/WebKit/LayoutTests/fast/gradients/css3-gradient-parsing.html
@@ -53,18 +53,18 @@ debug('<p>-webkit-radial-gradient</p>'); shouldBe('testGradient("background-image: -webkit-radial-gradient(white, black)", "background-image")', '"-webkit-radial-gradient(center, white, black)"'); -shouldBe('testGradient("background-image: -webkit-radial-gradient(bottom right, white, black)", "background-image")', '"-webkit-radial-gradient(100% 100%, white, black)"'); +shouldBe('testGradient("background-image: -webkit-radial-gradient(bottom right, white, black)", "background-image")', '"-webkit-radial-gradient(right bottom, white, black)"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(cover, white, black)", "background-image")', '"-webkit-radial-gradient(center, ellipse cover, white, black)"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(circle, white, black)", "background-image")', '"-webkit-radial-gradient(center, circle cover, white, black)"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(circle contain, white, black)", "background-image")', '"-webkit-radial-gradient(center, circle contain, white, black)"'); -shouldBe('testGradient("background-image: -webkit-radial-gradient(top, circle contain, white, black)", "background-image")', '"-webkit-radial-gradient(50% 0%, circle contain, white, black)"'); -shouldBe('testGradient("background-image: -webkit-radial-gradient(top left, circle contain, white, black)", "background-image")', '"-webkit-radial-gradient(0% 0%, circle contain, white, black)"'); +shouldBe('testGradient("background-image: -webkit-radial-gradient(top, circle contain, white, black)", "background-image")', '"-webkit-radial-gradient(center top, circle contain, white, black)"'); +shouldBe('testGradient("background-image: -webkit-radial-gradient(top left, circle contain, white, black)", "background-image")', '"-webkit-radial-gradient(left top, circle contain, white, black)"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(10px 20%, circle contain, white, black)", "background-image")', '"-webkit-radial-gradient(10px 20%, circle contain, white, black)"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(10px, 20%, circle contain, white, black)", "background-image")', '"none"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(circle 10px 20%, circle contain, white, black)", "background-image")', '"none"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(circle 10px, circle contain, white, black)", "background-image")', '"none"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(center, 10px, white, black)", "background-image")', '"none"'); -shouldBe('testGradient("background-image: -webkit-radial-gradient(center, 10px 10px, white, black)", "background-image")', '"-webkit-radial-gradient(50% 50%, 10px 10px, white, black)"'); +shouldBe('testGradient("background-image: -webkit-radial-gradient(center, 10px 10px, white, black)", "background-image")', '"-webkit-radial-gradient(center center, 10px 10px, white, black)"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(ellipse farthest-corner, white, black)", "background-image")', '"-webkit-radial-gradient(center, ellipse farthest-corner, white, black)"'); shouldBe('testGradient("background-image: -webkit-radial-gradient(circle closest-side, white, black)", "background-image")', '"-webkit-radial-gradient(center, circle closest-side, white, black)"');
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-gradient-parsing-expected.txt b/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-gradient-parsing-expected.txt index 565771d..fe964bc 100644 --- a/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-gradient-parsing-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-gradient-parsing-expected.txt
@@ -41,7 +41,7 @@ PASS testGradient("background-image: radial-gradient(white, black)") is "radial-gradient(white, black)" -PASS testGradient("background-image: radial-gradient(at bottom right, white, black)") is "radial-gradient(at 100% 100%, white, black)" +PASS testGradient("background-image: radial-gradient(at bottom right, white, black)") is "radial-gradient(at right bottom, white, black)" PASS testGradient("background-image: radial-gradient(farthest-corner, white, black)") is "radial-gradient(white, black)" PASS testGradient("background-image: radial-gradient(farthest-corner, white, 35%, black)") is "radial-gradient(white, 35%, black)" PASS testGradient("background-image: radial-gradient(closest-side, white, black)") is "radial-gradient(closest-side, white, black)" @@ -51,8 +51,8 @@ PASS testGradient("background-image: radial-gradient(circle, white, black)") is "radial-gradient(circle, white, black)" PASS testGradient("background-image: radial-gradient(circle farthest-corner, white, black)") is "radial-gradient(circle, white, black)" PASS testGradient("background-image: radial-gradient(circle closest-side, white, black)") is "radial-gradient(circle closest-side, white, black)" -PASS testGradient("background-image: radial-gradient(circle closest-side at top, white, black)") is "radial-gradient(circle closest-side at 50% 0%, white, black)" -PASS testGradient("background-image: radial-gradient(circle closest-side at top left, white, black)") is "radial-gradient(circle closest-side at 0% 0%, white, black)" +PASS testGradient("background-image: radial-gradient(circle closest-side at top, white, black)") is "radial-gradient(circle closest-side at center top, white, black)" +PASS testGradient("background-image: radial-gradient(circle closest-side at top left, white, black)") is "radial-gradient(circle closest-side at left top, white, black)" PASS testGradient("background-image: radial-gradient(circle closest-side at 10px 20%, white, black)") is "radial-gradient(circle closest-side at 10px 20%, white, black)" PASS testGradient("background-image: radial-gradient(at 10px 20% circle closest-side, white, black)") is "none" PASS testGradient("background-image: radial-gradient(circle at 10px 20% circle, white, black)") is "none" @@ -69,10 +69,10 @@ PASS testGradient("background-image: radial-gradient(ellipse 10px, white, 25%, 75%, black)") is "none" PASS testGradient("background-image: radial-gradient(ellipse 10px 20px, white, black)") is "radial-gradient(10px 20px, white, black)" PASS testGradient("background-image: radial-gradient(circle 10px, white, black)") is "radial-gradient(10px, white, black)" -PASS testGradient("background-image: radial-gradient(10px 10px at center, white, black)") is "radial-gradient(10px 10px at 50% 50%, white, black)" -PASS testGradient("background-image: radial-gradient(10px 10px at center, white, 50%, black)") is "radial-gradient(10px 10px at 50% 50%, white, 50%, black)" -PASS testGradient("background-image: radial-gradient(10px 10px at center, white, 0%, black)") is "radial-gradient(10px 10px at 50% 50%, white, 0%, black)" -PASS testGradient("background-image: radial-gradient(10px 10px at center, white, 100%, black)") is "radial-gradient(10px 10px at 50% 50%, white, 100%, black)" +PASS testGradient("background-image: radial-gradient(10px 10px at center, white, black)") is "radial-gradient(10px 10px at center center, white, black)" +PASS testGradient("background-image: radial-gradient(10px 10px at center, white, 50%, black)") is "radial-gradient(10px 10px at center center, white, 50%, black)" +PASS testGradient("background-image: radial-gradient(10px 10px at center, white, 0%, black)") is "radial-gradient(10px 10px at center center, white, 0%, black)" +PASS testGradient("background-image: radial-gradient(10px 10px at center, white, 100%, black)") is "radial-gradient(10px 10px at center center, white, 100%, black)" repeating-radial-gradient
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-gradient-parsing.html b/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-gradient-parsing.html index 1793fcf..bb5f971 100644 --- a/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-gradient-parsing.html +++ b/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-gradient-parsing.html
@@ -60,7 +60,7 @@ debug('<p>radial-gradient</p>'); shouldBe('testGradient("background-image: radial-gradient(white, black)")', '"radial-gradient(white, black)"'); -shouldBe('testGradient("background-image: radial-gradient(at bottom right, white, black)")', '"radial-gradient(at 100% 100%, white, black)"'); +shouldBe('testGradient("background-image: radial-gradient(at bottom right, white, black)")', '"radial-gradient(at right bottom, white, black)"'); shouldBe('testGradient("background-image: radial-gradient(farthest-corner, white, black)")', '"radial-gradient(white, black)"'); shouldBe('testGradient("background-image: radial-gradient(farthest-corner, white, 35%, black)")', '"radial-gradient(white, 35%, black)"'); shouldBe('testGradient("background-image: radial-gradient(closest-side, white, black)")', '"radial-gradient(closest-side, white, black)"'); @@ -70,8 +70,8 @@ shouldBe('testGradient("background-image: radial-gradient(circle, white, black)")', '"radial-gradient(circle, white, black)"'); shouldBe('testGradient("background-image: radial-gradient(circle farthest-corner, white, black)")', '"radial-gradient(circle, white, black)"'); shouldBe('testGradient("background-image: radial-gradient(circle closest-side, white, black)")', '"radial-gradient(circle closest-side, white, black)"'); -shouldBe('testGradient("background-image: radial-gradient(circle closest-side at top, white, black)")', '"radial-gradient(circle closest-side at 50% 0%, white, black)"'); -shouldBe('testGradient("background-image: radial-gradient(circle closest-side at top left, white, black)")', '"radial-gradient(circle closest-side at 0% 0%, white, black)"'); +shouldBe('testGradient("background-image: radial-gradient(circle closest-side at top, white, black)")', '"radial-gradient(circle closest-side at center top, white, black)"'); +shouldBe('testGradient("background-image: radial-gradient(circle closest-side at top left, white, black)")', '"radial-gradient(circle closest-side at left top, white, black)"'); shouldBe('testGradient("background-image: radial-gradient(circle closest-side at 10px 20%, white, black)")', '"radial-gradient(circle closest-side at 10px 20%, white, black)"'); shouldBe('testGradient("background-image: radial-gradient(at 10px 20% circle closest-side, white, black)")', '"none"'); shouldBe('testGradient("background-image: radial-gradient(circle at 10px 20% circle, white, black)")', '"none"'); @@ -88,10 +88,10 @@ shouldBe('testGradient("background-image: radial-gradient(ellipse 10px, white, 25%, 75%, black)")', '"none"'); shouldBe('testGradient("background-image: radial-gradient(ellipse 10px 20px, white, black)")', '"radial-gradient(10px 20px, white, black)"'); shouldBe('testGradient("background-image: radial-gradient(circle 10px, white, black)")', '"radial-gradient(10px, white, black)"'); -shouldBe('testGradient("background-image: radial-gradient(10px 10px at center, white, black)")', '"radial-gradient(10px 10px at 50% 50%, white, black)"'); -shouldBe('testGradient("background-image: radial-gradient(10px 10px at center, white, 50%, black)")', '"radial-gradient(10px 10px at 50% 50%, white, 50%, black)"'); -shouldBe('testGradient("background-image: radial-gradient(10px 10px at center, white, 0%, black)")', '"radial-gradient(10px 10px at 50% 50%, white, 0%, black)"'); -shouldBe('testGradient("background-image: radial-gradient(10px 10px at center, white, 100%, black)")', '"radial-gradient(10px 10px at 50% 50%, white, 100%, black)"'); +shouldBe('testGradient("background-image: radial-gradient(10px 10px at center, white, black)")', '"radial-gradient(10px 10px at center center, white, black)"'); +shouldBe('testGradient("background-image: radial-gradient(10px 10px at center, white, 50%, black)")', '"radial-gradient(10px 10px at center center, white, 50%, black)"'); +shouldBe('testGradient("background-image: radial-gradient(10px 10px at center, white, 0%, black)")', '"radial-gradient(10px 10px at center center, white, 0%, black)"'); +shouldBe('testGradient("background-image: radial-gradient(10px 10px at center, white, 100%, black)")', '"radial-gradient(10px 10px at center center, white, 100%, black)"'); debug('<p>repeating-radial-gradient</p>'); shouldBe('testGradient("background-image: repeating-radial-gradient(white, black)")', '"repeating-radial-gradient(white, black)"');
diff --git a/third_party/WebKit/LayoutTests/harness-tests/mojo-helpers.html b/third_party/WebKit/LayoutTests/harness-tests/mojo-helpers.html index 79cbcec0..005b8cdc 100644 --- a/third_party/WebKit/LayoutTests/harness-tests/mojo-helpers.html +++ b/third_party/WebKit/LayoutTests/harness-tests/mojo-helpers.html
@@ -16,12 +16,17 @@ mojo_test(mojo => { return new Promise(resolve => { - // Complete the test as soon as a request comes in for a Frobinator service. - mojo.serviceRegistry.addServiceOverrideForTesting('Frobinator', resolve); + let calls = 0; + // Complete the test as soon as two requests come in for a Frobinator service. + mojo.serviceRegistry.addServiceOverrideForTesting('Frobinator', () => { + if (++calls == 2) + resolve(); + }); // Try to connect to the browser's Frobinator service. This should be // intercepted by the above override. mojo.serviceRegistry.connectToService('Frobinator'); + mojo.serviceRegistry.connectToService('Frobinator'); }); }, 'Service registry overrides should be properly intercepted.');
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-snap-size-1/snap-height-dynamic-001-expected.txt b/third_party/WebKit/LayoutTests/imported/csswg-test/css-snap-size-1/snap-height-dynamic-001-expected.txt deleted file mode 100644 index 53950e1..0000000 --- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-snap-size-1/snap-height-dynamic-001-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL CSS Snap Size: snap-height dynamic change assert_not_equals: Height must change when snap-height changes got disallowed value 28 -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html new file mode 100644 index 0000000..f47492d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes-negative-playback-rate.html
@@ -0,0 +1,424 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<script> +var duration = 100000; + +function assert_unresolved(value) { + assert_equals(value, null); +} + +function idleAnimation() { + var animation = document.documentElement.animate([], duration); + animation.playbackRate = -1; + animation.cancel(); + return animation; +} + +function runningAnimation() { + var animation = idleAnimation(); + animation.play(); + animation.startTime = document.timeline.currentTime + duration; + return animation; +} + +function pendingStartTimeAnimation() { + var animation = idleAnimation(); + animation.play(); + return animation; +} + +function pendingStartTimeAndCurrentTimeAnimation() { + var animation = idleAnimation(); + animation.play(); + animation.pause(); + animation.play(); + return animation; +} + +function pausedAnimation() { + var animation = idleAnimation(); + animation.pause(); + return animation; +} + +function finishedAnimation() { + var animation = idleAnimation(); + animation.play(); + animation.finish(); + return animation; +} + +test(function() { + var animation = idleAnimation(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle"); + +test(function() { + var animation = pendingStartTimeAnimation(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "pending startTime"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime and currentTime"); + +test(function() { + var animation = runningAnimation(); + assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'running'); +}, "running"); + +test(function() { + var animation = pausedAnimation(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'paused'); +}, "paused"); + +test(function() { + var animation = finishedAnimation(); + assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'finished'); +}, "finished"); + +test(function() { + var animation = idleAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "idle -> play()"); + +test(function() { + var animation = idleAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'paused'); +}, "idle -> pause()"); + +test(function() { + var animation = idleAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle -> cancel()"); + +test(function() { + var animation = idleAnimation(); + animation.finish(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle -> finish()"); + +test(function() { + var animation = idleAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "idle -> reverse()"); + +test(function() { + var animation = idleAnimation(); + animation.currentTime = 1000; + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle -> set currentTime"); + +test(function() { + var animation = idleAnimation(); + animation.startTime = 1000; + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle -> set startTime"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "pending startTime -> play()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime -> pause()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "pending startTime -> cancel()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.finish(); + assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'finished'); +}, "pending startTime -> finish()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "pending startTime -> reverse()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.currentTime = 1000; + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'pending'); +}, "pending startTime -> set currentTime"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.startTime = document.timeline.currentTime + 1000; + assert_equals(animation.startTime, document.timeline.currentTime + 1000); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'running'); +}, "pending startTime -> set startTime"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime & currentTime -> play()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime & currentTime -> pause()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "pending startTime & currentTime -> cancel()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.finish(); + assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'finished'); +}, "pending startTime & currentTime -> finish()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime & currentTime -> reverse()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.currentTime = 1000; + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'pending'); +}, "pending startTime & currentTime -> set currentTime"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.startTime = document.timeline.currentTime + duration; + assert_equals(animation.startTime, document.timeline.currentTime + duration); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'running'); +}, "pending startTime & currentTime -> set startTime"); + +test(function() { + var animation = runningAnimation(); + var startTime = animation.startTime; + var currentTime = animation.currentTime; + animation.play(); + assert_equals(animation.startTime, startTime); + assert_equals(animation.currentTime, currentTime); + assert_equals(animation.playState, 'running'); +}, "running -> play()"); + +test(function() { + var animation = runningAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "running -> pause()"); + +test(function() { + var animation = runningAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "running -> cancel()"); + +test(function() { + var animation = runningAnimation(); + animation.finish(); + assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'finished'); +}, "running -> finish()"); + +test(function() { + var animation = runningAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "running -> reverse()"); + +test(function() { + var animation = runningAnimation(); + animation.currentTime = 1000; + assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'running'); +}, "running -> set currentTime"); + +test(function() { + var animation = runningAnimation(); + animation.startTime = document.timeline.currentTime + 1000; + assert_equals(animation.startTime, document.timeline.currentTime + 1000); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'running'); +}, "running -> set startTime"); + +test(function() { + var animation = pausedAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "paused -> play()"); + +test(function() { + var animation = pausedAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'paused'); +}, "paused -> pause()"); + +test(function() { + var animation = pausedAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "paused -> cancel()"); + +test(function() { + var animation = pausedAnimation(); + animation.finish(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'paused'); +}, "paused -> finish()"); + +test(function() { + var animation = pausedAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "paused -> reverse()"); + +test(function() { + var animation = pausedAnimation(); + animation.currentTime = 1000; + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'paused'); +}, "paused -> set currentTime"); + +test(function() { + var animation = pausedAnimation(); + animation.startTime = 1000; + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'paused'); +}, "paused -> set startTime"); + +test(function() { + var animation = finishedAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "finished -> play()"); + +test(function() { + var animation = finishedAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'paused'); +}, "finished -> pause()"); + +test(function() { + var animation = finishedAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "finished -> cancel()"); + +test(function() { + var animation = finishedAnimation(); + animation.finish(); + assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'finished'); +}, "finished -> finish()"); + +test(function() { + var animation = finishedAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "finished -> reverse()"); + +test(function() { + var animation = finishedAnimation(); + animation.currentTime = 1000; + assert_equals(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime)); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'running'); +}, "finished -> set currentTime"); +</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes.html b/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes.html new file mode 100644 index 0000000..667dd1ba --- /dev/null +++ b/third_party/WebKit/LayoutTests/web-animations-api/animation-state-changes.html
@@ -0,0 +1,423 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<script> +var duration = 100000; + +function assert_unresolved(value) { + assert_equals(value, null); +} + +function idleAnimation() { + var animation = document.documentElement.animate([], duration); + animation.cancel(); + return animation; +} + +function runningAnimation() { + var animation = idleAnimation(); + animation.play(); + animation.startTime = document.timeline.currentTime; + return animation; +} + +function pendingStartTimeAnimation() { + var animation = idleAnimation(); + animation.play(); + return animation; +} + +function pendingStartTimeAndCurrentTimeAnimation() { + var animation = idleAnimation(); + animation.play(); + animation.pause(); + animation.play(); + return animation; +} + +function pausedAnimation() { + var animation = idleAnimation(); + animation.pause(); + return animation; +} + +function finishedAnimation() { + var animation = idleAnimation(); + animation.play(); + animation.finish(); + return animation; +} + +test(function() { + var animation = idleAnimation(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle"); + +test(function() { + var animation = pendingStartTimeAnimation(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "pending startTime"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime and currentTime"); + +test(function() { + var animation = runningAnimation(); + assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'running'); +}, "running"); + +test(function() { + var animation = pausedAnimation(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'paused'); +}, "paused"); + +test(function() { + var animation = finishedAnimation(); + assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'finished'); +}, "finished"); + +test(function() { + var animation = idleAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "idle -> play()"); + +test(function() { + var animation = idleAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'paused'); +}, "idle -> pause()"); + +test(function() { + var animation = idleAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle -> cancel()"); + +test(function() { + var animation = idleAnimation(); + animation.finish(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle -> finish()"); + +test(function() { + var animation = idleAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "idle -> reverse()"); + +test(function() { + var animation = idleAnimation(); + animation.currentTime = 1000; + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle -> set currentTime"); + +test(function() { + var animation = idleAnimation(); + animation.startTime = 1000; + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "idle -> set startTime"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "pending startTime -> play()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime -> pause()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "pending startTime -> cancel()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.finish(); + assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'finished'); +}, "pending startTime -> finish()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "pending startTime -> reverse()"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.currentTime = 1000; + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'pending'); +}, "pending startTime -> set currentTime"); + +test(function() { + var animation = pendingStartTimeAnimation(); + animation.startTime = document.timeline.currentTime - 1000; + assert_equals(animation.startTime, document.timeline.currentTime - 1000); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'running'); +}, "pending startTime -> set startTime"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime & currentTime -> play()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime & currentTime -> pause()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "pending startTime & currentTime -> cancel()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.finish(); + assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'finished'); +}, "pending startTime & currentTime -> finish()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "pending startTime & currentTime -> reverse()"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.currentTime = 1000; + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'pending'); +}, "pending startTime & currentTime -> set currentTime"); + +test(function() { + var animation = pendingStartTimeAndCurrentTimeAnimation(); + animation.startTime = document.timeline.currentTime; + assert_equals(animation.startTime, document.timeline.currentTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'running'); +}, "pending startTime & currentTime -> set startTime"); + +test(function() { + var animation = runningAnimation(); + var startTime = animation.startTime; + var currentTime = animation.currentTime; + animation.play(); + assert_equals(animation.startTime, startTime); + assert_equals(animation.currentTime, currentTime); + assert_equals(animation.playState, 'running'); +}, "running -> play()"); + +test(function() { + var animation = runningAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "running -> pause()"); + +test(function() { + var animation = runningAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "running -> cancel()"); + +test(function() { + var animation = runningAnimation(); + animation.finish(); + assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'finished'); +}, "running -> finish()"); + +test(function() { + var animation = runningAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'pending'); +}, "running -> reverse()"); + +test(function() { + var animation = runningAnimation(); + animation.currentTime = 1000; + assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'running'); +}, "running -> set currentTime"); + +test(function() { + var animation = runningAnimation(); + animation.startTime = document.timeline.currentTime - 1000; + assert_equals(animation.startTime, document.timeline.currentTime - 1000); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'running'); +}, "running -> set startTime"); + +test(function() { + var animation = pausedAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "paused -> play()"); + +test(function() { + var animation = pausedAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'paused'); +}, "paused -> pause()"); + +test(function() { + var animation = pausedAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "paused -> cancel()"); + +test(function() { + var animation = pausedAnimation(); + animation.finish(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'paused'); +}, "paused -> finish()"); + +test(function() { + var animation = pausedAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "paused -> reverse()"); + +test(function() { + var animation = pausedAnimation(); + animation.currentTime = 1000; + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'paused'); +}, "paused -> set currentTime"); + +test(function() { + var animation = pausedAnimation(); + animation.startTime = 1000; + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'paused'); +}, "paused -> set startTime"); + +test(function() { + var animation = finishedAnimation(); + animation.play(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, 0); + assert_equals(animation.playState, 'pending'); +}, "finished -> play()"); + +test(function() { + var animation = finishedAnimation(); + animation.pause(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'paused'); +}, "finished -> pause()"); + +test(function() { + var animation = finishedAnimation(); + animation.cancel(); + assert_unresolved(animation.startTime); + assert_unresolved(animation.currentTime); + assert_equals(animation.playState, 'idle'); +}, "finished -> cancel()"); + +test(function() { + var animation = finishedAnimation(); + animation.finish(); + assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'finished'); +}, "finished -> finish()"); + +test(function() { + var animation = finishedAnimation(); + animation.reverse(); + assert_unresolved(animation.startTime); + assert_equals(animation.currentTime, duration); + assert_equals(animation.playState, 'pending'); +}, "finished -> reverse()"); + +test(function() { + var animation = finishedAnimation(); + animation.currentTime = 1000; + assert_equals(animation.startTime, document.timeline.currentTime - animation.currentTime); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'running'); +}, "finished -> set currentTime"); +</script>
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/player-state-changes.html b/third_party/WebKit/LayoutTests/web-animations-api/player-state-changes.html deleted file mode 100644 index 0b95f24..0000000 --- a/third_party/WebKit/LayoutTests/web-animations-api/player-state-changes.html +++ /dev/null
@@ -1,418 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> - -<script> -function assert_unresolved(value) { - assert_equals(value, null); -} - -function idlePlayer() { - var player = document.documentElement.animate([], 100000); - player.cancel(); - return player; -} - -function runningPlayer() { - var player = document.documentElement.animate([], 100000); - player.startTime = document.timeline.currentTime; - return player; -} - -function pendingStartTimePlayer() { - var player = document.documentElement.animate([], 100000); - return player; -} - -function pendingStartTimeAndCurrentTimePlayer() { - var player = document.documentElement.animate([], 100000); - player.pause(); - player.play(); - return player; -} - -function pausedPlayer() { - var player = document.documentElement.animate([], 100000); - player.pause(); - player.currentTime = 0; - return player; -} - -function finishedPlayer() { - var player = document.documentElement.animate([], 100000); - player.finish(); - return player; -} - -test(function() { - var player = idlePlayer(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "idle"); - -test(function() { - var player = pendingStartTimePlayer(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'pending'); -}, "pending startTime"); - -test(function() { - var player = pendingStartTimeAndCurrentTimePlayer(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'pending'); -}, "pending startTime and currentTime"); - -test(function() { - var player = runningPlayer(); - assert_equals(player.startTime, document.timeline.currentTime - player.currentTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'running'); -}, "running"); - -test(function() { - var player = pausedPlayer(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'paused'); -}, "paused"); - -test(function() { - var player = finishedPlayer(); - assert_equals(player.startTime, document.timeline.currentTime - player.currentTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'finished'); -}, "finished"); - -test(function() { - var player = idlePlayer(); - player.play(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'pending'); -}, "idle -> play()"); - -test(function() { - var player = idlePlayer(); - player.pause(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "idle -> pause()"); - -test(function() { - var player = idlePlayer(); - player.cancel(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "idle -> cancel()"); - -test(function() { - var player = idlePlayer(); - player.finish(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "idle -> finish()"); - -test(function() { - var player = idlePlayer(); - player.reverse(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'pending'); -}, "idle -> reverse()"); - -test(function() { - var player = idlePlayer(); - player.currentTime = 1000; - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "idle -> set currentTime"); - -test(function() { - var player = idlePlayer(); - player.startTime = 1000; - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "idle -> set startTime"); - -test(function() { - var player = pendingStartTimePlayer(); - player.play(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'pending'); -}, "pending startTime -> play()"); - -test(function() { - var player = pendingStartTimePlayer(); - player.pause(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'pending'); -}, "pending startTime -> pause()"); - -test(function() { - var player = pendingStartTimePlayer(); - player.cancel(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "pending startTime -> cancel()"); - -test(function() { - var player = pendingStartTimePlayer(); - player.finish(); - assert_equals(player.startTime, document.timeline.currentTime - player.currentTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'finished'); -}, "pending startTime -> finish()"); - -test(function() { - var player = pendingStartTimePlayer(); - player.reverse(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'pending'); -}, "pending startTime -> reverse()"); - -test(function() { - var player = pendingStartTimePlayer(); - player.currentTime = 1000; - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 1000); - assert_equals(player.playState, 'pending'); -}, "pending startTime -> set currentTime"); - -test(function() { - var player = pendingStartTimePlayer(); - player.startTime = document.timeline.currentTime - 1000; - assert_equals(player.startTime, document.timeline.currentTime - 1000); - assert_equals(player.currentTime, 1000); - assert_equals(player.playState, 'running'); -}, "pending startTime -> set startTime"); - -test(function() { - var player = pendingStartTimeAndCurrentTimePlayer(); - player.play(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'pending'); -}, "pending startTime & currentTime -> play()"); - -test(function() { - var player = pendingStartTimeAndCurrentTimePlayer(); - player.pause(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'pending'); -}, "pending startTime & currentTime -> pause()"); - -test(function() { - var player = pendingStartTimeAndCurrentTimePlayer(); - player.cancel(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "pending startTime & currentTime -> cancel()"); - -test(function() { - var player = pendingStartTimeAndCurrentTimePlayer(); - player.finish(); - assert_equals(player.startTime, document.timeline.currentTime - player.currentTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'finished'); -}, "pending startTime & currentTime -> finish()"); - -test(function() { - var player = pendingStartTimeAndCurrentTimePlayer(); - player.reverse(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'pending'); -}, "pending startTime & currentTime -> reverse()"); - -test(function() { - var player = pendingStartTimeAndCurrentTimePlayer(); - player.currentTime = 1000; - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 1000); - assert_equals(player.playState, 'pending'); -}, "pending startTime & currentTime -> set currentTime"); - -test(function() { - var player = pendingStartTimeAndCurrentTimePlayer(); - player.startTime = document.timeline.currentTime; - assert_equals(player.startTime, document.timeline.currentTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'running'); -}, "pending startTime & currentTime -> set startTime"); - -test(function() { - var player = runningPlayer(); - var startTime = player.startTime; - var currentTime = player.currentTime; - player.play(); - assert_equals(player.startTime, startTime); - assert_equals(player.currentTime, currentTime); - assert_equals(player.playState, 'running'); -}, "running -> play()"); - -test(function() { - var player = runningPlayer(); - player.pause(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'pending'); -}, "running -> pause()"); - -test(function() { - var player = runningPlayer(); - player.cancel(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "running -> cancel()"); - -test(function() { - var player = runningPlayer(); - player.finish(); - assert_equals(player.startTime, document.timeline.currentTime - player.currentTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'finished'); -}, "running -> finish()"); - -test(function() { - var player = runningPlayer(); - player.reverse(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'pending'); -}, "running -> reverse()"); - -test(function() { - var player = runningPlayer(); - player.currentTime = 1000; - assert_equals(player.startTime, document.timeline.currentTime - player.currentTime); - assert_equals(player.currentTime, 1000); - assert_equals(player.playState, 'running'); -}, "running -> set currentTime"); - -test(function() { - var player = runningPlayer(); - player.startTime = document.timeline.currentTime - 1000; - assert_equals(player.startTime, document.timeline.currentTime - 1000); - assert_equals(player.currentTime, 1000); - assert_equals(player.playState, 'running'); -}, "running -> set startTime"); - -test(function() { - var player = pausedPlayer(); - player.play(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'pending'); -}, "paused -> play()"); - -test(function() { - var player = pausedPlayer(); - player.pause(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'paused'); -}, "paused -> pause()"); - -test(function() { - var player = pausedPlayer(); - player.cancel(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "paused -> cancel()"); - -test(function() { - var player = pausedPlayer(); - player.finish(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'paused'); -}, "paused -> finish()"); - -test(function() { - var player = pausedPlayer(); - player.reverse(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'pending'); -}, "paused -> reverse()"); - -test(function() { - var player = pausedPlayer(); - player.currentTime = 1000; - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 1000); - assert_equals(player.playState, 'paused'); -}, "paused -> set currentTime"); - -test(function() { - var player = pausedPlayer(); - player.startTime = 1000; - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'paused'); -}, "paused -> set startTime"); - -test(function() { - var player = finishedPlayer(); - player.play(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 0); - assert_equals(player.playState, 'pending'); -}, "finished -> play()"); - -test(function() { - var player = finishedPlayer(); - player.pause(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'paused'); -}, "finished -> pause()"); - -test(function() { - var player = finishedPlayer(); - player.cancel(); - assert_unresolved(player.startTime); - assert_unresolved(player.currentTime); - assert_equals(player.playState, 'idle'); -}, "finished -> cancel()"); - -test(function() { - var player = finishedPlayer(); - player.finish(); - assert_equals(player.startTime, document.timeline.currentTime - player.currentTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'finished'); -}, "finished -> finish()"); - -test(function() { - var player = finishedPlayer(); - player.reverse(); - assert_unresolved(player.startTime); - assert_equals(player.currentTime, 100000); - assert_equals(player.playState, 'pending'); -}, "finished -> reverse()"); - -test(function() { - var player = finishedPlayer(); - player.currentTime = 1000; - assert_equals(player.startTime, document.timeline.currentTime - player.currentTime); - assert_equals(player.currentTime, 1000); - assert_equals(player.playState, 'running'); -}, "finished -> set currentTime"); -</script>
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp index 1cf24ad..e465472 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp
@@ -231,7 +231,7 @@ // Inform main thread to re-queue the data. m_loadingTaskRunner->postTask( - BLINK_FROM_HERE, bind(&SourceStream::fetchDataFromResourceBuffer, this, 0)); + BLINK_FROM_HERE, threadSafeBind(&SourceStream::fetchDataFromResourceBuffer, AllowCrossThreadAccess(this), 0)); } void didFinishLoading()
diff --git a/third_party/WebKit/Source/core/animation/Animation.cpp b/third_party/WebKit/Source/core/animation/Animation.cpp index f99282a..f1a90d5 100644 --- a/third_party/WebKit/Source/core/animation/Animation.cpp +++ b/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -483,12 +483,12 @@ Animation::AnimationPlayState Animation::calculatePlayState() { + if (m_paused && !m_currentTimePending) + return Paused; if (m_playState == Idle) return Idle; - if (m_currentTimePending || (isNull(m_startTime) && !m_paused && m_playbackRate != 0)) + if (m_currentTimePending || (isNull(m_startTime) && m_playbackRate != 0)) return Pending; - if (m_paused) - return Paused; if (limited()) return Finished; return Running; @@ -501,11 +501,17 @@ PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); + double newCurrentTime = currentTimeInternal(); + if (calculatePlayState() == Idle) { + newCurrentTime = m_playbackRate < 0 ? effectEnd() : 0; + } + if (playing()) { m_currentTimePending = true; } + m_paused = true; - setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand); + setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand); } void Animation::unpause() @@ -861,7 +867,7 @@ m_holdTime = currentTimeInternal(); m_held = true; - // TODO + m_paused = false; m_playState = Idle; m_startTime = nullValue(); m_currentTimePending = false;
diff --git a/third_party/WebKit/Source/core/animation/AnimationTest.cpp b/third_party/WebKit/Source/core/animation/AnimationTest.cpp index 7860930..e5cc4df5 100644 --- a/third_party/WebKit/Source/core/animation/AnimationTest.cpp +++ b/third_party/WebKit/Source/core/animation/AnimationTest.cpp
@@ -825,8 +825,8 @@ EXPECT_TRUE(std::isnan(animation->currentTime())); EXPECT_TRUE(std::isnan(animation->startTime())); animation->pause(); - EXPECT_EQ(Animation::Idle, animation->playStateInternal()); - EXPECT_TRUE(std::isnan(animation->currentTime())); + EXPECT_EQ(Animation::Paused, animation->playStateInternal()); + EXPECT_EQ(0, animation->currentTime()); EXPECT_TRUE(std::isnan(animation->startTime())); }
diff --git a/third_party/WebKit/Source/core/css/CSSGradientValue.cpp b/third_party/WebKit/Source/core/css/CSSGradientValue.cpp index 0a763778..2f8c60f 100644 --- a/third_party/WebKit/Source/core/css/CSSGradientValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
@@ -524,6 +524,8 @@ case CSSValueRight: ASSERT(isHorizontal); return size.width(); + case CSSValueCenter: + return origin + sign * .5f * edgeDistance; default: break; }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index c1b512d..f453d18 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -3392,6 +3392,138 @@ return nullptr; } +static PassRefPtrWillBeRawPtr<CSSValue> consumeBackgroundBlendMode(CSSParserTokenRange& range) +{ + CSSValueID id = range.peek().id(); + if (id == CSSValueNormal || id == CSSValueOverlay || (id >= CSSValueMultiply && id <= CSSValueLuminosity)) + return consumeIdent(range); + return nullptr; +} + +static PassRefPtrWillBeRawPtr<CSSValue> consumeBackgroundAttachment(CSSParserTokenRange& range) +{ + return consumeIdent<CSSValueScroll, CSSValueFixed, CSSValueLocal>(range); +} + +static PassRefPtrWillBeRawPtr<CSSValue> consumeBackgroundBox(CSSParserTokenRange& range) +{ + return consumeIdent<CSSValueBorderBox, CSSValuePaddingBox, CSSValueContentBox>(range); +} + +static PassRefPtrWillBeRawPtr<CSSValue> consumeBackgroundComposite(CSSParserTokenRange& range) +{ + return consumeIdentRange(range, CSSValueClear, CSSValuePlusLighter); +} + +static PassRefPtrWillBeRawPtr<CSSValue> consumeMaskSourceType(CSSParserTokenRange& range) +{ + ASSERT(RuntimeEnabledFeatures::cssMaskSourceTypeEnabled()); + return consumeIdent<CSSValueAuto, CSSValueAlpha, CSSValueLuminance>(range); +} + +static PassRefPtrWillBeRawPtr<CSSValue> consumePrefixedBackgroundBox(CSSPropertyID property, CSSParserTokenRange& range, const CSSParserContext& context) +{ + // The values 'border', 'padding' and 'content' are deprecated and do not apply to the version of the property that has the -webkit- prefix removed. + if (RefPtrWillBeRawPtr<CSSValue> value = consumeIdentRange(range, CSSValueBorder, CSSValuePaddingBox)) + return value.release(); + if ((property == CSSPropertyWebkitBackgroundClip || property == CSSPropertyWebkitMaskClip) && range.peek().id() == CSSValueText) + return consumeIdent(range); + return nullptr; +} + +static PassRefPtrWillBeRawPtr<CSSValue> consumeBackgroundSize(CSSPropertyID unresolvedProperty, CSSParserTokenRange& range, CSSParserMode mode) +{ + if (identMatches<CSSValueContain, CSSValueCover>(range.peek().id())) + return consumeIdent(range); + + RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontal = consumeIdent<CSSValueAuto>(range); + if (!horizontal) + horizontal = consumeLengthOrPercent(range, mode, ValueRangeAll, UnitlessQuirk::Forbid); + + RefPtrWillBeRawPtr<CSSPrimitiveValue> vertical = nullptr; + if (!range.atEnd()) { + if (range.peek().id() == CSSValueAuto) // `auto' is the default + range.consumeIncludingWhitespace(); + else + vertical = consumeLengthOrPercent(range, mode, ValueRangeAll, UnitlessQuirk::Forbid); + } else if (unresolvedProperty == CSSPropertyAliasWebkitBackgroundSize) { + // Legacy syntax: "-webkit-background-size: 10px" is equivalent to "background-size: 10px 10px". + vertical = horizontal; + } + if (!vertical) + return horizontal; + return CSSValuePair::create(horizontal.release(), vertical.release(), CSSValuePair::KeepIdenticalValues); +} + +static PassRefPtrWillBeRawPtr<CSSValue> consumeBackgroundComponent(CSSPropertyID unresolvedProperty, CSSParserTokenRange& range, const CSSParserContext& context) +{ + switch (unresolvedProperty) { + case CSSPropertyBackgroundClip: + return consumeBackgroundBox(range); + case CSSPropertyBackgroundBlendMode: + return consumeBackgroundBlendMode(range); + case CSSPropertyBackgroundAttachment: + return consumeBackgroundAttachment(range); + case CSSPropertyBackgroundOrigin: + return consumeBackgroundBox(range); + case CSSPropertyWebkitBackgroundComposite: + case CSSPropertyWebkitMaskComposite: + return consumeBackgroundComposite(range); + case CSSPropertyMaskSourceType: + return consumeMaskSourceType(range); + case CSSPropertyWebkitBackgroundClip: + case CSSPropertyWebkitBackgroundOrigin: + case CSSPropertyWebkitMaskClip: + case CSSPropertyWebkitMaskOrigin: + return consumePrefixedBackgroundBox(unresolvedProperty, range, context); + case CSSPropertyBackgroundImage: + case CSSPropertyWebkitMaskImage: + return consumeImage(range, context); + case CSSPropertyBackgroundPositionX: + case CSSPropertyWebkitMaskPositionX: + return consumePositionX(range, context.mode()); + case CSSPropertyBackgroundPositionY: + case CSSPropertyWebkitMaskPositionY: + return consumePositionY(range, context.mode()); + case CSSPropertyBackgroundSize: + case CSSPropertyAliasWebkitBackgroundSize: + case CSSPropertyWebkitMaskSize: + return consumeBackgroundSize(unresolvedProperty, range, context.mode()); + case CSSPropertyBackgroundColor: + return consumeColor(range, context.mode()); + default: + break; + }; + return nullptr; +} + +static void addBackgroundValue(RefPtrWillBeRawPtr<CSSValue>& list, PassRefPtrWillBeRawPtr<CSSValue> value) +{ + if (list) { + if (!list->isBaseValueList()) { + RefPtrWillBeRawPtr<CSSValue> firstValue = list.release(); + list = CSSValueList::createCommaSeparated(); + toCSSValueList(list.get())->append(firstValue.release()); + } + toCSSValueList(list.get())->append(value); + } else { + // To conserve memory we don't actually wrap a single value in a list. + list = value; + } +} + +static PassRefPtrWillBeRawPtr<CSSValue> consumeCommaSeparatedBackgroundComponent(CSSPropertyID unresolvedProperty, CSSParserTokenRange& range, const CSSParserContext& context) +{ + RefPtrWillBeRawPtr<CSSValue> result = nullptr; + do { + RefPtrWillBeRawPtr<CSSValue> value = consumeBackgroundComponent(unresolvedProperty, range, context); + if (!value) + return nullptr; + addBackgroundValue(result, value); + } while (consumeCommaIncludingWhitespace(range)); + return result.release(); +} + PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty) { CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); @@ -3555,6 +3687,7 @@ case CSSPropertyColumnRuleColor: return consumeColor(m_range, m_context.mode()); case CSSPropertyColor: + case CSSPropertyBackgroundColor: return consumeColor(m_range, m_context.mode(), inQuirksMode()); case CSSPropertyWebkitBorderStartWidth: case CSSPropertyWebkitBorderEndWidth: @@ -3724,6 +3857,29 @@ case CSSPropertyImageOrientation: ASSERT(RuntimeEnabledFeatures::imageOrientationEnabled()); return consumeImageOrientation(m_range, m_context.mode()); + case CSSPropertyBackgroundAttachment: + case CSSPropertyBackgroundBlendMode: + case CSSPropertyBackgroundClip: + case CSSPropertyBackgroundImage: + case CSSPropertyBackgroundOrigin: + case CSSPropertyBackgroundPositionX: + case CSSPropertyBackgroundPositionY: + case CSSPropertyBackgroundSize: + case CSSPropertyMaskSourceType: + case CSSPropertyWebkitBackgroundComposite: + case CSSPropertyWebkitBackgroundClip: + case CSSPropertyWebkitBackgroundOrigin: + case CSSPropertyWebkitMaskClip: + case CSSPropertyWebkitMaskComposite: + case CSSPropertyWebkitMaskImage: + case CSSPropertyWebkitMaskOrigin: + case CSSPropertyWebkitMaskPositionX: + case CSSPropertyWebkitMaskPositionY: + case CSSPropertyWebkitMaskSize: + return consumeCommaSeparatedBackgroundComponent(unresolvedProperty, m_range, m_context); + case CSSPropertyWebkitMaskRepeatX: + case CSSPropertyWebkitMaskRepeatY: + return nullptr; default: CSSParserValueList valueList(m_range); if (valueList.size()) {
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp index 647911c..c47bdf3 100644 --- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -271,41 +271,6 @@ RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; switch (propId) { - case CSSPropertyBackgroundColor: // <color> | inherit - parsedValue = parseColor(m_valueList->current(), inQuirksMode() && !inShorthand()); - if (parsedValue) - m_valueList->next(); - break; - - case CSSPropertyBackgroundBlendMode: - case CSSPropertyBackgroundAttachment: - case CSSPropertyBackgroundClip: - case CSSPropertyWebkitBackgroundClip: - case CSSPropertyWebkitBackgroundComposite: - case CSSPropertyBackgroundImage: - case CSSPropertyBackgroundOrigin: - case CSSPropertyMaskSourceType: - case CSSPropertyWebkitBackgroundOrigin: - case CSSPropertyBackgroundPositionX: - case CSSPropertyBackgroundPositionY: - case CSSPropertyBackgroundSize: - case CSSPropertyWebkitMaskClip: - case CSSPropertyWebkitMaskComposite: - case CSSPropertyWebkitMaskImage: - case CSSPropertyWebkitMaskOrigin: - case CSSPropertyWebkitMaskPositionX: - case CSSPropertyWebkitMaskPositionY: - case CSSPropertyWebkitMaskSize: - case CSSPropertyWebkitMaskRepeatX: - case CSSPropertyWebkitMaskRepeatY: - { - RefPtrWillBeRawPtr<CSSValue> dummyValue = nullptr; - CSSPropertyID propId1, propId2; - if (!parseFillProperty(unresolvedProperty, propId1, propId2, parsedValue, dummyValue)) - return nullptr; - ASSERT(!dummyValue); - break; - } case CSSPropertyJustifySelf: ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); parsedValue = parseItemPositionOverflowPosition();
diff --git a/third_party/WebKit/Source/core/fetch/Resource.h b/third_party/WebKit/Source/core/fetch/Resource.h index fb1f31f..03bdb79 100644 --- a/third_party/WebKit/Source/core/fetch/Resource.h +++ b/third_party/WebKit/Source/core/fetch/Resource.h
@@ -336,7 +336,6 @@ class CacheHandler; void cancelTimerFired(Timer<Resource>*); - void switchClientsToRevalidatedResource(); void revalidationSucceeded(const ResourceResponse&); void revalidationFailed();
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h index d3bd7fe2..8b92350 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -141,7 +141,6 @@ String getCacheIdentifier() const; - void scheduleDocumentResourcesGC(); bool clientDefersImage(const KURL&) const; static void determineRequestContext(ResourceRequest&, Resource::Type, bool isMainFrame); void determineRequestContext(ResourceRequest&, Resource::Type); @@ -182,8 +181,6 @@ void willTerminateResourceLoader(ResourceLoader*); - ResourceLoadPriority modifyPriorityForExperiments(ResourceLoadPriority, Resource::Type, const FetchRequest&); - Member<FetchContext> m_context; HashSet<String> m_validatedURLs;
diff --git a/third_party/WebKit/Source/core/page/FocusController.cpp b/third_party/WebKit/Source/core/page/FocusController.cpp index 00331f9..4617e58 100644 --- a/third_party/WebKit/Source/core/page/FocusController.cpp +++ b/third_party/WebKit/Source/core/page/FocusController.cpp
@@ -72,7 +72,8 @@ class FocusNavigationScope { STACK_ALLOCATED(); public: - Node* rootNode() const; + Element* firstElement() const; + Element* lastElement() const; Element* owner() const; static FocusNavigationScope focusNavigationScopeOf(const Element&); static FocusNavigationScope ownedByNonFocusableFocusScopeOwner(Element&); @@ -82,6 +83,7 @@ private: explicit FocusNavigationScope(TreeScope*); + ContainerNode& rootNode() const; RawPtrWillBeMember<TreeScope> m_rootTreeScope; }; @@ -91,20 +93,31 @@ ASSERT(treeScope); } -Node* FocusNavigationScope::rootNode() const +ContainerNode& FocusNavigationScope::rootNode() const { - return &m_rootTreeScope->rootNode(); + return m_rootTreeScope->rootNode(); +} + +Element* FocusNavigationScope::firstElement() const +{ + ContainerNode& root = rootNode(); + return root.isElementNode() ? &toElement(root) : ElementTraversal::next(root); +} + +Element* FocusNavigationScope::lastElement() const +{ + return ElementTraversal::lastWithin(rootNode()); } Element* FocusNavigationScope::owner() const { - Node* root = rootNode(); - if (root->isShadowRoot()) { - ShadowRoot* shadowRoot = toShadowRoot(root); - return shadowRoot->isYoungest() ? shadowRoot->host() : shadowRoot->shadowInsertionPointOfYoungerShadowRoot(); + ContainerNode& root = rootNode(); + if (root.isShadowRoot()) { + ShadowRoot& shadowRoot = toShadowRoot(root); + return shadowRoot.isYoungest() ? shadowRoot.host() : shadowRoot.shadowInsertionPointOfYoungerShadowRoot(); } // FIXME: Figure out the right thing for OOPI here. - if (Frame* frame = root->document().frame()) + if (Frame* frame = root.document().frame()) return frame->deprecatedLocalOwner(); return nullptr; } @@ -203,11 +216,8 @@ } #if ENABLE(ASSERT) -inline bool isNonFocusableShadowHost(const Node& node) +inline bool isNonFocusableShadowHost(const Element& element) { - if (!node.isElementNode()) - return false; - const Element& element = toElement(node); return isShadowHostWithoutCustomFocusLogic(element) && !element.isFocusable(); } #endif @@ -232,162 +242,154 @@ return element.authorShadowRoot() && element.authorShadowRoot()->delegatesFocus(); } -inline int adjustedTabIndex(Node& node) +inline int adjustedTabIndex(Element& element) { - return node.isElementNode() && isNonFocusableFocusScopeOwner(toElement(node)) ? 0 : node.tabIndex(); + return isNonFocusableFocusScopeOwner(element) ? 0 : element.tabIndex(); } -inline bool shouldVisit(Node& node) +inline bool shouldVisit(Element& element) { - if (!node.isElementNode()) - return false; - Element& element = toElement(node); return element.isKeyboardFocusable() || isNonFocusableFocusScopeOwner(element); } -Element* findElementWithExactTabIndex(Node* start, int tabIndex, WebFocusType type) +Element* findElementWithExactTabIndex(Element* start, int tabIndex, WebFocusType type) { // Search is inclusive of start - for (Node* node = start; node; node = type == WebFocusTypeForward ? ElementTraversal::next(*node) : ElementTraversal::previous(*node)) { - if (shouldVisit(*node) && adjustedTabIndex(*node) == tabIndex) - return toElement(node); + for (Element* element = start; element; element = type == WebFocusTypeForward ? ElementTraversal::next(*element) : ElementTraversal::previous(*element)) { + if (shouldVisit(*element) && adjustedTabIndex(*element) == tabIndex) + return element; } return nullptr; } -Element* nextElementWithGreaterTabIndex(Node* start, int tabIndex) +Element* nextElementWithGreaterTabIndex(Element* start, int tabIndex) { // Search is inclusive of start int winningTabIndex = std::numeric_limits<short>::max() + 1; - Node* winner = nullptr; - for (Node& node : NodeTraversal::startsAt(start)) { - int currentTabIndex = adjustedTabIndex(node); - if (shouldVisit(node) && currentTabIndex > tabIndex && currentTabIndex < winningTabIndex) { - winner = &node; + Element* winner = nullptr; + for (Element& element : ElementTraversal::startsAt(start)) { + int currentTabIndex = adjustedTabIndex(element); + if (shouldVisit(element) && currentTabIndex > tabIndex && currentTabIndex < winningTabIndex) { + winner = &element; winningTabIndex = currentTabIndex; } } - ASSERT(!winner || winner->isElementNode()); - return toElement(winner); + return winner; } -Element* previousElementWithLowerTabIndex(Node* start, int tabIndex) +Element* previousElementWithLowerTabIndex(Element* start, int tabIndex) { // Search is inclusive of start int winningTabIndex = 0; - Node* winner = nullptr; - for (Node* node = start; node; node = ElementTraversal::previous(*node)) { - int currentTabIndex = adjustedTabIndex(*node); - if (shouldVisit(*node) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) { - winner = node; + Element* winner = nullptr; + for (Element* element = start; element; element = ElementTraversal::previous(*element)) { + int currentTabIndex = adjustedTabIndex(*element); + if (shouldVisit(*element) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) { + winner = element; winningTabIndex = currentTabIndex; } } - ASSERT(!winner || winner->isElementNode()); - return toElement(winner); + return winner; } -Element* nextFocusableElement(const FocusNavigationScope& scope, Node* start) +Element* nextFocusableElement(const FocusNavigationScope& scope, Element* start) { if (start) { int tabIndex = adjustedTabIndex(*start); - // If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order + // If an element is excluded from the normal tabbing cycle, the next focusable element is determined by tree order if (tabIndex < 0) { - for (Node& node : NodeTraversal::startsAfter(*start)) { - if (shouldVisit(node) && adjustedTabIndex(node) >= 0) - return &toElement(node); + for (Element& element : ElementTraversal::startsAfter(*start)) { + if (shouldVisit(element) && adjustedTabIndex(element) >= 0) + return &element; } } else { - // First try to find a node with the same tabindex as start that comes after start in the scope. + // First try to find an element with the same tabindex as start that comes after start in the scope. if (Element* winner = findElementWithExactTabIndex(ElementTraversal::next(*start), tabIndex, WebFocusTypeForward)) return winner; } if (!tabIndex) { - // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order. + // We've reached the last element in the document with a tabindex of 0. This is the end of the tabbing order. return nullptr; } } - // Look for the first node in the scope that: + // Look for the first element in the scope that: // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and // 2) comes first in the scope, if there's a tie. - if (Element* winner = nextElementWithGreaterTabIndex(scope.rootNode(), start ? adjustedTabIndex(*start) : 0)) + if (Element* winner = nextElementWithGreaterTabIndex(scope.firstElement(), start ? adjustedTabIndex(*start) : 0)) return winner; - // There are no nodes with a tabindex greater than start's tabindex, - // so find the first node with a tabindex of 0. - return findElementWithExactTabIndex(scope.rootNode(), 0, WebFocusTypeForward); + // There are no elements with a tabindex greater than start's tabindex, + // so find the first element with a tabindex of 0. + return findElementWithExactTabIndex(scope.firstElement(), 0, WebFocusTypeForward); } -Element* previousFocusableElement(const FocusNavigationScope& scope, Node* start) +Element* previousFocusableElement(const FocusNavigationScope& scope, Element* start) { - Node* last = nullptr; - for (Node* node = scope.rootNode(); node; node = node->lastChild()) - last = node; - ASSERT(last); + Element* lastElement = scope.lastElement(); - // First try to find the last node in the scope that comes before start and has the same tabindex as start. - // If start is null, find the last node in the scope with a tabindex of 0. - Node* startingNode; - int startingTabIndex; + // First try to find the last element in the scope that comes before start and has the same tabindex as start. + // If start is null, find the last element in the scope with a tabindex of 0. + Element* startElement; + int startTabIndex; if (start) { - startingNode = ElementTraversal::previous(*start); - startingTabIndex = adjustedTabIndex(*start); + startElement = ElementTraversal::previous(*start); + startTabIndex = adjustedTabIndex(*start); } else { - startingNode = last; - startingTabIndex = 0; + startElement = lastElement; + startTabIndex = 0; } - // However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order - if (startingTabIndex < 0) { - for (Node* node = startingNode; node; node = ElementTraversal::previous(*node)) { - if (shouldVisit(*node) && adjustedTabIndex(*node) >= 0) - return toElement(node); + // However, if an element is excluded from the normal tabbing cycle, the previous focusable element is determined by tree order + if (startTabIndex < 0) { + for (Element* element = startElement; element; element = ElementTraversal::previous(*element)) { + if (shouldVisit(*element) && adjustedTabIndex(*element) >= 0) + return element; } } else { - if (Element* winner = findElementWithExactTabIndex(startingNode, startingTabIndex, WebFocusTypeBackward)) + if (Element* winner = findElementWithExactTabIndex(startElement, startTabIndex, WebFocusTypeBackward)) return winner; } - // There are no nodes before start with the same tabindex as start, so look for a node that: + // There are no elements before start with the same tabindex as start, so look for an element that: // 1) has the highest non-zero tabindex (that is less than start's tabindex), and // 2) comes last in the scope, if there's a tie. - startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::numeric_limits<short>::max(); - return previousElementWithLowerTabIndex(last, startingTabIndex); + startTabIndex = (start && startTabIndex) ? startTabIndex : std::numeric_limits<short>::max(); + return previousElementWithLowerTabIndex(lastElement, startTabIndex); } -// Searches through the given tree scope, starting from start node, for the next/previous -// selectable element that comes after/before start node. +// Searches through the given tree scope, starting from start element, for the next/previous +// selectable element that comes after/before start element. // The order followed is as specified in the HTML spec[1], which is elements with tab indexes // first (from lowest to highest), and then elements without tab indexes (in document order). // The search algorithm also conforms the Shadow DOM spec[2], which inserts sequence in a shadow // tree into its host. // -// @param start The node from which to start searching. The node after this will be focused. +// @param start The element from which to start searching. The element after this will be focused. // May be null. -// @return The focus element that comes after/before start node. +// @return The focus element that comes after/before start element. // // [1] https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation // [2] https://w3c.github.io/webcomponents/spec/shadow/#focus-navigation -inline Element* findFocusableElementInternal(WebFocusType type, const FocusNavigationScope& scope, Node* node) +inline Element* findFocusableElementInternal(WebFocusType type, const FocusNavigationScope& scope, Element* element) { - Element* found = (type == WebFocusTypeForward) ? nextFocusableElement(scope, node) : previousFocusableElement(scope, node); + Element* found = (type == WebFocusTypeForward) ? nextFocusableElement(scope, element) : previousFocusableElement(scope, element); return found; } -Element* findFocusableElementRecursivelyForward(const FocusNavigationScope& scope, Node* start) +Element* findFocusableElementRecursivelyForward(const FocusNavigationScope& scope, Element* start) { - // Starting node is exclusive. + // Starting element is exclusive. Element* found = findFocusableElementInternal(WebFocusTypeForward, scope, start); while (found) { if (isShadowHostDelegatesFocus(*found)) { - // If tabindex is positive, find focusable node inside its shadow tree. + // If tabindex is positive, find focusable element inside its shadow tree. if (found->tabIndex() >= 0 && isShadowHostWithoutCustomFocusLogic(*found)) { FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHost(*found); if (Element* foundInInnerFocusScope = findFocusableElementRecursivelyForward(innerScope, nullptr)) return foundInInnerFocusScope; } - // Skip to the next node in the same scope. + // Skip to the next element in the same scope. found = findFocusableElementInternal(WebFocusTypeForward, scope, found); continue; } @@ -406,9 +408,9 @@ return nullptr; } -Element* findFocusableElementRecursivelyBackward(const FocusNavigationScope& scope, Node* start) +Element* findFocusableElementRecursivelyBackward(const FocusNavigationScope& scope, Element* start) { - // Starting node is exclusive. + // Starting element is exclusive. Element* found = findFocusableElementInternal(WebFocusTypeBackward, scope, start); while (found) { // Now |found| is on a focusable shadow host. @@ -434,7 +436,7 @@ } // Now |found| is on a non focusable scope owner (either shadow host or <shadow>). - // Find focusable node in descendant scope. If not found, find next focusable node within the + // Find focusable element in descendant scope. If not found, find next focusable element within the // current scope. if (isNonFocusableFocusScopeOwner(*found)) { FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(*found); @@ -451,7 +453,7 @@ return nullptr; } -Element* findFocusableElementRecursively(WebFocusType type, const FocusNavigationScope& scope, Node* start) +Element* findFocusableElementRecursively(WebFocusType type, const FocusNavigationScope& scope, Element* start) { return (type == WebFocusTypeForward) ? findFocusableElementRecursivelyForward(scope, start) : @@ -477,19 +479,19 @@ return element; } -Element* findFocusableElementAcrossFocusScopesForward(const FocusNavigationScope& scope, Node* currentNode) +Element* findFocusableElementAcrossFocusScopesForward(const FocusNavigationScope& scope, Element* current) { - ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode)); + ASSERT(!current || !isNonFocusableShadowHost(*current)); Element* found; - if (currentNode && currentNode->isElementNode() && isShadowHostWithoutCustomFocusLogic(*toElement(currentNode))) { - FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHost(*toElement(currentNode)); + if (current && isShadowHostWithoutCustomFocusLogic(*current)) { + FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHost(*current); Element* foundInInnerFocusScope = findFocusableElementRecursivelyForward(innerScope, nullptr); - found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableElementRecursivelyForward(scope, currentNode); + found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableElementRecursivelyForward(scope, current); } else { - found = findFocusableElementRecursivelyForward(scope, currentNode); + found = findFocusableElementRecursivelyForward(scope, current); } - // If there's no focusable node to advance to, move up the focus scopes until we find one. + // If there's no focusable element to advance to, move up the focus scopes until we find one. FocusNavigationScope currentScope = scope; while (!found) { Element* owner = currentScope.owner(); @@ -501,12 +503,12 @@ return findFocusableElementDescendingDownIntoFrameDocument(WebFocusTypeForward, found); } -Element* findFocusableElementAcrossFocusScopesBackward(const FocusNavigationScope& scope, Node* currentNode) +Element* findFocusableElementAcrossFocusScopesBackward(const FocusNavigationScope& scope, Element* current) { - ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode)); - Element* found = findFocusableElementRecursivelyBackward(scope, currentNode); + ASSERT(!current || !isNonFocusableShadowHost(*current)); + Element* found = findFocusableElementRecursivelyBackward(scope, current); - // If there's no focusable node to advance to, move up the focus scopes until we find one. + // If there's no focusable element to advance to, move up the focus scopes until we find one. FocusNavigationScope currentScope = scope; while (!found) { Element* owner = currentScope.owner(); @@ -522,11 +524,11 @@ return findFocusableElementDescendingDownIntoFrameDocument(WebFocusTypeBackward, found); } -Element* findFocusableElementAcrossFocusScopes(WebFocusType type, const FocusNavigationScope& scope, Node* currentNode) +Element* findFocusableElementAcrossFocusScopes(WebFocusType type, const FocusNavigationScope& scope, Element* current) { return (type == WebFocusTypeForward) ? - findFocusableElementAcrossFocusScopesForward(scope, currentNode) : - findFocusableElementAcrossFocusScopesBackward(scope, currentNode); + findFocusableElementAcrossFocusScopesForward(scope, current) : + findFocusableElementAcrossFocusScopesBackward(scope, current); } inline Element* adjustToElement(Node* node, WebFocusType type) @@ -781,7 +783,7 @@ ASSERT(element); if (element == document->focusedElement()) { - // Focus wrapped around to the same node. + // Focus wrapped around to the same element. return true; } @@ -805,13 +807,13 @@ return true; } - // FIXME: It would be nice to just be able to call setFocusedElement(node) + // FIXME: It would be nice to just be able to call setFocusedElement(element) // here, but we can't do that because some elements (e.g. HTMLInputElement // and HTMLTextAreaElement) do extra work in their focus() methods. Document& newDocument = element->document(); if (&newDocument != document) { - // Focus is going away from this document, so clear the focused node. + // Focus is going away from this document, so clear the focused element. document->clearFocusedElement(); } @@ -916,7 +918,7 @@ } setFocusedFrame(newFocusedFrame); - // Setting the focused node can result in losing our last reft to node when JS event handlers fire. + // Setting the focused element can result in losing our last reft to element when JS event handlers fire. RefPtrWillBeRawPtr<Element> protect = element; ALLOW_UNUSED_LOCAL(protect); if (newDocument) {
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index 2b68b35..42d731c 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -583,6 +583,8 @@ || rareInheritedData->m_textCombine != other.rareInheritedData->m_textCombine || rareInheritedData->m_tabSize != other.rareInheritedData->m_tabSize || rareInheritedData->listStyleImage != other.rareInheritedData->listStyleImage + || rareInheritedData->m_snapHeightUnit != other.rareInheritedData->m_snapHeightUnit + || rareInheritedData->m_snapHeightPosition != other.rareInheritedData->m_snapHeightPosition || rareInheritedData->textStrokeWidth != other.rareInheritedData->textStrokeWidth) return true;
diff --git a/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp b/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp index a9550dc9..541f56b 100644 --- a/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp +++ b/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp
@@ -28,6 +28,7 @@ #include "platform/audio/ReverbConvolver.h" #include "platform/Task.h" +#include "platform/ThreadSafeFunctional.h" #include "platform/audio/AudioBus.h" #include "platform/audio/VectorMath.h" #include "public/platform/Platform.h" @@ -168,7 +169,7 @@ // Now that we've buffered more input, post another task to the background thread. if (m_backgroundThread) - m_backgroundThread->taskRunner()->postTask(BLINK_FROM_HERE, new Task(WTF::bind(&ReverbConvolver::processInBackground, this))); + m_backgroundThread->taskRunner()->postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&ReverbConvolver::processInBackground, AllowCrossThreadAccess(this)))); } void ReverbConvolver::reset()
diff --git a/third_party/WebKit/Source/platform/heap/GCTaskRunner.h b/third_party/WebKit/Source/platform/heap/GCTaskRunner.h index 631cf59e8..af91955 100644 --- a/third_party/WebKit/Source/platform/heap/GCTaskRunner.h +++ b/third_party/WebKit/Source/platform/heap/GCTaskRunner.h
@@ -31,6 +31,7 @@ #ifndef GCTaskRunner_h #define GCTaskRunner_h +#include "platform/ThreadSafeFunctional.h" #include "platform/heap/ThreadState.h" #include "public/platform/WebTaskRunner.h" #include "public/platform/WebThread.h" @@ -47,24 +48,18 @@ // GCTask has an empty run() method. Its only purpose is to guarantee // that MessageLoop will have a task to process which will result // in GCTaskRunner::didProcessTask being executed. - m_taskRunner->postTask(BLINK_FROM_HERE, new GCTask); + m_taskRunner->postTask(BLINK_FROM_HERE, threadSafeBind(&runGCTask)); } private: - class GCTask final : public WebTaskRunner::Task { - USING_FAST_MALLOC(GCTask); - public: - virtual ~GCTask() { } - - void run() override - { - // Don't do anything here because we don't know if this is - // a nested event loop or not. GCTaskRunner::didProcessTask - // will enter correct safepoint for us. - // We are not calling onInterrupted() because that always - // conservatively enters safepoint with pointers on stack. - } - }; + static void runGCTask() + { + // Don't do anything here because we don't know if this is + // a nested event loop or not. GCTaskRunner::didProcessTask + // will enter correct safepoint for us. + // We are not calling onInterrupted() because that always + // conservatively enters safepoint with pointers on stack. + } WebTaskRunner* m_taskRunner; };
diff --git a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp index 6dc019f..cb771fa8 100644 --- a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp +++ b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
@@ -40,17 +40,9 @@ namespace blink { namespace testing { -class QuitTask : public WebTaskRunner::Task { -public: - virtual void run() - { - exitRunLoop(); - } -}; - void runPendingTasks() { - Platform::current()->currentThread()->taskRunner()->postTask(BLINK_FROM_HERE, new QuitTask); + Platform::current()->currentThread()->taskRunner()->postTask(BLINK_FROM_HERE, bind(&exitRunLoop)); enterRunLoop(); } @@ -66,10 +58,10 @@ PassRefPtr<SharedBuffer> readFromFile(const String& path) { StringUTF8Adaptor utf8(path); - base::FilePath file_path = base::FilePath::FromUTF8Unsafe( + base::FilePath filePath = base::FilePath::FromUTF8Unsafe( std::string(utf8.data(), utf8.length())); std::string buffer; - base::ReadFileToString(file_path, &buffer); + base::ReadFileToString(filePath, &buffer); return SharedBuffer::create(buffer.data(), buffer.size()); }
diff --git a/ui/webui/resources/css/widgets.css b/ui/webui/resources/css/widgets.css index d03f528a..5a5dbc2 100644 --- a/ui/webui/resources/css/widgets.css +++ b/ui/webui/resources/css/widgets.css
@@ -38,7 +38,7 @@ min-width: 4em; padding-top: 1px; padding-bottom: 1px; -<if expr="is_win"> +<if expr="is_win or is_macosx"> /* The following platform-specific rule is necessary to get adjacent * buttons, text inputs, and so forth to align on their borders while also * aligning on the text's baselines. */