diff --git a/DEPS b/DEPS index 2e9e9306..aa30f2c 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': '46bd8103300461a53af05e58a389bf1aaf67ac3a', + 'v8_revision': '72905fa422cb537075320ab89e80929c7c0931c1', # 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. @@ -427,7 +427,7 @@ # gRPC, an RPC framework. For Blimp use only. 'src/third_party/grpc': - Var('chromium_git') + '/external/github.com/grpc/grpc' + '@' + 'b4cc5fc16c1368149c8a20c51248a18009ff8254', + Var('chromium_git') + '/external/github.com/grpc/grpc' + '@' + '5945dfa700a0566be7ea6691cc8a86ecb4a53924', # DevTools node modules. Used on Linux buildbots only. 'src/third_party/WebKit/Source/devtools/devtools-node-modules':
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc index a0421634..d5ceb17 100644 --- a/chrome/browser/devtools/devtools_sanity_browsertest.cc +++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -1122,6 +1122,22 @@ RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning); } +IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestTempFileIncognito) { + GURL url("about:blank"); + ui_test_utils::BrowserAddedObserver window_observer; + chrome::NewEmptyWindow(browser()->profile()->GetOffTheRecordProfile()); + Browser* new_browser = window_observer.WaitForSingleNewBrowser(); + ui_test_utils::NavigateToURL(new_browser, url); + DevToolsWindow* window = DevToolsWindowTesting::OpenDevToolsWindowSync( + new_browser->tab_strip_model()->GetWebContentsAt(0), false); + RunTestFunction(window, "testTempFile"); + DevToolsWindowTesting::CloseDevToolsWindowSync(window); +} + +IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestTempFile) { + RunTest("testTempFile", kDebuggerTestPage); +} + // Tests network timing. IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) { RunTest("testNetworkTiming", kSlowTestPage);
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.cc b/chrome/browser/ntp_snippets/download_suggestions_provider.cc index 1189dd79..7dfb81d6 100644 --- a/chrome/browser/ntp_snippets/download_suggestions_provider.cc +++ b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
@@ -25,6 +25,7 @@ #include "components/offline_pages/core/offline_page_model_query.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "components/variations/variations_associated_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/image/image.h" @@ -51,7 +52,7 @@ int GetMaxSuggestionsCount() { bool assets_enabled = base::FeatureList::IsEnabled(features::kAssetDownloadSuggestionsFeature); - return ntp_snippets::GetParamAsInt( + return variations::GetVariationParamByFeatureAsInt( assets_enabled ? features::kAssetDownloadSuggestionsFeature : features::kOfflinePageDownloadSuggestionsFeature, kMaxSuggestionsCountParamName, kDefaultMaxSuggestionsCount);
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 4cc65f26..9956202f 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -91,6 +91,7 @@ #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/content_switches.h" #include "content/public/common/resource_request_body.h" #include "content/public/common/url_constants.h" @@ -2834,6 +2835,11 @@ // a server redirect. IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrossProcessServerRedirect) { + // Cross-process navigations don't happen for prerendering with PlzNavigate, + // since we decide on a process after redirects are followed. + if (content::IsBrowserSideNavigationEnabled()) + return; + // Force everything to be a process swap. SwapProcessesContentBrowserClient test_browser_client; content::ContentBrowserClient* original_browser_client = @@ -2851,6 +2857,11 @@ // See http://crbug.com/341134 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrossProcessServerRedirectNoHang) { + // Cross-process navigations don't happen for prerendering with PlzNavigate, + // since we decide on a process after redirects are followed. + if (content::IsBrowserSideNavigationEnabled()) + return; + const char kDestPath[] = "/prerender/prerender_page.html"; // Force everything to be a process swap. SwapProcessesContentBrowserClient test_browser_client;
diff --git a/chrome/browser/ui/webui/devtools_ui.cc b/chrome/browser/ui/webui/devtools_ui.cc index e16afaa..fcd2ce99 100644 --- a/chrome/browser/ui/webui/devtools_ui.cc +++ b/chrome/browser/ui/webui/devtools_ui.cc
@@ -15,6 +15,8 @@ #include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_frontend_host.h" +#include "content/public/browser/site_instance.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -26,6 +28,7 @@ #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_request_context_getter.h" +#include "storage/browser/fileapi/file_system_context.h" #include "third_party/WebKit/public/public_features.h" using content::BrowserThread; @@ -438,8 +441,15 @@ new DevToolsDataSource(profile->GetRequestContext())); GURL url = web_ui->GetWebContents()->GetVisibleURL(); - if (url.spec() == SanitizeFrontendURL(url).spec()) - bindings_.reset(new DevToolsUIBindings(web_ui->GetWebContents())); + if (url.spec() != SanitizeFrontendURL(url).spec()) + return; + + if (profile->IsOffTheRecord()) { + GURL site = content::SiteInstance::GetSiteForURL(profile, url); + content::BrowserContext::GetStoragePartitionForSite(profile, site)-> + GetFileSystemContext()->EnableTemporaryFileSystemInIncognito(); + } + bindings_.reset(new DevToolsUIBindings(web_ui->GetWebContents())); } DevToolsUI::~DevToolsUI() {
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 13c35f6..fa1ec9d 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -9059.0.0 \ No newline at end of file +9064.0.0 \ No newline at end of file
diff --git a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc index b27ba5d9..c8f9346 100644 --- a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc +++ b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
@@ -49,20 +49,22 @@ // Note that bookmarks can be shown that do not meet this threshold. base::Time GetThresholdTime() { return base::Time::Now() - - base::TimeDelta::FromDays(GetParamAsInt( + base::TimeDelta::FromDays(variations::GetVariationParamByFeatureAsInt( ntp_snippets::kBookmarkSuggestionsFeature, kMaxBookmarkAgeInDaysParamName, kMaxBookmarkAgeInDays)); } // The maximum number of suggestions ever provided. int GetMaxCount() { - return GetParamAsInt(ntp_snippets::kBookmarkSuggestionsFeature, - kMaxBookmarksParamName, kMaxBookmarks); + return variations::GetVariationParamByFeatureAsInt( + ntp_snippets::kBookmarkSuggestionsFeature, kMaxBookmarksParamName, + kMaxBookmarks); } bool AreDesktopVisitsConsidered() { - return GetParamAsBool(ntp_snippets::kBookmarkSuggestionsFeature, - kConsiderDesktopVisitsParamName, false); + return variations::GetVariationParamByFeatureAsBool( + ntp_snippets::kBookmarkSuggestionsFeature, + kConsiderDesktopVisitsParamName, false); } } // namespace
diff --git a/components/ntp_snippets/features.cc b/components/ntp_snippets/features.cc index fe007b5..085257b 100644 --- a/components/ntp_snippets/features.cc +++ b/components/ntp_snippets/features.cc
@@ -4,7 +4,6 @@ #include "components/ntp_snippets/features.h" -#include "base/strings/string_number_conversions.h" #include "components/variations/variations_associated_data.h" namespace ntp_snippets { @@ -42,46 +41,4 @@ const base::Feature kFetchMoreFeature{"NTPSuggestionsFetchMore", base::FEATURE_ENABLED_BY_DEFAULT}; -int GetParamAsInt(const base::Feature& feature, - const std::string& param_name, - const int default_value) { - std::string value_as_string = - variations::GetVariationParamValueByFeature(feature, param_name); - int value_as_int = 0; - if (!base::StringToInt(value_as_string, &value_as_int)) { - if (!value_as_string.empty()) { - LOG(WARNING) << "Failed to parse variation param " << param_name - << " with string value " << value_as_string - << " under feature " << feature.name - << " into an int. Falling back to default value of " - << default_value; - } - value_as_int = default_value; - } - return value_as_int; -} - - -bool GetParamAsBool(const base::Feature& feature, - const std::string& param_name, - bool default_value) { - std::string value_as_string = - variations::GetVariationParamValueByFeature(feature, param_name); - if (value_as_string == "true") { - return true; - } - if (value_as_string == "false") { - return false; - } - - if (!value_as_string.empty()) { - LOG(WARNING) << "Failed to parse variation param " << param_name - << " with string value " << value_as_string - << " under feature " << feature.name - << " into a bool. Falling back to default value of " - << default_value; - } - return default_value; -} - } // namespace ntp_snippets
diff --git a/components/ntp_snippets/features.h b/components/ntp_snippets/features.h index 25a3a295..3e90b3f 100644 --- a/components/ntp_snippets/features.h +++ b/components/ntp_snippets/features.h
@@ -38,17 +38,6 @@ // Feature to enable the Fetch More action extern const base::Feature kFetchMoreFeature; -// Returns a feature param as an int instead of a string. -int GetParamAsInt(const base::Feature& feature, - const std::string& param_name, - int default_value); - -// Returns a feature param as a bool instead of a string. -// TODO(jkrcal): Use this function in other code in the ntp_snippets component. -bool GetParamAsBool(const base::Feature& feature, - const std::string& param_name, - bool default_value); - } // namespace ntp_snippets #endif // COMPONENTS_NTP_SNIPPETS_FEATURES_H_
diff --git a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.cc b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.cc index 1585a67..f27892f 100644 --- a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.cc +++ b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.cc
@@ -20,6 +20,7 @@ #include "components/offline_pages/core/offline_page_model_query.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "components/variations/variations_associated_data.h" #include "grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/image/image.h" @@ -38,9 +39,9 @@ const char* kMaxSuggestionsCountParamName = "recent_tabs_max_count"; int GetMaxSuggestionsCount() { - return GetParamAsInt(kRecentOfflineTabSuggestionsFeature, - kMaxSuggestionsCountParamName, - kDefaultMaxSuggestionsCount); + return variations::GetVariationParamByFeatureAsInt( + kRecentOfflineTabSuggestionsFeature, kMaxSuggestionsCountParamName, + kDefaultMaxSuggestionsCount); } struct OrderOfflinePagesByMostRecentlyCreatedFirst {
diff --git a/components/ntp_snippets/remote/remote_suggestions_hard_scheduler.h b/components/ntp_snippets/remote/remote_suggestions_hard_scheduler.h new file mode 100644 index 0000000..6487e2f8 --- /dev/null +++ b/components/ntp_snippets/remote/remote_suggestions_hard_scheduler.h
@@ -0,0 +1,38 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_HARD_SCHEDULER_H_ +#define COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_HARD_SCHEDULER_H_ + +#include "base/macros.h" +#include "base/time/time.h" + +namespace ntp_snippets { + +// Interface to schedule "hard" periodic fetches of snippets. These "hard" +// fetches must get triggered according to their schedule independent of whether +// Chrome is running at that moment. +class RemoteSuggestionsHardScheduler { + public: + // Schedule periodic fetching of snippets, with different periods depending on + // network state. Once per period, the concrete implementation should call + // RemoteSuggestionsScheduler::Updater::HardUpdate() where the updater is + // obtained from ContentSuggestionsService. Any of the periods can be zero to + // indicate that the corresponding task should not be scheduled. + virtual bool Schedule(base::TimeDelta period_wifi, + base::TimeDelta period_fallback) = 0; + + // Cancel any scheduled tasks. + virtual bool Unschedule() = 0; + + protected: + RemoteSuggestionsHardScheduler() = default; + + private: + DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsHardScheduler); +}; + +} // namespace ntp_snippets + +#endif // COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_HARD_SCHEDULER_H_
diff --git a/components/ntp_snippets/remote/remote_suggestions_scheduler.h b/components/ntp_snippets/remote/remote_suggestions_scheduler.h new file mode 100644 index 0000000..bad65c9 --- /dev/null +++ b/components/ntp_snippets/remote/remote_suggestions_scheduler.h
@@ -0,0 +1,61 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_SCHEDULER_H_ +#define COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_SCHEDULER_H_ + +#include "base/macros.h" +#include "base/time/time.h" + +namespace ntp_snippets { + +// Class to take care of scheduling of periodic updates of snippets. There are +// two types of scheduled updates: +// - "hard" ones that should outlive current running instance of Chrome. These +// should get triggered according to their schedule even if Chrome is not +// running at the given moment. This is OS-dependent, may be unavilable on +// some platforms. +// - "soft" ones that get triggered only if Chrome stays running until the +// scheduled point. +class RemoteSuggestionsScheduler { + public: + // Interface to perform the scheduled update. + class Updater { + virtual void HardUpdate(); + virtual void SoftUpdate(); + }; + + // The passed in |updater| is called when an update is due according to the + // schedule. Note that hard fetches get access to the |updater| via the keyed + // ContentSuggestionService because the concrete instance passed to + // RemoteSuggestionsScheduler when the hard fetch was scheduled may not exist + // any more when the hard update is due. + explicit RemoteSuggestionsScheduler(Updater* updater); + + // Schedules both "soft" and "hard" fetches. First removes existing schedule + // before scheduling new updates. + void Schedule(); + + // Removes any existing schedule. + void Unschedule(); + + // Schedule periodic fetching of snippets, with different periods depending on + // network state. Once per period, the concrete implementation should call + // RemoteSuggestionsUpdater::HardUpdate where RemoteSuggestionsUpdater is + // obtained from ContentSuggestionsService. + // Any of the periods can be zero to indicate that the corresponding task + // should not be scheduled. + virtual bool Schedule(base::TimeDelta period_wifi, + base::TimeDelta period_fallback) = 0; + + // Cancel any scheduled tasks. + virtual bool Unschedule() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsHardScheduler); +}; + +} // namespace ntp_snippets + +#endif // COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_HARD_SCHEDULER_H_
diff --git a/components/ntp_snippets/sessions/foreign_sessions_suggestions_provider.cc b/components/ntp_snippets/sessions/foreign_sessions_suggestions_provider.cc index 5178292..c82de249 100644 --- a/components/ntp_snippets/sessions/foreign_sessions_suggestions_provider.cc +++ b/components/ntp_snippets/sessions/foreign_sessions_suggestions_provider.cc
@@ -22,6 +22,7 @@ #include "components/prefs/pref_service.h" #include "components/sessions/core/session_types.h" #include "components/sync_sessions/synced_session.h" +#include "components/variations/variations_associated_data.h" #include "grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/image/image.h" @@ -49,18 +50,19 @@ "max_foreign_tabs_age_in_minutes"; int GetMaxForeignTabsTotal() { - return GetParamAsInt(ntp_snippets::kForeignSessionsSuggestionsFeature, - kMaxForeignTabsTotalParamName, kMaxForeignTabsTotal); + return variations::GetVariationParamByFeatureAsInt( + ntp_snippets::kForeignSessionsSuggestionsFeature, + kMaxForeignTabsTotalParamName, kMaxForeignTabsTotal); } int GetMaxForeignTabsPerDevice() { - return GetParamAsInt(ntp_snippets::kForeignSessionsSuggestionsFeature, - kMaxForeignTabsPerDeviceParamName, - kMaxForeignTabsPerDevice); + return variations::GetVariationParamByFeatureAsInt( + ntp_snippets::kForeignSessionsSuggestionsFeature, + kMaxForeignTabsPerDeviceParamName, kMaxForeignTabsPerDevice); } TimeDelta GetMaxForeignTabAge() { - return TimeDelta::FromMinutes(GetParamAsInt( + return TimeDelta::FromMinutes(variations::GetVariationParamByFeatureAsInt( ntp_snippets::kForeignSessionsSuggestionsFeature, kMaxForeignTabAgeInMinutesParamName, kMaxForeignTabAgeInMinutes)); }
diff --git a/components/ntp_snippets/user_classifier.cc b/components/ntp_snippets/user_classifier.cc index 10a26ac..35b5389 100644 --- a/components/ntp_snippets/user_classifier.cc +++ b/components/ntp_snippets/user_classifier.cc
@@ -91,22 +91,11 @@ static_cast<int>(UserClassifier::Metric::COUNT), "Fill in info for all metrics."); -double GetParamValue(const char* param_name, double default_value) { - std::string param_value_str = variations::GetVariationParamValueByFeature( - kArticleSuggestionsFeature, param_name); - double param_value = 0; - if (!base::StringToDouble(param_value_str, ¶m_value)) { - LOG_IF(WARNING, !param_value_str.empty()) - << "Invalid variation parameter for " << param_name; - return default_value; - } - return param_value; -} - // Computes the discount rate. double GetDiscountRatePerHour() { - double discount_rate_per_day = - GetParamValue(kDiscountRatePerDayParam, kDiscountRatePerDay); + double discount_rate_per_day = variations::GetVariationParamByFeatureAsDouble( + kArticleSuggestionsFeature, kDiscountRatePerDayParam, + kDiscountRatePerDay); // Check for illegal values. if (discount_rate_per_day <= 0 || discount_rate_per_day >= 1) { DLOG(WARNING) << "Illegal value " << discount_rate_per_day @@ -121,17 +110,20 @@ } double GetInitialHoursBetweenEvents(UserClassifier::Metric metric) { - return GetParamValue( + return variations::GetVariationParamByFeatureAsDouble( + kArticleSuggestionsFeature, kInitialHoursBetweenEventsParams[static_cast<int>(metric)], kInitialHoursBetweenEvents[static_cast<int>(metric)]); } double GetMinHours() { - return GetParamValue(kMinHoursParam, kMinHours); + return variations::GetVariationParamByFeatureAsDouble( + kArticleSuggestionsFeature, kMinHoursParam, kMinHours); } double GetMaxHours() { - return GetParamValue(kMaxHoursParam, kMaxHours); + return variations::GetVariationParamByFeatureAsDouble( + kArticleSuggestionsFeature, kMaxHoursParam, kMaxHours); } // Returns the new value of the metric using its |old_value|, assuming @@ -195,11 +187,15 @@ min_hours_(GetMinHours()), max_hours_(GetMaxHours()), active_consumer_scrolls_at_least_once_per_hours_( - GetParamValue(kActiveConsumerScrollsAtLeastOncePerHoursParam, - kActiveConsumerScrollsAtLeastOncePerHours)), + variations::GetVariationParamByFeatureAsDouble( + kArticleSuggestionsFeature, + kActiveConsumerScrollsAtLeastOncePerHoursParam, + kActiveConsumerScrollsAtLeastOncePerHours)), rare_user_opens_ntp_at_most_once_per_hours_( - GetParamValue(kRareUserOpensNTPAtMostOncePerHoursParam, - kRareUserOpensNTPAtMostOncePerHours)) { + variations::GetVariationParamByFeatureAsDouble( + kArticleSuggestionsFeature, + kRareUserOpensNTPAtMostOncePerHoursParam, + kRareUserOpensNTPAtMostOncePerHours)) { // The pref_service_ can be null in tests. if (!pref_service_) { return;
diff --git a/components/reading_list/ios/reading_list_entry.cc b/components/reading_list/ios/reading_list_entry.cc index 4908274..b3fc0e0 100644 --- a/components/reading_list/ios/reading_list_entry.cc +++ b/components/reading_list/ios/reading_list_entry.cc
@@ -324,7 +324,7 @@ int64_t first_read_time_us = 0; if (pb_entry.has_first_read_time_us()) { - creation_time_us = pb_entry.first_read_time_us(); + first_read_time_us = pb_entry.first_read_time_us(); } int64_t update_time_us = 0; @@ -368,22 +368,27 @@ } if (creation_time_us_ < other.creation_time_us_) { creation_time_us_ = std::move(other.creation_time_us_); - } - if (state_ == UNSEEN) { - state_ = std::move(other.state_); - } else if (other.state_ != UNSEEN) { - // Both are not UNSEEN, take the newer one. - if (update_time_us_ < other.update_time_us_) { - state_ = std::move(other.state_); - } else if (update_time_us_ == other.update_time_us_) { - // Both states are likely the same, but if they are not, READ should win. - if (other.state_ == READ) { - state_ = std::move(other.state_); - } + first_read_time_us_ = std::move(other.first_read_time_us_); + } else if (creation_time_us_ == other.creation_time_us_) { + // The first_time_read_us from |other| is used if + // - this.first_time_read_us == 0: the entry was never read in this device. + // - this.first_time_read_us > other.first_time_read_us: the entry was + // first read on another device. + if (first_read_time_us_ == 0 || + (other.first_read_time_us_ != 0 && + other.first_read_time_us_ < first_read_time_us_)) { + first_read_time_us_ = std::move(other.first_read_time_us_); } } if (update_time_us_ < other.update_time_us_) { update_time_us_ = std::move(other.update_time_us_); + state_ = std::move(other.state_); + } else if (update_time_us_ == other.update_time_us_) { + if (state_ == UNSEEN) { + state_ = std::move(other.state_); + } else if (other.state_ == READ) { + state_ = std::move(other.state_); + } } #if !defined(NDEBUG) std::unique_ptr<sync_pb::ReadingListSpecifics> new_this_pb(
diff --git a/components/reading_list/ios/reading_list_entry_unittest.cc b/components/reading_list/ios/reading_list_entry_unittest.cc index 0157f4c..bf9dec3 100644 --- a/components/reading_list/ios/reading_list_entry_unittest.cc +++ b/components/reading_list/ios/reading_list_entry_unittest.cc
@@ -317,6 +317,8 @@ } // Tests the merging of two ReadingListEntry. +// Additional merging tests are done in +// ReadingListStoreTest.CompareEntriesForSync TEST(ReadingListEntry, MergeWithEntry) { ReadingListEntry local_entry(GURL("http://example.com/"), "title"); local_entry.SetDistilledState(ReadingListEntry::ERROR); @@ -339,24 +341,3 @@ base::TimeDelta delta = merge_next_call - next_call; EXPECT_NEAR(delta.InMillisecondsRoundedUp(), 0, 10); } - -// Tests the merging of two ReadingListEntry, the oldest one SEEN and the newer -// UNSEEN. -TEST(ReadingListEntry, MergeWithEntrySeen) { - ReadingListEntry local_entry(GURL("http://example.com/"), "title"); - local_entry.SetRead(true); - int64_t local_update_time_us = local_entry.UpdateTime(); - local_entry.SetDistilledPath(base::FilePath("distilled/page.html")); - - ReadingListEntry sync_entry(GURL("http://example.com/"), "title2"); - int64_t sync_update_time_us = sync_entry.UpdateTime(); - EXPECT_NE(local_update_time_us, sync_update_time_us); - local_entry.MergeWithEntry(sync_entry); - EXPECT_EQ(local_entry.URL().spec(), "http://example.com/"); - EXPECT_EQ(local_entry.Title(), "title2"); - EXPECT_TRUE(local_entry.HasBeenSeen()); - EXPECT_EQ(local_entry.UpdateTime(), sync_update_time_us); - EXPECT_EQ(local_entry.FailedDownloadCounter(), 0); - EXPECT_EQ(local_entry.DistilledState(), ReadingListEntry::PROCESSED); - EXPECT_EQ(local_entry.DistilledPath().value(), "distilled/page.html"); -}
diff --git a/components/reading_list/ios/reading_list_store.cc b/components/reading_list/ios/reading_list_store.cc index 26ebf29..beb300b 100644 --- a/components/reading_list/ios/reading_list_store.cc +++ b/components/reading_list/ios/reading_list_store.cc
@@ -442,5 +442,14 @@ lhs.status() == sync_pb::ReadingListSpecifics::READ)) return false; } + if (rhs.creation_time_us() == lhs.creation_time_us()) { + if (rhs.first_read_time_us() == 0 && lhs.first_read_time_us() != 0) { + return false; + } + if (rhs.first_read_time_us() > lhs.first_read_time_us() && + lhs.first_read_time_us() != 0) { + return false; + } + } return true; }
diff --git a/components/reading_list/ios/reading_list_store.h b/components/reading_list/ios/reading_list_store.h index 4dd3cfe8..c8463c8 100644 --- a/components/reading_list/ios/reading_list_store.h +++ b/components/reading_list/ios/reading_list_store.h
@@ -79,11 +79,23 @@ // Entries are in increasing order if all the fields respect increasing order. // - URL must be the same. // - title must verify rhs.title.compare(lhs.title) >= 0 - // - rhs.creation_time_us >= lhs.creation_time_us - // - rhs.update_time_us >= lhs.update_time_us - // - if rhs.update_time_us > lhs.update_time_us, rhs.state can be anything. - // - if rhs.update_time_us == lhs.update_time_us, rhs.state >= lhs.state in - // the order UNSEEN, UNREAD, READ. + // - creation_time_us: + // rhs.creation_time_us >= lhs.creation_time_us + // - rhs.first_read_time_us: + // if rhs.creation_time_us > lhs.creation_time_us, + // rhs.first_read_time_us can be anything. + // if rhs.creation_time_us == lhs.creation_time_us + // and rhs.first_read_time_us == 0 + // rhs.first_read_time_us can be anything. + // if rhs.creation_time_us == lhs.creation_time_us, + // rhs.first_read_time_us <= lhs.first_read_time_us + // - update_time_us: + // rhs.update_time_us >= lhs.update_time_us + // - state: + // if rhs.update_time_us > lhs.update_time_us + // rhs.state can be anything. + // if rhs.update_time_us == lhs.update_time_us + // rhs.state >= lhs.state in the order UNSEEN, UNREAD, READ. static bool CompareEntriesForSync(const sync_pb::ReadingListSpecifics& lhs, const sync_pb::ReadingListSpecifics& rhs);
diff --git a/components/reading_list/ios/reading_list_store_unittest.mm b/components/reading_list/ios/reading_list_store_unittest.mm index 3c49c74..e6e00304 100644 --- a/components/reading_list/ios/reading_list_store_unittest.mm +++ b/components/reading_list/ios/reading_list_store_unittest.mm
@@ -17,6 +17,30 @@ #include "components/sync/model/model_type_store_test_util.h" #include "testing/gtest/include/gtest/gtest.h" +// Tests that the transition from |entryA| to |entryB| is possible (|possible| +// is true) or not. +void ExpectAB(const sync_pb::ReadingListSpecifics& entryA, + const sync_pb::ReadingListSpecifics& entryB, + bool possible) { + EXPECT_EQ(ReadingListStore::CompareEntriesForSync(entryA, entryB), possible); + std::unique_ptr<ReadingListEntry> a = + ReadingListEntry::FromReadingListSpecifics(entryA); + std::unique_ptr<ReadingListEntry> b = + ReadingListEntry::FromReadingListSpecifics(entryB); + a->MergeWithEntry(*b); + std::unique_ptr<sync_pb::ReadingListSpecifics> mergedEntry = + a->AsReadingListSpecifics(); + if (possible) { + // If transition is possible, the merge should be B. + EXPECT_EQ(entryB.SerializeAsString(), mergedEntry->SerializeAsString()); + } else { + // If transition is not possible, the transition shold be possible to the + // merged state. + EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, *mergedEntry)); + EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryB, *mergedEntry)); + } +} + class FakeModelTypeChangeProcessorObserver { public: virtual void Put(const std::string& client_tag, @@ -293,48 +317,73 @@ TEST_F(ReadingListStoreTest, CompareEntriesForSync) { sync_pb::ReadingListSpecifics entryA; sync_pb::ReadingListSpecifics entryB; - entryA.set_url("http://foo.bar"); - entryB.set_url("http://foo.bar"); + entryA.set_entry_id("http://foo.bar/"); + entryB.set_entry_id("http://foo.bar/"); + entryA.set_url("http://foo.bar/"); + entryB.set_url("http://foo.bar/"); entryA.set_title("Foo Bar"); entryB.set_title("Foo Bar"); entryA.set_status(sync_pb::ReadingListSpecifics::UNREAD); entryB.set_status(sync_pb::ReadingListSpecifics::UNREAD); entryA.set_creation_time_us(10); entryB.set_creation_time_us(10); + entryA.set_first_read_time_us(50); + entryB.set_first_read_time_us(50); entryA.set_update_time_us(100); entryB.set_update_time_us(100); // Equal entries can be submitted. - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, true); // Try to update each field. // You cannot change the URL of an entry. - entryA.set_url("http://foo.foo"); + entryA.set_url("http://foo.foo/"); EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); - entryA.set_url("http://foo.bar"); + entryA.set_url("http://foo.bar/"); // You can set a title to a title later in alphabetical order. entryA.set_title(""); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); entryA.set_title("Foo Aar"); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); entryA.set_title("Foo Ba"); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); entryA.set_title("Foo Bar"); entryA.set_creation_time_us(9); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); + entryA.set_first_read_time_us(51); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); + entryA.set_first_read_time_us(49); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); + entryA.set_first_read_time_us(0); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); + entryA.set_first_read_time_us(50); + entryB.set_first_read_time_us(0); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); + entryB.set_first_read_time_us(50); entryA.set_creation_time_us(10); + entryA.set_first_read_time_us(51); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); + entryA.set_first_read_time_us(0); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); + entryA.set_first_read_time_us(50); entryA.set_update_time_us(99); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); sync_pb::ReadingListSpecifics::ReadingListEntryStatus status_oder[3] = { sync_pb::ReadingListSpecifics::UNSEEN, sync_pb::ReadingListSpecifics::UNREAD, @@ -343,20 +392,20 @@ entryA.set_status(status_oder[index_a]); for (int index_b = 0; index_b < 3; index_b++) { entryB.set_status(status_oder[index_b]); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); } } entryA.set_update_time_us(100); for (int index_a = 0; index_a < 3; index_a++) { entryA.set_status(status_oder[index_a]); entryB.set_status(status_oder[index_a]); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, true); for (int index_b = index_a + 1; index_b < 3; index_b++) { entryB.set_status(status_oder[index_b]); - EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, entryB)); - EXPECT_FALSE(ReadingListStore::CompareEntriesForSync(entryB, entryA)); + ExpectAB(entryA, entryB, true); + ExpectAB(entryB, entryA, false); } } }
diff --git a/components/variations/variations_associated_data.cc b/components/variations/variations_associated_data.cc index 465aed5..6701105 100644 --- a/components/variations/variations_associated_data.cc +++ b/components/variations/variations_associated_data.cc
@@ -13,6 +13,7 @@ #include "base/memory/singleton.h" #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_param_associator.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "components/variations/variations_http_header_provider.h" @@ -190,6 +191,64 @@ return GetVariationParamValue(trial->trial_name(), param_name); } +int GetVariationParamByFeatureAsInt(const base::Feature& feature, + const std::string& param_name, + int default_value) { + std::string value_as_string = + GetVariationParamValueByFeature(feature, param_name); + int value_as_int = 0; + if (!base::StringToInt(value_as_string, &value_as_int)) { + if (!value_as_string.empty()) { + DLOG(WARNING) << "Failed to parse variation param " << param_name + << " with string value " << value_as_string + << " under feature " << feature.name + << " into an int. Falling back to default value of " + << default_value; + } + value_as_int = default_value; + } + return value_as_int; +} + +double GetVariationParamByFeatureAsDouble(const base::Feature& feature, + const std::string& param_name, + double default_value) { + std::string value_as_string = + GetVariationParamValueByFeature(feature, param_name); + double value_as_double = 0; + if (!base::StringToDouble(value_as_string, &value_as_double)) { + if (!value_as_string.empty()) { + DLOG(WARNING) << "Failed to parse variation param " << param_name + << " with string value " << value_as_string + << " under feature " << feature.name + << " into a double. Falling back to default value of " + << default_value; + } + value_as_double = default_value; + } + return value_as_double; +} + +bool GetVariationParamByFeatureAsBool(const base::Feature& feature, + const std::string& param_name, + bool default_value) { + std::string value_as_string = + variations::GetVariationParamValueByFeature(feature, param_name); + if (value_as_string == "true") + return true; + if (value_as_string == "false") + return false; + + if (!value_as_string.empty()) { + DLOG(WARNING) << "Failed to parse variation param " << param_name + << " with string value " << value_as_string + << " under feature " << feature.name + << " into a bool. Falling back to default value of " + << default_value; + } + return default_value; +} + // Functions below are exposed for testing explicitly behind this namespace. // They simply wrap existing functions in this file. namespace testing {
diff --git a/components/variations/variations_associated_data.h b/components/variations/variations_associated_data.h index 0734e8b..ad359a4 100644 --- a/components/variations/variations_associated_data.h +++ b/components/variations/variations_associated_data.h
@@ -152,13 +152,38 @@ // with at most one variation, through the variation's associated field trial, // and selected group. See base/feature_list.h for more information on // features. If the feature is not enabled, or the specified parameter does not -// exist, returns an empty string.Calling this function will result in the +// exist, returns an empty string. Calling this function will result in the // associated field trial being marked as active if found (i.e. group() will be // called on it), if it wasn't already. Currently, this information is only // available from the browser process. Thread safe. std::string GetVariationParamValueByFeature(const base::Feature& feature, const std::string& param_name); +// Same as GetVariationParamValueByFeature(). On top of that, it converts the +// string value into an int using base::StringToInt() and returns it, if +// successful. Otherwise, it returns |default_value|. If the string value is not +// empty and the conversion does not succeed, it produces a warning to LOG. +int GetVariationParamByFeatureAsInt(const base::Feature& feature, + const std::string& param_name, + int default_value); + +// Same as GetVariationParamValueByFeature(). On top of that, it converts the +// string value into a double using base::StringToDouble() and returns it, if +// successful. Otherwise, it returns |default_value|. If the string value is not +// empty and the conversion does not succeed, it produces a warning to LOG. +double GetVariationParamByFeatureAsDouble(const base::Feature& feature, + const std::string& param_name, + double default_value); + +// Same as GetVariationParamValueByFeature(). On top of that, it converts the +// string value into a boolean and returns it, if successful. Otherwise, it +// returns |default_value|. The only string representations accepted here are +// "true" and "false". If the string value is not empty and the conversion does +// not succeed, it produces a warning to LOG. +bool GetVariationParamByFeatureAsBool(const base::Feature& feature, + const std::string& param_name, + bool default_value); + // Expose some functions for testing. namespace testing {
diff --git a/components/variations/variations_associated_data_unittest.cc b/components/variations/variations_associated_data_unittest.cc index 40ff746..2217bd5 100644 --- a/components/variations/variations_associated_data_unittest.cc +++ b/components/variations/variations_associated_data_unittest.cc
@@ -403,4 +403,89 @@ EXPECT_EQ(std::string(), GetVariationParamValueByFeature(kFeature, "x")); } +TEST_F(VariationsAssociatedDataTest, GetVariationParamByFeatureAsInt) { + const std::string kTrialName = "GetVariationParamsByFeature"; + const base::Feature kFeature{"TestFeature", + base::FEATURE_DISABLED_BY_DEFAULT}; + + std::map<std::string, std::string> params; + params["a"] = "1"; + params["b"] = "1.5"; + params["c"] = "foo"; + params["d"] = ""; + // "e" is not registered + variations::AssociateVariationParams(kTrialName, "A", params); + scoped_refptr<base::FieldTrial> trial( + CreateFieldTrial(kTrialName, 100, "A", NULL)); + + CreateFeatureWithTrial(kFeature, base::FeatureList::OVERRIDE_ENABLE_FEATURE, + trial.get()); + + std::map<std::string, std::string> actualParams; + EXPECT_EQ(1, GetVariationParamByFeatureAsInt(kFeature, "a", 0)); + EXPECT_EQ(0, GetVariationParamByFeatureAsInt(kFeature, "b", 0)); // invalid + EXPECT_EQ(0, GetVariationParamByFeatureAsInt(kFeature, "c", 0)); // invalid + EXPECT_EQ(0, GetVariationParamByFeatureAsInt(kFeature, "d", 0)); // empty + EXPECT_EQ(0, GetVariationParamByFeatureAsInt(kFeature, "e", 0)); // empty +} + +TEST_F(VariationsAssociatedDataTest, GetVariationParamByFeatureAsDouble) { + const std::string kTrialName = "GetVariationParamsByFeature"; + const base::Feature kFeature{"TestFeature", + base::FEATURE_DISABLED_BY_DEFAULT}; + + std::map<std::string, std::string> params; + params["a"] = "1"; + params["b"] = "1.5"; + params["c"] = "1.0e-10"; + params["d"] = "foo"; + params["e"] = ""; + // "f" is not registered + variations::AssociateVariationParams(kTrialName, "A", params); + scoped_refptr<base::FieldTrial> trial( + CreateFieldTrial(kTrialName, 100, "A", NULL)); + + CreateFeatureWithTrial(kFeature, base::FeatureList::OVERRIDE_ENABLE_FEATURE, + trial.get()); + + std::map<std::string, std::string> actualParams; + EXPECT_EQ(1, GetVariationParamByFeatureAsDouble(kFeature, "a", 0)); + EXPECT_EQ(1.5, GetVariationParamByFeatureAsDouble(kFeature, "b", 0)); + EXPECT_EQ(1.0e-10, GetVariationParamByFeatureAsDouble(kFeature, "c", 0)); + EXPECT_EQ(0, + GetVariationParamByFeatureAsDouble(kFeature, "d", 0)); // invalid + EXPECT_EQ(0, GetVariationParamByFeatureAsDouble(kFeature, "e", 0)); // empty + EXPECT_EQ(0, GetVariationParamByFeatureAsDouble(kFeature, "f", 0)); // empty +} + +TEST_F(VariationsAssociatedDataTest, GetVariationParamByFeatureAsBool) { + const std::string kTrialName = "GetVariationParamsByFeature"; + const base::Feature kFeature{"TestFeature", + base::FEATURE_DISABLED_BY_DEFAULT}; + + std::map<std::string, std::string> params; + params["a"] = "true"; + params["b"] = "false"; + params["c"] = "1"; + params["d"] = "False"; + params["e"] = ""; + // "f" is not registered + variations::AssociateVariationParams(kTrialName, "A", params); + scoped_refptr<base::FieldTrial> trial( + CreateFieldTrial(kTrialName, 100, "A", NULL)); + + CreateFeatureWithTrial(kFeature, base::FeatureList::OVERRIDE_ENABLE_FEATURE, + trial.get()); + + std::map<std::string, std::string> actualParams; + EXPECT_TRUE(GetVariationParamByFeatureAsBool(kFeature, "a", false)); + EXPECT_FALSE(GetVariationParamByFeatureAsBool(kFeature, "b", true)); + EXPECT_FALSE( + GetVariationParamByFeatureAsBool(kFeature, "c", false)); // invalid + EXPECT_TRUE( + GetVariationParamByFeatureAsBool(kFeature, "d", true)); // invalid + EXPECT_TRUE(GetVariationParamByFeatureAsBool(kFeature, "e", true)); // empty + EXPECT_TRUE(GetVariationParamByFeatureAsBool(kFeature, "f", true)); // empty +} + } // namespace variations
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index d1e82aa..a4339e9 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/guid.h" +#include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "base/time/time.h" #include "content/browser/message_port_message_filter.h" @@ -27,6 +28,7 @@ #include "content/public/common/child_process_host.h" #include "content/public/common/content_client.h" #include "content/public/common/origin_util.h" +#include "net/base/url_util.h" namespace content { @@ -37,6 +39,38 @@ // going down. int g_next_navigation_provider_id = -2; +// A request handler derivative used to handle navigation requests when +// skip_service_worker flag is set. It tracks the document URL and sets the url +// to the provider host. +class ServiceWorkerURLTrackingRequestHandler + : public ServiceWorkerRequestHandler { + public: + ServiceWorkerURLTrackingRequestHandler( + base::WeakPtr<ServiceWorkerContextCore> context, + base::WeakPtr<ServiceWorkerProviderHost> provider_host, + base::WeakPtr<storage::BlobStorageContext> blob_storage_context, + ResourceType resource_type) + : ServiceWorkerRequestHandler(context, + provider_host, + blob_storage_context, + resource_type) {} + ~ServiceWorkerURLTrackingRequestHandler() override {} + + // Called via custom URLRequestJobFactory. + net::URLRequestJob* MaybeCreateJob( + net::URLRequest* request, + net::NetworkDelegate* network_delegate, + ResourceContext* resource_context) override { + const GURL stripped_url = net::SimplifyUrlForRequest(request->url()); + provider_host_->SetDocumentUrl(stripped_url); + provider_host_->SetTopmostFrameUrl(request->first_party_for_cookies()); + return nullptr; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLTrackingRequestHandler); +}; + } // anonymous namespace ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback( @@ -333,19 +367,24 @@ RequestContextType request_context_type, RequestContextFrameType frame_type, base::WeakPtr<storage::BlobStorageContext> blob_storage_context, - scoped_refptr<ResourceRequestBodyImpl> body) { + scoped_refptr<ResourceRequestBodyImpl> body, + bool skip_service_worker) { + if (skip_service_worker) { + if (!ServiceWorkerUtils::IsMainResourceType(resource_type)) + return std::unique_ptr<ServiceWorkerRequestHandler>(); + return base::MakeUnique<ServiceWorkerURLTrackingRequestHandler>( + context_, AsWeakPtr(), blob_storage_context, resource_type); + } if (IsHostToRunningServiceWorker()) { - return std::unique_ptr<ServiceWorkerRequestHandler>( - new ServiceWorkerContextRequestHandler( - context_, AsWeakPtr(), blob_storage_context, resource_type)); + return base::MakeUnique<ServiceWorkerContextRequestHandler>( + context_, AsWeakPtr(), blob_storage_context, resource_type); } if (ServiceWorkerUtils::IsMainResourceType(resource_type) || controlling_version()) { - return std::unique_ptr<ServiceWorkerRequestHandler>( - new ServiceWorkerControlleeRequestHandler( - context_, AsWeakPtr(), blob_storage_context, request_mode, - credentials_mode, redirect_mode, resource_type, - request_context_type, frame_type, body)); + return base::MakeUnique<ServiceWorkerControlleeRequestHandler>( + context_, AsWeakPtr(), blob_storage_context, request_mode, + credentials_mode, redirect_mode, resource_type, request_context_type, + frame_type, body); } return std::unique_ptr<ServiceWorkerRequestHandler>(); }
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 3cfc6ea..0d18381 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -174,7 +174,8 @@ RequestContextType request_context_type, RequestContextFrameType frame_type, base::WeakPtr<storage::BlobStorageContext> blob_storage_context, - scoped_refptr<ResourceRequestBodyImpl> body); + scoped_refptr<ResourceRequestBodyImpl> body, + bool skip_service_worker); // Used to get a ServiceWorkerObjectInfo to send to the renderer. Finds an // existing ServiceWorkerHandle, and increments its reference count, or else
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc index 02eafc2..c129326 100644 --- a/content/browser/service_worker/service_worker_request_handler.cc +++ b/content/browser/service_worker/service_worker_request_handler.cc
@@ -67,20 +67,11 @@ RequestContextType request_context_type, RequestContextFrameType frame_type, scoped_refptr<ResourceRequestBodyImpl> body) { - if (skip_service_worker) { - // TODO(horo): Does this work properly for PlzNavigate? - if (ServiceWorkerUtils::IsMainResourceType(resource_type)) { - provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url())); - provider_host->SetTopmostFrameUrl(request->first_party_for_cookies()); - } - return; - } - std::unique_ptr<ServiceWorkerRequestHandler> handler( provider_host->CreateRequestHandler( request_mode, credentials_mode, redirect_mode, resource_type, request_context_type, frame_type, blob_storage_context->AsWeakPtr(), - body)); + body, skip_service_worker)); if (!handler) return;
diff --git a/content/browser/service_worker/service_worker_request_handler_unittest.cc b/content/browser/service_worker/service_worker_request_handler_unittest.cc index 414f01b..1c243f1b 100644 --- a/content/browser/service_worker/service_worker_request_handler_unittest.cc +++ b/content/browser/service_worker/service_worker_request_handler_unittest.cc
@@ -10,8 +10,8 @@ #include "content/browser/fileapi/mock_url_request_delegate.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/service_worker_context_core.h" +#include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_provider_host.h" -#include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_test_utils.h" #include "content/common/resource_request_body_impl.h" #include "content/common/service_worker/service_worker_utils.h" @@ -19,7 +19,9 @@ #include "content/public/common/request_context_type.h" #include "content/public/common/resource_type.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "net/url_request/redirect_info.h" #include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_job.h" #include "storage/browser/blob/blob_storage_context.h" #include "testing/gtest/include/gtest/gtest.h" @@ -29,9 +31,6 @@ int kMockProviderId = 1; -void EmptyCallback() { -} - } class ServiceWorkerRequestHandlerTest : public testing::Test { @@ -42,13 +41,6 @@ void SetUp() override { helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath())); - // A new unstored registration/version. - registration_ = new ServiceWorkerRegistration(GURL("https://host/scope/"), - 1L, context()->AsWeakPtr()); - version_ = new ServiceWorkerVersion(registration_.get(), - GURL("https://host/script.js"), 1L, - context()->AsWeakPtr()); - // An empty host. std::unique_ptr<ServiceWorkerProviderHost> host( new ServiceWorkerProviderHost( @@ -56,29 +48,12 @@ kMockProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW, ServiceWorkerProviderHost::FrameSecurityLevel::SECURE, context()->AsWeakPtr(), nullptr)); - host->SetDocumentUrl(GURL("https://host/scope/")); provider_host_ = host->AsWeakPtr(); context()->AddProviderHost(std::move(host)); - context()->storage()->LazyInitialize(base::Bind(&EmptyCallback)); - base::RunLoop().RunUntilIdle(); - - version_->set_fetch_handler_existence( - ServiceWorkerVersion::FetchHandlerExistence::EXISTS); - version_->SetStatus(ServiceWorkerVersion::ACTIVATED); - registration_->SetActiveVersion(version_); - context()->storage()->StoreRegistration( - registration_.get(), - version_.get(), - base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); - provider_host_->AssociateRegistration(registration_.get(), - false /* notify_controllerchange */); - base::RunLoop().RunUntilIdle(); } void TearDown() override { - version_ = nullptr; - registration_ = nullptr; helper_.reset(); } @@ -87,30 +62,52 @@ return helper_->context_wrapper(); } - bool InitializeHandlerCheck(const std::string& url, - const std::string& method, - bool skip_service_worker, - ResourceType resource_type) { - const GURL kDocUrl(url); + std::unique_ptr<net::URLRequest> CreateRequest(const std::string& url, + const std::string& method) { std::unique_ptr<net::URLRequest> request = - url_request_context_.CreateRequest(kDocUrl, net::DEFAULT_PRIORITY, + url_request_context_.CreateRequest(GURL(url), net::DEFAULT_PRIORITY, &url_request_delegate_); request->set_method(method); + return request; + } + + void InitializeHandler(net::URLRequest* request, + bool skip_service_worker, + ResourceType resource_type) { ServiceWorkerRequestHandler::InitializeHandler( - request.get(), context_wrapper(), &blob_storage_context_, + request, context_wrapper(), &blob_storage_context_, helper_->mock_render_process_id(), kMockProviderId, skip_service_worker, FETCH_REQUEST_MODE_NO_CORS, FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE, resource_type, REQUEST_CONTEXT_TYPE_HYPERLINK, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL, nullptr); - return ServiceWorkerRequestHandler::GetHandler(request.get()) != nullptr; + } + + static ServiceWorkerRequestHandler* GetHandler(net::URLRequest* request) { + return ServiceWorkerRequestHandler::GetHandler(request); + } + + std::unique_ptr<net::URLRequestJob> MaybeCreateJob(net::URLRequest* request) { + return std::unique_ptr<net::URLRequestJob>( + GetHandler(request)->MaybeCreateJob( + request, url_request_context_.network_delegate(), + context_wrapper()->resource_context())); + } + + void InitializeHandlerSimpleTest(const std::string& url, + const std::string& method, + bool skip_service_worker, + ResourceType resource_type) { + std::unique_ptr<net::URLRequest> request = CreateRequest(url, method); + InitializeHandler(request.get(), skip_service_worker, resource_type); + ASSERT_TRUE(GetHandler(request.get())); + MaybeCreateJob(request.get()); + EXPECT_EQ(url, provider_host_->document_url().spec()); } protected: TestBrowserThreadBundle browser_thread_bundle_; std::unique_ptr<EmbeddedWorkerTestHelper> helper_; - scoped_refptr<ServiceWorkerRegistration> registration_; - scoped_refptr<ServiceWorkerVersion> version_; base::WeakPtr<ServiceWorkerProviderHost> provider_host_; net::URLRequestContext url_request_context_; MockURLRequestDelegate url_request_delegate_; @@ -120,51 +117,57 @@ class ServiceWorkerRequestHandlerTestP : public MojoServiceWorkerTestP<ServiceWorkerRequestHandlerTest> {}; -TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler) { +TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler_FTP) { + std::unique_ptr<net::URLRequest> request = + CreateRequest("ftp://host/scope/doc", "GET"); + InitializeHandler(request.get(), false, RESOURCE_TYPE_MAIN_FRAME); // Cannot initialize a handler for non-secure origins. - EXPECT_FALSE(InitializeHandlerCheck( - "ftp://host/scope/doc", "GET", false, RESOURCE_TYPE_MAIN_FRAME)); - // HTTP is ok because it might redirect to HTTPS. - EXPECT_TRUE(InitializeHandlerCheck("http://host/scope/doc", "GET", false, - RESOURCE_TYPE_MAIN_FRAME)); - EXPECT_TRUE(InitializeHandlerCheck("https://host/scope/doc", "GET", false, - RESOURCE_TYPE_MAIN_FRAME)); + EXPECT_FALSE(GetHandler(request.get())); +} +TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler_HTTP_MAIN_FRAME) { + // HTTP should have the handler because the response is possible to be a + // redirect to HTTPS. + InitializeHandlerSimpleTest("http://host/scope/doc", "GET", false, + RESOURCE_TYPE_MAIN_FRAME); +} + +TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler_HTTPS_MAIN_FRAME) { + InitializeHandlerSimpleTest("https://host/scope/doc", "GET", false, + RESOURCE_TYPE_MAIN_FRAME); +} + +TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler_HTTP_SUB_FRAME) { + // HTTP should have the handler because the response is possible to be a + // redirect to HTTPS. + InitializeHandlerSimpleTest("http://host/scope/doc", "GET", false, + RESOURCE_TYPE_SUB_FRAME); +} + +TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler_HTTPS_SUB_FRAME) { + InitializeHandlerSimpleTest("https://host/scope/doc", "GET", false, + RESOURCE_TYPE_SUB_FRAME); +} + +TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler_HTTPS_OPTIONS) { // OPTIONS is also supported. See crbug.com/434660. - EXPECT_TRUE(InitializeHandlerCheck( - "https://host/scope/doc", "OPTIONS", false, RESOURCE_TYPE_MAIN_FRAME)); + InitializeHandlerSimpleTest("https://host/scope/doc", "OPTIONS", false, + RESOURCE_TYPE_MAIN_FRAME); +} - // Check provider host's URL after initializing a handler for main - // frame. - provider_host_->SetDocumentUrl(GURL("")); - EXPECT_FALSE(InitializeHandlerCheck( - "http://host/scope/doc", "GET", true, RESOURCE_TYPE_MAIN_FRAME)); - EXPECT_STREQ("http://host/scope/doc", - provider_host_->document_url().spec().c_str()); - EXPECT_FALSE(InitializeHandlerCheck( - "https://host/scope/doc", "GET", true, RESOURCE_TYPE_MAIN_FRAME)); - EXPECT_STREQ("https://host/scope/doc", - provider_host_->document_url().spec().c_str()); +TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler_HTTPS_SKIP) { + InitializeHandlerSimpleTest("https://host/scope/doc", "GET", true, + RESOURCE_TYPE_MAIN_FRAME); +} - // Check provider host's URL after initializing a handler for a subframe. - provider_host_->SetDocumentUrl(GURL("")); - EXPECT_FALSE(InitializeHandlerCheck( - "http://host/scope/doc", "GET", true, RESOURCE_TYPE_SUB_FRAME)); - EXPECT_STREQ("http://host/scope/doc", - provider_host_->document_url().spec().c_str()); - EXPECT_FALSE(InitializeHandlerCheck( - "https://host/scope/doc", "GET", true, RESOURCE_TYPE_SUB_FRAME)); - EXPECT_STREQ("https://host/scope/doc", - provider_host_->document_url().spec().c_str()); - +TEST_P(ServiceWorkerRequestHandlerTestP, InitializeHandler_IMAGE) { // Check provider host's URL after initializing a handler for an image. - provider_host_->SetDocumentUrl(GURL("")); - EXPECT_FALSE(InitializeHandlerCheck( - "http://host/scope/doc", "GET", true, RESOURCE_TYPE_IMAGE)); - EXPECT_STREQ("", provider_host_->document_url().spec().c_str()); - EXPECT_FALSE(InitializeHandlerCheck( - "https://host/scope/doc", "GET", true, RESOURCE_TYPE_IMAGE)); - EXPECT_STREQ("", provider_host_->document_url().spec().c_str()); + provider_host_->SetDocumentUrl(GURL("https://host/scope/doc")); + std::unique_ptr<net::URLRequest> request = + CreateRequest("https://host/scope/image", "GET"); + InitializeHandler(request.get(), true, RESOURCE_TYPE_IMAGE); + ASSERT_FALSE(GetHandler(request.get())); + EXPECT_EQ(GURL("https://host/scope/doc"), provider_host_->document_url()); } INSTANTIATE_TEST_CASE_P(ServiceWorkerRequestHandlerTest,
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index a6ac11c7..b3b5ca7 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -134,6 +134,7 @@ 'Linux ChromiumOS Builder' : { 'additional_compile_targets' : [ "All" ] }, + 'Linux ChromiumOS Ozone Builder' : {}, }, 'testers': {
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc index 3e9141a..f983b65 100644 --- a/gpu/config/gpu_info_collector_win.cc +++ b/gpu/config/gpu_info_collector_win.cc
@@ -423,8 +423,11 @@ } if (id.length() <= 20) { - gpu_info->basic_info_state = kCollectInfoNonFatalFailure; - return kCollectInfoNonFatalFailure; + // Check if it is the RDP mirror driver "RDPUDD Chained DD" + if (wcscmp(dd.DeviceString, L"RDPUDD Chained DD") != 0) { + gpu_info->basic_info_state = kCollectInfoNonFatalFailure; + return kCollectInfoNonFatalFailure; + } } DeviceIDToVendorAndDevice(id, &gpu_info->gpu.vendor_id,
diff --git a/storage/browser/fileapi/file_system_context.cc b/storage/browser/fileapi/file_system_context.cc index f1fcf23e..d6308377 100644 --- a/storage/browser/fileapi/file_system_context.cc +++ b/storage/browser/fileapi/file_system_context.cc
@@ -483,11 +483,9 @@ return CrackFileSystemURL(FileSystemURL(origin, type, path)); } -#if defined(OS_CHROMEOS) void FileSystemContext::EnableTemporaryFileSystemInIncognito() { sandbox_backend_->set_enable_temporary_file_system_in_incognito(true); } -#endif bool FileSystemContext::CanServeURLRequest(const FileSystemURL& url) const { // We never support accessing files in isolated filesystems via an URL.
diff --git a/storage/browser/fileapi/file_system_context.h b/storage/browser/fileapi/file_system_context.h index 0da374c..5822a2fa 100644 --- a/storage/browser/fileapi/file_system_context.h +++ b/storage/browser/fileapi/file_system_context.h
@@ -282,10 +282,7 @@ FileSystemType type, const base::FilePath& path) const; -#if defined(OS_CHROMEOS) - // Used only on ChromeOS for now. void EnableTemporaryFileSystemInIncognito(); -#endif SandboxFileSystemBackendDelegate* sandbox_delegate() { return sandbox_delegate_.get();
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index eec63dfb..9922392 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -2220,6 +2220,7 @@ "All" ] }, + "Linux ChromiumOS Ozone Builder": {}, "Linux Debug (NVIDIA)": { "gtest_tests": [ {
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter index 9007d016..fd0562d 100644 --- a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter +++ b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter
@@ -2,8 +2,6 @@ -PDFExtensionTest.PdfAccessibilityInOOPIF -PlatformAppUrlRedirectorBrowserTest.PrerenderedClickInTabIntercepted -PredictorBrowserTest.RendererInitiatedNavigationPreconnect --PrerenderBrowserTest.PrerenderCrossProcessServerRedirect --PrerenderBrowserTest.PrerenderCrossProcessServerRedirectNoHang -ThreatDOMDetailsTest.Everything # https://crbug.com/652767: NavigationHandle::GetResponseHeaders sometimes
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations index c667847..5800fbe 100644 --- a/third_party/WebKit/LayoutTests/LeakExpectations +++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -133,6 +133,9 @@ crbug.com/664874 http/tests/xmlhttprequest/workers/xmlhttprequest-allowed-with-disabled-web-security.html [ Leak ] crbug.com/664874 virtual/mojo-loading/http/tests/xmlhttprequest/workers/xmlhttprequest-allowed-with-disabled-web-security.html [ Leak ] +crbug.com/672740 http/tests/security/mixedContent/websocket/insecure-websocket-in-secure-page-worker.html [ Leak Pass ] +crbug.com/672740 virtual/mojo-loading/http/tests/security/mixedContent/websocket/insecure-websocket-in-secure-page-worker.html [ Leak Pass ] + ########################################################################### # WARNING: Memory leaks must be fixed asap. Sheriff is expected to revert # # culprit CLs instead of suppressing the leaks. If you have any question, #
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 2838160..91e1f4b 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -91,10 +91,10 @@ crbug.com/626748 virtual/spinvalidation/paint/invalidation/table/cached-change-row-border-color.html [ Skip ] crbug.com/626748 virtual/spinvalidation/paint/invalidation/table/cached-change-tbody-border-color.html [ Skip ] -crbug.com/645667 virtual/spinvalidation/paint/invalidation/outline-clip-change.html [ Crash ] +crbug.com/645667 virtual/spinvalidation/paint/invalidation/outline-clip-change.html [ Crash Failure ] crbug.com/645667 virtual/spinvalidation/paint/invalidation/filter-repaint-accelerated-on-accelerated-filter.html [ Crash ] crbug.com/645667 virtual/spinvalidation/paint/invalidation/position-change-keeping-geometry.html [ Crash ] -crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/marker-viewBox-changes.svg [ Crash ] +crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/marker-viewBox-changes.svg [ Crash Failure ] crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/should-not-repaint-composited-descendants.html [ Crash ] crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/resize-repaint.html [ Crash ] crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/shrink-layer.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/independent-inheritance-fast-path.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/independent-inheritance-fast-path.html index 506963e3..d7d8dd50 100644 --- a/third_party/WebKit/LayoutTests/fast/css/invalidation/independent-inheritance-fast-path.html +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/independent-inheritance-fast-path.html
@@ -17,6 +17,7 @@ ["whiteSpace", "normal", "nowrap"], ["borderCollapse", "separate", "collapse"], ["emptyCells", "show", "hide"], + ["captionSide", "left", "right"], ]; independent_properties.forEach(function(test_data)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirect.php b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirect.php new file mode 100644 index 0000000..2cfb1fc --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirect.php
@@ -0,0 +1,5 @@ +<?php + $url = "http://127.0.0.1:8000/inspector/service-workers/resources/" . + "bypass-for-network-redirected.html"; + header("Location: $url"); +?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirected.html b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirected.html new file mode 100644 index 0000000..ac10bc8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/resources/bypass-for-network-redirected.html
@@ -0,0 +1,4 @@ +<script> +navigator.serviceWorker.getRegistration().then(r => + console.log("getRegistration finished")); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect-expected.txt new file mode 100644 index 0000000..d859416 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect-expected.txt
@@ -0,0 +1,6 @@ +CONSOLE MESSAGE: line 3: getRegistration finished +Tests "Bypass for network" checkbox with redirection doesn't cause crash. + + +Success +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html new file mode 100644 index 0000000..ea267868 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html
@@ -0,0 +1,47 @@ +<html> +<head> +<script src="../inspector-test.js"></script> +<script src="service-workers-test.js"></script> +<script src="../resources-test.js"></script> +<script> + +function loadIframe() +{ + var frame = document.createElement('iframe'); + frame.src = "http://localhost:8000/inspector/service-workers/resources/" + + "bypass-for-network-redirect.php" + document.body.appendChild(frame); +} + +function test() +{ + UI.inspectorView.showPanel("sources") + .then(function(){ + Common.settings.settingForTest("bypassServiceWorker").set(true); + var callback; + var promise = new Promise((fulfill) => callback = fulfill); + InspectorTest.addConsoleSniffer(message => { + if (message.messageText == "getRegistration finished") { + callback(); + } + }, true); + InspectorTest.evaluateInPage("loadIframe()"); + return promise; + }) + .then(function() { + InspectorTest.addResult("Success"); + InspectorTest.completeTest(); + }) + .catch(function(exception) { + InspectorTest.addResult("Error"); + InspectorTest.addResult(exception); + InspectorTest.completeTest(); + }); +} + +</script> +</head> +<body onload="runTest()"> +<p>Tests "Bypass for network" checkbox with redirection doesn't cause crash.<p> +</body> +</html>
diff --git a/third_party/WebKit/Source/core/animation/BUILD.gn b/third_party/WebKit/Source/core/animation/BUILD.gn index d97848d..b72f1034 100644 --- a/third_party/WebKit/Source/core/animation/BUILD.gn +++ b/third_party/WebKit/Source/core/animation/BUILD.gn
@@ -47,6 +47,8 @@ "CSSImageSliceInterpolationType.h", "CSSInterpolationType.cpp", "CSSInterpolationType.h", + "CSSInterpolationTypesMap.cpp", + "CSSInterpolationTypesMap.h", "CSSLengthInterpolationType.cpp", "CSSLengthInterpolationType.h", "CSSLengthListInterpolationType.cpp", @@ -119,6 +121,7 @@ "InterpolationEffect.cpp", "InterpolationEffect.h", "InterpolationType.h", + "InterpolationTypesMap.h", "InterpolationValue.h", "InvalidatableInterpolation.cpp", "InvalidatableInterpolation.h", @@ -152,8 +155,6 @@ "PrimitiveInterpolation.h", "PropertyHandle.cpp", "PropertyHandle.h", - "PropertyInterpolationTypesMapping.cpp", - "PropertyInterpolationTypesMapping.h", "SVGAngleInterpolationType.cpp", "SVGAngleInterpolationType.h", "SVGIntegerInterpolationType.cpp", @@ -162,6 +163,8 @@ "SVGIntegerOptionalIntegerInterpolationType.h", "SVGInterpolationType.cpp", "SVGInterpolationType.h", + "SVGInterpolationTypesMap.cpp", + "SVGInterpolationTypesMap.h", "SVGLengthInterpolationType.cpp", "SVGLengthInterpolationType.h", "SVGLengthListInterpolationType.cpp",
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationTypesMap.cpp b/third_party/WebKit/Source/core/animation/CSSInterpolationTypesMap.cpp new file mode 100644 index 0000000..1b2774fe --- /dev/null +++ b/third_party/WebKit/Source/core/animation/CSSInterpolationTypesMap.cpp
@@ -0,0 +1,300 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/animation/CSSInterpolationTypesMap.h" + +#include "core/animation/CSSBasicShapeInterpolationType.h" +#include "core/animation/CSSBorderImageLengthBoxInterpolationType.h" +#include "core/animation/CSSClipInterpolationType.h" +#include "core/animation/CSSColorInterpolationType.h" +#include "core/animation/CSSFilterListInterpolationType.h" +#include "core/animation/CSSFontSizeInterpolationType.h" +#include "core/animation/CSSFontWeightInterpolationType.h" +#include "core/animation/CSSImageInterpolationType.h" +#include "core/animation/CSSImageListInterpolationType.h" +#include "core/animation/CSSImageSliceInterpolationType.h" +#include "core/animation/CSSLengthInterpolationType.h" +#include "core/animation/CSSLengthListInterpolationType.h" +#include "core/animation/CSSLengthPairInterpolationType.h" +#include "core/animation/CSSNumberInterpolationType.h" +#include "core/animation/CSSOffsetRotationInterpolationType.h" +#include "core/animation/CSSPaintInterpolationType.h" +#include "core/animation/CSSPathInterpolationType.h" +#include "core/animation/CSSPositionAxisListInterpolationType.h" +#include "core/animation/CSSPositionInterpolationType.h" +#include "core/animation/CSSRotateInterpolationType.h" +#include "core/animation/CSSScaleInterpolationType.h" +#include "core/animation/CSSShadowListInterpolationType.h" +#include "core/animation/CSSSizeListInterpolationType.h" +#include "core/animation/CSSTextIndentInterpolationType.h" +#include "core/animation/CSSTransformInterpolationType.h" +#include "core/animation/CSSTransformOriginInterpolationType.h" +#include "core/animation/CSSTranslateInterpolationType.h" +#include "core/animation/CSSValueInterpolationType.h" +#include "core/animation/CSSVisibilityInterpolationType.h" +#include "core/css/CSSPropertyMetadata.h" +#include "core/css/PropertyRegistry.h" +#include "wtf/PtrUtil.h" +#include <memory> + +namespace blink { + +const InterpolationTypes& CSSInterpolationTypesMap::get( + const PropertyHandle& property) const { + using ApplicableTypesMap = + HashMap<PropertyHandle, std::unique_ptr<const InterpolationTypes>>; + DEFINE_STATIC_LOCAL(ApplicableTypesMap, applicableTypesMap, ()); + auto entry = applicableTypesMap.find(property); + if (entry != applicableTypesMap.end()) + return *entry->value.get(); + + std::unique_ptr<InterpolationTypes> applicableTypes = + WTF::makeUnique<InterpolationTypes>(); + + CSSPropertyID cssProperty = property.isCSSProperty() + ? property.cssProperty() + : property.presentationAttribute(); + // We treat presentation attributes identically to their CSS property + // equivalents when interpolating. + PropertyHandle usedProperty = + property.isCSSProperty() ? property : PropertyHandle(cssProperty); + switch (cssProperty) { + case CSSPropertyBaselineShift: + case CSSPropertyBorderBottomWidth: + case CSSPropertyBorderLeftWidth: + case CSSPropertyBorderRightWidth: + case CSSPropertyBorderTopWidth: + case CSSPropertyBottom: + case CSSPropertyCx: + case CSSPropertyCy: + case CSSPropertyFlexBasis: + case CSSPropertyHeight: + case CSSPropertyLeft: + case CSSPropertyLetterSpacing: + case CSSPropertyMarginBottom: + case CSSPropertyMarginLeft: + case CSSPropertyMarginRight: + case CSSPropertyMarginTop: + case CSSPropertyMaxHeight: + case CSSPropertyMaxWidth: + case CSSPropertyMinHeight: + case CSSPropertyMinWidth: + case CSSPropertyOffsetDistance: + case CSSPropertyOutlineOffset: + case CSSPropertyOutlineWidth: + case CSSPropertyPaddingBottom: + case CSSPropertyPaddingLeft: + case CSSPropertyPaddingRight: + case CSSPropertyPaddingTop: + case CSSPropertyPerspective: + case CSSPropertyR: + case CSSPropertyRight: + case CSSPropertyRx: + case CSSPropertyRy: + case CSSPropertyShapeMargin: + case CSSPropertyStrokeDashoffset: + case CSSPropertyStrokeWidth: + case CSSPropertyTop: + case CSSPropertyVerticalAlign: + case CSSPropertyWebkitBorderHorizontalSpacing: + case CSSPropertyWebkitBorderVerticalSpacing: + case CSSPropertyColumnGap: + case CSSPropertyColumnRuleWidth: + case CSSPropertyColumnWidth: + case CSSPropertyWebkitPerspectiveOriginX: + case CSSPropertyWebkitPerspectiveOriginY: + case CSSPropertyWebkitTransformOriginX: + case CSSPropertyWebkitTransformOriginY: + case CSSPropertyWebkitTransformOriginZ: + case CSSPropertyWidth: + case CSSPropertyWordSpacing: + case CSSPropertyX: + case CSSPropertyY: + applicableTypes->append( + WTF::makeUnique<CSSLengthInterpolationType>(usedProperty)); + break; + case CSSPropertyFlexGrow: + case CSSPropertyFlexShrink: + case CSSPropertyFillOpacity: + case CSSPropertyFloodOpacity: + case CSSPropertyFontSizeAdjust: + case CSSPropertyOpacity: + case CSSPropertyOrphans: + case CSSPropertyShapeImageThreshold: + case CSSPropertyStopOpacity: + case CSSPropertyStrokeMiterlimit: + case CSSPropertyStrokeOpacity: + case CSSPropertyColumnCount: + case CSSPropertyWidows: + case CSSPropertyZIndex: + applicableTypes->append( + WTF::makeUnique<CSSNumberInterpolationType>(usedProperty)); + break; + case CSSPropertyLineHeight: + applicableTypes->append( + WTF::makeUnique<CSSLengthInterpolationType>(usedProperty)); + applicableTypes->append( + WTF::makeUnique<CSSNumberInterpolationType>(usedProperty)); + break; + case CSSPropertyBackgroundColor: + case CSSPropertyBorderBottomColor: + case CSSPropertyBorderLeftColor: + case CSSPropertyBorderRightColor: + case CSSPropertyBorderTopColor: + case CSSPropertyColor: + case CSSPropertyFloodColor: + case CSSPropertyLightingColor: + case CSSPropertyOutlineColor: + case CSSPropertyStopColor: + case CSSPropertyTextDecorationColor: + case CSSPropertyColumnRuleColor: + case CSSPropertyWebkitTextStrokeColor: + applicableTypes->append( + WTF::makeUnique<CSSColorInterpolationType>(usedProperty)); + break; + case CSSPropertyFill: + case CSSPropertyStroke: + applicableTypes->append( + WTF::makeUnique<CSSPaintInterpolationType>(usedProperty)); + break; + case CSSPropertyD: + applicableTypes->append( + WTF::makeUnique<CSSPathInterpolationType>(usedProperty)); + break; + case CSSPropertyBoxShadow: + case CSSPropertyTextShadow: + applicableTypes->append( + WTF::makeUnique<CSSShadowListInterpolationType>(usedProperty)); + break; + case CSSPropertyBorderImageSource: + case CSSPropertyListStyleImage: + case CSSPropertyWebkitMaskBoxImageSource: + applicableTypes->append( + WTF::makeUnique<CSSImageInterpolationType>(usedProperty)); + break; + case CSSPropertyBackgroundImage: + case CSSPropertyWebkitMaskImage: + applicableTypes->append( + WTF::makeUnique<CSSImageListInterpolationType>(usedProperty)); + break; + case CSSPropertyStrokeDasharray: + applicableTypes->append( + WTF::makeUnique<CSSLengthListInterpolationType>(usedProperty)); + break; + case CSSPropertyFontWeight: + applicableTypes->append( + WTF::makeUnique<CSSFontWeightInterpolationType>(usedProperty)); + break; + case CSSPropertyVisibility: + applicableTypes->append( + WTF::makeUnique<CSSVisibilityInterpolationType>(usedProperty)); + break; + case CSSPropertyClip: + applicableTypes->append( + WTF::makeUnique<CSSClipInterpolationType>(usedProperty)); + break; + case CSSPropertyOffsetRotation: + case CSSPropertyOffsetRotate: + applicableTypes->append( + WTF::makeUnique<CSSOffsetRotationInterpolationType>(usedProperty)); + break; + case CSSPropertyBackgroundPositionX: + case CSSPropertyBackgroundPositionY: + case CSSPropertyWebkitMaskPositionX: + case CSSPropertyWebkitMaskPositionY: + applicableTypes->append( + WTF::makeUnique<CSSPositionAxisListInterpolationType>(usedProperty)); + break; + case CSSPropertyObjectPosition: + case CSSPropertyOffsetAnchor: + case CSSPropertyOffsetPosition: + case CSSPropertyPerspectiveOrigin: + applicableTypes->append( + WTF::makeUnique<CSSPositionInterpolationType>(usedProperty)); + break; + case CSSPropertyBorderBottomLeftRadius: + case CSSPropertyBorderBottomRightRadius: + case CSSPropertyBorderTopLeftRadius: + case CSSPropertyBorderTopRightRadius: + applicableTypes->append( + WTF::makeUnique<CSSLengthPairInterpolationType>(usedProperty)); + break; + case CSSPropertyTranslate: + applicableTypes->append( + WTF::makeUnique<CSSTranslateInterpolationType>(usedProperty)); + break; + case CSSPropertyTransformOrigin: + applicableTypes->append( + WTF::makeUnique<CSSTransformOriginInterpolationType>(usedProperty)); + break; + case CSSPropertyBackgroundSize: + case CSSPropertyWebkitMaskSize: + applicableTypes->append( + WTF::makeUnique<CSSSizeListInterpolationType>(usedProperty)); + break; + case CSSPropertyBorderImageOutset: + case CSSPropertyBorderImageWidth: + case CSSPropertyWebkitMaskBoxImageOutset: + case CSSPropertyWebkitMaskBoxImageWidth: + applicableTypes->append( + WTF::makeUnique<CSSBorderImageLengthBoxInterpolationType>( + usedProperty)); + break; + case CSSPropertyScale: + applicableTypes->append( + WTF::makeUnique<CSSScaleInterpolationType>(usedProperty)); + break; + case CSSPropertyFontSize: + applicableTypes->append( + WTF::makeUnique<CSSFontSizeInterpolationType>(usedProperty)); + break; + case CSSPropertyTextIndent: + applicableTypes->append( + WTF::makeUnique<CSSTextIndentInterpolationType>(usedProperty)); + break; + case CSSPropertyBorderImageSlice: + case CSSPropertyWebkitMaskBoxImageSlice: + applicableTypes->append( + WTF::makeUnique<CSSImageSliceInterpolationType>(usedProperty)); + break; + case CSSPropertyClipPath: + case CSSPropertyShapeOutside: + applicableTypes->append( + WTF::makeUnique<CSSBasicShapeInterpolationType>(usedProperty)); + break; + case CSSPropertyRotate: + applicableTypes->append( + WTF::makeUnique<CSSRotateInterpolationType>(usedProperty)); + break; + case CSSPropertyBackdropFilter: + case CSSPropertyFilter: + applicableTypes->append( + WTF::makeUnique<CSSFilterListInterpolationType>(usedProperty)); + break; + case CSSPropertyTransform: + applicableTypes->append( + WTF::makeUnique<CSSTransformInterpolationType>(usedProperty)); + break; + default: + DCHECK(!CSSPropertyMetadata::isInterpolableProperty(cssProperty)); + // TODO(crbug.com/671904): Look up m_registry for custom property + // InterpolationTypes. + break; + } + + applicableTypes->append( + WTF::makeUnique<CSSValueInterpolationType>(usedProperty)); + + auto addResult = applicableTypesMap.add(property, std::move(applicableTypes)); + return *addResult.storedValue->value.get(); +} + +size_t CSSInterpolationTypesMap::version() const { + // Property registrations are never removed so the number of registered + // custom properties is equivalent to how many changes there have been to the + // property registry. + return m_registry ? m_registry->registrationCount() : 0; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationTypesMap.h b/third_party/WebKit/Source/core/animation/CSSInterpolationTypesMap.h new file mode 100644 index 0000000..88561ce --- /dev/null +++ b/third_party/WebKit/Source/core/animation/CSSInterpolationTypesMap.h
@@ -0,0 +1,29 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CSSInterpolationTypesMap_h +#define CSSInterpolationTypesMap_h + +#include "core/animation/InterpolationTypesMap.h" +#include "platform/heap/Handle.h" + +namespace blink { + +class PropertyRegistry; + +class CSSInterpolationTypesMap : public InterpolationTypesMap { + public: + CSSInterpolationTypesMap(const PropertyRegistry* registry) + : m_registry(registry) {} + + const InterpolationTypes& get(const PropertyHandle&) const final; + size_t version() const final; + + private: + Member<const PropertyRegistry> m_registry; +}; + +} // namespace blink + +#endif // CSSInterpolationTypesMap_h
diff --git a/third_party/WebKit/Source/core/animation/InterpolationEnvironment.h b/third_party/WebKit/Source/core/animation/InterpolationEnvironment.h index cfae242..61d76ad 100644 --- a/third_party/WebKit/Source/core/animation/InterpolationEnvironment.h +++ b/third_party/WebKit/Source/core/animation/InterpolationEnvironment.h
@@ -5,6 +5,7 @@ #ifndef InterpolationEnvironment_h #define InterpolationEnvironment_h +#include "core/animation/InterpolationTypesMap.h" #include "platform/heap/Handle.h" #include "wtf/Allocator.h" @@ -18,15 +19,25 @@ STACK_ALLOCATED(); public: - explicit InterpolationEnvironment(StyleResolverState& state) - : m_state(&state), m_svgElement(nullptr), m_svgBaseValue(nullptr) {} + explicit InterpolationEnvironment(const InterpolationTypesMap& map, + StyleResolverState& state) + : m_interpolationTypesMap(map), + m_state(&state), + m_svgElement(nullptr), + m_svgBaseValue(nullptr) {} - explicit InterpolationEnvironment(SVGElement& svgElement, + explicit InterpolationEnvironment(const InterpolationTypesMap& map, + SVGElement& svgElement, const SVGPropertyBase& svgBaseValue) - : m_state(nullptr), + : m_interpolationTypesMap(map), + m_state(nullptr), m_svgElement(&svgElement), m_svgBaseValue(&svgBaseValue) {} + const InterpolationTypesMap& interpolationTypesMap() const { + return m_interpolationTypesMap; + } + StyleResolverState& state() { DCHECK(m_state); return *m_state; @@ -51,6 +62,7 @@ } private: + const InterpolationTypesMap& m_interpolationTypesMap; StyleResolverState* m_state; Member<SVGElement> m_svgElement; Member<const SVGPropertyBase> m_svgBaseValue;
diff --git a/third_party/WebKit/Source/core/animation/InterpolationTypesMap.h b/third_party/WebKit/Source/core/animation/InterpolationTypesMap.h new file mode 100644 index 0000000..a52a795 --- /dev/null +++ b/third_party/WebKit/Source/core/animation/InterpolationTypesMap.h
@@ -0,0 +1,28 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef InterpolationTypesMap_h +#define InterpolationTypesMap_h + +#include "wtf/Vector.h" +#include <memory> + +namespace blink { + +class InterpolationType; +class PropertyHandle; + +using InterpolationTypes = Vector<std::unique_ptr<const InterpolationType>>; + +class InterpolationTypesMap { + STACK_ALLOCATED(); + + public: + virtual const InterpolationTypes& get(const PropertyHandle&) const = 0; + virtual size_t version() const { return 0; } +}; + +} // namespace blink + +#endif // InterpolationTypesMap_h
diff --git a/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp b/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp index e480166..ef975f9 100644 --- a/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp +++ b/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp
@@ -32,7 +32,7 @@ const InterpolationEnvironment& environment, const UnderlyingValueOwner& underlyingValueOwner) const { DCHECK(m_currentFraction != 0 && m_currentFraction != 1); - for (const auto& interpolationType : m_interpolationTypes) { + for (const auto& interpolationType : *m_interpolationTypes) { if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && (!underlyingValueOwner || underlyingValueOwner.type() != *interpolationType)) @@ -59,7 +59,7 @@ const UnderlyingValueOwner& underlyingValueOwner) const { if (keyframe.isNeutral() && !underlyingValueOwner) return nullptr; - for (const auto& interpolationType : m_interpolationTypes) { + for (const auto& interpolationType : *m_interpolationTypes) { if (keyframe.isNeutral() && underlyingValueOwner.type() != *interpolationType) continue; @@ -89,7 +89,7 @@ std::unique_ptr<TypedInterpolationValue> InvalidatableInterpolation::maybeConvertUnderlyingValue( const InterpolationEnvironment& environment) const { - for (const auto& interpolationType : m_interpolationTypes) { + for (const auto& interpolationType : *m_interpolationTypes) { InterpolationValue result = interpolationType->maybeConvertUnderlyingValue(environment); if (result) @@ -144,6 +144,9 @@ const InterpolationEnvironment& environment, const UnderlyingValueOwner& underlyingValueOwner) const { DCHECK(!std::isnan(m_currentFraction)); + DCHECK(m_interpolationTypes && + m_interpolationTypesVersion == + environment.interpolationTypesMap().version()); if (isConversionCacheValid(environment, underlyingValueOwner)) return m_cachedValue.get(); clearConversionCache(); @@ -172,6 +175,22 @@ return m_cachedValue.get(); } +void InvalidatableInterpolation::ensureValidInterpolationTypes( + const InterpolationEnvironment& environment) const { + const InterpolationTypesMap& map = environment.interpolationTypesMap(); + size_t latestVersion = map.version(); + if (m_interpolationTypes && m_interpolationTypesVersion == latestVersion) { + return; + } + const InterpolationTypes* latestInterpolationTypes = &map.get(m_property); + DCHECK(latestInterpolationTypes); + if (m_interpolationTypes != latestInterpolationTypes) { + clearConversionCache(); + } + m_interpolationTypes = latestInterpolationTypes; + m_interpolationTypesVersion = latestVersion; +} + void InvalidatableInterpolation::setFlagIfInheritUsed( InterpolationEnvironment& environment) const { if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute()) @@ -208,6 +227,7 @@ UnderlyingValueOwner underlyingValueOwner; const InvalidatableInterpolation& firstInterpolation = toInvalidatableInterpolation(*interpolations.at(startingIndex)); + firstInterpolation.ensureValidInterpolationTypes(environment); if (firstInterpolation.dependsOnUnderlyingValue()) { underlyingValueOwner.set( firstInterpolation.maybeConvertUnderlyingValue(environment)); @@ -235,6 +255,7 @@ const InvalidatableInterpolation& currentInterpolation = toInvalidatableInterpolation(*interpolations.at(i)); DCHECK(currentInterpolation.dependsOnUnderlyingValue()); + currentInterpolation.ensureValidInterpolationTypes(environment); const TypedInterpolationValue* currentValue = currentInterpolation.ensureValidConversion(environment, underlyingValueOwner);
diff --git a/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.h b/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.h index 1763d46..c45d3a08 100644 --- a/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.h +++ b/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.h
@@ -6,8 +6,8 @@ #define InvalidatableInterpolation_h #include "core/animation/InterpolationType.h" +#include "core/animation/InterpolationTypesMap.h" #include "core/animation/PrimitiveInterpolation.h" -#include "core/animation/PropertyInterpolationTypesMapping.h" #include "core/animation/StyleInterpolation.h" #include "core/animation/TypedInterpolationValue.h" #include <memory> @@ -21,12 +21,10 @@ public: static PassRefPtr<InvalidatableInterpolation> create( PropertyHandle property, - const InterpolationTypes& interpolationTypes, PassRefPtr<PropertySpecificKeyframe> startKeyframe, PassRefPtr<PropertySpecificKeyframe> endKeyframe) { - return adoptRef(new InvalidatableInterpolation(property, interpolationTypes, - std::move(startKeyframe), - std::move(endKeyframe))); + return adoptRef(new InvalidatableInterpolation( + property, std::move(startKeyframe), std::move(endKeyframe))); } PropertyHandle getProperty() const final { return m_property; } @@ -40,12 +38,12 @@ private: InvalidatableInterpolation(PropertyHandle property, - const InterpolationTypes& interpolationTypes, PassRefPtr<PropertySpecificKeyframe> startKeyframe, PassRefPtr<PropertySpecificKeyframe> endKeyframe) : Interpolation(nullptr, nullptr), m_property(property), - m_interpolationTypes(interpolationTypes), + m_interpolationTypes(nullptr), + m_interpolationTypesVersion(0), m_startKeyframe(startKeyframe), m_endKeyframe(endKeyframe), m_currentFraction(std::numeric_limits<double>::quiet_NaN()), @@ -58,6 +56,7 @@ const TypedInterpolationValue* ensureValidConversion( const InterpolationEnvironment&, const UnderlyingValueOwner&) const; + void ensureValidInterpolationTypes(const InterpolationEnvironment&) const; void clearConversionCache() const; bool isConversionCacheValid(const InterpolationEnvironment&, const UnderlyingValueOwner&) const; @@ -75,7 +74,8 @@ double underlyingFraction() const; const PropertyHandle m_property; - const InterpolationTypes& m_interpolationTypes; + mutable const InterpolationTypes* m_interpolationTypes; + mutable size_t m_interpolationTypesVersion; RefPtr<PropertySpecificKeyframe> m_startKeyframe; RefPtr<PropertySpecificKeyframe> m_endKeyframe; double m_currentFraction;
diff --git a/third_party/WebKit/Source/core/animation/Keyframe.cpp b/third_party/WebKit/Source/core/animation/Keyframe.cpp index 5c733374..bf504e4a 100644 --- a/third_party/WebKit/Source/core/animation/Keyframe.cpp +++ b/third_party/WebKit/Source/core/animation/Keyframe.cpp
@@ -5,7 +5,6 @@ #include "core/animation/Keyframe.h" #include "core/animation/InvalidatableInterpolation.h" -#include "core/animation/PropertyInterpolationTypesMapping.h" namespace blink { @@ -15,8 +14,7 @@ const Keyframe::PropertySpecificKeyframe& end) const { // const_cast to take refs. return InvalidatableInterpolation::create( - propertyHandle, PropertyInterpolationTypesMapping::get(propertyHandle), - const_cast<PropertySpecificKeyframe*>(this), + propertyHandle, const_cast<PropertySpecificKeyframe*>(this), const_cast<PropertySpecificKeyframe*>(&end)); }
diff --git a/third_party/WebKit/Source/core/animation/PropertyInterpolationTypesMapping.cpp b/third_party/WebKit/Source/core/animation/PropertyInterpolationTypesMapping.cpp deleted file mode 100644 index dd28e10..0000000 --- a/third_party/WebKit/Source/core/animation/PropertyInterpolationTypesMapping.cpp +++ /dev/null
@@ -1,432 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/animation/PropertyInterpolationTypesMapping.h" - -#include "core/HTMLNames.h" -#include "core/animation/CSSBasicShapeInterpolationType.h" -#include "core/animation/CSSBorderImageLengthBoxInterpolationType.h" -#include "core/animation/CSSClipInterpolationType.h" -#include "core/animation/CSSColorInterpolationType.h" -#include "core/animation/CSSFilterListInterpolationType.h" -#include "core/animation/CSSFontSizeInterpolationType.h" -#include "core/animation/CSSFontWeightInterpolationType.h" -#include "core/animation/CSSImageInterpolationType.h" -#include "core/animation/CSSImageListInterpolationType.h" -#include "core/animation/CSSImageSliceInterpolationType.h" -#include "core/animation/CSSLengthInterpolationType.h" -#include "core/animation/CSSLengthListInterpolationType.h" -#include "core/animation/CSSLengthPairInterpolationType.h" -#include "core/animation/CSSNumberInterpolationType.h" -#include "core/animation/CSSOffsetRotationInterpolationType.h" -#include "core/animation/CSSPaintInterpolationType.h" -#include "core/animation/CSSPathInterpolationType.h" -#include "core/animation/CSSPositionAxisListInterpolationType.h" -#include "core/animation/CSSPositionInterpolationType.h" -#include "core/animation/CSSRotateInterpolationType.h" -#include "core/animation/CSSScaleInterpolationType.h" -#include "core/animation/CSSShadowListInterpolationType.h" -#include "core/animation/CSSSizeListInterpolationType.h" -#include "core/animation/CSSTextIndentInterpolationType.h" -#include "core/animation/CSSTransformInterpolationType.h" -#include "core/animation/CSSTransformOriginInterpolationType.h" -#include "core/animation/CSSTranslateInterpolationType.h" -#include "core/animation/CSSValueInterpolationType.h" -#include "core/animation/CSSVisibilityInterpolationType.h" -#include "core/animation/InterpolationType.h" -#include "core/animation/SVGAngleInterpolationType.h" -#include "core/animation/SVGIntegerInterpolationType.h" -#include "core/animation/SVGIntegerOptionalIntegerInterpolationType.h" -#include "core/animation/SVGLengthInterpolationType.h" -#include "core/animation/SVGLengthListInterpolationType.h" -#include "core/animation/SVGNumberInterpolationType.h" -#include "core/animation/SVGNumberListInterpolationType.h" -#include "core/animation/SVGNumberOptionalNumberInterpolationType.h" -#include "core/animation/SVGPathInterpolationType.h" -#include "core/animation/SVGPointListInterpolationType.h" -#include "core/animation/SVGRectInterpolationType.h" -#include "core/animation/SVGTransformListInterpolationType.h" -#include "core/animation/SVGValueInterpolationType.h" -#include "core/css/CSSPropertyMetadata.h" -#include "wtf/PtrUtil.h" -#include <memory> - -namespace blink { - -const InterpolationTypes& PropertyInterpolationTypesMapping::get( - const PropertyHandle& property) { - using ApplicableTypesMap = - HashMap<PropertyHandle, std::unique_ptr<const InterpolationTypes>>; - DEFINE_STATIC_LOCAL(ApplicableTypesMap, applicableTypesMap, ()); - auto entry = applicableTypesMap.find(property); - if (entry != applicableTypesMap.end()) - return *entry->value.get(); - - std::unique_ptr<InterpolationTypes> applicableTypes = - WTF::makeUnique<InterpolationTypes>(); - - if (property.isCSSProperty() || property.isPresentationAttribute()) { - CSSPropertyID cssProperty = property.isCSSProperty() - ? property.cssProperty() - : property.presentationAttribute(); - // We treat presentation attributes identically to their CSS property - // equivalents when interpolating. - PropertyHandle usedProperty = - property.isCSSProperty() ? property : PropertyHandle(cssProperty); - switch (cssProperty) { - case CSSPropertyBaselineShift: - case CSSPropertyBorderBottomWidth: - case CSSPropertyBorderLeftWidth: - case CSSPropertyBorderRightWidth: - case CSSPropertyBorderTopWidth: - case CSSPropertyBottom: - case CSSPropertyCx: - case CSSPropertyCy: - case CSSPropertyFlexBasis: - case CSSPropertyHeight: - case CSSPropertyLeft: - case CSSPropertyLetterSpacing: - case CSSPropertyMarginBottom: - case CSSPropertyMarginLeft: - case CSSPropertyMarginRight: - case CSSPropertyMarginTop: - case CSSPropertyMaxHeight: - case CSSPropertyMaxWidth: - case CSSPropertyMinHeight: - case CSSPropertyMinWidth: - case CSSPropertyOffsetDistance: - case CSSPropertyOutlineOffset: - case CSSPropertyOutlineWidth: - case CSSPropertyPaddingBottom: - case CSSPropertyPaddingLeft: - case CSSPropertyPaddingRight: - case CSSPropertyPaddingTop: - case CSSPropertyPerspective: - case CSSPropertyR: - case CSSPropertyRight: - case CSSPropertyRx: - case CSSPropertyRy: - case CSSPropertyShapeMargin: - case CSSPropertyStrokeDashoffset: - case CSSPropertyStrokeWidth: - case CSSPropertyTop: - case CSSPropertyVerticalAlign: - case CSSPropertyWebkitBorderHorizontalSpacing: - case CSSPropertyWebkitBorderVerticalSpacing: - case CSSPropertyColumnGap: - case CSSPropertyColumnRuleWidth: - case CSSPropertyColumnWidth: - case CSSPropertyWebkitPerspectiveOriginX: - case CSSPropertyWebkitPerspectiveOriginY: - case CSSPropertyWebkitTransformOriginX: - case CSSPropertyWebkitTransformOriginY: - case CSSPropertyWebkitTransformOriginZ: - case CSSPropertyWidth: - case CSSPropertyWordSpacing: - case CSSPropertyX: - case CSSPropertyY: - applicableTypes->append( - WTF::makeUnique<CSSLengthInterpolationType>(usedProperty)); - break; - case CSSPropertyFlexGrow: - case CSSPropertyFlexShrink: - case CSSPropertyFillOpacity: - case CSSPropertyFloodOpacity: - case CSSPropertyFontSizeAdjust: - case CSSPropertyOpacity: - case CSSPropertyOrphans: - case CSSPropertyShapeImageThreshold: - case CSSPropertyStopOpacity: - case CSSPropertyStrokeMiterlimit: - case CSSPropertyStrokeOpacity: - case CSSPropertyColumnCount: - case CSSPropertyWidows: - case CSSPropertyZIndex: - applicableTypes->append( - WTF::makeUnique<CSSNumberInterpolationType>(usedProperty)); - break; - case CSSPropertyLineHeight: - applicableTypes->append( - WTF::makeUnique<CSSLengthInterpolationType>(usedProperty)); - applicableTypes->append( - WTF::makeUnique<CSSNumberInterpolationType>(usedProperty)); - break; - case CSSPropertyBackgroundColor: - case CSSPropertyBorderBottomColor: - case CSSPropertyBorderLeftColor: - case CSSPropertyBorderRightColor: - case CSSPropertyBorderTopColor: - case CSSPropertyColor: - case CSSPropertyFloodColor: - case CSSPropertyLightingColor: - case CSSPropertyOutlineColor: - case CSSPropertyStopColor: - case CSSPropertyTextDecorationColor: - case CSSPropertyColumnRuleColor: - case CSSPropertyWebkitTextStrokeColor: - applicableTypes->append( - WTF::makeUnique<CSSColorInterpolationType>(usedProperty)); - break; - case CSSPropertyFill: - case CSSPropertyStroke: - applicableTypes->append( - WTF::makeUnique<CSSPaintInterpolationType>(usedProperty)); - break; - case CSSPropertyD: - applicableTypes->append( - WTF::makeUnique<CSSPathInterpolationType>(usedProperty)); - break; - case CSSPropertyBoxShadow: - case CSSPropertyTextShadow: - applicableTypes->append( - WTF::makeUnique<CSSShadowListInterpolationType>(usedProperty)); - break; - case CSSPropertyBorderImageSource: - case CSSPropertyListStyleImage: - case CSSPropertyWebkitMaskBoxImageSource: - applicableTypes->append( - WTF::makeUnique<CSSImageInterpolationType>(usedProperty)); - break; - case CSSPropertyBackgroundImage: - case CSSPropertyWebkitMaskImage: - applicableTypes->append( - WTF::makeUnique<CSSImageListInterpolationType>(usedProperty)); - break; - case CSSPropertyStrokeDasharray: - applicableTypes->append( - WTF::makeUnique<CSSLengthListInterpolationType>(usedProperty)); - break; - case CSSPropertyFontWeight: - applicableTypes->append( - WTF::makeUnique<CSSFontWeightInterpolationType>(usedProperty)); - break; - case CSSPropertyVisibility: - applicableTypes->append( - WTF::makeUnique<CSSVisibilityInterpolationType>(usedProperty)); - break; - case CSSPropertyClip: - applicableTypes->append( - WTF::makeUnique<CSSClipInterpolationType>(usedProperty)); - break; - case CSSPropertyOffsetRotate: - case CSSPropertyOffsetRotation: - applicableTypes->append( - WTF::makeUnique<CSSOffsetRotationInterpolationType>(usedProperty)); - break; - case CSSPropertyBackgroundPositionX: - case CSSPropertyBackgroundPositionY: - case CSSPropertyWebkitMaskPositionX: - case CSSPropertyWebkitMaskPositionY: - applicableTypes->append( - WTF::makeUnique<CSSPositionAxisListInterpolationType>( - usedProperty)); - break; - case CSSPropertyObjectPosition: - case CSSPropertyOffsetAnchor: - case CSSPropertyOffsetPosition: - case CSSPropertyPerspectiveOrigin: - applicableTypes->append( - WTF::makeUnique<CSSPositionInterpolationType>(usedProperty)); - break; - case CSSPropertyBorderBottomLeftRadius: - case CSSPropertyBorderBottomRightRadius: - case CSSPropertyBorderTopLeftRadius: - case CSSPropertyBorderTopRightRadius: - applicableTypes->append( - WTF::makeUnique<CSSLengthPairInterpolationType>(usedProperty)); - break; - case CSSPropertyTranslate: - applicableTypes->append( - WTF::makeUnique<CSSTranslateInterpolationType>(usedProperty)); - break; - case CSSPropertyTransformOrigin: - applicableTypes->append( - WTF::makeUnique<CSSTransformOriginInterpolationType>(usedProperty)); - break; - case CSSPropertyBackgroundSize: - case CSSPropertyWebkitMaskSize: - applicableTypes->append( - WTF::makeUnique<CSSSizeListInterpolationType>(usedProperty)); - break; - case CSSPropertyBorderImageOutset: - case CSSPropertyBorderImageWidth: - case CSSPropertyWebkitMaskBoxImageOutset: - case CSSPropertyWebkitMaskBoxImageWidth: - applicableTypes->append(WTF::wrapUnique( - new CSSBorderImageLengthBoxInterpolationType(usedProperty))); - break; - case CSSPropertyScale: - applicableTypes->append( - WTF::makeUnique<CSSScaleInterpolationType>(usedProperty)); - break; - case CSSPropertyFontSize: - applicableTypes->append( - WTF::makeUnique<CSSFontSizeInterpolationType>(usedProperty)); - break; - case CSSPropertyTextIndent: - applicableTypes->append( - WTF::makeUnique<CSSTextIndentInterpolationType>(usedProperty)); - break; - case CSSPropertyBorderImageSlice: - case CSSPropertyWebkitMaskBoxImageSlice: - applicableTypes->append( - WTF::makeUnique<CSSImageSliceInterpolationType>(usedProperty)); - break; - case CSSPropertyClipPath: - case CSSPropertyShapeOutside: - applicableTypes->append( - WTF::makeUnique<CSSBasicShapeInterpolationType>(usedProperty)); - break; - case CSSPropertyRotate: - applicableTypes->append( - WTF::makeUnique<CSSRotateInterpolationType>(usedProperty)); - break; - case CSSPropertyBackdropFilter: - case CSSPropertyFilter: - applicableTypes->append( - WTF::makeUnique<CSSFilterListInterpolationType>(usedProperty)); - break; - case CSSPropertyTransform: - applicableTypes->append( - WTF::makeUnique<CSSTransformInterpolationType>(usedProperty)); - break; - default: - DCHECK(!CSSPropertyMetadata::isInterpolableProperty(cssProperty)); - } - - applicableTypes->append( - WTF::makeUnique<CSSValueInterpolationType>(usedProperty)); - - } else { - const QualifiedName& attribute = property.svgAttribute(); - if (attribute == SVGNames::orientAttr) { - applicableTypes->append( - WTF::makeUnique<SVGAngleInterpolationType>(attribute)); - } else if (attribute == SVGNames::numOctavesAttr || - attribute == SVGNames::targetXAttr || - attribute == SVGNames::targetYAttr) { - applicableTypes->append( - WTF::makeUnique<SVGIntegerInterpolationType>(attribute)); - } else if (attribute == SVGNames::orderAttr) { - applicableTypes->append(WTF::wrapUnique( - new SVGIntegerOptionalIntegerInterpolationType(attribute))); - } else if (attribute == SVGNames::cxAttr || attribute == SVGNames::cyAttr || - attribute == SVGNames::fxAttr || attribute == SVGNames::fyAttr || - attribute == SVGNames::heightAttr || - attribute == SVGNames::markerHeightAttr || - attribute == SVGNames::markerWidthAttr || - attribute == SVGNames::rAttr || - attribute == SVGNames::refXAttr || - attribute == SVGNames::refYAttr || - attribute == SVGNames::rxAttr || attribute == SVGNames::ryAttr || - attribute == SVGNames::startOffsetAttr || - attribute == SVGNames::textLengthAttr || - attribute == SVGNames::widthAttr || - attribute == SVGNames::x1Attr || attribute == SVGNames::x2Attr || - attribute == SVGNames::y1Attr || attribute == SVGNames::y2Attr) { - applicableTypes->append( - WTF::makeUnique<SVGLengthInterpolationType>(attribute)); - } else if (attribute == SVGNames::dxAttr || attribute == SVGNames::dyAttr) { - applicableTypes->append( - WTF::makeUnique<SVGNumberInterpolationType>(attribute)); - applicableTypes->append( - WTF::makeUnique<SVGLengthListInterpolationType>(attribute)); - } else if (attribute == SVGNames::xAttr || attribute == SVGNames::yAttr) { - applicableTypes->append( - WTF::makeUnique<SVGLengthInterpolationType>(attribute)); - applicableTypes->append( - WTF::makeUnique<SVGLengthListInterpolationType>(attribute)); - } else if (attribute == SVGNames::amplitudeAttr || - attribute == SVGNames::azimuthAttr || - attribute == SVGNames::biasAttr || - attribute == SVGNames::diffuseConstantAttr || - attribute == SVGNames::divisorAttr || - attribute == SVGNames::elevationAttr || - attribute == SVGNames::exponentAttr || - attribute == SVGNames::interceptAttr || - attribute == SVGNames::k1Attr || attribute == SVGNames::k2Attr || - attribute == SVGNames::k3Attr || attribute == SVGNames::k4Attr || - attribute == SVGNames::limitingConeAngleAttr || - attribute == SVGNames::offsetAttr || - attribute == SVGNames::pathLengthAttr || - attribute == SVGNames::pointsAtXAttr || - attribute == SVGNames::pointsAtYAttr || - attribute == SVGNames::pointsAtZAttr || - attribute == SVGNames::scaleAttr || - attribute == SVGNames::seedAttr || - attribute == SVGNames::slopeAttr || - attribute == SVGNames::specularConstantAttr || - attribute == SVGNames::specularExponentAttr || - attribute == SVGNames::surfaceScaleAttr || - attribute == SVGNames::zAttr) { - applicableTypes->append( - WTF::makeUnique<SVGNumberInterpolationType>(attribute)); - } else if (attribute == SVGNames::kernelMatrixAttr || - attribute == SVGNames::rotateAttr || - attribute == SVGNames::tableValuesAttr || - attribute == SVGNames::valuesAttr) { - applicableTypes->append( - WTF::makeUnique<SVGNumberListInterpolationType>(attribute)); - } else if (attribute == SVGNames::baseFrequencyAttr || - attribute == SVGNames::kernelUnitLengthAttr || - attribute == SVGNames::radiusAttr || - attribute == SVGNames::stdDeviationAttr) { - applicableTypes->append( - WTF::makeUnique<SVGNumberOptionalNumberInterpolationType>(attribute)); - } else if (attribute == SVGNames::dAttr) { - applicableTypes->append( - WTF::makeUnique<SVGPathInterpolationType>(attribute)); - } else if (attribute == SVGNames::pointsAttr) { - applicableTypes->append( - WTF::makeUnique<SVGPointListInterpolationType>(attribute)); - } else if (attribute == SVGNames::viewBoxAttr) { - applicableTypes->append( - WTF::makeUnique<SVGRectInterpolationType>(attribute)); - } else if (attribute == SVGNames::gradientTransformAttr || - attribute == SVGNames::patternTransformAttr || - attribute == SVGNames::transformAttr) { - applicableTypes->append( - WTF::makeUnique<SVGTransformListInterpolationType>(attribute)); - } else if (attribute == HTMLNames::classAttr || - attribute == SVGNames::clipPathUnitsAttr || - attribute == SVGNames::edgeModeAttr || - attribute == SVGNames::filterUnitsAttr || - attribute == SVGNames::gradientUnitsAttr || - attribute == SVGNames::hrefAttr || - attribute == SVGNames::inAttr || - attribute == SVGNames::in2Attr || - attribute == SVGNames::lengthAdjustAttr || - attribute == SVGNames::markerUnitsAttr || - attribute == SVGNames::maskContentUnitsAttr || - attribute == SVGNames::maskUnitsAttr || - attribute == SVGNames::methodAttr || - attribute == SVGNames::modeAttr || - attribute == SVGNames::operatorAttr || - attribute == SVGNames::patternContentUnitsAttr || - attribute == SVGNames::patternUnitsAttr || - attribute == SVGNames::preserveAlphaAttr || - attribute == SVGNames::preserveAspectRatioAttr || - attribute == SVGNames::primitiveUnitsAttr || - attribute == SVGNames::resultAttr || - attribute == SVGNames::spacingAttr || - attribute == SVGNames::spreadMethodAttr || - attribute == SVGNames::stitchTilesAttr || - attribute == SVGNames::targetAttr || - attribute == SVGNames::typeAttr || - attribute == SVGNames::xChannelSelectorAttr || - attribute == SVGNames::yChannelSelectorAttr) { - // Use default SVGValueInterpolationType. - } else { - NOTREACHED(); - } - - applicableTypes->append( - WTF::makeUnique<SVGValueInterpolationType>(attribute)); - } - - auto addResult = applicableTypesMap.add(property, std::move(applicableTypes)); - return *addResult.storedValue->value.get(); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/PropertyInterpolationTypesMapping.h b/third_party/WebKit/Source/core/animation/PropertyInterpolationTypesMapping.h deleted file mode 100644 index 57fc605..0000000 --- a/third_party/WebKit/Source/core/animation/PropertyInterpolationTypesMapping.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PropertyInterpolationTypesMapping_h -#define PropertyInterpolationTypesMapping_h - -#include "wtf/Vector.h" -#include <memory> - -namespace blink { - -class InterpolationType; -class PropertyHandle; - -using InterpolationTypes = Vector<std::unique_ptr<const InterpolationType>>; - -namespace PropertyInterpolationTypesMapping { - -const InterpolationTypes& get(const PropertyHandle&); -}; - -} // namespace blink - -#endif // PropertyInterpolationTypesMapping_h
diff --git a/third_party/WebKit/Source/core/animation/SVGInterpolationTypesMap.cpp b/third_party/WebKit/Source/core/animation/SVGInterpolationTypesMap.cpp new file mode 100644 index 0000000..1aca982 --- /dev/null +++ b/third_party/WebKit/Source/core/animation/SVGInterpolationTypesMap.cpp
@@ -0,0 +1,166 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/animation/SVGInterpolationTypesMap.h" + +#include "core/HTMLNames.h" +#include "core/animation/SVGAngleInterpolationType.h" +#include "core/animation/SVGIntegerInterpolationType.h" +#include "core/animation/SVGIntegerOptionalIntegerInterpolationType.h" +#include "core/animation/SVGLengthInterpolationType.h" +#include "core/animation/SVGLengthListInterpolationType.h" +#include "core/animation/SVGNumberInterpolationType.h" +#include "core/animation/SVGNumberListInterpolationType.h" +#include "core/animation/SVGNumberOptionalNumberInterpolationType.h" +#include "core/animation/SVGPathInterpolationType.h" +#include "core/animation/SVGPointListInterpolationType.h" +#include "core/animation/SVGRectInterpolationType.h" +#include "core/animation/SVGTransformListInterpolationType.h" +#include "core/animation/SVGValueInterpolationType.h" +#include "core/css/CSSPropertyMetadata.h" +#include "wtf/PtrUtil.h" +#include <memory> + +namespace blink { + +const InterpolationTypes& SVGInterpolationTypesMap::get( + const PropertyHandle& property) const { + using ApplicableTypesMap = + HashMap<PropertyHandle, std::unique_ptr<const InterpolationTypes>>; + DEFINE_STATIC_LOCAL(ApplicableTypesMap, applicableTypesMap, ()); + auto entry = applicableTypesMap.find(property); + if (entry != applicableTypesMap.end()) + return *entry->value.get(); + + std::unique_ptr<InterpolationTypes> applicableTypes = + WTF::makeUnique<InterpolationTypes>(); + + const QualifiedName& attribute = property.svgAttribute(); + if (attribute == SVGNames::orientAttr) { + applicableTypes->append( + WTF::makeUnique<SVGAngleInterpolationType>(attribute)); + } else if (attribute == SVGNames::numOctavesAttr || + attribute == SVGNames::targetXAttr || + attribute == SVGNames::targetYAttr) { + applicableTypes->append( + WTF::makeUnique<SVGIntegerInterpolationType>(attribute)); + } else if (attribute == SVGNames::orderAttr) { + applicableTypes->append( + WTF::makeUnique<SVGIntegerOptionalIntegerInterpolationType>(attribute)); + } else if (attribute == SVGNames::cxAttr || attribute == SVGNames::cyAttr || + attribute == SVGNames::fxAttr || attribute == SVGNames::fyAttr || + attribute == SVGNames::heightAttr || + attribute == SVGNames::markerHeightAttr || + attribute == SVGNames::markerWidthAttr || + attribute == SVGNames::rAttr || attribute == SVGNames::refXAttr || + attribute == SVGNames::refYAttr || attribute == SVGNames::rxAttr || + attribute == SVGNames::ryAttr || + attribute == SVGNames::startOffsetAttr || + attribute == SVGNames::textLengthAttr || + attribute == SVGNames::widthAttr || + attribute == SVGNames::x1Attr || attribute == SVGNames::x2Attr || + attribute == SVGNames::y1Attr || attribute == SVGNames::y2Attr) { + applicableTypes->append( + WTF::makeUnique<SVGLengthInterpolationType>(attribute)); + } else if (attribute == SVGNames::dxAttr || attribute == SVGNames::dyAttr) { + applicableTypes->append( + WTF::makeUnique<SVGNumberInterpolationType>(attribute)); + applicableTypes->append( + WTF::makeUnique<SVGLengthListInterpolationType>(attribute)); + } else if (attribute == SVGNames::xAttr || attribute == SVGNames::yAttr) { + applicableTypes->append( + WTF::makeUnique<SVGLengthInterpolationType>(attribute)); + applicableTypes->append( + WTF::makeUnique<SVGLengthListInterpolationType>(attribute)); + } else if (attribute == SVGNames::amplitudeAttr || + attribute == SVGNames::azimuthAttr || + attribute == SVGNames::biasAttr || + attribute == SVGNames::diffuseConstantAttr || + attribute == SVGNames::divisorAttr || + attribute == SVGNames::elevationAttr || + attribute == SVGNames::exponentAttr || + attribute == SVGNames::interceptAttr || + attribute == SVGNames::k1Attr || attribute == SVGNames::k2Attr || + attribute == SVGNames::k3Attr || attribute == SVGNames::k4Attr || + attribute == SVGNames::limitingConeAngleAttr || + attribute == SVGNames::offsetAttr || + attribute == SVGNames::pathLengthAttr || + attribute == SVGNames::pointsAtXAttr || + attribute == SVGNames::pointsAtYAttr || + attribute == SVGNames::pointsAtZAttr || + attribute == SVGNames::scaleAttr || + attribute == SVGNames::seedAttr || + attribute == SVGNames::slopeAttr || + attribute == SVGNames::specularConstantAttr || + attribute == SVGNames::specularExponentAttr || + attribute == SVGNames::surfaceScaleAttr || + attribute == SVGNames::zAttr) { + applicableTypes->append( + WTF::makeUnique<SVGNumberInterpolationType>(attribute)); + } else if (attribute == SVGNames::kernelMatrixAttr || + attribute == SVGNames::rotateAttr || + attribute == SVGNames::tableValuesAttr || + attribute == SVGNames::valuesAttr) { + applicableTypes->append( + WTF::makeUnique<SVGNumberListInterpolationType>(attribute)); + } else if (attribute == SVGNames::baseFrequencyAttr || + attribute == SVGNames::kernelUnitLengthAttr || + attribute == SVGNames::radiusAttr || + attribute == SVGNames::stdDeviationAttr) { + applicableTypes->append( + WTF::makeUnique<SVGNumberOptionalNumberInterpolationType>(attribute)); + } else if (attribute == SVGNames::dAttr) { + applicableTypes->append( + WTF::makeUnique<SVGPathInterpolationType>(attribute)); + } else if (attribute == SVGNames::pointsAttr) { + applicableTypes->append( + WTF::makeUnique<SVGPointListInterpolationType>(attribute)); + } else if (attribute == SVGNames::viewBoxAttr) { + applicableTypes->append( + WTF::makeUnique<SVGRectInterpolationType>(attribute)); + } else if (attribute == SVGNames::gradientTransformAttr || + attribute == SVGNames::patternTransformAttr || + attribute == SVGNames::transformAttr) { + applicableTypes->append( + WTF::makeUnique<SVGTransformListInterpolationType>(attribute)); + } else if (attribute == HTMLNames::classAttr || + attribute == SVGNames::clipPathUnitsAttr || + attribute == SVGNames::edgeModeAttr || + attribute == SVGNames::filterUnitsAttr || + attribute == SVGNames::gradientUnitsAttr || + attribute == SVGNames::hrefAttr || attribute == SVGNames::inAttr || + attribute == SVGNames::in2Attr || + attribute == SVGNames::lengthAdjustAttr || + attribute == SVGNames::markerUnitsAttr || + attribute == SVGNames::maskContentUnitsAttr || + attribute == SVGNames::maskUnitsAttr || + attribute == SVGNames::methodAttr || + attribute == SVGNames::modeAttr || + attribute == SVGNames::operatorAttr || + attribute == SVGNames::patternContentUnitsAttr || + attribute == SVGNames::patternUnitsAttr || + attribute == SVGNames::preserveAlphaAttr || + attribute == SVGNames::preserveAspectRatioAttr || + attribute == SVGNames::primitiveUnitsAttr || + attribute == SVGNames::resultAttr || + attribute == SVGNames::spacingAttr || + attribute == SVGNames::spreadMethodAttr || + attribute == SVGNames::stitchTilesAttr || + attribute == SVGNames::targetAttr || + attribute == SVGNames::typeAttr || + attribute == SVGNames::xChannelSelectorAttr || + attribute == SVGNames::yChannelSelectorAttr) { + // Use default SVGValueInterpolationType. + } else { + NOTREACHED(); + } + + applicableTypes->append( + WTF::makeUnique<SVGValueInterpolationType>(attribute)); + + auto addResult = applicableTypesMap.add(property, std::move(applicableTypes)); + return *addResult.storedValue->value.get(); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/SVGInterpolationTypesMap.h b/third_party/WebKit/Source/core/animation/SVGInterpolationTypesMap.h new file mode 100644 index 0000000..7de36c0 --- /dev/null +++ b/third_party/WebKit/Source/core/animation/SVGInterpolationTypesMap.h
@@ -0,0 +1,21 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SVGInterpolationTypesMap_h +#define SVGInterpolationTypesMap_h + +#include "core/animation/InterpolationTypesMap.h" + +namespace blink { + +class SVGInterpolationTypesMap : public InterpolationTypesMap { + public: + SVGInterpolationTypesMap() {} + + const InterpolationTypes& get(const PropertyHandle&) const final; +}; + +} // namespace blink + +#endif // SVGInterpolationTypesMap_h
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in index 317166e2..f7b8105 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.in +++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -207,7 +207,7 @@ break-before type_name=EBreak break-inside type_name=EBreak buffered-rendering svg -caption-side inherited, keyword_only, keywords=[top|bottom|left|right], initial_keyword=top +caption-side inherited, keyword_only, independent, keywords=[top|bottom|left|right], initial_keyword=top caret-color inherited, custom_all clear clip interpolable, converter=convertClip, custom_all
diff --git a/third_party/WebKit/Source/core/css/PropertyRegistry.h b/third_party/WebKit/Source/core/css/PropertyRegistry.h index b9212cb..0c33122 100644 --- a/third_party/WebKit/Source/core/css/PropertyRegistry.h +++ b/third_party/WebKit/Source/core/css/PropertyRegistry.h
@@ -52,6 +52,7 @@ const CSSValue* initial, PassRefPtr<CSSVariableData> initialVariableData); const Registration* registration(const AtomicString&) const; + size_t registrationCount() const { return m_registrations.size(); } DEFINE_INLINE_TRACE() { visitor->trace(m_registrations); }
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp index 7747665..02a6b5c1 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -35,6 +35,7 @@ #include "core/MediaTypeNames.h" #include "core/StylePropertyShorthand.h" #include "core/animation/AnimationTimeline.h" +#include "core/animation/CSSInterpolationTypesMap.h" #include "core/animation/ElementAnimations.h" #include "core/animation/InterpolationEnvironment.h" #include "core/animation/InvalidatableInterpolation.h" @@ -1230,7 +1231,8 @@ continue; const Interpolation& interpolation = *entry.value.front(); if (interpolation.isInvalidatableInterpolation()) { - InterpolationEnvironment environment(state); + CSSInterpolationTypesMap map(state.document().propertyRegistry()); + InterpolationEnvironment environment(map, state); InvalidatableInterpolation::applyStack(entry.value, environment); } else { // TODO(alancutter): Remove this old code path once animations have
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp index d5feaa1..fce91f7 100644 --- a/third_party/WebKit/Source/core/dom/Node.cpp +++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -2300,6 +2300,7 @@ } HTMLSlotElement* Node::assignedSlot() const { + // assignedSlot doesn't need to call updateDistribution(). DCHECK(!isPseudoElement()); if (ShadowRoot* root = v1ShadowRootOfParent()) return root->ensureSlotAssignment().findSlot(*this); @@ -2307,7 +2308,7 @@ } HTMLSlotElement* Node::assignedSlotForBinding() { - updateDistribution(); + // assignedSlot doesn't need to call updateDistribution(). if (ShadowRoot* root = v1ShadowRootOfParent()) { if (root->type() == ShadowRootType::Open) return root->ensureSlotAssignment().findSlot(*this);
diff --git a/third_party/WebKit/Source/core/editing/iterators/CharacterIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/CharacterIterator.cpp index 73404be..19b4b31 100644 --- a/third_party/WebKit/Source/core/editing/iterators/CharacterIterator.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/CharacterIterator.cpp
@@ -189,6 +189,8 @@ advance(offset); const PositionTemplate<Strategy> startPos = startPosition(); + if (!length) + return EphemeralRangeTemplate<Strategy>(startPos, startPos); if (length > 1) advance(length - 1); return EphemeralRangeTemplate<Strategy>(startPos, endPosition());
diff --git a/third_party/WebKit/Source/core/editing/iterators/CharacterIteratorTest.cpp b/third_party/WebKit/Source/core/editing/iterators/CharacterIteratorTest.cpp index 6fc4293..a5e54ed 100644 --- a/third_party/WebKit/Source/core/editing/iterators/CharacterIteratorTest.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/CharacterIteratorTest.cpp
@@ -53,4 +53,21 @@ EXPECT_EQ(Position(textNode, 3), result.endPosition()); } +TEST_F(CharacterIteratorTest, CollapsedSubrange) { + static const char* bodyContent = + "<div id='div' contenteditable='true'>hello</div>"; + setBodyContent(bodyContent); + document().view()->updateAllLifecyclePhases(); + + Node* textNode = document().getElementById("div")->lastChild(); + Range* entireRange = Range::create(document(), textNode, 1, textNode, 4); + EXPECT_EQ(1, entireRange->startOffset()); + EXPECT_EQ(4, entireRange->endOffset()); + + const EphemeralRange& result = + calculateCharacterSubrange(EphemeralRange(entireRange), 2, 0); + EXPECT_EQ(Position(textNode, 3), result.startPosition()); + EXPECT_EQ(Position(textNode, 3), result.endPosition()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/History.cpp b/third_party/WebKit/Source/core/frame/History.cpp index ff278e4..470ca160 100644 --- a/third_party/WebKit/Source/core/frame/History.cpp +++ b/third_party/WebKit/Source/core/frame/History.cpp
@@ -84,7 +84,7 @@ } void History::setScrollRestoration(const String& value) { - ASSERT(value == "manual" || value == "auto"); + DCHECK(value == "manual" || value == "auto"); if (!frame() || !frame()->loader().client()) return; @@ -133,14 +133,15 @@ if (!frame() || !frame()->loader().client()) return; - ASSERT(isMainThread()); + DCHECK(isMainThread()); Document* activeDocument = toDocument(context); if (!activeDocument) return; if (!activeDocument->frame() || - !activeDocument->frame()->canNavigate(*frame())) + !activeDocument->frame()->canNavigate(*frame())) { return; + } if (!NavigationDisablerForUnload::isNavigationAllowed()) return; @@ -185,8 +186,9 @@ RefPtr<SecurityOrigin> requestedOrigin = SecurityOrigin::create(url); if (requestedOrigin->isUnique() || - !requestedOrigin->isSameSchemeHostPort(documentOrigin)) + !requestedOrigin->isSameSchemeHostPort(documentOrigin)) { return false; + } return true; }
diff --git a/third_party/WebKit/Source/core/frame/History.h b/third_party/WebKit/Source/core/frame/History.h index 11622ba..5c30f08 100644 --- a/third_party/WebKit/Source/core/frame/History.h +++ b/third_party/WebKit/Source/core/frame/History.h
@@ -42,6 +42,7 @@ class ExceptionState; class SecurityOrigin; +// This class corresponds to the History interface. class CORE_EXPORT History final : public GarbageCollectedFinalized<History>, public ScriptWrappable, public DOMWindowProperty {
diff --git a/third_party/WebKit/Source/core/frame/Location.cpp b/third_party/WebKit/Source/core/frame/Location.cpp index bd0a124..dd3626c 100644 --- a/third_party/WebKit/Source/core/frame/Location.cpp +++ b/third_party/WebKit/Source/core/frame/Location.cpp
@@ -112,8 +112,9 @@ if (!m_frame) return origins; for (Frame* frame = m_frame->tree().parent(); frame; - frame = frame->tree().parent()) + frame = frame->tree().parent()) { origins->append(frame->securityContext()->getSecurityOrigin()->toString()); + } return origins; } @@ -255,7 +256,7 @@ LocalDOMWindow* enteredWindow, ExceptionState* exceptionState, SetLocation locationPolicy) { - ASSERT(m_frame); + DCHECK(m_frame); if (!m_frame || !m_frame->host()) return; @@ -263,11 +264,12 @@ return; if (!currentWindow->frame()->canNavigate(*m_frame)) { - if (exceptionState) + if (exceptionState) { exceptionState->throwSecurityError( "The current window does not have permission to navigate the target " "frame to '" + url + "'."); + } return; }
diff --git a/third_party/WebKit/Source/core/html/LinkStyle.cpp b/third_party/WebKit/Source/core/html/LinkStyle.cpp index 9460d3c1..82bb9d8e 100644 --- a/third_party/WebKit/Source/core/html/LinkStyle.cpp +++ b/third_party/WebKit/Source/core/html/LinkStyle.cpp
@@ -236,40 +236,41 @@ void LinkStyle::setDisabledState(bool disabled) { LinkStyle::DisabledState oldDisabledState = m_disabledState; m_disabledState = disabled ? Disabled : EnabledViaScript; - if (oldDisabledState != m_disabledState) { - // If we change the disabled state while the sheet is still loading, then we - // have to perform three checks: - if (styleSheetIsLoading()) { - // Check #1: The sheet becomes disabled while loading. - if (m_disabledState == Disabled) - removePendingSheet(); + if (oldDisabledState == m_disabledState) + return; - // Check #2: An alternate sheet becomes enabled while it is still loading. - if (m_owner->relAttribute().isAlternate() && - m_disabledState == EnabledViaScript) - addPendingSheet(Blocking); + // If we change the disabled state while the sheet is still loading, then we + // have to perform three checks: + if (styleSheetIsLoading()) { + // Check #1: The sheet becomes disabled while loading. + if (m_disabledState == Disabled) + removePendingSheet(); - // Check #3: A main sheet becomes enabled while it was still loading and - // after it was disabled via script. It takes really terrible code to make - // this happen (a double toggle for no reason essentially). This happens - // on virtualplastic.net, which manages to do about 12 enable/disables on - // only 3 sheets. :) - if (!m_owner->relAttribute().isAlternate() && - m_disabledState == EnabledViaScript && oldDisabledState == Disabled) - addPendingSheet(Blocking); + // Check #2: An alternate sheet becomes enabled while it is still loading. + if (m_owner->relAttribute().isAlternate() && + m_disabledState == EnabledViaScript) + addPendingSheet(Blocking); - // If the sheet is already loading just bail. - return; - } + // Check #3: A main sheet becomes enabled while it was still loading and + // after it was disabled via script. It takes really terrible code to make + // this happen (a double toggle for no reason essentially). This happens + // on virtualplastic.net, which manages to do about 12 enable/disables on + // only 3 sheets. :) + if (!m_owner->relAttribute().isAlternate() && + m_disabledState == EnabledViaScript && oldDisabledState == Disabled) + addPendingSheet(Blocking); - if (m_sheet) { - m_sheet->setDisabled(disabled); - return; - } - - if (m_disabledState == EnabledViaScript && m_owner->shouldProcessStyle()) - process(); + // If the sheet is already loading just bail. + return; } + + if (m_sheet) { + m_sheet->setDisabled(disabled); + return; + } + + if (m_disabledState == EnabledViaScript && m_owner->shouldProcessStyle()) + process(); } void LinkStyle::setCrossOriginStylesheetStatus(CSSStyleSheet* sheet) { @@ -407,7 +408,7 @@ if (title.isEmpty() || !isUnset() || m_owner->isAlternate()) return; - KURL href = m_owner->getNonEmptyURLAttribute(hrefAttr); + const KURL& href = m_owner->getNonEmptyURLAttribute(hrefAttr); if (href.isValid() && !href.isEmpty()) { document().styleEngine().setPreferredStylesheetSetNameIfNotSet( title, updateActiveSheets);
diff --git a/third_party/WebKit/Source/core/html/TextControlElement.cpp b/third_party/WebKit/Source/core/html/TextControlElement.cpp index 91f0510..1b1bf9d 100644 --- a/third_party/WebKit/Source/core/html/TextControlElement.cpp +++ b/third_party/WebKit/Source/core/html/TextControlElement.cpp
@@ -865,7 +865,7 @@ return enclosingTextControl(position.computeContainerNode()); } -TextControlElement* enclosingTextControl(Node* container) { +TextControlElement* enclosingTextControl(const Node* container) { if (!container) return nullptr; Element* ancestor = container->ownerShadowHost();
diff --git a/third_party/WebKit/Source/core/html/TextControlElement.h b/third_party/WebKit/Source/core/html/TextControlElement.h index 2d050e2..d95e6a18 100644 --- a/third_party/WebKit/Source/core/html/TextControlElement.h +++ b/third_party/WebKit/Source/core/html/TextControlElement.h
@@ -223,7 +223,7 @@ DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(TextControlElement); TextControlElement* enclosingTextControl(const Position&); -TextControlElement* enclosingTextControl(Node*); +TextControlElement* enclosingTextControl(const Node*); } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/BUILD.gn b/third_party/WebKit/Source/core/layout/BUILD.gn index 8dac83d2..fad269e2 100644 --- a/third_party/WebKit/Source/core/layout/BUILD.gn +++ b/third_party/WebKit/Source/core/layout/BUILD.gn
@@ -313,6 +313,8 @@ "ng/ng_layout_opportunity_iterator.h", "ng/ng_layout_opportunity_tree_node.cc", "ng/ng_layout_opportunity_tree_node.h", + "ng/ng_legacy_block_layout_algorithm.cc", + "ng/ng_legacy_block_layout_algorithm.h", "ng/ng_length_utils.cc", "ng/ng_length_utils.h", "ng/ng_macros.h",
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc index d8fae61..4369972 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -180,7 +180,8 @@ NGBlockNode* first_child, NGConstraintSpace* constraint_space, NGBreakToken* break_token) - : state_(kStateInit), + : NGLayoutAlgorithm(kBlockLayoutAlgorithm), + state_(kStateInit), style_(style), first_child_(first_child), constraint_space_(constraint_space), @@ -190,9 +191,9 @@ } NGLayoutStatus NGBlockLayoutAlgorithm::Layout( - NGFragmentBase*, + NGPhysicalFragmentBase* child_fragment, NGPhysicalFragmentBase** fragment_out, - NGLayoutAlgorithm**) { + NGLayoutAlgorithm** algorithm_out) { switch (state_) { case kStateInit: { border_and_padding_ = @@ -235,14 +236,12 @@ builder_->SetDirection(constraint_space_->Direction()); builder_->SetWritingMode(constraint_space_->WritingMode()); builder_->SetInlineSize(inline_size).SetBlockSize(block_size); - current_child_ = first_child_; - if (current_child_) - space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); - state_ = kStateChildLayout; + current_child_ = first_child_; + state_ = kStatePrepareForChildLayout; return kNotFinished; } - case kStateChildLayout: { + case kStatePrepareForChildLayout: { if (current_child_) { // TODO(atotic): uncomment this code when implementing oof layout. // This code cannot be turned on because it prevents layout of @@ -253,17 +252,32 @@ // GetChildSpaceOffset()); // } // else - if (!LayoutCurrentChild()) - return kNotFinished; - current_child_ = current_child_->NextSibling(); - if (current_child_) { - space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); - return kNotFinished; - } + space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); + *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( + current_child_, space_for_current_child_); + state_ = kStateChildLayout; + return kChildAlgorithmRequired; } + state_ = kStateFinalize; return kNotFinished; } + case kStateChildLayout: { + DCHECK(current_child_); + DCHECK(child_fragment); + + // TODO(layout_ng): Seems like a giant hack to call this here. + current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment), + space_for_current_child_); + + FinishCurrentChildLayout( + new NGFragment(space_for_current_child_->WritingMode(), + current_child_->Style()->direction(), + toNGPhysicalFragment(child_fragment))); + current_child_ = current_child_->NextSibling(); + state_ = kStatePrepareForChildLayout; + return kNotFinished; + } case kStateFinalize: { content_size_ += border_and_padding_.block_end; @@ -284,11 +298,8 @@ return kNewFragment; } -bool NGBlockLayoutAlgorithm::LayoutCurrentChild() { - NGFragmentBase* fragment; - if (!current_child_->Layout(space_for_current_child_, &fragment)) - return false; - +void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( + NGFragmentBase* fragment) { NGBoxStrut child_margins = ComputeMargins( *space_for_current_child_, CurrentChildStyle(), constraint_space_->WritingMode(), constraint_space_->Direction()); @@ -302,7 +313,6 @@ fragment_offset = PositionFragment(*fragment, child_margins); } builder_->AddChild(fragment, fragment_offset); - return true; } NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h index e7e7375..c9c4a70 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -36,7 +36,7 @@ NGConstraintSpace* space, NGBreakToken* break_token = nullptr); - NGLayoutStatus Layout(NGFragmentBase*, + NGLayoutStatus Layout(NGPhysicalFragmentBase*, NGPhysicalFragmentBase**, NGLayoutAlgorithm**) override; @@ -45,7 +45,7 @@ private: // Creates a new constraint space for the current child. NGConstraintSpace* CreateConstraintSpaceForCurrentChild() const; - bool LayoutCurrentChild(); + void FinishCurrentChildLayout(NGFragmentBase* fragment); // Computes collapsed margins for 2 adjoining blocks and updates the resultant // fragment's MarginStrut if needed. @@ -98,7 +98,12 @@ const ComputedStyle& Style() const { return *style_; } - enum State { kStateInit, kStateChildLayout, kStateFinalize }; + enum State { + kStateInit, + kStatePrepareForChildLayout, + kStateChildLayout, + kStateFinalize + }; State state_; RefPtr<const ComputedStyle> style_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc index 7ba9e05..195b4b0a 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -9,6 +9,7 @@ #include "core/layout/ng/ng_constraint_space_builder.h" #include "core/layout/ng/ng_physical_fragment_base.h" #include "core/layout/ng/ng_physical_fragment.h" +#include "core/layout/ng/ng_layout_coordinator.h" #include "core/layout/ng/ng_length_utils.h" #include "core/layout/ng/ng_units.h" #include "core/style/ComputedStyle.h" @@ -33,11 +34,18 @@ NGPhysicalFragment* RunBlockLayoutAlgorithm(NGConstraintSpace* space, NGBlockNode* first_child) { - NGBlockLayoutAlgorithm algorithm(style_, first_child, space); - NGPhysicalFragmentBase* frag; - while (!algorithm.Layout(nullptr, &frag, nullptr)) - continue; - return toNGPhysicalFragment(frag); + NGBlockNode parent(style_.get()); + parent.SetFirstChild(first_child); + + NGLayoutCoordinator coordinator(&parent, space); + NGPhysicalFragmentBase* fragment; + coordinator.Tick(&fragment); + EXPECT_EQ(kBlockLayoutAlgorithm, + coordinator.GetAlgorithmStackForTesting()[0]->algorithmType()); + while (!coordinator.Tick(&fragment)) + ; + + return toNGPhysicalFragment(fragment); } RefPtr<ComputedStyle> style_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc index c9c627e..38a1351a 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -61,9 +61,7 @@ fragment_ = toNGPhysicalFragment(fragment); - if (layout_box_) { - CopyFragmentDataToLayoutBox(*constraint_space); - } + UpdateLayoutBox(fragment_, constraint_space); } else { DCHECK(layout_box_); fragment_ = RunOldLayout(*constraint_space); @@ -75,6 +73,14 @@ return true; } +void NGBlockNode::UpdateLayoutBox(NGPhysicalFragment* fragment, + const NGConstraintSpace* constraint_space) { + fragment_ = fragment; + if (layout_box_) { + CopyFragmentDataToLayoutBox(*constraint_space); + } +} + bool NGBlockNode::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) { if (!CanUseNewLayout()) { DCHECK(layout_box_); @@ -94,19 +100,14 @@ } DCHECK(!layout_coordinator_) << "Can't interleave Layout and ComputeMinAndMaxContentSizes"; + + NGConstraintSpace* constraint_space = + NGConstraintSpaceBuilder( + FromPlatformWritingMode(Style()->getWritingMode())) + .SetTextDirection(Style()->direction()) + .ToConstraintSpace(); + if (!minmax_algorithm_) { - NGConstraintSpaceBuilder builder( - FromPlatformWritingMode(Style()->getWritingMode())); - - builder.SetAvailableSize(NGLogicalSize(LayoutUnit(), LayoutUnit())); - builder.SetPercentageResolutionSize( - NGLogicalSize(LayoutUnit(), LayoutUnit())); - NGConstraintSpace* constraint_space = - NGConstraintSpaceBuilder( - FromPlatformWritingMode(Style()->getWritingMode())) - .SetTextDirection(Style()->direction()) - .ToConstraintSpace(); - minmax_algorithm_ = new NGBlockLayoutAlgorithm( Style(), toNGBlockNode(FirstChild()), constraint_space); } @@ -122,9 +123,12 @@ // TODO(cbiesinger): Replace the loops below with a state machine like in // Layout. + NGLayoutCoordinator* minmax_coordinator = + new NGLayoutCoordinator(this, constraint_space); + // Have to synthesize this value. NGPhysicalFragmentBase* physical_fragment; - while (!minmax_algorithm_->Layout(nullptr, &physical_fragment, nullptr)) + while (!minmax_coordinator->Tick(&physical_fragment)) continue; NGFragment* fragment = new NGFragment( FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), @@ -133,7 +137,7 @@ sizes->min_content = fragment->InlineOverflow(); // Now, redo with infinite space for max_content - NGConstraintSpace* constraint_space = + constraint_space = NGConstraintSpaceBuilder( FromPlatformWritingMode(Style()->getWritingMode())) .SetTextDirection(Style()->direction()) @@ -141,9 +145,8 @@ .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) .ToConstraintSpace(); - minmax_algorithm_ = new NGBlockLayoutAlgorithm( - Style(), toNGBlockNode(FirstChild()), constraint_space); - while (!minmax_algorithm_->Layout(nullptr, &physical_fragment, nullptr)) + minmax_coordinator = new NGLayoutCoordinator(this, constraint_space); + while (!minmax_coordinator->Tick(&physical_fragment)) continue; fragment = new NGFragment(FromPlatformWritingMode(Style()->getWritingMode()),
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h index d23ea7b..49513cd 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -57,6 +57,13 @@ DECLARE_VIRTUAL_TRACE(); + // Runs layout on layout_box_ and creates a fragment for the resulting + // geometry. + NGPhysicalFragment* RunOldLayout(const NGConstraintSpace&); + + void UpdateLayoutBox(NGPhysicalFragment* fragment, + const NGConstraintSpace* constraint_space); + private: // This is necessary for interop between old and new trees -- after our parent // positions us, it calls this function so we can store the position on the @@ -70,10 +77,6 @@ // data to the layout box. void CopyFragmentDataToLayoutBox(const NGConstraintSpace&); - // Runs layout on layout_box_ and creates a fragment for the resulting - // geometry. - NGPhysicalFragment* RunOldLayout(const NGConstraintSpace&); - // We can either wrap a layout_box_ or a style_/next_sibling_/first_child_ // combination. LayoutBox* layout_box_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc index 1cbd272..55c3995 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
@@ -18,7 +18,8 @@ NGInlineNode* first_child, NGConstraintSpace* constraint_space, NGBreakToken* break_token) - : style_(style), + : NGLayoutAlgorithm(kInlineLayoutAlgorithm), + style_(style), first_child_(first_child), constraint_space_(constraint_space), break_token_(break_token) { @@ -26,7 +27,7 @@ } NGLayoutStatus NGInlineLayoutAlgorithm::Layout( - NGFragmentBase*, + NGPhysicalFragmentBase*, NGPhysicalFragmentBase** fragment_out, NGLayoutAlgorithm**) { NGFragmentBuilder builder(NGPhysicalFragmentBase::kFragmentBox);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h index 31589fe2..eb96187 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h
@@ -35,7 +35,7 @@ NGConstraintSpace* space, NGBreakToken* break_token = nullptr); - NGLayoutStatus Layout(NGFragmentBase*, + NGLayoutStatus Layout(NGPhysicalFragmentBase*, NGPhysicalFragmentBase**, NGLayoutAlgorithm**) override;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h index 9c1e9b3..e90fcb57 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h
@@ -15,18 +15,24 @@ struct MinAndMaxContentSizes; class NGBlockNode; class NGConstraintSpace; -class NGFragmentBase; class NGPhysicalFragmentBase; enum NGLayoutStatus { kNotFinished, kChildAlgorithmRequired, kNewFragment }; +enum NGLayoutAlgorithmType { + kBlockLayoutAlgorithm, + kInlineLayoutAlgorithm, + kLegacyBlockLayoutAlgorithm, + kTextLayoutAlgorithm +}; + // Base class for all LayoutNG algorithms. class CORE_EXPORT NGLayoutAlgorithm : public GarbageCollectedFinalized<NGLayoutAlgorithm> { WTF_MAKE_NONCOPYABLE(NGLayoutAlgorithm); public: - NGLayoutAlgorithm() {} + NGLayoutAlgorithm(NGLayoutAlgorithmType type) : type_(type) {} virtual ~NGLayoutAlgorithm() {} // Actual layout function. Lays out the children and descendents within the @@ -39,7 +45,7 @@ // be set with the NGBlockNode that needs to be layed out next. // If it returns NewFragment, the NGPhysicalFragmentBase out parameter // will contain the new fragment. - virtual NGLayoutStatus Layout(NGFragmentBase*, + virtual NGLayoutStatus Layout(NGPhysicalFragmentBase*, NGPhysicalFragmentBase**, NGLayoutAlgorithm**) = 0; @@ -58,6 +64,11 @@ } DEFINE_INLINE_VIRTUAL_TRACE() {} + + NGLayoutAlgorithmType algorithmType() const { return type_; } + + private: + NGLayoutAlgorithmType type_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc index 15adc8a..3876200 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc
@@ -5,6 +5,7 @@ #include "core/layout/ng/ng_layout_coordinator.h" #include "core/layout/ng/ng_layout_input_node.h" +#include "core/layout/ng/ng_physical_fragment_base.h" namespace blink { @@ -15,20 +16,28 @@ NGLayoutInputNode::AlgorithmForInputNode(input_node, constraint_space)); } -bool NGLayoutCoordinator::Tick(NGPhysicalFragmentBase** fragment) { +bool NGLayoutCoordinator::Tick(NGPhysicalFragmentBase** out_fragment) { NGLayoutAlgorithm* child_algorithm; // Tick should never be called without a layout algorithm on the stack. DCHECK(layout_algorithms_.size()); - // TODO(layout-dev): store box from last tick and pass it into Layout here. - switch ( - layout_algorithms_.back()->Layout(nullptr, fragment, &child_algorithm)) { + NGPhysicalFragmentBase* fragment; + NGPhysicalFragmentBase* in_fragment = fragment_; + fragment_ = nullptr; + + switch (layout_algorithms_.back()->Layout(in_fragment, &fragment, + &child_algorithm)) { case kNotFinished: return false; case kNewFragment: layout_algorithms_.pop_back(); - return (layout_algorithms_.size() == 0); + if (layout_algorithms_.size() == 0) { + *out_fragment = fragment; + return true; + } + fragment_ = fragment; + return false; case kChildAlgorithmRequired: layout_algorithms_.append(child_algorithm); return false; @@ -40,5 +49,6 @@ DEFINE_TRACE(NGLayoutCoordinator) { visitor->trace(layout_algorithms_); + visitor->trace(fragment_); } }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.h index b4f8628e..6926e1d 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.h
@@ -24,8 +24,14 @@ DECLARE_TRACE() + const HeapVector<Member<NGLayoutAlgorithm>>& GetAlgorithmStackForTesting() + const { + return layout_algorithms_; + }; + private: HeapVector<Member<NGLayoutAlgorithm>> layout_algorithms_; + Member<NGPhysicalFragmentBase> fragment_; }; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc index 71273e9d..6a0798d 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc
@@ -10,6 +10,7 @@ #include "core/layout/ng/ng_inline_node.h" #include "core/layout/ng/ng_inline_layout_algorithm.h" #include "core/layout/ng/ng_layout_algorithm.h" +#include "core/layout/ng/ng_legacy_block_layout_algorithm.h" #include "core/style/ComputedStyle.h" namespace blink { @@ -23,12 +24,16 @@ DCHECK(input_node->Type() == kLegacyBlock); NGBlockNode* block = toNGBlockNode(input_node); - if (block->HasInlineChildren()) - return new NGInlineLayoutAlgorithm( - block->Style(), toNGInlineNode(block->FirstChild()), + if (block->CanUseNewLayout()) { + if (block->HasInlineChildren()) + return new NGInlineLayoutAlgorithm( + block->Style(), toNGInlineNode(block->FirstChild()), + constraint_space->ChildSpace(block->Style())); + return new NGBlockLayoutAlgorithm( + block->Style(), toNGBlockNode(block->FirstChild()), constraint_space->ChildSpace(block->Style())); - return new NGBlockLayoutAlgorithm( - block->Style(), toNGBlockNode(block->FirstChild()), - constraint_space->ChildSpace(block->Style())); + } + + return new NGLegacyBlockLayoutAlgorithm(block, constraint_space); } }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_legacy_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_legacy_block_layout_algorithm.cc new file mode 100644 index 0000000..015213d --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_legacy_block_layout_algorithm.cc
@@ -0,0 +1,31 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/layout/ng/ng_legacy_block_layout_algorithm.h" + +#include "core/layout/ng/ng_physical_fragment.h" + +namespace blink { + +NGLegacyBlockLayoutAlgorithm::NGLegacyBlockLayoutAlgorithm( + NGBlockNode* block, + const NGConstraintSpace* constraint_space) + : NGLayoutAlgorithm(kLegacyBlockLayoutAlgorithm), + block_(block), + constraint_space_(constraint_space) {} + +NGLayoutStatus NGLegacyBlockLayoutAlgorithm::Layout( + NGPhysicalFragmentBase*, + NGPhysicalFragmentBase** fragment_out, + NGLayoutAlgorithm**) { + *fragment_out = block_->RunOldLayout(*constraint_space_); + return kNewFragment; +} + +DEFINE_TRACE(NGLegacyBlockLayoutAlgorithm) { + NGLayoutAlgorithm::trace(visitor); + visitor->trace(block_); + visitor->trace(constraint_space_); +} +}
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_legacy_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_legacy_block_layout_algorithm.h new file mode 100644 index 0000000..c0147c1 --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_legacy_block_layout_algorithm.h
@@ -0,0 +1,34 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NGLegacyBlockLayoutAlgorithm_h +#define NGLegacyBlockLayoutAlgorithm_h + +#include "core/CoreExport.h" +#include "core/layout/ng/ng_block_node.h" +#include "core/layout/ng/ng_constraint_space.h" +#include "core/layout/ng/ng_layout_algorithm.h" +#include "wtf/RefPtr.h" + +namespace blink { + +// A class for legacy block layout (blocks that can't be handled by NG yet). +// Defers to the old layout method of the block +class CORE_EXPORT NGLegacyBlockLayoutAlgorithm : public NGLayoutAlgorithm { + public: + NGLegacyBlockLayoutAlgorithm(NGBlockNode*, const NGConstraintSpace*); + + NGLayoutStatus Layout(NGPhysicalFragmentBase*, + NGPhysicalFragmentBase**, + NGLayoutAlgorithm**) override; + + DECLARE_VIRTUAL_TRACE(); + + private: + Member<NGBlockNode> block_; + Member<const NGConstraintSpace> constraint_space_; +}; +} + +#endif // NGLegacyBlockLayoutAlgorithm_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc index 4de2cda..f72caec 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc
@@ -14,14 +14,15 @@ NGInlineNode* inline_box, NGConstraintSpace* constraint_space, NGBreakToken* break_token) - : inline_box_(inline_box), + : NGLayoutAlgorithm(kTextLayoutAlgorithm), + inline_box_(inline_box), constraint_space_(constraint_space), break_token_(break_token) { DCHECK(inline_box_); } NGLayoutStatus NGTextLayoutAlgorithm::Layout( - NGFragmentBase*, + NGPhysicalFragmentBase*, NGPhysicalFragmentBase** fragment_out, NGLayoutAlgorithm**) { // TODO(layout-dev): implement.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h index 2150df5..c286ffb 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h
@@ -30,7 +30,7 @@ NGConstraintSpace* space, NGBreakToken* break_token = nullptr); - NGLayoutStatus Layout(NGFragmentBase*, + NGLayoutStatus Layout(NGPhysicalFragmentBase*, NGPhysicalFragmentBase**, NGLayoutAlgorithm**) override;
diff --git a/third_party/WebKit/Source/core/svg/SVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGElement.cpp index 6c7113ac..41faa266 100644 --- a/third_party/WebKit/Source/core/svg/SVGElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGElement.cpp
@@ -33,6 +33,7 @@ #include "core/animation/ElementAnimations.h" #include "core/animation/InterpolationEnvironment.h" #include "core/animation/InvalidatableInterpolation.h" +#include "core/animation/SVGInterpolationTypesMap.h" #include "core/css/CSSCursorImageValue.h" #include "core/css/resolver/StyleResolver.h" #include "core/dom/Document.h" @@ -234,8 +235,9 @@ KeyframeEffectReadOnly::DefaultPriority, isSVGAttributeHandle); for (auto& entry : activeInterpolationsMap) { const QualifiedName& attribute = entry.key.svgAttribute(); + SVGInterpolationTypesMap map; InterpolationEnvironment environment( - *this, propertyFromAttribute(attribute)->baseValueBase()); + map, *this, propertyFromAttribute(attribute)->baseValueBase()); InvalidatableInterpolation::applyStack(entry.value, environment); } svgRareData()->setWebAnimatedAttributesDirty(false);
diff --git a/third_party/WebKit/Source/core/workers/BUILD.gn b/third_party/WebKit/Source/core/workers/BUILD.gn index db516ceb..073e6975 100644 --- a/third_party/WebKit/Source/core/workers/BUILD.gn +++ b/third_party/WebKit/Source/core/workers/BUILD.gn
@@ -35,6 +35,8 @@ "SharedWorkerThread.h", "ThreadedMessagingProxyBase.cpp", "ThreadedMessagingProxyBase.h", + "ThreadedObjectProxyBase.cpp", + "ThreadedObjectProxyBase.h", "ThreadedWorkletGlobalScope.cpp", "ThreadedWorkletGlobalScope.h", "ThreadedWorkletMessagingProxy.cpp",
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.cpp b/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.cpp index 720bd9d..0a5aa09 100644 --- a/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.cpp +++ b/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.cpp
@@ -97,6 +97,8 @@ } void InProcessWorkerObjectProxy::countFeature(UseCounter::Feature feature) { + // TODO(nhiroki): Move this to ThreadedObjectProxyBase so that + // ThreadedWorklets can record API use (https://crbug.com/667357). getParentFrameTaskRunners() ->get(TaskType::Internal) ->postTask(BLINK_FROM_HERE, @@ -105,6 +107,8 @@ } void InProcessWorkerObjectProxy::countDeprecation(UseCounter::Feature feature) { + // TODO(nhiroki): Move this to ThreadedObjectProxyBase so that + // ThreadedWorklets can record API use (https://crbug.com/667357). getParentFrameTaskRunners() ->get(TaskType::Internal) ->postTask( @@ -126,37 +130,6 @@ WTF::passed(location->clone()), exceptionId)); } -void InProcessWorkerObjectProxy::reportConsoleMessage( - MessageSource source, - MessageLevel level, - const String& message, - SourceLocation* location) { - getParentFrameTaskRunners() - ->get(TaskType::Internal) - ->postTask( - BLINK_FROM_HERE, - crossThreadBind(&InProcessWorkerMessagingProxy::reportConsoleMessage, - m_messagingProxyWeakPtr, source, level, message, - WTF::passed(location->clone()))); -} - -void InProcessWorkerObjectProxy::postMessageToPageInspector( - const String& message) { - // The TaskType of Inspector tasks need to be Unthrottled because they need to - // run even on a suspended page. - getParentFrameTaskRunners() - ->get(TaskType::Unthrottled) - ->postTask(BLINK_FROM_HERE, - crossThreadBind( - &InProcessWorkerMessagingProxy::postMessageToPageInspector, - m_messagingProxyWeakPtr, message)); -} - -ParentFrameTaskRunners* -InProcessWorkerObjectProxy::getParentFrameTaskRunners() { - return m_parentFrameTaskRunners.get(); -} - void InProcessWorkerObjectProxy::didCreateWorkerGlobalScope( WorkerOrWorkletGlobalScope* globalScope) { DCHECK(!m_workerGlobalScope); @@ -169,35 +142,16 @@ startPendingActivityTimer(); } -void InProcessWorkerObjectProxy::didCloseWorkerGlobalScope() { - getParentFrameTaskRunners() - ->get(TaskType::Internal) - ->postTask( - BLINK_FROM_HERE, - crossThreadBind(&InProcessWorkerMessagingProxy::terminateGlobalScope, - m_messagingProxyWeakPtr)); -} - void InProcessWorkerObjectProxy::willDestroyWorkerGlobalScope() { m_timer.reset(); m_workerGlobalScope = nullptr; } -void InProcessWorkerObjectProxy::didTerminateWorkerThread() { - // This will terminate the MessagingProxy. - getParentFrameTaskRunners() - ->get(TaskType::Internal) - ->postTask(BLINK_FROM_HERE, - crossThreadBind( - &InProcessWorkerMessagingProxy::workerThreadTerminated, - m_messagingProxyWeakPtr)); -} - InProcessWorkerObjectProxy::InProcessWorkerObjectProxy( const WeakPtr<InProcessWorkerMessagingProxy>& messagingProxyWeakPtr, ParentFrameTaskRunners* parentFrameTaskRunners) - : m_messagingProxyWeakPtr(messagingProxyWeakPtr), - m_parentFrameTaskRunners(parentFrameTaskRunners), + : ThreadedObjectProxyBase(parentFrameTaskRunners), + m_messagingProxyWeakPtr(messagingProxyWeakPtr), m_defaultIntervalInSec(kDefaultIntervalInSec), m_nextIntervalInSec(kDefaultIntervalInSec), m_maxIntervalInSec(kMaxIntervalInSec) {} @@ -224,4 +178,9 @@ startPendingActivityTimer(); } +WeakPtr<ThreadedMessagingProxyBase> +InProcessWorkerObjectProxy::messagingProxyWeakPtr() { + return m_messagingProxyWeakPtr; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.h b/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.h index 280f32f9..1a226509 100644 --- a/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.h +++ b/third_party/WebKit/Source/core/workers/InProcessWorkerObjectProxy.h
@@ -33,6 +33,7 @@ #include "core/CoreExport.h" #include "core/dom/MessagePort.h" +#include "core/workers/ThreadedObjectProxyBase.h" #include "core/workers/WorkerReportingProxy.h" #include "platform/Timer.h" #include "platform/heap/Handle.h" @@ -44,18 +45,16 @@ class InProcessWorkerMessagingProxy; class ParentFrameTaskRunners; +class ThreadedMessagingProxyBase; class WorkerGlobalScope; class WorkerOrWorkletGlobalScope; -// A proxy to talk to the parent worker object. This object is created and -// destroyed on the parent context thread (i.e. usually the main thread), and -// used on the worker thread for proxying messages to the -// InProcessWorkerMessagingProxy on the parent context thread. -// InProcessWorkerMessagingProxy always outlives this proxy. +// A proxy to talk to the parent worker object. See class comments on +// ThreadedObjectProxyBase.h for lifetime of this class etc. // // This also checks pending activities on WorkerGlobalScope and reports a result // to the message proxy when an exponential backoff timer is fired. -class CORE_EXPORT InProcessWorkerObjectProxy : public WorkerReportingProxy { +class CORE_EXPORT InProcessWorkerObjectProxy : public ThreadedObjectProxyBase { USING_FAST_MALLOC(InProcessWorkerObjectProxy); WTF_MAKE_NONCOPYABLE(InProcessWorkerObjectProxy); @@ -70,28 +69,22 @@ void confirmMessageFromWorkerObject(); void startPendingActivityTimer(); - // WorkerReportingProxy overrides. - void countFeature(UseCounter::Feature) override; - void countDeprecation(UseCounter::Feature) override; + // ThreadedMessagingProxyBase overrides. + void countFeature(UseCounter::Feature) final; + void countDeprecation(UseCounter::Feature) final; void reportException(const String& errorMessage, std::unique_ptr<SourceLocation>, int exceptionId) override; - void reportConsoleMessage(MessageSource, - MessageLevel, - const String& message, - SourceLocation*) override; - void postMessageToPageInspector(const String&) override; - ParentFrameTaskRunners* getParentFrameTaskRunners() override; void didCreateWorkerGlobalScope(WorkerOrWorkletGlobalScope*) override; void didEvaluateWorkerScript(bool success) override; - void didCloseWorkerGlobalScope() override; void willDestroyWorkerGlobalScope() override; - void didTerminateWorkerThread() override; protected: InProcessWorkerObjectProxy(const WeakPtr<InProcessWorkerMessagingProxy>&, ParentFrameTaskRunners*); + WeakPtr<ThreadedMessagingProxyBase> messagingProxyWeakPtr() final; + private: friend class InProcessWorkerMessagingProxyForTest; @@ -102,10 +95,6 @@ // the tasks. WeakPtr<InProcessWorkerMessagingProxy> m_messagingProxyWeakPtr; - // Used to post a task to InProcessWorkerMessagingProxy on the parent context - // thread. - CrossThreadPersistent<ParentFrameTaskRunners> m_parentFrameTaskRunners; - // Used for checking pending activities on the worker global scope. This is // cancelled when the worker global scope is destroyed. std::unique_ptr<Timer<InProcessWorkerObjectProxy>> m_timer;
diff --git a/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.cpp b/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.cpp new file mode 100644 index 0000000..29b67952e --- /dev/null +++ b/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.cpp
@@ -0,0 +1,71 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/workers/ThreadedObjectProxyBase.h" + +#include "core/dom/ExecutionContext.h" +#include "core/inspector/ConsoleMessage.h" +#include "core/workers/ParentFrameTaskRunners.h" +#include "core/workers/ThreadedMessagingProxyBase.h" +#include "platform/CrossThreadFunctional.h" +#include "platform/WebTaskRunner.h" +#include "wtf/Functional.h" +#include "wtf/PtrUtil.h" +#include <memory> + +namespace blink { + +void ThreadedObjectProxyBase::reportConsoleMessage(MessageSource source, + MessageLevel level, + const String& message, + SourceLocation* location) { + getParentFrameTaskRunners() + ->get(TaskType::Internal) + ->postTask( + BLINK_FROM_HERE, + crossThreadBind(&ThreadedMessagingProxyBase::reportConsoleMessage, + messagingProxyWeakPtr(), source, level, message, + WTF::passed(location->clone()))); +} + +void ThreadedObjectProxyBase::postMessageToPageInspector( + const String& message) { + // The TaskType of Inspector tasks need to be Unthrottled because they need to + // run even on a suspended page. + getParentFrameTaskRunners() + ->get(TaskType::Unthrottled) + ->postTask(BLINK_FROM_HERE, + crossThreadBind( + &ThreadedMessagingProxyBase::postMessageToPageInspector, + messagingProxyWeakPtr(), message)); +} + +ParentFrameTaskRunners* ThreadedObjectProxyBase::getParentFrameTaskRunners() { + return m_parentFrameTaskRunners.get(); +} + +void ThreadedObjectProxyBase::didCloseWorkerGlobalScope() { + getParentFrameTaskRunners() + ->get(TaskType::Internal) + ->postTask( + BLINK_FROM_HERE, + crossThreadBind(&ThreadedMessagingProxyBase::terminateGlobalScope, + messagingProxyWeakPtr())); +} + +void ThreadedObjectProxyBase::didTerminateWorkerThread() { + // This will terminate the MessagingProxy. + getParentFrameTaskRunners() + ->get(TaskType::Internal) + ->postTask( + BLINK_FROM_HERE, + crossThreadBind(&ThreadedMessagingProxyBase::workerThreadTerminated, + messagingProxyWeakPtr())); +} + +ThreadedObjectProxyBase::ThreadedObjectProxyBase( + ParentFrameTaskRunners* parentFrameTaskRunners) + : m_parentFrameTaskRunners(parentFrameTaskRunners) {} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.h b/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.h new file mode 100644 index 0000000..9bc7176 --- /dev/null +++ b/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.h
@@ -0,0 +1,54 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ThreadedObjectProxyBase_h +#define ThreadedObjectProxyBase_h + +#include "bindings/core/v8/SourceLocation.h" +#include "core/CoreExport.h" +#include "core/dom/MessagePort.h" +#include "core/workers/WorkerReportingProxy.h" + +namespace blink { + +class ThreadedMessagingProxyBase; + +// A proxy to talk to the parent object. This object is created and destroyed on +// the main thread, and used on the worker thread for proxying messages to the +// ThreadedMessagingProxyBase on the main thread. ThreadedMessagingProxyBase +// always outlives this proxy. +class CORE_EXPORT ThreadedObjectProxyBase : public WorkerReportingProxy { + USING_FAST_MALLOC(ThreadedObjectProxyBase); + WTF_MAKE_NONCOPYABLE(ThreadedObjectProxyBase); + + public: + ~ThreadedObjectProxyBase() override = default; + + void reportPendingActivity(bool hasPendingActivity); + + // WorkerReportingProxy overrides. + void countFeature(UseCounter::Feature) override{}; + void countDeprecation(UseCounter::Feature) override{}; + void reportConsoleMessage(MessageSource, + MessageLevel, + const String& message, + SourceLocation*) override; + void postMessageToPageInspector(const String&) override; + ParentFrameTaskRunners* getParentFrameTaskRunners() override; + void didCloseWorkerGlobalScope() override; + void didTerminateWorkerThread() override; + + protected: + explicit ThreadedObjectProxyBase(ParentFrameTaskRunners*); + virtual WeakPtr<ThreadedMessagingProxyBase> messagingProxyWeakPtr() = 0; + + private: + // Used to post a task to ThreadedMessagingProxyBase on the parent context + // thread. + CrossThreadPersistent<ParentFrameTaskRunners> m_parentFrameTaskRunners; +}; + +} // namespace blink + +#endif // ThreadedObjectProxyBase_h
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.cpp index b2b3a03..4bee693 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.cpp +++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.cpp
@@ -4,13 +4,7 @@ #include "core/workers/ThreadedWorkletObjectProxy.h" -#include "core/dom/ExecutionContext.h" -#include "core/inspector/ConsoleMessage.h" -#include "core/workers/ParentFrameTaskRunners.h" #include "core/workers/ThreadedWorkletMessagingProxy.h" -#include "platform/CrossThreadFunctional.h" -#include "platform/WebTaskRunner.h" -#include "wtf/Functional.h" #include "wtf/PtrUtil.h" #include <memory> @@ -28,73 +22,15 @@ DCHECK(m_messagingProxyWeakPtr); } -void ThreadedWorkletObjectProxy::countFeature(UseCounter::Feature) { - // TODO(nhiroki): Support UseCounter for ThreadedWorklets. We could do the - // same thing with InProcessWorkerObjectProxy here. - // (https://crbug.com/376039) -} - -void ThreadedWorkletObjectProxy::countDeprecation(UseCounter::Feature) { - // TODO(nhiroki): Support UseCounter for ThreadedWorklets. We could do the - // same thing with InProcessWorkerObjectProxy here. - // (https://crbug.com/376039) -} - -void ThreadedWorkletObjectProxy::reportConsoleMessage( - MessageSource source, - MessageLevel level, - const String& message, - SourceLocation* location) { - getParentFrameTaskRunners() - ->get(TaskType::Internal) - ->postTask( - BLINK_FROM_HERE, - crossThreadBind(&ThreadedWorkletMessagingProxy::reportConsoleMessage, - m_messagingProxyWeakPtr, source, level, message, - WTF::passed(location->clone()))); -} - -void ThreadedWorkletObjectProxy::postMessageToPageInspector( - const String& message) { - DCHECK(m_messagingProxyWeakPtr->getExecutionContext()->isDocument()); - // The TaskType of Inspector tasks need to be Unthrottled because they need to - // run even on a suspended page. - getParentFrameTaskRunners() - ->get(TaskType::Unthrottled) - ->postTask(BLINK_FROM_HERE, - crossThreadBind( - &ThreadedWorkletMessagingProxy::postMessageToPageInspector, - m_messagingProxyWeakPtr, message)); -} - -ParentFrameTaskRunners* -ThreadedWorkletObjectProxy::getParentFrameTaskRunners() { - return m_parentFrameTaskRunners.get(); -} - -void ThreadedWorkletObjectProxy::didCloseWorkerGlobalScope() { - getParentFrameTaskRunners() - ->get(TaskType::Internal) - ->postTask( - BLINK_FROM_HERE, - crossThreadBind(&ThreadedWorkletMessagingProxy::terminateGlobalScope, - m_messagingProxyWeakPtr)); -} - -void ThreadedWorkletObjectProxy::didTerminateWorkerThread() { - // This will terminate the MessagingProxy. - getParentFrameTaskRunners() - ->get(TaskType::Internal) - ->postTask(BLINK_FROM_HERE, - crossThreadBind( - &ThreadedWorkletMessagingProxy::workerThreadTerminated, - m_messagingProxyWeakPtr)); -} - ThreadedWorkletObjectProxy::ThreadedWorkletObjectProxy( const WeakPtr<ThreadedWorkletMessagingProxy>& messagingProxyWeakPtr, ParentFrameTaskRunners* parentFrameTaskRunners) - : m_messagingProxyWeakPtr(messagingProxyWeakPtr), - m_parentFrameTaskRunners(parentFrameTaskRunners) {} + : ThreadedObjectProxyBase(parentFrameTaskRunners), + m_messagingProxyWeakPtr(messagingProxyWeakPtr) {} + +WeakPtr<ThreadedMessagingProxyBase> +ThreadedWorkletObjectProxy::messagingProxyWeakPtr() { + return m_messagingProxyWeakPtr; +} } // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h index 4c04c47..78bbe629 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h +++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h
@@ -8,17 +8,16 @@ #include "bindings/core/v8/SourceLocation.h" #include "core/CoreExport.h" #include "core/dom/MessagePort.h" +#include "core/workers/ThreadedObjectProxyBase.h" #include "core/workers/WorkerReportingProxy.h" namespace blink { class ThreadedWorkletMessagingProxy; -// A proxy to talk to the parent worklet object. This object is created and -// destroyed on the main thread, and used on the worklet thread for proxying -// messages to the ThreadedWorkletMessagingProxy on the main thread. -// ThreadedWorkletMessagingProxy always outlives this proxy. -class CORE_EXPORT ThreadedWorkletObjectProxy : public WorkerReportingProxy { +// A proxy to talk to the parent worker object. See class comments on +// ThreadedObjectProxyBase.h for lifetime of this class etc. +class CORE_EXPORT ThreadedWorkletObjectProxy : public ThreadedObjectProxyBase { USING_FAST_MALLOC(ThreadedWorkletObjectProxy); WTF_MAKE_NONCOPYABLE(ThreadedWorkletObjectProxy); @@ -30,36 +29,24 @@ void reportPendingActivity(bool hasPendingActivity); - // WorkerReportingProxy overrides. - void countFeature(UseCounter::Feature) override; - void countDeprecation(UseCounter::Feature) override; + // ThreadedObjectProxyBase overrides. void reportException(const String& errorMessage, std::unique_ptr<SourceLocation>, - int exceptionId) override {} - void reportConsoleMessage(MessageSource, - MessageLevel, - const String& message, - SourceLocation*) override; - void postMessageToPageInspector(const String&) override; - ParentFrameTaskRunners* getParentFrameTaskRunners() override; - void didEvaluateWorkerScript(bool success) override {} - void didCloseWorkerGlobalScope() override; - void willDestroyWorkerGlobalScope() override {} - void didTerminateWorkerThread() override; + int exceptionId) final {} + void didEvaluateWorkerScript(bool success) final {} + void willDestroyWorkerGlobalScope() final {} protected: ThreadedWorkletObjectProxy(const WeakPtr<ThreadedWorkletMessagingProxy>&, ParentFrameTaskRunners*); + WeakPtr<ThreadedMessagingProxyBase> messagingProxyWeakPtr() final; + private: // No guarantees about the lifetimes of tasks posted by this proxy wrt the // ThreadedWorkletMessagingProxy so a weak pointer must be used when posting // the tasks. WeakPtr<ThreadedWorkletMessagingProxy> m_messagingProxyWeakPtr; - - // Used to post a task to ThreadedWorkletMessagingProxy on the parent context - // thread. - CrossThreadPersistent<ParentFrameTaskRunners> m_parentFrameTaskRunners; }; } // namespace blink
diff --git a/third_party/WebKit/Source/devtools/front_end/Tests.js b/third_party/WebKit/Source/devtools/front_end/Tests.js index 74afd920..62714a8 100644 --- a/third_party/WebKit/Source/devtools/front_end/Tests.js +++ b/third_party/WebKit/Source/devtools/front_end/Tests.js
@@ -871,6 +871,12 @@ Bindings.TempFile.ensureTempStorageCleared().then(() => this.releaseControl()); }; + TestSuite.prototype.testTempFile = function() { + this.takeControl(); + Bindings.TempFile.create('test-file', 'test') + .then(() => this.releaseControl(), (error) => this.fail(String(error))); + }; + TestSuite.prototype.waitForTestResultsInConsole = function() { var messages = SDK.multitargetConsoleModel.messages(); for (var i = 0; i < messages.length; ++i) {
diff --git a/third_party/WebKit/Source/web/TextFinder.cpp b/third_party/WebKit/Source/web/TextFinder.cpp index 9f8410f7f..6bdd96d 100644 --- a/third_party/WebKit/Source/web/TextFinder.cpp +++ b/third_party/WebKit/Source/web/TextFinder.cpp
@@ -379,7 +379,7 @@ m_currentActiveMatchFrame = true; foundActiveMatch = true; // We also know which tickmark is active now. - m_activeMatchIndex = matchCount - 1; + m_activeMatchIndex = m_totalMatchCount + matchCount - 1; // To stop looking for the active tickmark, we set this flag. m_locatingActiveRect = false;
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index d473c31..3d209f9 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -5004,6 +5004,88 @@ EXPECT_FALSE(activeNow); } +struct FakeTimerSetter { + FakeTimerSetter() { + s_timeElapsed = 0.0; + m_originalTimeFunction = setTimeFunctionsForTesting(returnMockTime); + } + + ~FakeTimerSetter() { setTimeFunctionsForTesting(m_originalTimeFunction); } + static double returnMockTime() { + s_timeElapsed += 1.0; + return s_timeElapsed; + } + + private: + TimeFunction m_originalTimeFunction; + static double s_timeElapsed; +}; +double FakeTimerSetter::s_timeElapsed = 0.; + +TEST_P(ParameterizedWebFrameTest, FindInPageJavaScriptUpdatesDOMProperOrdinal) { + FakeTimerSetter fakeTimer; + + const WebString searchPattern = WebString::fromUTF8("abc"); + // We have 2 occurrences of the pattern in our text. + const char* html = + "foo bar foo bar foo abc bar foo bar foo bar foo bar foo bar foo bar foo " + "bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo " + "bar foo bar foo abc bar <div id='new_text'></div>"; + + FindUpdateWebFrameClient client; + FrameTestHelpers::WebViewHelper webViewHelper; + webViewHelper.initialize(true, &client); + + WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl(); + FrameTestHelpers::loadHTMLString(frame, html, + URLTestHelpers::toKURL(m_baseURL)); + webViewHelper.resize(WebSize(640, 480)); + webViewHelper.webView()->setFocus(true); + runPendingTasks(); + + const int findIdentifier = 12345; + WebFindOptions options; + + // The first search that will start the scoping process. + frame->requestFind(findIdentifier, searchPattern, options); + EXPECT_FALSE(client.findResultsAreReady()); + EXPECT_EQ(1, client.count()); + EXPECT_TRUE(frame->ensureTextFinder().scopingInProgress()); + + // The scoping won't find all the entries on the first run due to the fake + // timer. + while (frame->ensureTextFinder().scopingInProgress()) + runPendingTasks(); + + EXPECT_EQ(2, client.count()); + EXPECT_EQ(1, client.activeIndex()); + + options.findNext = true; + + // The second search will jump to the next match without any scoping. + frame->requestFind(findIdentifier, searchPattern, options); + + EXPECT_EQ(2, client.count()); + EXPECT_EQ(2, client.activeIndex()); + EXPECT_FALSE(frame->ensureTextFinder().scopingInProgress()); + + // Insert new text, which contains occurence of |searchText|. + frame->executeScript( + WebScriptSource("var textDiv = document.getElementById('new_text');" + "textDiv.innerHTML = 'foo abc';")); + + // The third search will find a new match and initiate a new scoping. + frame->requestFind(findIdentifier, searchPattern, options); + + EXPECT_TRUE(frame->ensureTextFinder().scopingInProgress()); + + while (frame->ensureTextFinder().scopingInProgress()) + runPendingTasks(); + + EXPECT_EQ(3, client.count()); + EXPECT_EQ(3, client.activeIndex()); +} + static WebPoint topLeft(const WebRect& rect) { return WebPoint(rect.x, rect.y); }
diff --git a/third_party/WebKit/Source/wtf/BUILD.gn b/third_party/WebKit/Source/wtf/BUILD.gn index f1b449d..11fccb12 100644 --- a/third_party/WebKit/Source/wtf/BUILD.gn +++ b/third_party/WebKit/Source/wtf/BUILD.gn
@@ -334,6 +334,7 @@ "text/StringBuilderTest.cpp", "text/StringImplTest.cpp", "text/StringOperatorsTest.cpp", + "text/StringToNumberTest.cpp", "text/StringViewTest.cpp", "text/TextCodecICUTest.cpp", "text/TextCodecLatin1Test.cpp",
diff --git a/third_party/WebKit/Source/wtf/StdLibExtras.h b/third_party/WebKit/Source/wtf/StdLibExtras.h index 885f9dd..454e1a18 100644 --- a/third_party/WebKit/Source/wtf/StdLibExtras.h +++ b/third_party/WebKit/Source/wtf/StdLibExtras.h
@@ -33,7 +33,7 @@ #include "wtf/TypeTraits.h" #include <cstddef> -#if ENABLE(ASSERT) +#if DCHECK_IS_ON() #include "wtf/Noncopyable.h" #include "wtf/Threading.h" @@ -90,7 +90,7 @@ } }; -#if ENABLE(ASSERT) +#if DCHECK_IS_ON() #define DEFINE_STATIC_LOCAL_CHECK_THREADSAFE_ACCESS(Name) \ static StaticLocalVerifier Name##StaticLocalVerifier; \ ASSERT(Name##StaticLocalVerifier.isNotRacy())
diff --git a/third_party/WebKit/Source/wtf/text/StringToNumber.cpp b/third_party/WebKit/Source/wtf/text/StringToNumber.cpp index 9fa2ff5a..423bf68 100644 --- a/third_party/WebKit/Source/wtf/text/StringToNumber.cpp +++ b/third_party/WebKit/Source/wtf/text/StringToNumber.cpp
@@ -7,6 +7,7 @@ #include "wtf/ASCIICType.h" #include "wtf/dtoa.h" #include "wtf/text/StringImpl.h" +#include <type_traits> namespace WTF { @@ -29,10 +30,13 @@ size_t length, bool* ok, int base) { - static const IntegralType integralMax = + static_assert(std::is_integral<IntegralType>::value, + "IntegralType must be an integral type."); + static constexpr IntegralType integralMax = std::numeric_limits<IntegralType>::max(); - static const bool isSigned = std::numeric_limits<IntegralType>::is_signed; - const IntegralType maxMultiplier = integralMax / base; + static constexpr IntegralType integralMin = + std::numeric_limits<IntegralType>::min(); + static constexpr bool isSigned = std::numeric_limits<IntegralType>::is_signed; IntegralType value = 0; bool isOk = false; @@ -70,27 +74,31 @@ else digitValue = c - 'A' + 10; - if (value > maxMultiplier || - (value == maxMultiplier && - digitValue > (integralMax % base) + isNegative)) + bool overflow; + if (isNegative) { + // Overflow condition: + // value * base - digitValue < integralMin + // <=> value < (integralMin + digitValue) / base + // We must be careful of rounding errors here, but the default rounding + // mode (round to zero) works well, so we can use this formula as-is. + overflow = value < (integralMin + digitValue) / base; + } else { + // Overflow condition: + // value * base + digitValue > integralMax + // <=> value > (integralMax + digitValue) / base + // Ditto regarding rounding errors. + overflow = value > (integralMax - digitValue) / base; + } + if (overflow) goto bye; - value = base * value + digitValue; + if (isNegative) + value = base * value - digitValue; + else + value = base * value + digitValue; ++data; } -#if COMPILER(MSVC) -#pragma warning(push, 0) -#pragma warning(disable : 4146) -#endif - - if (isNegative) - value = -value; - -#if COMPILER(MSVC) -#pragma warning(pop) -#endif - // skip trailing space while (length && isSpaceOrNewline(*data)) { --length;
diff --git a/third_party/WebKit/Source/wtf/text/StringToNumberTest.cpp b/third_party/WebKit/Source/wtf/text/StringToNumberTest.cpp new file mode 100644 index 0000000..429147c --- /dev/null +++ b/third_party/WebKit/Source/wtf/text/StringToNumberTest.cpp
@@ -0,0 +1,126 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "wtf/text/StringToNumber.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include <cstring> + +namespace WTF { + +TEST(StringToNumberTest, TestCharactersToIntStrict) { +#define EXPECT_VALID(string, expectedValue, base) \ + do { \ + bool ok; \ + int value = charactersToIntStrict(reinterpret_cast<const LChar*>(string), \ + std::strlen(string), &ok, base); \ + EXPECT_TRUE(ok); \ + EXPECT_EQ(value, expectedValue); \ + } while (false) + +#define EXPECT_INVALID(string, base) \ + do { \ + bool ok; \ + charactersToIntStrict(reinterpret_cast<const LChar*>(string), \ + std::strlen(string), &ok, base); \ + EXPECT_FALSE(ok); \ + } while (false) + +#define EXPECT_VALID_DECIMAL(string, expectedValue) \ + EXPECT_VALID(string, expectedValue, 10) +#define EXPECT_INVALID_DECIMAL(string) EXPECT_INVALID(string, 10) +#define EXPECT_VALID_HEXADECIMAL(string, expectedValue) \ + EXPECT_VALID(string, expectedValue, 16) +#define EXPECT_INVALID_HEXADECIMAL(string) EXPECT_INVALID(string, 16) + + EXPECT_VALID_DECIMAL("1", 1); + EXPECT_VALID_DECIMAL("2", 2); + EXPECT_VALID_DECIMAL("9", 9); + EXPECT_VALID_DECIMAL("10", 10); + EXPECT_VALID_DECIMAL("0", 0); + EXPECT_VALID_DECIMAL("-0", 0); + EXPECT_VALID_DECIMAL("-1", -1); + EXPECT_VALID_DECIMAL("-2", -2); + EXPECT_VALID_DECIMAL("-9", -9); + EXPECT_VALID_DECIMAL("-10", -10); + EXPECT_VALID_DECIMAL("+0", 0); + EXPECT_VALID_DECIMAL("+1", 1); + EXPECT_VALID_DECIMAL("+2", 2); + EXPECT_VALID_DECIMAL("+9", 9); + EXPECT_VALID_DECIMAL("+10", 10); + EXPECT_VALID_DECIMAL("00", 0); + EXPECT_VALID_DECIMAL("+00", 0); + EXPECT_VALID_DECIMAL("-00", 0); + EXPECT_VALID_DECIMAL("01", 1); + EXPECT_VALID_DECIMAL("-01", -1); + EXPECT_VALID_DECIMAL("00000000000000000000", 0); + EXPECT_INVALID_DECIMAL("a"); + EXPECT_INVALID_DECIMAL("1a"); + EXPECT_INVALID_DECIMAL("a1"); + EXPECT_INVALID_DECIMAL("-a"); + EXPECT_INVALID_DECIMAL(""); + EXPECT_INVALID_DECIMAL("-"); + EXPECT_INVALID_DECIMAL("--1"); + EXPECT_INVALID_DECIMAL("++1"); + EXPECT_INVALID_DECIMAL("+-1"); + EXPECT_INVALID_DECIMAL("-+1"); + EXPECT_INVALID_DECIMAL("0-"); + EXPECT_INVALID_DECIMAL("0+"); + + EXPECT_VALID_DECIMAL("2147483647", 2147483647); + EXPECT_VALID_DECIMAL("02147483647", 2147483647); + EXPECT_INVALID_DECIMAL("2147483648"); + EXPECT_INVALID_DECIMAL("2147483649"); + EXPECT_INVALID_DECIMAL("2147483650"); + EXPECT_INVALID_DECIMAL("2147483700"); + EXPECT_INVALID_DECIMAL("2147484000"); + EXPECT_INVALID_DECIMAL("2200000000"); + EXPECT_INVALID_DECIMAL("3000000000"); + EXPECT_INVALID_DECIMAL("10000000000"); + EXPECT_VALID_DECIMAL("-2147483647", -2147483647); + EXPECT_VALID_DECIMAL("-2147483648", -2147483647 - 1); + EXPECT_INVALID_DECIMAL("-2147483649"); + EXPECT_INVALID_DECIMAL("-2147483650"); + EXPECT_INVALID_DECIMAL("-2147483700"); + EXPECT_INVALID_DECIMAL("-2147484000"); + EXPECT_INVALID_DECIMAL("-2200000000"); + EXPECT_INVALID_DECIMAL("-3000000000"); + EXPECT_INVALID_DECIMAL("-10000000000"); + + EXPECT_VALID_HEXADECIMAL("1", 1); + EXPECT_VALID_HEXADECIMAL("a", 0xA); + EXPECT_VALID_HEXADECIMAL("A", 0xA); + EXPECT_VALID_HEXADECIMAL("+a", 0xA); + EXPECT_VALID_HEXADECIMAL("+A", 0xA); + EXPECT_VALID_HEXADECIMAL("-a", -0xA); + EXPECT_VALID_HEXADECIMAL("-A", -0xA); + + EXPECT_VALID_HEXADECIMAL("7fffffff", 0x7FFFFFFF); + EXPECT_INVALID_HEXADECIMAL("80000000"); + EXPECT_INVALID_HEXADECIMAL("8000000a"); + EXPECT_INVALID_HEXADECIMAL("8000000f"); + EXPECT_INVALID_HEXADECIMAL("90000000"); + EXPECT_INVALID_HEXADECIMAL("fffffff0"); + EXPECT_INVALID_HEXADECIMAL("ffffffff"); + EXPECT_INVALID_HEXADECIMAL("100000000"); + EXPECT_INVALID_HEXADECIMAL("7fffffff0"); + EXPECT_VALID_HEXADECIMAL("-7fffffff", -0x7FFFFFFF); + EXPECT_VALID_HEXADECIMAL("-80000000", -0x7FFFFFFF - 1); + EXPECT_INVALID_HEXADECIMAL("-80000001"); + EXPECT_INVALID_HEXADECIMAL("-8000000a"); + EXPECT_INVALID_HEXADECIMAL("-8000000f"); + EXPECT_INVALID_HEXADECIMAL("-80000010"); + EXPECT_INVALID_HEXADECIMAL("-90000000"); + EXPECT_INVALID_HEXADECIMAL("-f0000000"); + EXPECT_INVALID_HEXADECIMAL("-fffffff0"); + EXPECT_INVALID_HEXADECIMAL("-ffffffff"); + +#undef EXPECT_VALID_DECIMAL +#undef EXPECT_INVALID_DECIMAL +#undef EXPECT_VALID_HEXADECIMAL +#undef EXPECT_INVALID_HEXADECIMAL +#undef EXPECT_VALID +#undef EXPECT_INVALID +} +}
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 3cf2be53..90f5d6a2 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -234,6 +234,7 @@ 'GPU Win x64 Builder': 'gpu_tests_deqp_gles_release_trybot', 'GPU Win x64 Builder (dbg)': 'gpu_tests_deqp_gles_debug_trybot', 'Linux ChromiumOS Builder': 'gpu_fyi_tests_chromeos_release_trybot', + 'Linux ChromiumOS Ozone Builder': 'gpu_fyi_tests_chromeos_ozone_release_trybot', 'Mac GPU ASAN Release': 'gpu_fyi_tests_release_trybot_asan', }, @@ -1145,6 +1146,10 @@ 'debug_trybot', 'x86', ], + 'gpu_fyi_tests_chromeos_ozone_release_trybot': [ + 'gpu_fyi_tests', 'release_trybot', 'chromeos', 'ozone', + ], + 'gpu_fyi_tests_chromeos_release_trybot': [ 'gpu_fyi_tests', 'release_trybot', 'chromeos', ],