diff --git a/DEPS b/DEPS index fe1289d..6fcea8f 100644 --- a/DEPS +++ b/DEPS
@@ -44,7 +44,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': '35e8c7b52802e62281d3c2b5e6c8694a54f7cdc0', + 'v8_revision': 'c4ab5a664f9f210baaab32b169f802e48ae4cc32', # 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.
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 7320d4a..d469ca2 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -1014,9 +1014,6 @@ </receiver> - <meta-data android:name="com.google.android.gms.version" - android:value="@integer/google_play_services_version" /> - <meta-data android:name="org.chromium.content.browser.SMART_CLIP_PROVIDER" android:value="org.chromium.content.browser.SmartClipProvider"/>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 4cdb0d7..59ee04ea 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1652,6 +1652,10 @@ flag_descriptions::kServiceWorkerNavigationPreloadName, flag_descriptions::kServiceWorkerNavigationPreloadDescription, kOsAll, FEATURE_VALUE_TYPE(features::kServiceWorkerNavigationPreload)}, + {"enable-service-worker-script-streaming", + flag_descriptions::kServiceWorkerScriptStreamingName, + flag_descriptions::kServiceWorkerScriptStreamingDescription, kOsAll, + FEATURE_VALUE_TYPE(features::kServiceWorkerScriptStreaming)}, {"enable-suggestions-with-substring-match", flag_descriptions::kSuggestionsWithSubStringMatchName, flag_descriptions::kSuggestionsWithSubStringMatchDescription, kOsAll,
diff --git a/chrome/browser/banners/app_banner_settings_helper.h b/chrome/browser/banners/app_banner_settings_helper.h index 6e2b8585..5c6cc2f 100644 --- a/chrome/browser/banners/app_banner_settings_helper.h +++ b/chrome/browser/banners/app_banner_settings_helper.h
@@ -63,10 +63,10 @@ // the banner from being shown too often. APP_BANNER_EVENT_DID_SHOW, // Records the latest time a banner was dismissed by the user. Used to - // suppress the banenr for some time if the user explicitly didn't want it. + // suppress the banner for some time if the user explicitly didn't want it. APP_BANNER_EVENT_DID_BLOCK, - // Records the latest time the user adds a site to the homescreen from a - // banner, or launched that site from homescreen. Used to ensure banenrs are + // Records the latest time the user added a site to the homescreen from a + // banner, or launched that site from homescreen. Used to ensure banners are // not shown for sites which were added, and to determine if sites were // launched recently. APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc index 5a1e84c..66ec6d60 100644 --- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -1703,7 +1703,9 @@ "domAutomationController.send(pod.classList.contains('advanced'));", account_id_1_.Serialize().c_str()), &advanced)); - EXPECT_FALSE(advanced); + // Public session pods switch to advanced form immediately upon being + // clicked, instead of waiting for animation to end which were in the old UI. + EXPECT_TRUE(advanced); // Manually select a different locale. ASSERT_TRUE(content::ExecuteScript(
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc index 7a81ac5..c6b31c58 100644 --- a/chrome/browser/download/download_prefs.cc +++ b/chrome/browser/download/download_prefs.cc
@@ -317,7 +317,9 @@ DCHECK(extension[0] == base::FilePath::kExtensionSeparator); extension.erase(0, 1); #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) - if (extension == FILE_PATH_LITERAL("pdf") && ShouldOpenPdfInSystemReader()) + if (base::FilePath::CompareEqualIgnoreCase(extension, + FILE_PATH_LITERAL("pdf")) && + ShouldOpenPdfInSystemReader()) return true; #endif
diff --git a/chrome/browser/download/download_request_limiter_unittest.cc b/chrome/browser/download/download_request_limiter_unittest.cc index d748ff7..4699b79 100644 --- a/chrome/browser/download/download_request_limiter_unittest.cc +++ b/chrome/browser/download/download_request_limiter_unittest.cc
@@ -373,7 +373,7 @@ // The state should not be reset on a renderer-initiated load to either the // same host or a different host, in either the main frame or the subframe. content::NavigationSimulator::NavigateAndCommitFromDocument( - GURL("http://fooeybar.com/bar"), web_contents()->GetMainFrame()); + GURL("http://fooey.com/bar2"), web_contents()->GetMainFrame()); LoadCompleted(); ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED, download_request_limiter_->GetDownloadStatus(web_contents()));
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 1a30db5..28578c3 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1053,6 +1053,13 @@ "Enable web pages to use the experimental service worker navigation " "preload API."; +const char kServiceWorkerScriptStreamingName[] = + "Service worker script streaming."; +const char kServiceWorkerScriptStreamingDescription[] = + "Installed scripts for a service worker are sent over a dedicated " + "message pipe and data pipes, and that is never be blocked on the main " + "thread."; + const char kSettingsWindowName[] = "Show settings in a window"; const char kSettingsWindowDescription[] = "Settings will be shown in a dedicated window instead of as a browser tab.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 8085303d..5370c7f 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -651,6 +651,9 @@ extern const char kServiceWorkerNavigationPreloadName[]; extern const char kServiceWorkerNavigationPreloadDescription[]; +extern const char kServiceWorkerScriptStreamingName[]; +extern const char kServiceWorkerScriptStreamingDescription[]; + extern const char kSettingsWindowName[]; extern const char kSettingsWindowDescription[];
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc index 56e33801..4bbf55c 100644 --- a/chrome/browser/net/websocket_browsertest.cc +++ b/chrome/browser/net/websocket_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/login/login_handler.h" @@ -299,7 +300,14 @@ // HTTPS connection limits should not be applied to wss:. This is only tested // for secure connections here because the unencrypted case is tested in the // Blink layout tests, and browser tests are expensive to run. -IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SSLConnectionLimit) { +// Flaky on windows. https://crbug.com/753261 +#if defined(OS_WIN) +#define MAYBE_SSLConnectionLimit DISABLED_SSLConnectionLimit +#else +#define MAYBE_SSLConnectionLimit SSLConnectionLimit +#endif + +IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, MAYBE_SSLConnectionLimit) { ASSERT_TRUE(wss_server_.Start()); NavigateToHTTPS("multiple-connections.html");
diff --git a/chrome/browser/resources/chromeos/login/oobe.html b/chrome/browser/resources/chromeos/login/oobe.html index 2d946e2..995f3fb4 100644 --- a/chrome/browser/resources/chromeos/login/oobe.html +++ b/chrome/browser/resources/chromeos/login/oobe.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <meta name="google" value="notranslate"> <title i18n-content="title"></title> -<include src="login_shared.html"> +<include src="md_login_shared.html"> <include src="login_non_lock_shared.html"> <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://oobe/custom_elements.html"> @@ -15,7 +15,7 @@ <script src="chrome://oobe/oobe.js"></script> </head> <body class="oobe-display chromeos" i18n-values=".style.fontFamily:fontfamily;"> - <include src="screen_container.html"> + <include src="md_screen_container.html"> <include src="accessibility_menu.html"> <div id="popup-overlay" class="popup-overlay" hidden> <include src="oobe_screen_eula_installation_settings_overlay.html">
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js index e11aaaa6..3a245cb7 100644 --- a/chrome/browser/resources/chromeos/login/oobe.js +++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -7,7 +7,7 @@ * This is the main code for the OOBE WebUI implementation. */ -// <include src="login_shared.js"> +// <include src="md_login_shared.js"> // <include src="login_non_lock_shared.js"> // <include src="oobe_screen_auto_enrollment_check.js"> // <include src="oobe_screen_controller_pairing.js">
diff --git a/chrome/browser/resources/chromeos/login/oobe_screens.html b/chrome/browser/resources/chromeos/login/oobe_screens.html index 4f51fab..7b3f79ed 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screens.html +++ b/chrome/browser/resources/chromeos/login/oobe_screens.html
@@ -13,7 +13,7 @@ <include src="oobe_screen_hid_detection.html"> <include src="oobe_screen_voice_interaction_value_prop.html"> <include src="oobe_screen_wait_for_container_ready.html"> -<include src="../../../../../ui/login/account_picker/screen_account_picker.html"> +<include src="../../../../../ui/login/account_picker/md_screen_account_picker.html"> <include src="screen_error_message.html"> <include src="screen_arc_terms_of_service.html"> <include src="screen_gaia_signin.html">
diff --git a/chrome/browser/ui/webui/snippets_internals_message_handler.cc b/chrome/browser/ui/webui/snippets_internals_message_handler.cc index 441232f6..96b03881 100644 --- a/chrome/browser/ui/webui/snippets_internals_message_handler.cc +++ b/chrome/browser/ui/webui/snippets_internals_message_handler.cc
@@ -575,16 +575,20 @@ void SnippetsInternalsMessageHandler::PushDummySuggestion() { std::string json = - "{" - " \"ids\" : [\"http://url.com\"]," - " \"title\" : \"Pushed Dummy Title %s\"," - " \"snippet\" : \"Pushed Dummy Snippet\"," - " \"fullPageUrl\" : \"http://url.com\"," - " \"creationTime\" : \"%s\"," - " \"expirationTime\" : \"%s\"," - " \"attribution\" : \"Pushed Dummy Publisher\"," - " \"imageUrl\" : \"https://www.google.com/favicon.ico\" " - "}"; + "{\"categories\" : [{" + " \"id\": 1," + " \"localizedTitle\": \"section title\"," + " \"suggestions\" : [{" + " \"ids\" : [\"http://url.com\"]," + " \"title\" : \"Pushed Dummy Title %s\"," + " \"snippet\" : \"Pushed Dummy Snippet\"," + " \"fullPageUrl\" : \"http://url.com\"," + " \"creationTime\" : \"%s\"," + " \"expirationTime\" : \"%s\"," + " \"attribution\" : \"Pushed Dummy Publisher\"," + " \"imageUrl\" : \"https://www.google.com/favicon.ico\" " + " }]" + "}]}"; const base::Time now = base::Time::Now(); json = base::StringPrintf( @@ -592,24 +596,18 @@ TimeToJSONTimeString(now).c_str(), TimeToJSONTimeString(now + base::TimeDelta::FromMinutes(60)).c_str()); - std::unique_ptr<base::Value> suggestion_value = base::JSONReader::Read(json); - DCHECK(suggestion_value != nullptr); + gcm::IncomingMessage message; + message.data["payload"] = json; - const base::DictionaryValue* suggestion_dictionary = nullptr; - bool success = suggestion_value->GetAsDictionary(&suggestion_dictionary); - DCHECK(success); - - std::unique_ptr<RemoteSuggestion> suggestion = - RemoteSuggestion::CreateFromContentSuggestionsDictionary( - *suggestion_dictionary, /*remote_category_id=*/1, - /*fetch_time=*/now); - DCHECK(suggestion != nullptr); - - // TODO(vitaliii): Provide JSON directly to BreakingNewsAppHandler once it is - // connected to the provider. - static_cast<ntp_snippets::RemoteSuggestionsProviderImpl*>( - remote_suggestions_provider_) - ->PushArticleSuggestionToTheFrontForDebugging(std::move(suggestion)); + RemoteSuggestionsProvider* provider = + content_suggestions_service_->remote_suggestions_provider_for_debugging(); + DCHECK(provider); + ntp_snippets::BreakingNewsListener* listener = + static_cast<ntp_snippets::RemoteSuggestionsProviderImpl*>(provider) + ->breaking_news_listener_for_debugging(); + DCHECK(listener); + static_cast<ntp_snippets::BreakingNewsGCMAppHandler*>(listener)->OnMessage( + "com.google.breakingnews.gcm", message); } void SnippetsInternalsMessageHandler::OnDismissedSuggestionsLoaded(
diff --git a/chrome/test/android/unit_tests_apk/AndroidManifest.xml b/chrome/test/android/unit_tests_apk/AndroidManifest.xml index bfaf0c5f..3fdebe57 100644 --- a/chrome/test/android/unit_tests_apk/AndroidManifest.xml +++ b/chrome/test/android/unit_tests_apk/AndroidManifest.xml
@@ -30,8 +30,6 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - <meta-data android:name="com.google.android.gms.version" - android:value="@integer/google_play_services_version" /> </application> <instrumentation android:name="org.chromium.native_test.NativeTestInstrumentationTestRunner"
diff --git a/components/ntp_snippets/breaking_news/breaking_news_listener.h b/components/ntp_snippets/breaking_news/breaking_news_listener.h index 851184a..3647ce91 100644 --- a/components/ntp_snippets/breaking_news/breaking_news_listener.h +++ b/components/ntp_snippets/breaking_news/breaking_news_listener.h
@@ -28,6 +28,7 @@ // will be ignored. Must be called while listening. virtual void StopListening() = 0; }; + } // namespace ntp_snippets #endif // COMPONENTS_NTP_SNIPPETS_BREAKING_NEWS_BREAKING_NEWS_LISTENER_H_
diff --git a/components/ntp_snippets/content_suggestions_service.h b/components/ntp_snippets/content_suggestions_service.h index 86594f3..e1624e6f 100644 --- a/components/ntp_snippets/content_suggestions_service.h +++ b/components/ntp_snippets/content_suggestions_service.h
@@ -20,6 +20,7 @@ #include "components/history/core/browser/history_service.h" #include "components/history/core/browser/history_service_observer.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.h" #include "components/ntp_snippets/callbacks.h" #include "components/ntp_snippets/category.h" #include "components/ntp_snippets/category_rankers/category_ranker.h"
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc b/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc index d5e3bc6b..f1ef51de 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc
@@ -559,11 +559,6 @@ return kMaxSuggestionCount; } -void RemoteSuggestionsProviderImpl::PushArticleSuggestionToTheFrontForDebugging( - std::unique_ptr<RemoteSuggestion> suggestion) { - PrependArticleSuggestion(std::move(suggestion)); -} - //////////////////////////////////////////////////////////////////////////////// // Private methods
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl.h b/components/ntp_snippets/remote/remote_suggestions_provider_impl.h index 36b0167..44c02b5 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl.h +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl.h
@@ -144,8 +144,9 @@ // the constructor. CachedImageFetcher& GetImageFetcherForTesting() { return image_fetcher_; } - void PushArticleSuggestionToTheFrontForDebugging( - std::unique_ptr<RemoteSuggestion> suggestion); + BreakingNewsListener* breaking_news_listener_for_debugging() { + return breaking_news_raw_data_provider_.get(); + } private: friend class RemoteSuggestionsProviderImplTest;
diff --git a/components/ntp_snippets_strings.grdp b/components/ntp_snippets_strings.grdp index bda97c2a..672811e 100644 --- a/components/ntp_snippets_strings.grdp +++ b/components/ntp_snippets_strings.grdp
@@ -19,9 +19,17 @@ Articles aren't available right now </message> - <message name="IDS_NTP_ARTICLE_SUGGESTIONS_SECTION_HEADER" desc="Header of the articles section, which is a list of news articles displayed as cards on the New Tab Page."> - Articles for you - </message> + <if expr="use_titlecase"> + <message name="IDS_NTP_ARTICLE_SUGGESTIONS_SECTION_HEADER" desc="Header of the articles section, which is a list of news articles displayed as cards on the New Tab Page."> + Articles for You + </message> + </if> + + <if expr="not use_titlecase"> + <message name="IDS_NTP_ARTICLE_SUGGESTIONS_SECTION_HEADER" desc="Header of the articles section, which is a list of news articles displayed as cards on the New Tab Page."> + Articles for you + </message> + </if> <message name="IDS_NTP_ARTICLE_SUGGESTIONS_SECTION_EMPTY" desc="On the New Tab Page, text of the card explaining to the user that they can expect to see suggested articles in this area in the future."> Your suggested articles appear here @@ -52,9 +60,17 @@ Your nearby suggestions appear here </message> - <message name="IDS_NTP_READING_LIST_SUGGESTIONS_SECTION_HEADER" desc="Header of the Reading List section. The Reading List section shows a list of unread pages from the Reading List."> - Reading list - </message> + <if expr="use_titlecase"> + <message name="IDS_NTP_READING_LIST_SUGGESTIONS_SECTION_HEADER" desc="Header of the Reading List section. The Reading List section shows a list of unread pages from the Reading List."> + Reading List + </message> + </if> + + <if expr="not use_titlecase"> + <message name="IDS_NTP_READING_LIST_SUGGESTIONS_SECTION_HEADER" desc="Header of the Reading List section. The Reading List section shows a list of unread pages from the Reading List."> + Reading list + </message> + </if> <message name="IDS_NTP_READING_LIST_SUGGESTIONS_SECTION_EMPTY" desc="On the New Tab Page, text of the card explaining to the user that they can expect to see Reading List articles in this area in the future."> Pages from your reading list appear here
diff --git a/components/search_provider_logos/logo_tracker.cc b/components/search_provider_logos/logo_tracker.cc index 7fe8f2ba..9f0193ba 100644 --- a/components/search_provider_logos/logo_tracker.cc +++ b/components/search_provider_logos/logo_tracker.cc
@@ -37,10 +37,8 @@ base::TimeDelta offset = base::TimeDelta::FromMilliseconds(kMaxTimeToLiveMS * 3 / 2); base::Time distant_past = now - offset; - base::Time distant_future = now + offset; // Sanity check so logos aren't accidentally cached forever. - if (metadata.expiration_time < distant_past || - metadata.expiration_time > distant_future) { + if (metadata.expiration_time < distant_past) { return false; } return metadata.can_show_after_expiration || metadata.expiration_time >= now;
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc index ebd66c5c..6ec92852 100644 --- a/content/child/service_worker/service_worker_dispatcher.cc +++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -386,26 +386,6 @@ return registration; } -void ServiceWorkerDispatcher::OnAssociateRegistrationForController( - int provider_id, - const ServiceWorkerRegistrationObjectInfo& info, - const ServiceWorkerVersionAttributes& attrs) { - // Adopt the references sent from the browser process and pass them to the - // provider context if it exists. - std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration = - Adopt(info); - std::unique_ptr<ServiceWorkerHandleReference> installing = - Adopt(attrs.installing); - std::unique_ptr<ServiceWorkerHandleReference> waiting = Adopt(attrs.waiting); - std::unique_ptr<ServiceWorkerHandleReference> active = Adopt(attrs.active); - ProviderContextMap::iterator context = provider_contexts_.find(provider_id); - if (context != provider_contexts_.end()) { - context->second->OnAssociateRegistration( - std::move(registration), std::move(installing), std::move(waiting), - std::move(active)); - } -} - void ServiceWorkerDispatcher::OnRegistered( int thread_id, int request_id,
diff --git a/content/child/service_worker/service_worker_dispatcher.h b/content/child/service_worker/service_worker_dispatcher.h index 234b734..ff26eae 100644 --- a/content/child/service_worker/service_worker_dispatcher.h +++ b/content/child/service_worker/service_worker_dispatcher.h
@@ -165,13 +165,6 @@ const ServiceWorkerRegistrationObjectInfo& info, const ServiceWorkerVersionAttributes& attrs); - // TODO(falken): Change the caller to just call the appropriate function on - // ServiceWorkerProviderContext directly. - void OnAssociateRegistrationForController( - int provider_id, - const ServiceWorkerRegistrationObjectInfo& info, - const ServiceWorkerVersionAttributes& attrs); - static ServiceWorkerDispatcher* GetOrCreateThreadSpecificInstance( ThreadSafeSender* thread_safe_sender, base::SingleThreadTaskRunner* main_thread_task_runner);
diff --git a/content/child/service_worker/service_worker_dispatcher_unittest.cc b/content/child/service_worker/service_worker_dispatcher_unittest.cc index 2e7c41d..b2ac94c 100644 --- a/content/child/service_worker/service_worker_dispatcher_unittest.cc +++ b/content/child/service_worker/service_worker_dispatcher_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "content/child/service_worker/service_worker_dispatcher.h" + #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "content/child/service_worker/service_worker_handle_reference.h" @@ -73,13 +74,6 @@ return ContainsKey(dispatcher_->registrations_, registration_handle_id); } - void OnAssociateRegistrationForController( - int provider_id, - const ServiceWorkerRegistrationObjectInfo& info, - const ServiceWorkerVersionAttributes& attrs) { - dispatcher_->OnAssociateRegistrationForController(provider_id, info, attrs); - } - void OnSetControllerServiceWorker(int thread_id, int provider_id, const ServiceWorkerObjectInfo& info, @@ -163,62 +157,6 @@ std::set<uint32_t> used_features_; }; -TEST_F(ServiceWorkerDispatcherTest, OnAssociateRegistration_NoProviderContext) { - // Assume that these objects are passed from the browser process and own - // references to browser-side registration/worker representations. - ServiceWorkerRegistrationObjectInfo info; - ServiceWorkerVersionAttributes attrs; - CreateObjectInfoAndVersionAttributes(&info, &attrs); - - // The passed references should be adopted but immediately released because - // there is no provider context to own the references. - const int kProviderId = 10; - OnAssociateRegistrationForController(kProviderId, info, attrs); - ASSERT_EQ(4UL, ipc_sink()->message_count()); - EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, - ipc_sink()->GetMessageAt(0)->type()); - EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, - ipc_sink()->GetMessageAt(1)->type()); - EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, - ipc_sink()->GetMessageAt(2)->type()); - EXPECT_EQ(ServiceWorkerHostMsg_DecrementRegistrationRefCount::ID, - ipc_sink()->GetMessageAt(3)->type()); -} - -TEST_F(ServiceWorkerDispatcherTest, - OnAssociateRegistration_ProviderContextForController) { - // Assume that these objects are passed from the browser process and own - // references to browser-side registration/worker representations. - ServiceWorkerRegistrationObjectInfo info; - ServiceWorkerVersionAttributes attrs; - CreateObjectInfoAndVersionAttributes(&info, &attrs); - - // Set up ServiceWorkerProviderContext for ServiceWorkerGlobalScope. - const int kProviderId = 10; - scoped_refptr<ServiceWorkerProviderContext> provider_context( - new ServiceWorkerProviderContext( - kProviderId, SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, - mojom::ServiceWorkerProviderAssociatedRequest(), - thread_safe_sender())); - - // The passed references should be adopted and owned by the provider context. - OnAssociateRegistrationForController(kProviderId, info, attrs); - EXPECT_EQ(0UL, ipc_sink()->message_count()); - - // Destruction of the provider context should release references to the - // associated registration and its versions. - provider_context = nullptr; - ASSERT_EQ(4UL, ipc_sink()->message_count()); - EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, - ipc_sink()->GetMessageAt(0)->type()); - EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, - ipc_sink()->GetMessageAt(1)->type()); - EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, - ipc_sink()->GetMessageAt(2)->type()); - EXPECT_EQ(ServiceWorkerHostMsg_DecrementRegistrationRefCount::ID, - ipc_sink()->GetMessageAt(3)->type()); -} - TEST_F(ServiceWorkerDispatcherTest, OnSetControllerServiceWorker) { const int kProviderId = 10; bool should_notify_controllerchange = true; @@ -243,11 +181,9 @@ // (2) In the case there is no WebSWProviderClient but SWProviderContext for // the provider, the passed referecence should be adopted and owned by the // provider context. - scoped_refptr<ServiceWorkerProviderContext> provider_context( - new ServiceWorkerProviderContext( - kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW, - mojom::ServiceWorkerProviderAssociatedRequest(), - thread_safe_sender())); + auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>( + kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW, + mojom::ServiceWorkerProviderAssociatedRequest(), dispatcher()); ipc_sink()->ClearMessages(); OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active, should_notify_controllerchange, @@ -290,9 +226,9 @@ // provider context. In addition, the new reference should be created for the // provider client and immediately released due to limitation of the mock // implementation. - provider_context = new ServiceWorkerProviderContext( + provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>( kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW, - mojom::ServiceWorkerProviderAssociatedRequest(), thread_safe_sender()); + mojom::ServiceWorkerProviderAssociatedRequest(), dispatcher()); provider_client.reset( new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher())); ASSERT_FALSE(provider_client->is_set_controlled_called()); @@ -320,11 +256,9 @@ std::unique_ptr<MockWebServiceWorkerProviderClientImpl> provider_client( new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher())); - scoped_refptr<ServiceWorkerProviderContext> provider_context( - new ServiceWorkerProviderContext( - kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW, - mojom::ServiceWorkerProviderAssociatedRequest(), - thread_safe_sender())); + auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>( + kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW, + mojom::ServiceWorkerProviderAssociatedRequest(), dispatcher()); // Set the controller to kInvalidServiceWorkerHandle. OnSetControllerServiceWorker(
diff --git a/content/child/service_worker/service_worker_network_provider.cc b/content/child/service_worker/service_worker_network_provider.cc index b20919a..908fc029 100644 --- a/content/child/service_worker/service_worker_network_provider.cc +++ b/content/child/service_worker/service_worker_network_provider.cc
@@ -10,6 +10,8 @@ #include "content/child/service_worker/service_worker_dispatcher.h" #include "content/child/service_worker/service_worker_handle_reference.h" #include "content/child/service_worker/service_worker_provider_context.h" +#include "content/child/service_worker/service_worker_registration_handle_reference.h" +#include "content/child/thread_safe_sender.h" #include "content/common/navigation_params.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_provider_host_info.h" @@ -216,6 +218,7 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider() : provider_id_(kInvalidServiceWorkerProviderId) {} +// Constructor for service worker clients. ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider( int route_id, ServiceWorkerProviderType provider_type, @@ -240,34 +243,47 @@ DCHECK(host_info.host_request.is_pending()); DCHECK(host_info.host_request.handle().is_valid()); - context_ = new ServiceWorkerProviderContext( - provider_id_, provider_type, std::move(client_request), - ChildThreadImpl::current()->thread_safe_sender()); + ServiceWorkerDispatcher* dispatcher = + ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( + ChildThreadImpl::current()->thread_safe_sender(), + base::ThreadTaskRunnerHandle::Get().get()); + context_ = base::MakeRefCounted<ServiceWorkerProviderContext>( + provider_id_, provider_type, std::move(client_request), dispatcher); ChildThreadImpl::current()->channel()->GetRemoteAssociatedInterface( &dispatcher_host_); dispatcher_host_->OnProviderCreated(std::move(host_info)); } +// Constructor for service worker execution contexts. ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider( mojom::ServiceWorkerProviderInfoForStartWorkerPtr info) : provider_id_(info->provider_id) { - context_ = new ServiceWorkerProviderContext( + // Initialize the provider context with info for + // ServiceWorkerGlobalScope#registration. + ThreadSafeSender* sender = ChildThreadImpl::current()->thread_safe_sender(); + ServiceWorkerDispatcher* dispatcher = + ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( + sender, base::ThreadTaskRunnerHandle::Get().get()); + context_ = base::MakeRefCounted<ServiceWorkerProviderContext>( provider_id_, SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, - std::move(info->client_request), - ChildThreadImpl::current()->thread_safe_sender()); + std::move(info->client_request), dispatcher); + std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration = + ServiceWorkerRegistrationHandleReference::Adopt(info->registration, + sender); + std::unique_ptr<ServiceWorkerHandleReference> installing = + ServiceWorkerHandleReference::Adopt(info->attributes.installing, sender); + std::unique_ptr<ServiceWorkerHandleReference> waiting = + ServiceWorkerHandleReference::Adopt(info->attributes.waiting, sender); + std::unique_ptr<ServiceWorkerHandleReference> active = + ServiceWorkerHandleReference::Adopt(info->attributes.active, sender); + context_->SetRegistration(std::move(registration), std::move(installing), + std::move(waiting), std::move(active)); if (info->script_loader_factory_ptr_info.is_valid()) { script_loader_factory_.Bind( std::move(info->script_loader_factory_ptr_info)); } - ServiceWorkerDispatcher* dispatcher = - ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( - ChildThreadImpl::current()->thread_safe_sender(), - base::ThreadTaskRunnerHandle::Get().get()); - // TODO(shimazu): Set registration/attributes directly to |context_|. - dispatcher->OnAssociateRegistrationForController( - info->provider_id, info->registration, info->attributes); provider_host_.Bind(std::move(info->host_ptr_info)); }
diff --git a/content/child/service_worker/service_worker_provider_context.cc b/content/child/service_worker/service_worker_provider_context.cc index db1b7d9..2b18d46a 100644 --- a/content/child/service_worker/service_worker_provider_context.cc +++ b/content/child/service_worker/service_worker_provider_context.cc
@@ -20,15 +20,13 @@ class ServiceWorkerProviderContext::Delegate { public: virtual ~Delegate() {} - virtual void AssociateRegistration( + virtual void SetRegistration( std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, std::unique_ptr<ServiceWorkerHandleReference> installing, std::unique_ptr<ServiceWorkerHandleReference> waiting, std::unique_ptr<ServiceWorkerHandleReference> active) = 0; - virtual void GetAssociatedRegistration( - ServiceWorkerRegistrationObjectInfo* info, - ServiceWorkerVersionAttributes* attrs) = 0; - virtual bool HasAssociatedRegistration() = 0; + virtual void GetRegistration(ServiceWorkerRegistrationObjectInfo* info, + ServiceWorkerVersionAttributes* attrs) = 0; virtual void SetController( std::unique_ptr<ServiceWorkerHandleReference> controller) = 0; virtual ServiceWorkerHandleReference* controller() = 0; @@ -42,7 +40,7 @@ ControlleeDelegate() {} ~ControlleeDelegate() override {} - void AssociateRegistration( + void SetRegistration( std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, std::unique_ptr<ServiceWorkerHandleReference> /* installing */, std::unique_ptr<ServiceWorkerHandleReference> /* waiting */, @@ -57,14 +55,8 @@ controller_ = std::move(controller); } - bool HasAssociatedRegistration() override { - NOTREACHED(); - return false; - } - - void GetAssociatedRegistration( - ServiceWorkerRegistrationObjectInfo* /* info */, - ServiceWorkerVersionAttributes* /* attrs */) override { + void GetRegistration(ServiceWorkerRegistrationObjectInfo* /* info */, + ServiceWorkerVersionAttributes* /* attrs */) override { NOTREACHED(); } @@ -86,7 +78,7 @@ ControllerDelegate() {} ~ControllerDelegate() override {} - void AssociateRegistration( + void SetRegistration( std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, std::unique_ptr<ServiceWorkerHandleReference> installing, std::unique_ptr<ServiceWorkerHandleReference> waiting, @@ -103,12 +95,9 @@ NOTREACHED(); } - bool HasAssociatedRegistration() override { return !!registration_; } - - void GetAssociatedRegistration( - ServiceWorkerRegistrationObjectInfo* info, - ServiceWorkerVersionAttributes* attrs) override { - DCHECK(HasAssociatedRegistration()); + void GetRegistration(ServiceWorkerRegistrationObjectInfo* info, + ServiceWorkerVersionAttributes* attrs) override { + DCHECK(registration_); *info = registration_->info(); if (installing_) attrs->installing = installing_->info(); @@ -136,19 +125,15 @@ int provider_id, ServiceWorkerProviderType provider_type, mojom::ServiceWorkerProviderAssociatedRequest request, - ThreadSafeSender* thread_safe_sender) + ServiceWorkerDispatcher* dispatcher) : provider_id_(provider_id), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), - thread_safe_sender_(thread_safe_sender), binding_(this, std::move(request)) { if (provider_type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) delegate_.reset(new ControllerDelegate); else delegate_.reset(new ControlleeDelegate); - ServiceWorkerDispatcher* dispatcher = - ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( - thread_safe_sender_.get(), main_thread_task_runner_.get()); dispatcher->AddProviderContext(this); } @@ -160,15 +145,14 @@ } } -void ServiceWorkerProviderContext::OnAssociateRegistration( +void ServiceWorkerProviderContext::SetRegistration( std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, std::unique_ptr<ServiceWorkerHandleReference> installing, std::unique_ptr<ServiceWorkerHandleReference> waiting, std::unique_ptr<ServiceWorkerHandleReference> active) { DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); - delegate_->AssociateRegistration(std::move(registration), - std::move(installing), std::move(waiting), - std::move(active)); + delegate_->SetRegistration(std::move(registration), std::move(installing), + std::move(waiting), std::move(active)); } void ServiceWorkerProviderContext::OnSetControllerServiceWorker( @@ -182,15 +166,11 @@ event_dispatcher_.Bind(std::move(event_dispatcher_ptr_info)); } -void ServiceWorkerProviderContext::GetAssociatedRegistration( +void ServiceWorkerProviderContext::GetRegistration( ServiceWorkerRegistrationObjectInfo* info, ServiceWorkerVersionAttributes* attrs) { DCHECK(!main_thread_task_runner_->RunsTasksInCurrentSequence()); - delegate_->GetAssociatedRegistration(info, attrs); -} - -bool ServiceWorkerProviderContext::HasAssociatedRegistration() { - return delegate_->HasAssociatedRegistration(); + delegate_->GetRegistration(info, attrs); } ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() {
diff --git a/content/child/service_worker/service_worker_provider_context.h b/content/child/service_worker/service_worker_provider_context.h index 1501757..fbb37fd 100644 --- a/content/child/service_worker/service_worker_provider_context.h +++ b/content/child/service_worker/service_worker_provider_context.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/sequenced_task_runner_helpers.h" +#include "content/child/service_worker/service_worker_dispatcher.h" #include "content/common/content_export.h" #include "content/common/service_worker/service_worker_event_dispatcher.mojom.h" #include "content/common/service_worker/service_worker_provider_interfaces.mojom.h" @@ -27,7 +28,6 @@ class ServiceWorkerHandleReference; class ServiceWorkerRegistrationHandleReference; struct ServiceWorkerProviderContextDeleter; -class ThreadSafeSender; // ServiceWorkerProviderContext has different roles depending on if it's for a // "controllee" (a Document or Worker execution context), or a "controller" (a @@ -63,30 +63,32 @@ // context. |request| is an endpoint which is connected to // content::ServiceWorkerProviderHost which notifies changes of the // registration's and workers' status. |request| is bound with |binding_|. + // The new instance is registered to |dispatcher|, which is not owned. ServiceWorkerProviderContext( int provider_id, ServiceWorkerProviderType provider_type, mojom::ServiceWorkerProviderAssociatedRequest request, - ThreadSafeSender* thread_safe_sender); + ServiceWorkerDispatcher* dispatcher); - // Called from ServiceWorkerDispatcher. - void OnAssociateRegistration( + // For service worker execution contexts. Sets the registration for + // ServiceWorkerGlobalScope#registration. Called on the main thread. + void SetRegistration( std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, std::unique_ptr<ServiceWorkerHandleReference> installing, std::unique_ptr<ServiceWorkerHandleReference> waiting, std::unique_ptr<ServiceWorkerHandleReference> active); + + // For service worker clients. Sets the controller for + // ServiceWorkerContainer#controller. Called on the main thread. void OnSetControllerServiceWorker( std::unique_ptr<ServiceWorkerHandleReference> controller, const std::set<uint32_t>& used_features, mojom::ServiceWorkerEventDispatcherPtrInfo event_dispatcher_ptr_info); // Called on the worker thread. Used for initializing - // ServiceWorkerGlobalScope. - void GetAssociatedRegistration(ServiceWorkerRegistrationObjectInfo* info, - ServiceWorkerVersionAttributes* attrs); - - // May be called on the main or worker thread. - bool HasAssociatedRegistration(); + // ServiceWorkerGlobalScope#registration. + void GetRegistration(ServiceWorkerRegistrationObjectInfo* info, + ServiceWorkerVersionAttributes* attrs); int provider_id() const { return provider_id_; } @@ -113,13 +115,13 @@ const int provider_id_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; // Mojo binding for the |request| passed to the constructor. This keeps the // connection to the content::ServiceWorkerProviderHost in the browser process // alive. mojo::AssociatedBinding<mojom::ServiceWorkerProvider> binding_; - // To dispatch events to the controller ServiceWorker. + // Only used for controllee contexts. Used to dispatch events to the + // controller ServiceWorker. mojom::ServiceWorkerEventDispatcherPtr event_dispatcher_; std::unique_ptr<Delegate> delegate_;
diff --git a/content/child/service_worker/service_worker_provider_context_unittest.cc b/content/child/service_worker/service_worker_provider_context_unittest.cc new file mode 100644 index 0000000..0858fb2 --- /dev/null +++ b/content/child/service_worker/service_worker_provider_context_unittest.cc
@@ -0,0 +1,125 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/child/service_worker/service_worker_provider_context.h" + +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "content/child/service_worker/service_worker_dispatcher.h" +#include "content/child/service_worker/service_worker_handle_reference.h" +#include "content/child/service_worker/service_worker_provider_context.h" +#include "content/child/service_worker/service_worker_registration_handle_reference.h" +#include "content/child/service_worker/web_service_worker_impl.h" +#include "content/child/service_worker/web_service_worker_registration_impl.h" +#include "content/child/thread_safe_sender.h" +#include "content/common/service_worker/service_worker_messages.h" +#include "content/common/service_worker/service_worker_provider_interfaces.mojom.h" +#include "content/common/service_worker/service_worker_types.h" +#include "ipc/ipc_sync_message_filter.h" +#include "ipc/ipc_test_sink.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +namespace { + +class ServiceWorkerTestSender : public ThreadSafeSender { + public: + explicit ServiceWorkerTestSender(IPC::TestSink* ipc_sink) + : ThreadSafeSender(nullptr, nullptr), ipc_sink_(ipc_sink) {} + + bool Send(IPC::Message* message) override { return ipc_sink_->Send(message); } + + private: + ~ServiceWorkerTestSender() override {} + + IPC::TestSink* ipc_sink_; + + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTestSender); +}; + +} // namespace + +class ServiceWorkerProviderContextTest : public testing::Test { + public: + ServiceWorkerProviderContextTest() = default; + + void SetUp() override { + sender_ = new ServiceWorkerTestSender(&ipc_sink_); + dispatcher_.reset(new ServiceWorkerDispatcher(sender_.get(), nullptr)); + } + + void CreateObjectInfoAndVersionAttributes( + ServiceWorkerRegistrationObjectInfo* info, + ServiceWorkerVersionAttributes* attrs) { + info->handle_id = 10; + info->registration_id = 20; + + attrs->active.handle_id = 100; + attrs->active.version_id = 200; + attrs->waiting.handle_id = 101; + attrs->waiting.version_id = 201; + attrs->installing.handle_id = 102; + attrs->installing.version_id = 202; + } + + ThreadSafeSender* thread_safe_sender() { return sender_.get(); } + IPC::TestSink* ipc_sink() { return &ipc_sink_; } + ServiceWorkerDispatcher* dispatcher() { return dispatcher_.get(); } + + private: + base::MessageLoop message_loop_; + IPC::TestSink ipc_sink_; + std::unique_ptr<ServiceWorkerDispatcher> dispatcher_; + scoped_refptr<ServiceWorkerTestSender> sender_; + + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContextTest); +}; + +TEST_F(ServiceWorkerProviderContextTest, CreateForController) { + // Assume that these objects are passed from the browser process and own + // references to browser-side registration/worker representations. + ServiceWorkerRegistrationObjectInfo registration_info; + ServiceWorkerVersionAttributes version_attrs; + CreateObjectInfoAndVersionAttributes(®istration_info, &version_attrs); + std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration = + ServiceWorkerRegistrationHandleReference::Adopt(registration_info, + thread_safe_sender()); + std::unique_ptr<ServiceWorkerHandleReference> installing = + ServiceWorkerHandleReference::Adopt(version_attrs.installing, + thread_safe_sender()); + std::unique_ptr<ServiceWorkerHandleReference> waiting = + ServiceWorkerHandleReference::Adopt(version_attrs.waiting, + thread_safe_sender()); + std::unique_ptr<ServiceWorkerHandleReference> active = + ServiceWorkerHandleReference::Adopt(version_attrs.active, + thread_safe_sender()); + + // Set up ServiceWorkerProviderContext for ServiceWorkerGlobalScope. + const int kProviderId = 10; + auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>( + kProviderId, SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, + mojom::ServiceWorkerProviderAssociatedRequest(), dispatcher()); + + // The passed references should be adopted and owned by the provider context. + provider_context->SetRegistration(std::move(registration), + std::move(installing), std::move(waiting), + std::move(active)); + EXPECT_EQ(0UL, ipc_sink()->message_count()); + + // Destruction of the provider context should release references to the + // associated registration and its versions. + provider_context = nullptr; + ASSERT_EQ(4UL, ipc_sink()->message_count()); + EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, + ipc_sink()->GetMessageAt(0)->type()); + EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, + ipc_sink()->GetMessageAt(1)->type()); + EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID, + ipc_sink()->GetMessageAt(2)->type()); + EXPECT_EQ(ServiceWorkerHostMsg_DecrementRegistrationRefCount::ID, + ipc_sink()->GetMessageAt(3)->type()); +} + +} // namespace content
diff --git a/content/child/service_worker/service_worker_registration_handle_reference.h b/content/child/service_worker/service_worker_registration_handle_reference.h index 8f638bb..0e149052 100644 --- a/content/child/service_worker/service_worker_registration_handle_reference.h +++ b/content/child/service_worker/service_worker_registration_handle_reference.h
@@ -22,7 +22,7 @@ // managed in the browser process. The constructor and destructor sends a // message to increment or decrement the reference count to the browser // process. -class ServiceWorkerRegistrationHandleReference { +class CONTENT_EXPORT ServiceWorkerRegistrationHandleReference { public: // Creates a new ServiceWorkerRegistrationHandleReference and increments // ref-count.
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 879ca23..a0f1feac 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -604,7 +604,6 @@ service_worker_version_id_(service_worker_version_id), service_worker_scope_(service_worker_scope), script_url_(script_url), - is_script_streaming_(is_script_streaming), sender_(ChildThreadImpl::current()->thread_safe_sender()), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), proxy_(nullptr), @@ -622,13 +621,9 @@ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker", "ServiceWorkerContextClient", this, "script_url", script_url_.spec()); - if (is_script_streaming_) { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "START_WORKER_THREAD", - this); - } else { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker", "LOAD_SCRIPT", this, - "Type", "ResourceLoader"); - } + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "ServiceWorker", "LOAD_SCRIPT", this, "Source", + (is_script_streaming ? "InstalledScriptsManager" : "ResourceLoader")); } ServiceWorkerContextClient::~ServiceWorkerContextClient() {} @@ -734,16 +729,8 @@ void ServiceWorkerContextClient::WorkerScriptLoaded() { (*instance_host_)->OnScriptLoaded(); TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "LOAD_SCRIPT", this); - if (is_script_streaming_) { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATE_SCRIPT", this); - } else { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "START_WORKER_THREAD", - this); - } -} - -bool ServiceWorkerContextClient::HasAssociatedRegistration() { - return provider_context_ && provider_context_->HasAssociatedRegistration(); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "START_WORKER_CONTEXT", + this); } void ServiceWorkerContextClient::WorkerContextStarted( @@ -765,8 +752,7 @@ ServiceWorkerRegistrationObjectInfo registration_info; ServiceWorkerVersionAttributes version_attrs; - provider_context_->GetAssociatedRegistration(®istration_info, - &version_attrs); + provider_context_->GetRegistration(®istration_info, &version_attrs); DCHECK_NE(registration_info.registration_id, kInvalidServiceWorkerRegistrationId); @@ -779,13 +765,9 @@ (*instance_host_)->OnThreadStarted(WorkerThread::GetCurrentId()); - TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "START_WORKER_THREAD", this); - if (is_script_streaming_) { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker", "LOAD_SCRIPT", this, - "Type", "InstalledScriptsManager"); - } else { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATE_SCRIPT", this); - } + TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "START_WORKER_CONTEXT", + this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATE_SCRIPT", this); } void ServiceWorkerContextClient::DidEvaluateWorkerScript(bool success) {
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 897f2ca..91e9bdf5 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -135,7 +135,6 @@ void ClearCachedMetadata(const blink::WebURL&) override; void WorkerReadyForInspection() override; void WorkerContextFailedToStart() override; - bool HasAssociatedRegistration() override; void WorkerScriptLoaded() override; void WorkerContextStarted( blink::WebServiceWorkerContextProxy* proxy) override; @@ -369,10 +368,6 @@ const GURL service_worker_scope_; const GURL script_url_; - // True if the scripts for the worker are installed and its scripts are - // streamed from the browser process instead of ResourceLoader. - const bool is_script_streaming_; - scoped_refptr<ThreadSafeSender> sender_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; scoped_refptr<base::TaskRunner> worker_task_runner_;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index c5bbeaea..9efc433 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1391,6 +1391,7 @@ "../child/notifications/notification_data_conversions_unittest.cc", "../child/resource_dispatcher_unittest.cc", "../child/service_worker/service_worker_dispatcher_unittest.cc", + "../child/service_worker/service_worker_provider_context_unittest.cc", "../child/shared_memory_data_consumer_handle_unittest.cc", "../child/shared_memory_received_data_factory_unittest.cc", "../child/site_isolation_stats_gatherer_unittest.cc",
diff --git a/pdf/pdfium/fuzzers/BUILD.gn b/pdf/pdfium/fuzzers/BUILD.gn index d348751b..118e9cc 100644 --- a/pdf/pdfium/fuzzers/BUILD.gn +++ b/pdf/pdfium/fuzzers/BUILD.gn
@@ -28,7 +28,7 @@ "//v8:external_startup_data", ] dict = "dicts/pdf.dict" - seed_corpus = "src/third_party/pdfium/test" + seed_corpus = "//third_party/pdfium/test" } fuzzer_test("pdf_cmap_fuzzer") { @@ -145,7 +145,7 @@ dict = "dicts/pdf_codec_png.dict" seed_corpuses = [ "corpora/pdf_codec_png", - "//cc/test/data", + "//components/viz/test/data", "//third_party/WebKit/LayoutTests/images/png-suite/samples", "//third_party/WebKit/LayoutTests/images/resources/pngfuzz", ]
diff --git a/remoting/android/java/AndroidManifest.xml.jinja2 b/remoting/android/java/AndroidManifest.xml.jinja2 index 4fd0b3f..67cc7431 100644 --- a/remoting/android/java/AndroidManifest.xml.jinja2 +++ b/remoting/android/java/AndroidManifest.xml.jinja2
@@ -13,9 +13,6 @@ android:allowBackup="false" android:resizeableActivity="true" android:supportsPictureInPicture="false"> - <meta-data - android:name="com.google.android.gms.version" - android:value="@integer/google_play_services_version"/> <activity android:name="org.chromium.chromoting.Chromoting" android:configChanges="orientation|screenSize"
diff --git a/testing/libfuzzer/archive_corpus.py b/testing/libfuzzer/archive_corpus.py index 9d3bf93..a3fd29f 100755 --- a/testing/libfuzzer/archive_corpus.py +++ b/testing/libfuzzer/archive_corpus.py
@@ -28,6 +28,9 @@ corpus_files = [] for directory in args.corpus_directories: + if not os.path.exists(directory): + raise Exception('The given seed_corpus directory (%s) does not exist.' % + directory) for (dirpath, _, filenames) in os.walk(directory): for filename in filenames: full_filename = os.path.join(dirpath, filename)
diff --git a/testing/libfuzzer/efficient_fuzzer.md b/testing/libfuzzer/efficient_fuzzer.md index b14c7c0..01d34c45 100644 --- a/testing/libfuzzer/efficient_fuzzer.md +++ b/testing/libfuzzer/efficient_fuzzer.md
@@ -53,7 +53,7 @@ ``` fuzzer_test("my_protocol_fuzzer") { ... - seed_corpus = "src/fuzz/testcases" + seed_corpus = "test/fuzz/testcases" ... } ``` @@ -63,7 +63,7 @@ ``` fuzzer_test("my_protocol_fuzzer") { ... - seed_corpuses = [ "src/fuzz/testcases", "src/unittest/data" ] + seed_corpuses = [ "test/fuzz/testcases", "test/unittest/data" ] ... } ```
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn index 4fa3fca..4c39576 100644 --- a/testing/libfuzzer/fuzzers/BUILD.gn +++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -167,7 +167,7 @@ } libpng_seed_corpuses = [ - "//cc/test/data", + "//components/viz/test/data", "//third_party/WebKit/LayoutTests/images/png-suite/samples", "//third_party/WebKit/LayoutTests/images/resources/pngfuzz", ]
diff --git a/third_party/WebKit/LayoutTests/editing/assert_selection.html b/third_party/WebKit/LayoutTests/editing/assert_selection.html index 1c8d757..c66e881e 100644 --- a/third_party/WebKit/LayoutTests/editing/assert_selection.html +++ b/third_party/WebKit/LayoutTests/editing/assert_selection.html
@@ -147,7 +147,7 @@ '<b id="abc">abc</b>', '<b id="def">def</b>', '</div>', - ].join(''), + ], selection => { const document = selection.document; const host = document.getElementById('host');
diff --git a/third_party/WebKit/LayoutTests/editing/assert_selection.js b/third_party/WebKit/LayoutTests/editing/assert_selection.js index f9551de..dd110cc 100644 --- a/third_party/WebKit/LayoutTests/editing/assert_selection.js +++ b/third_party/WebKit/LayoutTests/editing/assert_selection.js
@@ -893,14 +893,14 @@ } /** - * @param {string} inputText + * @param {string} passedInputText * @param {function(!Selection)|string} * @param {string} expectedText * @param {Object=} opt_options * @return {!Sample} */ function assertSelection( - inputText, tester, expectedText, opt_options = {}) { + passedInputText, tester, expectedText, opt_options = {}) { const kDescription = 'description'; const kDumpAs = 'dumpAs'; const kRemoveSampleIfSucceeded = 'removeSampleIfSucceeded'; @@ -919,6 +919,14 @@ /** @type {boolean} */ const dumpFromRoot = options[kDumpFromRoot] || false; + const inputText = (() => { + if (typeof(passedInputText) === 'string') + return passedInputText; + if (Array.isArray(passedInputText)) + return passedInputText.join(""); + throw new Error('InputText must be a string or an array of strings.'); + })(); + checkExpectedText(expectedText); const sample = new Sample(inputText); if (typeof(tester) === 'function') {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/syntax/serializing-html-fragments/serializing-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/syntax/serializing-html-fragments/serializing-expected.txt index d32e2b9..6dd7c0f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/syntax/serializing-html-fragments/serializing-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/syntax/serializing-html-fragments/serializing-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 234 tests; 220 PASS, 14 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 234 tests; 222 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS innerHTML 0 PASS innerHTML 1 <a></a> PASS innerHTML 2 <a b="c"></a> @@ -58,13 +58,13 @@ FAIL innerHTML Attribute in the XML namespace with the prefix not set to xml: assert_equals: expected "<svg xml:foo=\"test\"></svg>" but got "<svg abc:foo=\"test\"></svg>" PASS innerHTML Non-'xmlns' attribute in the xmlns namespace PASS innerHTML 'xmlns' attribute in the xmlns namespace -FAIL innerHTML Attribute in non-standard namespace assert_equals: expected "<svg abc:def=\"test\"></svg>" but got "<svg def=\"test\"></svg>" +PASS innerHTML Attribute in non-standard namespace PASS innerHTML <span> starting with U+000A PASS outerHTML Attribute in the XML namespace FAIL outerHTML Attribute in the XML namespace with the prefix not set to xml: assert_equals: expected "<span><svg xml:foo=\"test\"></svg></span>" but got "<span><svg abc:foo=\"test\"></svg></span>" PASS outerHTML Non-'xmlns' attribute in the xmlns namespace PASS outerHTML 'xmlns' attribute in the xmlns namespace -FAIL outerHTML Attribute in non-standard namespace assert_equals: expected "<span><svg abc:def=\"test\"></svg></span>" but got "<span><svg def=\"test\"></svg></span>" +PASS outerHTML Attribute in non-standard namespace PASS outerHTML <span> starting with U+000A PASS innerHTML <pre> context starting with U+000A PASS innerHTML <textarea> context starting with U+000A
diff --git a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp index b08f574..b93ed45c 100644 --- a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp +++ b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp
@@ -129,12 +129,6 @@ return SelectionMode::kBlockCursor; } -static PositionInFlatTree FindFirstVisiblePosition( - const PositionInFlatTree& start) { - return MostForwardCaretPosition( - CreateVisiblePosition(start).DeepEquivalent()); -} - static PositionInFlatTree FindLastVisiblePosition( const PositionInFlatTree& end) { return MostBackwardCaretPosition(CreateVisiblePosition(end).DeepEquivalent()); @@ -391,40 +385,51 @@ // Find first/last LayoutObject and its offset. // TODO(yoichio): Find LayoutObject w/o canonicalization. - const PositionInFlatTree& start_pos = - FindFirstVisiblePosition(selection.StartPosition()); const PositionInFlatTree& end_pos = FindLastVisiblePosition(selection.EndPosition()); - if (start_pos.IsNull() || end_pos.IsNull()) + if (end_pos.IsNull()) return {}; // This case happens if we have // <div>foo<div style="visibility:hidden">^bar|</div>baz</div>. - if (start_pos >= end_pos) + if (selection.StartPosition() >= end_pos) return {}; - LayoutObject* const start_layout_object = - start_pos.AnchorNode()->GetLayoutObject(); LayoutObject* const end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); - DCHECK(start_layout_object); DCHECK(end_layout_object); - DCHECK(start_layout_object->View() == end_layout_object->View()); - if (!start_layout_object || !end_layout_object) + if (!end_layout_object) return {}; // Marking and collect invalidation candidate LayoutObjects. + LayoutObject* start_layout_object = nullptr; + int start_editing_offset = 0; PaintInvalidationSet invalidation_set; for (const Node& node : - EphemeralRangeInFlatTree(start_pos, end_pos).Nodes()) { + EphemeralRangeInFlatTree(selection.StartPosition(), end_pos).Nodes()) { LayoutObject* const layout_object = node.GetLayoutObject(); - if (!layout_object || layout_object == start_layout_object || - layout_object == end_layout_object || - !layout_object->CanBeSelectionLeaf()) + if (!layout_object || !layout_object->CanBeSelectionLeaf() || + layout_object->Style()->Visibility() != EVisibility::kVisible) + continue; + + if (!start_layout_object) { + start_layout_object = layout_object; + const PositionInFlatTree& offsetInAnchor = + selection.StartPosition().ToOffsetInAnchor(); + if (node == offsetInAnchor.AnchorNode()) + start_editing_offset = offsetInAnchor.OffsetInContainerNode(); + continue; + } + + if (layout_object == end_layout_object) continue; layout_object->SetSelectionStateIfNeeded(SelectionState::kInside); InsertLayoutObjectAndAncestorBlocks(&invalidation_set, layout_object); } + // No valid LayOutObject found. + if (!start_layout_object) + return {}; + if (start_layout_object == end_layout_object) { start_layout_object->SetSelectionStateIfNeeded( SelectionState::kStartAndEnd); @@ -444,9 +449,8 @@ DCHECK(end_layout_object->GetSelectionState() == SelectionState::kEnd || end_layout_object->GetSelectionState() == SelectionState::kStartAndEnd); - return {start_layout_object, start_pos.ComputeEditingOffset(), - end_layout_object, end_pos.ComputeEditingOffset(), - std::move(invalidation_set)}; + return {start_layout_object, start_editing_offset, end_layout_object, + end_pos.ComputeEditingOffset(), std::move(invalidation_set)}; } void LayoutSelection::SetHasPendingSelection() {
diff --git a/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.cpp b/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.cpp index 7c40a15..47a698f1 100644 --- a/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.cpp
@@ -365,7 +365,7 @@ QualifiedName prefixed_name = attribute.GetName(); if (document_is_html && !AttributeIsInSerializedNamespace(attribute)) { result.Append(' '); - result.Append(attribute.GetName().LocalName()); + result.Append(prefixed_name.ToString()); } else { if (attribute.NamespaceURI() == XMLNSNames::xmlnsNamespaceURI) { if (!attribute.Prefix() && attribute.LocalName() != g_xmlns_atom)
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.h b/third_party/WebKit/Source/core/frame/LocalFrameView.h index 468943db6..940304c 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.h +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.h
@@ -706,7 +706,10 @@ TransformPaintPropertyNode* PreTranslation() const { return pre_translation_.Get(); } - + void SetScrollNode(RefPtr<ScrollPaintPropertyNode> scroll_node) { + scroll_node_ = std::move(scroll_node); + } + ScrollPaintPropertyNode* ScrollNode() const { return scroll_node_.Get(); } void SetScrollTranslation( RefPtr<TransformPaintPropertyNode> scroll_translation) { scroll_translation_ = std::move(scroll_translation); @@ -714,7 +717,6 @@ TransformPaintPropertyNode* ScrollTranslation() const { return scroll_translation_.Get(); } - void SetContentClip(RefPtr<ClipPaintPropertyNode> content_clip) { content_clip_ = std::move(content_clip); } @@ -1162,6 +1164,7 @@ // enabled. RefPtr<TransformPaintPropertyNode> pre_translation_; RefPtr<TransformPaintPropertyNode> scroll_translation_; + RefPtr<ScrollPaintPropertyNode> scroll_node_; // The content clip clips the document (= LayoutView) but not the scrollbars. // TODO(trchen): This will not be needed once settings->rootLayerScrolls() is // enabled.
diff --git a/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl b/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl index bbbd08c..5948567 100644 --- a/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl +++ b/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl
@@ -35,8 +35,7 @@ // TODO(tkent): We need to declare this indexed property getter because our // IDL compiler doesn't support inheritance of indexed property // getters. crbug.com/752877 - // TODO(tkent): This getter should return Element. - [ImplementedAs=item] getter Node (unsigned long index); + [ImplementedAs=item] getter Element? (unsigned long index); // TODO(tkent): This should return only Element. crbug.com/695902 [ImplementedAs=namedGetter] getter (NodeList or Element)? namedItem(DOMString name);
diff --git a/third_party/WebKit/Source/core/layout/ng/README.md b/third_party/WebKit/Source/core/layout/ng/README.md index 8dd6c3b..08ea583 100644 --- a/third_party/WebKit/Source/core/layout/ng/README.md +++ b/third_party/WebKit/Source/core/layout/ng/README.md
@@ -116,3 +116,14 @@ `chromium\src>node lcov-result-merger\bin\lcov-result-merger.js *.info output.info` * Generate the coverage html from the master lcov file `chromium\src>C:\Perl64\bin\perl.exe dynamorio.git\third_party\lcov\genhtml output.info -o output` + +### Debugging ### +Both layout input node subtrees and layout output physical fragment subtrees +may be dumped to stderr, for debugging purposes. + +#### For layout input node subtree #### +Call NGLayoutInputNode::ShowNodeTree(). + +#### For physical fragment subtree #### +Call NGPhysicalFragment::ShowFragmentTree(). Fragments in the subtree are not +required to be marked as placed (i.e. know their offset).
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc index 5ca8d14..5c33430 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc
@@ -12,6 +12,74 @@ #include "core/layout/ng/ng_unpositioned_float.h" namespace blink { +namespace { + +#ifndef NDEBUG +void AppendFragmentOffsetAndSize(const NGPhysicalFragment* fragment, + StringBuilder* string_builder) { + string_builder->Append("offset:"); + if (fragment->IsPlaced()) + string_builder->Append(fragment->Offset().ToString()); + else + string_builder->Append("unplaced"); + string_builder->Append(" size:"); + string_builder->Append(fragment->Size().ToString()); +} + +void AppendFragmentToString(const NGPhysicalFragment* fragment, + StringBuilder* string_builder, + unsigned indent = 2) { + for (unsigned i = 0; i < indent; i++) + string_builder->Append(" "); + + if (fragment->IsBox()) { + string_builder->Append("PhysicalBoxFragment "); + AppendFragmentOffsetAndSize(fragment, string_builder); + + const auto* box = ToNGPhysicalBoxFragment(fragment); + string_builder->Append(" overflow:"); + string_builder->Append(box->OverflowSize().ToString()); + string_builder->Append("\n"); + + const auto& children = box->Children(); + for (unsigned i = 0; i < children.size(); i++) + AppendFragmentToString(children[i].Get(), string_builder, indent + 2); + return; + } + + if (fragment->IsLineBox()) { + string_builder->Append("NGPhysicalLineBoxFragment "); + AppendFragmentOffsetAndSize(fragment, string_builder); + + const auto* line_box = ToNGPhysicalLineBoxFragment(fragment); + string_builder->Append("\n"); + + const auto& children = line_box->Children(); + for (unsigned i = 0; i < children.size(); i++) + AppendFragmentToString(children[i].Get(), string_builder, indent + 2); + return; + } + + if (fragment->IsText()) { + string_builder->Append("PhysicalTextFragment "); + AppendFragmentOffsetAndSize(fragment, string_builder); + + const auto* text = ToNGPhysicalTextFragment(fragment); + string_builder->Append(" start: "); + string_builder->Append(String::Format("%u", text->StartOffset())); + string_builder->Append(" end: "); + string_builder->Append(String::Format("%u", text->EndOffset())); + string_builder->Append("\n"); + return; + } + + string_builder->Append("Unknown fragment type "); + AppendFragmentOffsetAndSize(fragment, string_builder); + string_builder->Append("\n"); +} +#endif // !NDEBUG + +} // namespace NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object, const ComputedStyle& style, @@ -88,4 +156,13 @@ Offset().ToString().Ascii().data(), IsPlaced()); } +#ifndef NDEBUG +void NGPhysicalFragment::ShowFragmentTree() const { + StringBuilder string_builder; + string_builder.Append(".:: LayoutNG Physical Fragment Tree ::.\n"); + AppendFragmentToString(this, &string_builder); + fprintf(stderr, "%s\n", string_builder.ToString().Utf8().data()); +} +#endif // !NDEBUG + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h index c3e4465c..c0785fa 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
@@ -85,6 +85,10 @@ String ToString() const; +#ifndef NDEBUG + void ShowFragmentTree() const; +#endif + // Override RefCounted's deref() to ensure operator delete is called on the // appropriate subclass type. void Deref() const {
diff --git a/third_party/WebKit/Source/core/paint/FindPropertiesNeedingUpdate.h b/third_party/WebKit/Source/core/paint/FindPropertiesNeedingUpdate.h index d6791a6..dc083da7 100644 --- a/third_party/WebKit/Source/core/paint/FindPropertiesNeedingUpdate.h +++ b/third_party/WebKit/Source/core/paint/FindPropertiesNeedingUpdate.h
@@ -66,6 +66,8 @@ original_pre_translation_ = pre_translation->Clone(); if (auto* content_clip = frame_view_->ContentClip()) original_content_clip_ = content_clip->Clone(); + if (auto* scroll_node = frame_view_->ScrollNode()) + original_scroll_node_ = scroll_node->Clone(); if (auto* scroll_translation = frame_view_->ScrollTranslation()) original_scroll_translation_ = scroll_translation->Clone(); } @@ -85,6 +87,8 @@ frame_view_->PreTranslation()); DCHECK_FRAMEVIEW_PROPERTY_EQ(original_content_clip_, frame_view_->ContentClip()); + DCHECK_FRAMEVIEW_PROPERTY_EQ(original_scroll_node_, + frame_view_->ScrollNode()); DCHECK_FRAMEVIEW_PROPERTY_EQ(original_scroll_translation_, frame_view_->ScrollTranslation()); @@ -98,6 +102,7 @@ bool needed_forced_subtree_update_; RefPtr<const TransformPaintPropertyNode> original_pre_translation_; RefPtr<const ClipPaintPropertyNode> original_content_clip_; + RefPtr<const ScrollPaintPropertyNode> original_scroll_node_; RefPtr<const TransformPaintPropertyNode> original_scroll_translation_; }; @@ -184,6 +189,8 @@ DCHECK_OBJECT_PROPERTY_EQ( object_, original_properties_->SvgLocalToBorderBoxTransform(), object_properties->SvgLocalToBorderBoxTransform()); + DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Scroll(), + object_properties->Scroll()); DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->ScrollTranslation(), object_properties->ScrollTranslation());
diff --git a/third_party/WebKit/Source/core/paint/ObjectPaintProperties.h b/third_party/WebKit/Source/core/paint/ObjectPaintProperties.h index 5051118..7cad67d1 100644 --- a/third_party/WebKit/Source/core/paint/ObjectPaintProperties.h +++ b/third_party/WebKit/Source/core/paint/ObjectPaintProperties.h
@@ -76,6 +76,7 @@ const TransformPaintPropertyNode* SvgLocalToBorderBoxTransform() const { return svg_local_to_border_box_transform_.Get(); } + const ScrollPaintPropertyNode* Scroll() const { return scroll_.Get(); } const TransformPaintPropertyNode* ScrollTranslation() const { return scroll_translation_.Get(); } @@ -159,6 +160,7 @@ bool ClearSvgLocalToBorderBoxTransform() { return Clear(svg_local_to_border_box_transform_); } + bool ClearScroll() { return Clear(scroll_); } bool ClearScrollTranslation() { return Clear(scroll_translation_); } bool ClearScrollbarPaintOffset() { return Clear(scrollbar_paint_offset_); } @@ -195,19 +197,15 @@ std::forward<Args>(args)...); } template <typename... Args> + UpdateResult UpdateScroll(Args&&... args) { + return Update(scroll_, std::forward<Args>(args)...); + } + template <typename... Args> UpdateResult UpdateScrollTranslation(Args&&... args) { DCHECK(!SvgLocalToBorderBoxTransform()) << "SVG elements cannot scroll so there should never be both a scroll " "translation and an SVG local to border box transform."; - if (scroll_translation_) { - return scroll_translation_->UpdateScrollTranslation( - std::forward<Args>(args)...) - ? UpdateResult::kValueChanged - : UpdateResult::kUnchanged; - } - scroll_translation_ = TransformPaintPropertyNode::CreateScrollTranslation( - std::forward<Args>(args)...); - return UpdateResult::kNewNodeCreated; + return Update(scroll_translation_, std::forward<Args>(args)...); } template <typename... Args> UpdateResult UpdateScrollbarPaintOffset(Args&&... args) { @@ -276,6 +274,8 @@ cloned->svg_local_to_border_box_transform_ = svg_local_to_border_box_transform_->Clone(); } + if (scroll_) + cloned->scroll_ = scroll_->Clone(); if (scroll_translation_) cloned->scroll_translation_ = scroll_translation_->Clone(); if (scrollbar_paint_offset_) @@ -328,6 +328,7 @@ RefPtr<TransformPaintPropertyNode> perspective_; // TODO(pdr): Only LayoutSVGRoot needs this and it should be moved there. RefPtr<TransformPaintPropertyNode> svg_local_to_border_box_transform_; + RefPtr<ScrollPaintPropertyNode> scroll_; RefPtr<TransformPaintPropertyNode> scroll_translation_; RefPtr<TransformPaintPropertyNode> scrollbar_paint_offset_; };
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp index 02fdf8e..c474094e 100644 --- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
@@ -135,8 +135,8 @@ // Verify that the background does not scroll. const PaintChunk& background_chunk = RootPaintController().PaintChunks()[0]; - EXPECT_FALSE(background_chunk.properties.property_tree_state.Transform() - ->IsScrollTranslation()); + auto* transform = background_chunk.properties.property_tree_state.Transform(); + EXPECT_EQ(nullptr, transform->ScrollNode()); const EffectPaintPropertyNode* effect_node = div.FirstFragment()->PaintProperties()->Effect();
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp index 971ab59..da97738 100644 --- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp +++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
@@ -268,12 +268,14 @@ saved_context_(tree_builder_context_.current) { DCHECK(!RuntimeEnabledFeatures::RootLayerScrollingEnabled()); + if (const auto* scroll_node = frame_view.ScrollNode()) { + DCHECK_EQ(scroll_node, saved_context_.scroll); + tree_builder_context_.current.scroll = saved_context_.scroll->Parent(); + } if (const auto* scroll_translation = frame_view.ScrollTranslation()) { DCHECK_EQ(scroll_translation, saved_context_.transform); - DCHECK_EQ(scroll_translation->ScrollNode(), saved_context_.scroll); tree_builder_context_.current.transform = saved_context_.transform->Parent(); - tree_builder_context_.current.scroll = saved_context_.scroll->Parent(); } DCHECK_EQ(frame_view.PreTranslation(), tree_builder_context_.current.transform);
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp index 3c8a7d884..43ccd2a 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -78,12 +78,9 @@ // True if a new property was created or a main thread scrolling reason changed // (which can affect descendants), false if an existing one was updated. -static bool UpdateScrollTranslation( +static bool UpdateScroll( LocalFrameView& frame_view, - RefPtr<const TransformPaintPropertyNode> parent, - const TransformationMatrix& matrix, - const FloatPoint3D& origin, - RefPtr<const ScrollPaintPropertyNode> scroll_parent, + RefPtr<const ScrollPaintPropertyNode> parent, const IntSize& clip, const IntSize& bounds, bool user_scrollable_horizontal, @@ -91,26 +88,41 @@ MainThreadScrollingReasons main_thread_scrolling_reasons, WebLayerScrollClient* scroll_client) { DCHECK(!RuntimeEnabledFeatures::RootLayerScrollingEnabled()); - // TODO(pdr): Set the correct compositing reasons here. auto element_id = CompositorElementIdFromLayoutObjectId( frame_view.GetLayoutView()->UniqueId(), CompositorElementIdNamespace::kScrollTranslation); - if (auto* existing_scroll_translation = frame_view.ScrollTranslation()) { - auto existing_reasons = existing_scroll_translation->ScrollNode() - ->GetMainThreadScrollingReasons(); - existing_scroll_translation->UpdateScrollTranslation( - std::move(parent), matrix, origin, false, 0, kCompositingReasonNone, - std::move(scroll_parent), IntPoint(), clip, bounds, - user_scrollable_horizontal, user_scrollable_vertical, - main_thread_scrolling_reasons, element_id, scroll_client); + if (auto* existing_scroll = frame_view.ScrollNode()) { + auto existing_reasons = existing_scroll->GetMainThreadScrollingReasons(); + existing_scroll->Update( + std::move(parent), IntPoint(), clip, bounds, user_scrollable_horizontal, + user_scrollable_vertical, main_thread_scrolling_reasons, element_id, + scroll_client); return existing_reasons != main_thread_scrolling_reasons; } - frame_view.SetScrollTranslation( - TransformPaintPropertyNode::CreateScrollTranslation( - std::move(parent), matrix, origin, false, 0, kCompositingReasonNone, - std::move(scroll_parent), IntPoint(), clip, bounds, - user_scrollable_horizontal, user_scrollable_vertical, - main_thread_scrolling_reasons, element_id, scroll_client)); + frame_view.SetScrollNode(ScrollPaintPropertyNode::Create( + std::move(parent), IntPoint(), clip, bounds, user_scrollable_horizontal, + user_scrollable_vertical, main_thread_scrolling_reasons, element_id, + scroll_client)); + return true; +} + +// True if a new property was created, false if an existing one was updated. +static bool UpdateScrollTranslation( + LocalFrameView& frame_view, + RefPtr<const TransformPaintPropertyNode> parent, + const TransformationMatrix& matrix, + PassRefPtr<ScrollPaintPropertyNode> scroll) { + DCHECK(!RuntimeEnabledFeatures::RootLayerScrollingEnabled()); + // TODO(pdr): Set the correct compositing reasons here. + if (auto* existing_scroll_translation = frame_view.ScrollTranslation()) { + existing_scroll_translation->Update( + std::move(parent), matrix, FloatPoint3D(), false, 0, + kCompositingReasonNone, CompositorElementId(), std::move(scroll)); + return false; + } + frame_view.SetScrollTranslation(TransformPaintPropertyNode::Create( + std::move(parent), matrix, FloatPoint3D(), false, 0, + kCompositingReasonNone, CompositorElementId(), std::move(scroll))); return true; } @@ -166,11 +178,7 @@ frame_view, context.current.clip, frame_view.PreTranslation(), content_clip, full_context.clip_changed); - ScrollOffset scroll_offset = frame_view.GetScrollOffset(); - if (frame_view.IsScrollable() || !scroll_offset.IsZero()) { - TransformationMatrix frame_scroll; - frame_scroll.Translate(-scroll_offset.Width(), -scroll_offset.Height()); - + if (frame_view.IsScrollable()) { IntSize scroll_clip = frame_view.VisibleContentSize(); IntSize scroll_bounds = frame_view.ContentsSize(); bool user_scrollable_horizontal = @@ -183,18 +191,31 @@ auto reasons = GetMainThreadScrollingReasons(frame_view, ancestor_reasons); - full_context.force_subtree_update |= UpdateScrollTranslation( - frame_view, frame_view.PreTranslation(), frame_scroll, FloatPoint3D(), - context.current.scroll, scroll_clip, scroll_bounds, + full_context.force_subtree_update |= UpdateScroll( + frame_view, context.current.scroll, scroll_clip, scroll_bounds, user_scrollable_horizontal, user_scrollable_vertical, reasons, frame_view.GetScrollableArea()); - } else { - if (frame_view.ScrollTranslation()) { - // Ensure pre-existing properties are cleared if there is no scrolling. - frame_view.SetScrollTranslation(nullptr); - // Rebuild all descendant properties because a property was removed. - full_context.force_subtree_update = true; - } + } else if (frame_view.ScrollNode()) { + // Ensure pre-existing properties are cleared if there is no scrolling. + frame_view.SetScrollNode(nullptr); + // Rebuild all descendant properties because a property was removed. + full_context.force_subtree_update = true; + } + + // A scroll translation node is created for static offset (e.g., overflow + // hidden with scroll offset) or cases that scroll and have a scroll node. + ScrollOffset scroll_offset = frame_view.GetScrollOffset(); + if (frame_view.IsScrollable() || !scroll_offset.IsZero()) { + TransformationMatrix frame_scroll; + frame_scroll.Translate(-scroll_offset.Width(), -scroll_offset.Height()); + full_context.force_subtree_update |= + UpdateScrollTranslation(frame_view, frame_view.PreTranslation(), + frame_scroll, frame_view.ScrollNode()); + } else if (frame_view.ScrollTranslation()) { + // Ensure pre-existing properties are cleared if there is no scrolling. + frame_view.SetScrollTranslation(nullptr); + // Rebuild all descendant properties because a property was removed. + full_context.force_subtree_update = true; } } @@ -209,10 +230,10 @@ context.current.transform = frame_view.PreTranslation(); DCHECK(frame_view.ContentClip()); context.current.clip = frame_view.ContentClip(); - if (const auto* scroll_translation = frame_view.ScrollTranslation()) { + if (const auto* scroll_node = frame_view.ScrollNode()) + context.current.scroll = scroll_node; + if (const auto* scroll_translation = frame_view.ScrollTranslation()) context.current.transform = scroll_translation; - context.current.scroll = scroll_translation->ScrollNode(); - } context.current.paint_offset = LayoutPoint(); context.current.rendering_context_id = 0; context.current.should_flatten_inherited_transform = true; @@ -946,13 +967,20 @@ ancestor_reasons); } -static bool NeedsScrollTranslation(const LayoutObject& object) { +static bool NeedsScrollNode(const LayoutObject& object) { if (!object.HasOverflowClip()) return false; - const LayoutBox& box = ToLayoutBox(object); - auto* scrollable_area = box.GetScrollableArea(); - IntSize scroll_offset = box.ScrolledContentOffset(); - return !scroll_offset.IsZero() || scrollable_area->ScrollsOverflow(); + return ToLayoutBox(object).GetScrollableArea()->ScrollsOverflow(); +} + +// True if a scroll translation is needed for static scroll offset (e.g., +// overflow hidden with scroll), or if a scroll node is needed for composited +// scrolling. +static bool NeedsScrollOrScrollTranslation(const LayoutObject& object) { + if (!object.HasOverflowClip()) + return false; + IntSize scroll_offset = ToLayoutBox(object).ScrolledContentOffset(); + return !scroll_offset.IsZero() || NeedsScrollNode(object); } void PaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation( @@ -961,13 +989,9 @@ PaintPropertyTreeBuilderFragmentContext& context, bool& force_subtree_update) { if (object.NeedsPaintPropertyUpdate() || force_subtree_update) { - if (NeedsScrollTranslation(object)) { + if (NeedsScrollNode(object)) { const LayoutBox& box = ToLayoutBox(object); auto* scrollable_area = box.GetScrollableArea(); - IntSize scroll_offset = box.ScrolledContentOffset(); - TransformationMatrix scroll_offset_matrix = - TransformationMatrix().Translate(-scroll_offset.Width(), - -scroll_offset.Height()); // The container bounds are snapped to integers to match the equivalent // bounds on cc::ScrollNode. The offset is snapped to match the current @@ -989,9 +1013,8 @@ // Main thread scrolling reasons depend on their ancestor's reasons // so ensure the entire subtree is updated when reasons change. - if (auto* existing_scroll_translation = properties.ScrollTranslation()) { - auto* existing_scroll_node = existing_scroll_translation->ScrollNode(); - if (existing_scroll_node->GetMainThreadScrollingReasons() != reasons) + if (auto* existing_scroll = properties.Scroll()) { + if (existing_scroll->GetMainThreadScrollingReasons() != reasons) force_subtree_update = true; } @@ -999,13 +1022,29 @@ object.UniqueId(), CompositorElementIdNamespace::kScrollTranslation); // TODO(pdr): Set the correct compositing reasons here. + auto result = properties.UpdateScroll( + context.current.scroll, bounds_offset, container_bounds, + scroll_bounds, user_scrollable_horizontal, user_scrollable_vertical, + reasons, element_id, scrollable_area); + force_subtree_update |= result.NewNodeCreated(); + } else { + // Ensure pre-existing properties are cleared. + force_subtree_update |= properties.ClearScroll(); + } + + // A scroll translation node is created for static offset (e.g., overflow + // hidden with scroll offset) or cases that scroll and have a scroll node. + if (NeedsScrollOrScrollTranslation(object)) { + const LayoutBox& box = ToLayoutBox(object); + IntSize scroll_offset = box.ScrolledContentOffset(); + TransformationMatrix scroll_offset_matrix = + TransformationMatrix().Translate(-scroll_offset.Width(), + -scroll_offset.Height()); auto result = properties.UpdateScrollTranslation( context.current.transform, scroll_offset_matrix, FloatPoint3D(), context.current.should_flatten_inherited_transform, context.current.rendering_context_id, kCompositingReasonNone, - context.current.scroll, bounds_offset, container_bounds, - scroll_bounds, user_scrollable_horizontal, user_scrollable_vertical, - reasons, element_id, scrollable_area); + CompositorElementId(), properties.Scroll()); force_subtree_update |= result.NewNodeCreated(); } else { // Ensure pre-existing properties are cleared. @@ -1013,9 +1052,10 @@ } } + if (properties.Scroll()) + context.current.scroll = properties.Scroll(); if (properties.ScrollTranslation()) { context.current.transform = properties.ScrollTranslation(); - context.current.scroll = context.current.transform->ScrollNode(); context.current.should_flatten_inherited_transform = false; } } @@ -1211,7 +1251,7 @@ NeedsFilter(object) || NeedsCssClip(object) || NeedsScrollbarPaintOffset(object) || NeedsOverflowClip(object) || NeedsPerspective(object) || NeedsSVGLocalToBorderBoxTransform(object) || - NeedsScrollTranslation(object); + NeedsScrollOrScrollTranslation(object); // We need at least the fragment for all PaintLayers, which store their // local border box properties on the fragment.
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp index ac3cd96..499036b 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -59,15 +59,12 @@ if (!frame_view) frame_view = GetDocument().View(); if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) { - const auto* scroll_translation = frame_view->GetLayoutView() - ->FirstFragment() - ->PaintProperties() - ->ScrollTranslation(); - return scroll_translation ? scroll_translation->ScrollNode() : nullptr; + return frame_view->GetLayoutView() + ->FirstFragment() + ->PaintProperties() + ->Scroll(); } - return frame_view->ScrollTranslation() - ? frame_view->ScrollTranslation()->ScrollNode() - : nullptr; + return frame_view->ScrollNode(); } const ObjectPaintProperties* @@ -2751,7 +2748,6 @@ " overflow: hidden;" " width: 5px;" " height: 3px;" - " border: 1px solid black;" " }" " .forceScroll {" " height: 79px;" @@ -2768,24 +2764,42 @@ const ObjectPaintProperties* overflow_hidden_scroll_properties = overflow_hidden->GetLayoutObject()->FirstFragment()->PaintProperties(); - // Because the frameView is does not scroll, overflowHidden's scroll should be - // under the root. + + // Because the overflow hidden does not scroll and only has a static scroll + // offset, there should be a scroll translation node but no scroll node. auto* scroll_translation = overflow_hidden_scroll_properties->ScrollTranslation(); - auto* overflow_hidden_scroll_node = scroll_translation->ScrollNode(); - EXPECT_TRUE(overflow_hidden_scroll_node->Parent()->IsRoot()); EXPECT_EQ(TransformationMatrix().Translate(0, -37), scroll_translation->Matrix()); - // This should match the overflow's dimensions and should not include the - // box's border. - EXPECT_EQ(IntSize(5, 3), overflow_hidden_scroll_node->ContainerBounds()); - // The scrolling content's bounds should include both the overflow's - // dimensions (5x3) and the 0x79 "forceScroll" object. - EXPECT_EQ(IntSize(5, 79), overflow_hidden_scroll_node->Bounds()); - // Although overflow: hidden is programmatically scrollable, it is not user - // scrollable. - EXPECT_FALSE(overflow_hidden_scroll_node->UserScrollableHorizontal()); - EXPECT_FALSE(overflow_hidden_scroll_node->UserScrollableVertical()); + EXPECT_EQ(nullptr, scroll_translation->ScrollNode()); + EXPECT_EQ(nullptr, overflow_hidden_scroll_properties->Scroll()); +} + +TEST_P(PaintPropertyTreeBuilderTest, FrameOverflowHiddenScrollProperties) { + SetBodyInnerHTML( + "<style>" + " html {" + " margin: 0px;" + " overflow: hidden;" + " width: 300px;" + " height: 300px;" + " }" + " .forceScroll {" + " height: 5000px;" + " }" + "</style>" + "<div class='forceScroll'></div>"); + + GetDocument().domWindow()->scrollTo(0, 37); + + GetDocument().View()->UpdateAllLifecyclePhases(); + + // Because the overflow hidden does not scroll and only has a static scroll + // offset, there should be a scroll translation node but no scroll node. + EXPECT_EQ(TransformationMatrix().Translate(0, -37), + FrameScrollTranslation()->Matrix()); + EXPECT_EQ(nullptr, FrameScrollTranslation()->ScrollNode()); + EXPECT_EQ(nullptr, FrameScroll()); } TEST_P(PaintPropertyTreeBuilderTest, NestedScrollProperties) { @@ -3394,9 +3408,8 @@ // stored directly on the ScrollNode. EXPECT_EQ(CompositorElementId(), properties->ScrollTranslation()->GetCompositorElementId()); - EXPECT_NE( - CompositorElementId(), - properties->ScrollTranslation()->ScrollNode()->GetCompositorElementId()); + EXPECT_NE(CompositorElementId(), + properties->Scroll()->GetCompositorElementId()); } TEST_P(PaintPropertyTreeBuilderTest, OverflowClipSubpixelPosition) {
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.cpp index f223403..38a7bd2 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.cpp
@@ -220,18 +220,16 @@ static void AddFrameViewProperties( const LocalFrameView& frame_view, PropertyTreePrinter<ScrollPaintPropertyNode>& printer) { - if (const auto* scroll_translation = frame_view.ScrollTranslation()) { - const auto* scroll_node = scroll_translation->ScrollNode(); + if (const auto* scroll_node = frame_view.ScrollNode()) printer.AddPropertyNode(scroll_node, "Scroll (FrameView)"); - } } static void AddObjectPaintProperties( const LayoutObject& object, const ObjectPaintProperties& paint_properties, PropertyTreePrinter<ScrollPaintPropertyNode>& printer) { - if (const auto* scroll_translation = paint_properties.ScrollTranslation()) { - printer.AddPropertyNode(scroll_translation->ScrollNode(), + if (const auto* scroll_node = paint_properties.Scroll()) { + printer.AddPropertyNode(scroll_node, "Scroll (" + object.DebugName() + ")"); } }
diff --git a/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp b/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp index dd1ff07..73dc443 100644 --- a/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp +++ b/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp
@@ -329,13 +329,7 @@ if (asked_to_terminate_) return; - // The browser is expected to associate a registration and then load the - // script. If there's no associated registration, the browser could not - // successfully handle the SetHostedVersionID IPC, and the script load came - // through the normal network stack rather than through service worker - // loading code. - if (!worker_context_client_->HasAssociatedRegistration() || - main_script_loader_->Failed()) { + if (main_script_loader_->Failed()) { TerminateWorkerContext(); return; }
diff --git a/third_party/WebKit/Source/modules/serviceworkers/WebEmbeddedWorkerImplTest.cpp b/third_party/WebKit/Source/modules/serviceworkers/WebEmbeddedWorkerImplTest.cpp index bf14909..5da92b4f65 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/WebEmbeddedWorkerImplTest.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/WebEmbeddedWorkerImplTest.cpp
@@ -54,13 +54,6 @@ return std::unique_ptr<WebServiceWorkerProvider>( CreateServiceWorkerProviderProxy()); } - - bool HasAssociatedRegistration() override { - return has_associated_registration_; - } - void SetHasAssociatedRegistration(bool has_associated_registration) { - has_associated_registration_ = has_associated_registration; - } void GetClient(const WebString&, std::unique_ptr<WebServiceWorkerClientCallbacks>) override { NOTREACHED(); @@ -111,7 +104,6 @@ void WaitUntilThreadTermination() { termination_event_.Wait(); } private: - bool has_associated_registration_ = true; WaitableEvent script_evaluated_event_; WaitableEvent termination_event_; }; @@ -295,38 +287,6 @@ ::testing::Mock::VerifyAndClearExpectations(mock_client_); } -TEST_F(WebEmbeddedWorkerImplTest, NoRegistration) { - EXPECT_CALL(*mock_client_, WorkerReadyForInspection()).Times(1); - start_data_.pause_after_download_mode = - WebEmbeddedWorkerStartData::kPauseAfterDownload; - worker_->StartWorkerContext(start_data_); - ::testing::Mock::VerifyAndClearExpectations(mock_client_); - - // Load the shadow page. - EXPECT_CALL(*mock_client_, CreateServiceWorkerNetworkProviderProxy()) - .WillOnce(::testing::Return(nullptr)); - if (mock_installed_scripts_manager_) { - EXPECT_CALL(*mock_installed_scripts_manager_, - IsScriptInstalled(start_data_.script_url)) - .Times(1) - .WillOnce(::testing::Return(false)); - } - Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests(); - ::testing::Mock::VerifyAndClearExpectations(mock_client_); - if (mock_installed_scripts_manager_) { - ::testing::Mock::VerifyAndClearExpectations( - mock_installed_scripts_manager_); - } - - // Load the script. - mock_client_->SetHasAssociatedRegistration(false); - EXPECT_CALL(*mock_client_, WorkerScriptLoaded()).Times(0); - EXPECT_CALL(*mock_client_, CreateServiceWorkerProviderProxy()).Times(0); - EXPECT_CALL(*mock_client_, WorkerContextFailedToStart()).Times(1); - Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests(); - ::testing::Mock::VerifyAndClearExpectations(mock_client_); -} - // The running worker is detected as a memory leak. crbug.com/586897 #if defined(ADDRESS_SANITIZER) #define MAYBE_DontPauseAfterDownload DISABLED_DontPauseAfterDownload
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 04f6fa0..25fd52ea 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -2067,7 +2067,7 @@ ] dict = "//testing/libfuzzer/fuzzers/dicts/png.dict" seed_corpuses = [ - "//cc/test/data", + "//components/viz/test/data", "//third_party/WebKit/LayoutTests/images/png-suite/samples", "//third_party/WebKit/LayoutTests/images/resources/pngfuzz", ]
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp index 8d1c7878..cbcc572 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -730,14 +730,15 @@ FakeScrollClient scroll_client; CompositorElementId expected_compositor_element_id = CompositorElementId(2); + RefPtr<ScrollPaintPropertyNode> scroll = ScrollPaintPropertyNode::Create( + ScrollPaintPropertyNode::Root(), IntPoint(), IntSize(11, 13), + IntSize(27, 31), true, false, 0 /* mainThreadScrollingReasons */, + expected_compositor_element_id, &scroll_client); RefPtr<TransformPaintPropertyNode> scroll_translation = - TransformPaintPropertyNode::CreateScrollTranslation( + TransformPaintPropertyNode::Create( TransformPaintPropertyNode::Root(), TransformationMatrix().Translate(7, 9), FloatPoint3D(), false, 0, - kCompositingReasonNone, ScrollPaintPropertyNode::Root(), IntPoint(), - IntSize(11, 13), IntSize(27, 31), true, false, - 0 /* mainThreadScrollingReasons */, expected_compositor_element_id, - &scroll_client); + kCompositingReasonNone, CompositorElementId(), scroll); TestPaintArtifact artifact; artifact @@ -789,13 +790,15 @@ } TEST_F(PaintArtifactCompositorTestWithPropertyTrees, TransformUnderScrollNode) { + RefPtr<ScrollPaintPropertyNode> scroll = ScrollPaintPropertyNode::Create( + ScrollPaintPropertyNode::Root(), IntPoint(), IntSize(11, 13), + IntSize(27, 31), true, false, 0 /* mainThreadScrollingReasons */, + CompositorElementId(), nullptr); RefPtr<TransformPaintPropertyNode> scroll_translation = - TransformPaintPropertyNode::CreateScrollTranslation( + TransformPaintPropertyNode::Create( TransformPaintPropertyNode::Root(), TransformationMatrix().Translate(7, 9), FloatPoint3D(), false, 0, - kCompositingReasonNone, ScrollPaintPropertyNode::Root(), IntPoint(), - IntSize(11, 13), IntSize(27, 31), true, false, - 0 /* mainThreadScrollingReasons */, CompositorElementId(), nullptr); + kCompositingReasonNone, CompositorElementId(), scroll); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::Create( @@ -836,24 +839,28 @@ CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5); CompositorElementId expected_compositor_element_id_a = CompositorElementId(2); + RefPtr<ScrollPaintPropertyNode> scroll_a = ScrollPaintPropertyNode::Create( + ScrollPaintPropertyNode::Root(), IntPoint(), IntSize(2, 3), IntSize(5, 7), + false, true, + MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, + expected_compositor_element_id_a, nullptr); RefPtr<TransformPaintPropertyNode> scroll_translation_a = - TransformPaintPropertyNode::CreateScrollTranslation( + TransformPaintPropertyNode::Create( TransformPaintPropertyNode::Root(), TransformationMatrix().Translate(11, 13), FloatPoint3D(), false, 0, - kCompositingReasonLayerForScrollingContents, - ScrollPaintPropertyNode::Root(), IntPoint(), IntSize(2, 3), - IntSize(5, 7), false, true, - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, - expected_compositor_element_id_a, nullptr); + kCompositingReasonLayerForScrollingContents, CompositorElementId(), + scroll_a); CompositorElementId expected_compositor_element_id_b = CompositorElementId(3); + RefPtr<ScrollPaintPropertyNode> scroll_b = ScrollPaintPropertyNode::Create( + scroll_translation_a->ScrollNode(), IntPoint(), IntSize(19, 23), + IntSize(29, 31), true, false, 0 /* mainThreadScrollingReasons */, + expected_compositor_element_id_b, nullptr); RefPtr<TransformPaintPropertyNode> scroll_translation_b = - TransformPaintPropertyNode::CreateScrollTranslation( + TransformPaintPropertyNode::Create( scroll_translation_a, TransformationMatrix().Translate(37, 41), FloatPoint3D(), false, 0, kCompositingReasonNone, - scroll_translation_a->ScrollNode(), IntPoint(), IntSize(19, 23), - IntSize(29, 31), true, false, 0 /* mainThreadScrollingReasons */, - expected_compositor_element_id_b, nullptr); + CompositorElementId(), scroll_b); TestPaintArtifact artifact; artifact.Chunk(scroll_translation_a, ClipPaintPropertyNode::Root(), effect) .RectDrawing(FloatRect(7, 11, 13, 17), Color::kWhite);
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp index 5edac71e..500f83f 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
@@ -310,7 +310,7 @@ layer->SetScrollTreeIndex(scroll_node_id); auto& compositor_scroll_node = *GetScrollTree().Node(scroll_node_id); - if (!transform->IsScrollTranslation()) + if (!transform->ScrollNode()) return; auto& compositor_transform_node =
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h index e9006c8..b13eb8b 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h
@@ -22,16 +22,16 @@ // A scroll node contains auxiliary scrolling information which includes how far // an area can be scrolled, main thread scrolling reasons, etc. Scroll nodes -// are owned by TransformPaintPropertyNodes that are used for the scroll offset -// translation. +// are referenced by TransformPaintPropertyNodes that are used for the scroll +// offset translation, though scroll offset translation can exist without a +// scroll node (e.g., overflow: hidden). // // Main thread scrolling reasons force scroll updates to go to the main thread // and can have dependencies on other nodes. For example, all parents of a // scroll node with background attachment fixed set should also have it set. // // The scroll tree differs from the other trees because it does not affect -// geometry directly. We may want to rename this class to reflect that it is -// more like rare scroll data for TransformPaintPropertyNode. +// geometry directly. class PLATFORM_EXPORT ScrollPaintPropertyNode : public PaintPropertyNode<ScrollPaintPropertyNode> { public:
diff --git a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.cpp b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.cpp index 850d6b8..490be54 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.cpp
@@ -45,8 +45,10 @@ flattens_inherited_transform_ ? "yes" : "no", rendering_context_id_, CompositingReasonsAsString(direct_compositing_reasons_).Ascii().data(), compositor_element_id_.ToString().c_str()); - if (scroll_) - return transform + " scroll=" + scroll_->ToString(); + if (scroll_) { + return String::Format("%s scroll=%p", transform.Utf8().data(), + scroll_.Get()); + } return transform; }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h index ef02f33c..0b441ed 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h
@@ -21,9 +21,9 @@ // A transform (e.g., created by css "transform" or "perspective", or for // internal positioning such as paint offset or scrolling) along with a -// reference to the parent TransformPaintPropertyNode. The scroll tree is owned -// by transform nodes and a transform node for scrolling will have a 2d -// translation for the scroll offset and an associated ScrollPaintPropertyNode. +// reference to the parent TransformPaintPropertyNode. The scroll tree is +// referenced by transform nodes and a transform node with an associated scroll +// node will be a 2d transform for scroll offset. // // The transform tree is rooted at a node with no parent. This root node should // not be modified. @@ -41,43 +41,19 @@ bool flattens_inherited_transform = false, unsigned rendering_context_id = 0, CompositingReasons direct_compositing_reasons = kCompositingReasonNone, - const CompositorElementId& compositor_element_id = - CompositorElementId()) { + const CompositorElementId& compositor_element_id = CompositorElementId(), + PassRefPtr<const ScrollPaintPropertyNode> scroll = nullptr) { + if (scroll) { + // If there is an associated scroll node, this can only be a 2d + // translation for scroll offset. + DCHECK(matrix.IsIdentityOr2DTranslation()); + // The scroll compositor element id should be stored on the scroll node. + DCHECK(!compositor_element_id); + } return AdoptRef(new TransformPaintPropertyNode( std::move(parent), matrix, origin, flattens_inherited_transform, - rendering_context_id, direct_compositing_reasons, - compositor_element_id)); - } - - static PassRefPtr<TransformPaintPropertyNode> CreateScrollTranslation( - PassRefPtr<const TransformPaintPropertyNode> parent, - const TransformationMatrix& matrix, - const FloatPoint3D& origin, - bool flattens_inherited_transform, - unsigned rendering_context_id, - CompositingReasons direct_compositing_reasons, - PassRefPtr<const ScrollPaintPropertyNode> parent_scroll, - const IntPoint& bounds_offset, - const IntSize& scroll_container_bounds, - const IntSize& bounds, - bool user_scrollable_horizontal, - bool user_scrollable_vertical, - MainThreadScrollingReasons main_thread_scrolling_reasons, - const CompositorElementId& compositor_element_id, - WebLayerScrollClient* scroll_client) { - // If this transform is for scroll offset, it should be a 2d translation. - DCHECK(matrix.IsIdentityOr2DTranslation()); - return AdoptRef(new TransformPaintPropertyNode( - std::move(parent), matrix, origin, flattens_inherited_transform, - rendering_context_id, direct_compositing_reasons, - // The compositor element id is empty because the element id is stored - // on the scroll node. - CompositorElementId(), - ScrollPaintPropertyNode::Create( - std::move(parent_scroll), bounds_offset, scroll_container_bounds, - bounds, user_scrollable_horizontal, user_scrollable_vertical, - main_thread_scrolling_reasons, compositor_element_id, - scroll_client))); + rendering_context_id, direct_compositing_reasons, compositor_element_id, + std::move(scroll))); } bool Update( @@ -87,14 +63,23 @@ bool flattens_inherited_transform = false, unsigned rendering_context_id = 0, CompositingReasons direct_compositing_reasons = kCompositingReasonNone, - CompositorElementId compositor_element_id = CompositorElementId()) { + CompositorElementId compositor_element_id = CompositorElementId(), + PassRefPtr<const ScrollPaintPropertyNode> scroll = nullptr) { bool parent_changed = PaintPropertyNode::Update(std::move(parent)); + if (scroll) { + // If there is an associated scroll node, this can only be a 2d + // translation for scroll offset. + DCHECK(matrix.IsIdentityOr2DTranslation()); + // The scroll compositor element id should be stored on the scroll node. + DCHECK(!compositor_element_id); + } + if (matrix == matrix_ && origin == origin_ && flattens_inherited_transform == flattens_inherited_transform_ && rendering_context_id == rendering_context_id_ && direct_compositing_reasons == direct_compositing_reasons_ && - compositor_element_id == compositor_element_id_) + compositor_element_id == compositor_element_id_ && scroll == scroll_) return parent_changed; SetChanged(); @@ -104,44 +89,14 @@ rendering_context_id_ = rendering_context_id; direct_compositing_reasons_ = direct_compositing_reasons; compositor_element_id_ = compositor_element_id; + scroll_ = std::move(scroll); return true; } - bool UpdateScrollTranslation( - PassRefPtr<const TransformPaintPropertyNode> parent, - const TransformationMatrix& matrix, - const FloatPoint3D& origin, - bool flattens_inherited_transform, - unsigned rendering_context_id, - CompositingReasons direct_compositing_reasons, - PassRefPtr<const ScrollPaintPropertyNode> parent_scroll, - const IntPoint& bounds_offset, - const IntSize& scroll_container_bounds, - const IntSize& bounds, - bool user_scrollable_horizontal, - bool user_scrollable_vertical, - MainThreadScrollingReasons main_thread_scrolling_reasons, - CompositorElementId compositor_element_id, - WebLayerScrollClient* scroll_client) { - bool changed = Update(std::move(parent), matrix, origin, - flattens_inherited_transform, rendering_context_id, - direct_compositing_reasons, CompositorElementId()); - DCHECK(scroll_); - DCHECK(matrix.IsIdentityOr2DTranslation()); - changed |= scroll_->Update( - std::move(parent_scroll), bounds_offset, scroll_container_bounds, - bounds, user_scrollable_horizontal, user_scrollable_vertical, - main_thread_scrolling_reasons, compositor_element_id, scroll_client); - return changed; - } - const TransformationMatrix& Matrix() const { return matrix_; } const FloatPoint3D& Origin() const { return origin_; } - // True if this transform is for the scroll offset translation. - bool IsScrollTranslation() const { return !!scroll_; } - // The associated scroll node if this transform is the scroll offset for - // scrolling, or nullptr otherwise. + // The associated scroll node, or nullptr otherwise. const ScrollPaintPropertyNode* ScrollNode() const { return scroll_.Get(); } // Returns the scroll node this transform scrolls with respect to. If this @@ -180,21 +135,19 @@ return AdoptRef(new TransformPaintPropertyNode( Parent(), matrix_, origin_, flattens_inherited_transform_, rendering_context_id_, direct_compositing_reasons_, - compositor_element_id_, scroll_ ? scroll_->Clone() : nullptr)); + compositor_element_id_, scroll_)); } // The equality operator is used by FindPropertiesNeedingUpdate.h for checking // if a transform node has changed. bool operator==(const TransformPaintPropertyNode& o) const { - if (scroll_ && o.scroll_ && !(*scroll_ == *o.scroll_)) - return false; return Parent() == o.Parent() && matrix_ == o.matrix_ && origin_ == o.origin_ && flattens_inherited_transform_ == o.flattens_inherited_transform_ && rendering_context_id_ == o.rendering_context_id_ && direct_compositing_reasons_ == o.direct_compositing_reasons_ && compositor_element_id_ == o.compositor_element_id_ && - !!scroll_ == !!o.scroll_; + scroll_ == o.scroll_; } String ToTreeString() const; @@ -211,7 +164,7 @@ unsigned rendering_context_id, CompositingReasons direct_compositing_reasons, CompositorElementId compositor_element_id, - PassRefPtr<ScrollPaintPropertyNode> scroll = nullptr) + PassRefPtr<const ScrollPaintPropertyNode> scroll = nullptr) : PaintPropertyNode(std::move(parent)), matrix_(matrix), origin_(origin), @@ -239,7 +192,7 @@ unsigned rendering_context_id_; CompositingReasons direct_compositing_reasons_; CompositorElementId compositor_element_id_; - RefPtr<ScrollPaintPropertyNode> scroll_; + RefPtr<const ScrollPaintPropertyNode> scroll_; mutable std::unique_ptr<GeometryMapperTransformCache> transform_cache_; };
diff --git a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h index 9b75b5c..6e97462 100644 --- a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h +++ b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h
@@ -108,12 +108,6 @@ // completed. Called on the main thread. virtual void WorkerContextFailedToStart() {} - // True if the running service worker has a service worker registration. This - // should never be false and is currently used as a sanity check that the - // worker started up using the expected code path. - // TODO(falken): Investigate removing this method. - virtual bool HasAssociatedRegistration() { return false; } - // The worker script successfully loaded. Called on the main thread when the // script is served from ResourceLoader or on the worker thread when the // script is served via WebServiceWorkerInstalledScriptsManager.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 97018e6..82080b9 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -23183,6 +23183,7 @@ <int value="-345838366" label="enable-hosted-apps-in-windows"/> <int value="-345324571" label="enable-quirks-client"/> <int value="-344343842" label="disable-experimental-app-list"/> + <int value="-343769596" label="ServiceWorkerScriptStreaming:disabled"/> <int value="-340622848" label="disable-javascript-harmony-shipping"/> <int value="-340255045" label="allow-nacl-socket-api"/> <int value="-340023285" label="WebNFC:enabled"/> @@ -23427,6 +23428,7 @@ <int value="477967119" label="enable-unified-media-pipeline"/> <int value="479906041" label="RunAllFlashInAllowMode:disabled"/> <int value="480544447" label="NonValidatingReloadOnRefreshContentV2:enabled"/> + <int value="481506759" label="ServiceWorkerScriptStreaming:enabled"/> <int value="492113129" label="ExperimentalAppBanners:enabled"/> <int value="493903641" label="disable-appcontainer"/> <int value="494733611" label="disable-drop-sync-credential"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 9bba6d1..07b438e 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -91330,6 +91330,7 @@ <suffix name="ForeignTabs" label="Open tabs on other devices"/> <suffix name="Experimental" label="Experimental"/> <suffix name="ReadingList" label="Reading List entries"/> + <suffix name="Contextual" label="Contextual suggestions"/> <affected-histogram name="NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible"/> <affected-histogram name="NewTabPage.ContentSuggestions.DismissedUnvisited"/>
diff --git a/ui/login/account_picker/md_screen_account_picker.css b/ui/login/account_picker/md_screen_account_picker.css index 491d148..6e69f2b 100644 --- a/ui/login/account_picker/md_screen_account_picker.css +++ b/ui/login/account_picker/md_screen_account_picker.css
@@ -100,6 +100,10 @@ display: block; } +.small-pod-container::-webkit-scrollbar-corner { + background-color: transparent; /* Hides the default white box. */ +} + .small-pod-container-mask { background: linear-gradient(#000, transparent); height: 112px;
diff --git a/ui/login/account_picker/md_user_pod_row.css b/ui/login/account_picker/md_user_pod_row.css index a01e0064..58dfca6 100644 --- a/ui/login/account_picker/md_user_pod_row.css +++ b/ui/login/account_picker/md_user_pod_row.css
@@ -165,7 +165,7 @@ top: 182px; } -.pod.focused:not(.multiprofiles-policy-applied) .auth-container { +.pod.focused:not(.multiprofiles-policy-applied):not(.public-account) .auth-container { display: flex; height: 40px; left: 51px; @@ -182,7 +182,7 @@ </if> } -html[dir=rtl] .pod.focused:not(.multiprofiles-policy-applied) .auth-container { +html[dir=rtl] .pod.focused:not(.multiprofiles-policy-applied):not(.public-account) .auth-container { left: auto; right: 51px; }
diff --git a/ui/login/account_picker/user_pod_row.css b/ui/login/account_picker/user_pod_row.css index 29bc6f66..b8a0ef6 100644 --- a/ui/login/account_picker/user_pod_row.css +++ b/ui/login/account_picker/user_pod_row.css
@@ -163,7 +163,7 @@ } .name-container, -.pod.focused:not(.multiprofiles-policy-applied) .auth-container { +.pod.focused:not(.multiprofiles-policy-applied):not(.public-account) .auth-container { background-color: white; display: flex; position: absolute;