diff --git a/DEPS b/DEPS index bee087b..2df13d7 100644 --- a/DEPS +++ b/DEPS
@@ -43,7 +43,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'ce76b7cd4c1f35fc6d4473a38f27c78e4481aa1d', + 'v8_revision': '20b025f9ca68e822ebcddb515f9300a5b8d995e7', # 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. @@ -87,7 +87,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'eff184407eb183c8f6ec65d74abc4356d466f448', + 'nacl_revision': 'c64289d884a477876419421b1a789e9fab58b940', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling dEQP # and whatever else without interference from each other. @@ -215,7 +215,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '067ab64dbee579393c17e5b80dfd3beffa3f39bf', # commit position 11616 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '4df8757c5f51f8f35d1728dac8bba3edd4a612e5', # commit position 11618 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'), @@ -275,7 +275,7 @@ 'src/third_party/catapult': Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' + - 'e26797f24e90bac9118d1b18195804000da67b51', + 'cd823453c2e0bdb3e1c15e58ef17365eb54d83da', 'src/third_party/openh264/src': Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index e6805756..81b3710 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1602,6 +1602,7 @@ r"^chrome/docs", r"^components/dom_distiller/core/css/distilledpage_ios.css", r"^components/flags_ui/resources/apple_flags.css", + r"^components/neterror/resources/neterror.css", r"^native_client_sdk")) file_filter = lambda f: input_api.FilterSourceFile( f, white_list=file_inclusion_pattern, black_list=black_list)
diff --git a/android_webview/native/state_serializer.cc b/android_webview/native/state_serializer.cc index 65eceb3..398b17e 100644 --- a/android_webview/native/state_serializer.cc +++ b/android_webview/native/state_serializer.cc
@@ -31,10 +31,7 @@ namespace { -// Sanity check value that we are restoring from a valid pickle. -// This can potentially used as an actual serialization version number in the -// future if we ever decide to support restoring from older versions. -const uint32_t AW_STATE_VERSION = 20151204; +const uint32_t AW_STATE_VERSION = internal::AW_STATE_VERSION_DATA_URL; } // namespace @@ -65,7 +62,10 @@ return false; } - // Please update AW_STATE_VERSION if serialization format is changed. + // Please update AW_STATE_VERSION and IsSupportedVersion() if serialization + // format is changed. + // Make sure the serialization format is updated in a backwards compatible + // way. return true; } @@ -75,7 +75,8 @@ DCHECK(iterator); DCHECK(web_contents); - if (!internal::RestoreHeaderFromPickle(iterator)) + uint32_t state_version = internal::RestoreHeaderFromPickle(iterator); + if (!state_version) return false; int entry_count = -1; @@ -98,7 +99,8 @@ entries.reserve(entry_count); for (int i = 0; i < entry_count; ++i) { entries.push_back(content::NavigationEntry::Create()); - if (!internal::RestoreNavigationEntryFromPickle(iterator, entries[i].get())) + if (!internal::RestoreNavigationEntryFromPickle(state_version, iterator, + entries[i].get())) return false; entries[i]->SetPageID(i); @@ -136,22 +138,39 @@ namespace internal { bool WriteHeaderToPickle(base::Pickle* pickle) { - return pickle->WriteUInt32(AW_STATE_VERSION); + return WriteHeaderToPickle(AW_STATE_VERSION, pickle); } -bool RestoreHeaderFromPickle(base::PickleIterator* iterator) { +bool WriteHeaderToPickle(uint32_t state_version, base::Pickle* pickle) { + return pickle->WriteUInt32(state_version); +} + +uint32_t RestoreHeaderFromPickle(base::PickleIterator* iterator) { uint32_t state_version = -1; if (!iterator->ReadUInt32(&state_version)) - return false; + return 0; - if (AW_STATE_VERSION != state_version) - return false; + if (IsSupportedVersion(state_version)) { + return state_version; + } - return true; + return 0; +} + +bool IsSupportedVersion(uint32_t state_version) { + return state_version == internal::AW_STATE_VERSION_INITIAL || + state_version == internal::AW_STATE_VERSION_DATA_URL; } bool WriteNavigationEntryToPickle(const content::NavigationEntry& entry, base::Pickle* pickle) { + return WriteNavigationEntryToPickle(AW_STATE_VERSION, entry, pickle); +} + +bool WriteNavigationEntryToPickle(uint32_t state_version, + const content::NavigationEntry& entry, + base::Pickle* pickle) { + DCHECK(IsSupportedVersion(state_version)); if (!pickle->WriteString(entry.GetURL().spec())) return false; @@ -179,7 +198,7 @@ if (!pickle->WriteString(entry.GetBaseURLForDataURL().spec())) return false; - { + if (state_version >= internal::AW_STATE_VERSION_DATA_URL) { const char* data = nullptr; size_t size = 0; scoped_refptr<const base::RefCountedString> s = entry.GetDataURLAsString(); @@ -202,13 +221,23 @@ if (!pickle->WriteInt(entry.GetHttpStatusCode())) return false; - // Please update AW_STATE_VERSION if serialization format is changed. + // Please update AW_STATE_VERSION and IsSupportedVersion() if serialization + // format is changed. + // Make sure the serialization format is updated in a backwards compatible + // way. return true; } bool RestoreNavigationEntryFromPickle(base::PickleIterator* iterator, content::NavigationEntry* entry) { + return RestoreNavigationEntryFromPickle(AW_STATE_VERSION, iterator, entry); +} + +bool RestoreNavigationEntryFromPickle(uint32_t state_version, + base::PickleIterator* iterator, + content::NavigationEntry* entry) { + DCHECK(IsSupportedVersion(state_version)); { string url; if (!iterator->ReadString(&url)) @@ -274,7 +303,7 @@ entry->SetBaseURLForDataURL(GURL(base_url_for_data_url)); } - { + if (state_version >= internal::AW_STATE_VERSION_DATA_URL) { const char* data; int size; if (!iterator->ReadData(&data, &size))
diff --git a/android_webview/native/state_serializer.h b/android_webview/native/state_serializer.h index b220ccf..644d5cca 100644 --- a/android_webview/native/state_serializer.h +++ b/android_webview/native/state_serializer.h
@@ -5,6 +5,8 @@ #ifndef ANDROID_WEBVIEW_NATIVE_STATE_SERIALIZER_H_ #define ANDROID_WEBVIEW_NATIVE_STATE_SERIALIZER_H_ +#include <cstdint> + #include "base/compiler_specific.h" namespace base { @@ -37,16 +39,30 @@ namespace internal { -// Functions below are individual helper functiosn called by functions above. +const uint32_t AW_STATE_VERSION_INITIAL = 20130814; +const uint32_t AW_STATE_VERSION_DATA_URL = 20151204; + +// Functions below are individual helper functions called by functions above. // They are broken up for unit testing, and should not be called out side of // tests. bool WriteHeaderToPickle(base::Pickle* pickle) WARN_UNUSED_RESULT; -bool RestoreHeaderFromPickle(base::PickleIterator* iterator) WARN_UNUSED_RESULT; +bool WriteHeaderToPickle(uint32_t state_version, + base::Pickle* pickle) WARN_UNUSED_RESULT; +uint32_t RestoreHeaderFromPickle(base::PickleIterator* iterator) + WARN_UNUSED_RESULT; +bool IsSupportedVersion(uint32_t state_version) WARN_UNUSED_RESULT; bool WriteNavigationEntryToPickle(const content::NavigationEntry& entry, base::Pickle* pickle) WARN_UNUSED_RESULT; -bool RestoreNavigationEntryFromPickle( - base::PickleIterator* iterator, - content::NavigationEntry* entry) WARN_UNUSED_RESULT; +bool WriteNavigationEntryToPickle(uint32_t state_version, + const content::NavigationEntry& entry, + base::Pickle* pickle) WARN_UNUSED_RESULT; +bool RestoreNavigationEntryFromPickle(base::PickleIterator* iterator, + content::NavigationEntry* entry) + WARN_UNUSED_RESULT; +bool RestoreNavigationEntryFromPickle(uint32_t state_version, + base::PickleIterator* iterator, + content::NavigationEntry* entry) + WARN_UNUSED_RESULT; } // namespace interanl
diff --git a/android_webview/native/state_serializer_unittest.cc b/android_webview/native/state_serializer_unittest.cc index a9671c6..9415367d 100644 --- a/android_webview/native/state_serializer_unittest.cc +++ b/android_webview/native/state_serializer_unittest.cc
@@ -21,23 +21,9 @@ namespace android_webview { -TEST(AndroidWebViewStateSerializerTest, TestHeaderSerialization) { - base::Pickle pickle; - bool result = internal::WriteHeaderToPickle(&pickle); - EXPECT_TRUE(result); +namespace { - base::PickleIterator iterator(pickle); - result = internal::RestoreHeaderFromPickle(&iterator); - EXPECT_TRUE(result); -} - -TEST(AndroidWebViewStateSerializerTest, TestNavigationEntrySerialization) { - // This is required for NavigationEntry::Create. - content::ContentClient content_client; - content::SetContentClient(&content_client); - content::ContentBrowserClient browser_client; - content::SetBrowserClientForTesting(&browser_client); - +scoped_ptr<content::NavigationEntry> CreateNavigationEntry() { scoped_ptr<content::NavigationEntry> entry( content::NavigationEntry::Create()); @@ -73,6 +59,51 @@ entry->SetIsOverridingUserAgent(is_overriding_user_agent); entry->SetTimestamp(timestamp); entry->SetHttpStatusCode(http_status_code); + return entry; +} + +} // namespace + +TEST(AndroidWebViewStateSerializerTest, TestHeaderSerialization) { + base::Pickle pickle; + bool result = internal::WriteHeaderToPickle(&pickle); + EXPECT_TRUE(result); + + base::PickleIterator iterator(pickle); + uint32_t version = internal::RestoreHeaderFromPickle(&iterator); + EXPECT_GT(version, 0U); +} + +TEST(AndroidWebViewStateSerializerTest, TestLegacyVersionHeaderSerialization) { + base::Pickle pickle; + bool result = internal::WriteHeaderToPickle( + internal::AW_STATE_VERSION_INITIAL, &pickle); + EXPECT_TRUE(result); + + base::PickleIterator iterator(pickle); + uint32_t version = internal::RestoreHeaderFromPickle(&iterator); + EXPECT_EQ(version, internal::AW_STATE_VERSION_INITIAL); +} + +TEST(AndroidWebViewStateSerializerTest, + TestUnsupportedVersionHeaderSerialization) { + base::Pickle pickle; + bool result = internal::WriteHeaderToPickle(20000101, &pickle); + EXPECT_TRUE(result); + + base::PickleIterator iterator(pickle); + uint32_t version = internal::RestoreHeaderFromPickle(&iterator); + EXPECT_EQ(version, 0U); +} + +TEST(AndroidWebViewStateSerializerTest, TestNavigationEntrySerialization) { + // This is required for NavigationEntry::Create. + content::ContentClient content_client; + content::SetContentClient(&content_client); + content::ContentBrowserClient browser_client; + content::SetBrowserClientForTesting(&browser_client); + + scoped_ptr<content::NavigationEntry> entry(CreateNavigationEntry()); base::Pickle pickle; bool result = internal::WriteNavigationEntryToPickle(*entry, &pickle); @@ -83,19 +114,59 @@ result = internal::RestoreNavigationEntryFromPickle(&iterator, copy.get()); EXPECT_TRUE(result); - EXPECT_EQ(url, copy->GetURL()); - EXPECT_EQ(virtual_url, copy->GetVirtualURL()); - EXPECT_EQ(referrer.url, copy->GetReferrer().url); - EXPECT_EQ(referrer.policy, copy->GetReferrer().policy); - EXPECT_EQ(title, copy->GetTitle()); - EXPECT_EQ(page_state, copy->GetPageState()); - EXPECT_EQ(has_post_data, copy->GetHasPostData()); - EXPECT_EQ(original_request_url, copy->GetOriginalRequestURL()); - EXPECT_EQ(base_url_for_data_url, copy->GetBaseURLForDataURL()); - EXPECT_EQ(data_url_as_string, copy->GetDataURLAsString()->data()); - EXPECT_EQ(is_overriding_user_agent, copy->GetIsOverridingUserAgent()); - EXPECT_EQ(timestamp, copy->GetTimestamp()); - EXPECT_EQ(http_status_code, copy->GetHttpStatusCode()); + EXPECT_EQ(entry->GetURL(), copy->GetURL()); + EXPECT_EQ(entry->GetVirtualURL(), copy->GetVirtualURL()); + EXPECT_EQ(entry->GetReferrer().url, copy->GetReferrer().url); + EXPECT_EQ(entry->GetReferrer().policy, copy->GetReferrer().policy); + EXPECT_EQ(entry->GetTitle(), copy->GetTitle()); + EXPECT_EQ(entry->GetPageState(), copy->GetPageState()); + EXPECT_EQ(entry->GetHasPostData(), copy->GetHasPostData()); + EXPECT_EQ(entry->GetOriginalRequestURL(), copy->GetOriginalRequestURL()); + EXPECT_EQ(entry->GetBaseURLForDataURL(), copy->GetBaseURLForDataURL()); + EXPECT_EQ(entry->GetDataURLAsString()->data(), + copy->GetDataURLAsString()->data()); + EXPECT_EQ(entry->GetIsOverridingUserAgent(), + copy->GetIsOverridingUserAgent()); + EXPECT_EQ(entry->GetTimestamp(), copy->GetTimestamp()); + EXPECT_EQ(entry->GetHttpStatusCode(), copy->GetHttpStatusCode()); +} + +TEST(AndroidWebViewStateSerializerTest, + TestLegacyNavigationEntrySerialization) { + // This is required for NavigationEntry::Create. + content::ContentClient content_client; + content::SetContentClient(&content_client); + content::ContentBrowserClient browser_client; + content::SetBrowserClientForTesting(&browser_client); + + scoped_ptr<content::NavigationEntry> entry(CreateNavigationEntry()); + + base::Pickle pickle; + bool result = internal::WriteNavigationEntryToPickle( + internal::AW_STATE_VERSION_INITIAL, *entry, &pickle); + EXPECT_TRUE(result); + + scoped_ptr<content::NavigationEntry> copy(content::NavigationEntry::Create()); + base::PickleIterator iterator(pickle); + result = internal::RestoreNavigationEntryFromPickle( + internal::AW_STATE_VERSION_INITIAL, &iterator, copy.get()); + EXPECT_TRUE(result); + + EXPECT_EQ(entry->GetURL(), copy->GetURL()); + EXPECT_EQ(entry->GetVirtualURL(), copy->GetVirtualURL()); + EXPECT_EQ(entry->GetReferrer().url, copy->GetReferrer().url); + EXPECT_EQ(entry->GetReferrer().policy, copy->GetReferrer().policy); + EXPECT_EQ(entry->GetTitle(), copy->GetTitle()); + EXPECT_EQ(entry->GetPageState(), copy->GetPageState()); + EXPECT_EQ(entry->GetHasPostData(), copy->GetHasPostData()); + EXPECT_EQ(entry->GetOriginalRequestURL(), copy->GetOriginalRequestURL()); + EXPECT_EQ(entry->GetBaseURLForDataURL(), copy->GetBaseURLForDataURL()); + // DataURL not supported by 20130814 format + EXPECT_FALSE(copy->GetDataURLAsString()); + EXPECT_EQ(entry->GetIsOverridingUserAgent(), + copy->GetIsOverridingUserAgent()); + EXPECT_EQ(entry->GetTimestamp(), copy->GetTimestamp()); + EXPECT_EQ(entry->GetHttpStatusCode(), copy->GetHttpStatusCode()); } TEST(AndroidWebViewStateSerializerTest, TestEmptyDataURLSerialization) {
diff --git a/base/time/time_mac.cc b/base/time/time_mac.cc index f2bc5ed..285e95a 100644 --- a/base/time/time_mac.cc +++ b/base/time/time_mac.cc
@@ -167,19 +167,23 @@ // static Time Time::FromExploded(bool is_local, const Exploded& exploded) { - CFGregorianDate date; - date.second = exploded.second + - exploded.millisecond / static_cast<double>(kMillisecondsPerSecond); - date.minute = exploded.minute; - date.hour = exploded.hour; - date.day = exploded.day_of_month; - date.month = exploded.month; - date.year = exploded.year; - base::ScopedCFTypeRef<CFTimeZoneRef> time_zone( - is_local ? CFTimeZoneCopySystem() : NULL); - CFAbsoluteTime seconds = CFGregorianDateGetAbsoluteTime(date, time_zone) + - kCFAbsoluteTimeIntervalSince1970; + is_local + ? CFTimeZoneCopySystem() + : CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, 0)); + base::ScopedCFTypeRef<CFCalendarRef> gregorian(CFCalendarCreateWithIdentifier( + kCFAllocatorDefault, kCFGregorianCalendar)); + CFCalendarSetTimeZone(gregorian, time_zone); + CFAbsoluteTime absolute_time; + // 'S' is not defined in componentDesc in Apple documentation, but can be + // found at http://www.opensource.apple.com/source/CF/CF-855.17/CFCalendar.c + CFCalendarComposeAbsoluteTime( + gregorian, &absolute_time, "yMdHmsS", exploded.year, exploded.month, + exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, + exploded.millisecond); + // Milliseconds from |exploded| is added back to |absolute_time| here + // because CFCalendar parameters are integer values. + CFAbsoluteTime seconds = absolute_time + kCFAbsoluteTimeIntervalSince1970; return Time(static_cast<int64_t>(seconds * kMicrosecondsPerSecond) + kWindowsEpochDeltaMicroseconds); } @@ -195,19 +199,25 @@ kCFAbsoluteTimeIntervalSince1970; base::ScopedCFTypeRef<CFTimeZoneRef> time_zone( - is_local ? CFTimeZoneCopySystem() : NULL); - CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(seconds, time_zone); - // 1 = Monday, ..., 7 = Sunday. - int cf_day_of_week = CFAbsoluteTimeGetDayOfWeek(seconds, time_zone); - - exploded->year = date.year; - exploded->month = date.month; - exploded->day_of_week = cf_day_of_week % 7; - exploded->day_of_month = date.day; - exploded->hour = date.hour; - exploded->minute = date.minute; + is_local + ? CFTimeZoneCopySystem() + : CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, 0)); + base::ScopedCFTypeRef<CFCalendarRef> gregorian(CFCalendarCreateWithIdentifier( + kCFAllocatorDefault, kCFGregorianCalendar)); + CFCalendarSetTimeZone(gregorian, time_zone); + int second, day_of_week; + // 'E' sets the day of week, but is not defined in componentDesc in Apple + // documentation. It can be found in open source code here: + // http://www.opensource.apple.com/source/CF/CF-855.17/CFCalendar.c + CFCalendarDecomposeAbsoluteTime(gregorian, seconds, "yMdHmsE", + &exploded->year, &exploded->month, + &exploded->day_of_month, &exploded->hour, + &exploded->minute, &second, &day_of_week); // Make sure seconds are rounded down towards -infinity. - exploded->second = floor(date.second); + exploded->second = floor(second); + // |Exploded|'s convention for day of week is 0 = Sunday, i.e. different + // from CF's 1 = Sunday. + exploded->day_of_week = (day_of_week - 1) % 7; // Calculate milliseconds ourselves, since we rounded the |seconds|, making // sure to round towards -infinity. exploded->millisecond =
diff --git a/build/all.gyp b/build/all.gyp index c62c52d..1984049 100644 --- a/build/all.gyp +++ b/build/all.gyp
@@ -611,6 +611,7 @@ '../gpu/gpu.gyp:gl_tests', '../gpu/gpu.gyp:angle_unittests', '../gpu/gpu.gyp:gpu_unittests', + '../gpu/gpu.gyp:command_buffer_gles2_tests', '../third_party/catapult/telemetry/telemetry.gyp:*', ], 'conditions': [ @@ -648,6 +649,7 @@ '../gpu/gpu.gyp:gl_tests', '../gpu/gpu.gyp:angle_unittests', '../gpu/gpu.gyp:gpu_unittests', + '../gpu/gpu.gyp:command_buffer_gles2_tests', '../third_party/catapult/telemetry/telemetry.gyp:*', ], 'conditions': [ @@ -844,6 +846,7 @@ '../content/content_shell_and_tests.gyp:content_gl_tests_apk', '../content/content_shell_and_tests.gyp:content_unittests_apk', '../content/content_shell_and_tests.gyp:video_decode_accelerator_unittest_apk', + '../gpu/gpu.gyp:command_buffer_gles2_tests_apk', '../gpu/gpu.gyp:gl_tests_apk', '../gpu/gpu.gyp:gpu_unittests_apk', '../ipc/ipc.gyp:ipc_tests_apk',
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi index de8cbbad..8effb92 100644 --- a/build/gn_migration.gypi +++ b/build/gn_migration.gypi
@@ -210,6 +210,7 @@ '../content/content_shell_and_tests.gyp:content_unittests_apk', '../content/content_shell_and_tests.gyp:video_decode_accelerator_unittest_apk', '../device/device_tests.gyp:device_unittests_apk', + '../gpu/gpu.gyp:command_buffer_gles2_tests_apk', '../gpu/gpu.gyp:gl_tests_apk', '../gpu/gpu.gyp:gpu_perftests_apk', '../gpu/gpu.gyp:gpu_unittests_apk',
diff --git a/chrome/VERSION b/chrome/VERSION index 08bff69..d12d335 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=50 MINOR=0 -BUILD=2651 +BUILD=2652 PATCH=0
diff --git a/chrome/android/java/res/layout/fre_choose_account.xml b/chrome/android/java/res/layout/fre_choose_account.xml index de5e94e..b6bccdda 100644 --- a/chrome/android/java/res/layout/fre_choose_account.xml +++ b/chrome/android/java/res/layout/fre_choose_account.xml
@@ -6,6 +6,7 @@ --> <org.chromium.chrome.browser.firstrun.AccountFirstRunView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:chrome="http://schemas.android.com/apk/res-auto" android:id="@+id/fre_account_layout" android:layout_width="match_parent" android:layout_height="match_parent" > @@ -13,7 +14,7 @@ <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginBottom="57dp" + android:layout_marginBottom="76dp" android:fillViewport="true" android:scrollbarStyle="outsideOverlay" > @@ -59,6 +60,7 @@ android:paddingStart="24dp" > <Spinner + style="@style/Widget.AppCompat.Spinner.Underlined" android:id="@+id/google_accounts_spinner" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -66,63 +68,86 @@ android:padding="0dp" android:textColor="@color/fre_text_color" /> - <TextView - android:id="@+id/description" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:lineSpacingMultiplier="1.4" - android:text="@string/fre_account_choice_description" - android:textColor="@color/fre_light_text_color" - android:textSize="@dimen/fre_normal_text_size" /> + + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <org.chromium.ui.widget.TextViewWithClickableSpans + android:id="@+id/description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:lineSpacingMultiplier="1.4" + android:text="@string/fre_account_choice_description" + android:textColor="@color/fre_light_text_color" + android:textSize="@dimen/fre_normal_text_size" + android:visibility="visible"/> + + <!-- We use an invisible TextView overlapping with the visible one to keep + the layout constant between text changes. This TextView will have its + contents programmatically set to the longest string the above TextView can + contain. --> + + <org.chromium.ui.widget.TextViewWithClickableSpans + android:id="@+id/longest_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:lineSpacingMultiplier="1.4" + android:textColor="@color/fre_light_text_color" + android:textSize="@dimen/fre_normal_text_size" + android:visibility="invisible"/> + + </FrameLayout> + </LinearLayout> </LinearLayout> </LinearLayout> </ScrollView> - <View android:id="@+id/button_bar_separator" - style="@style/ButtonBarTopDivider" - android:layout_gravity="bottom" - android:layout_marginBottom="56dp" /> - <LinearLayout android:id="@+id/button_bar" android:layout_width="match_parent" - android:layout_height="56dp" + android:layout_height="76dp" android:layout_gravity="bottom" - android:orientation="horizontal" > + android:orientation="horizontal" + android:padding="@dimen/fre_button_padding" > <!--suppress ButtonStyle --> <Button android:id="@+id/negative_button" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:gravity="start|center_vertical" - android:textDirection="locale" - android:paddingStart="@dimen/fre_button_padding" - android:paddingEnd="@dimen/fre_button_padding" + style="@style/ButtonCompatBorderless" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:text="@string/fre_skip_text" android:textAllCaps="true" android:textColor="@color/light_normal_color" - android:textSize="@dimen/fre_button_text_size" /> + android:textSize="15sp" /> + + <View + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" + android:visibility="invisible"/> <!--suppress ButtonStyle --> - <Button + <org.chromium.ui.widget.ButtonCompat android:id="@+id/positive_button" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:gravity="end|center_vertical" - android:textDirection="locale" - android:paddingStart="@dimen/fre_button_padding" - android:paddingEnd="@dimen/fre_button_padding" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:text="@string/choose_account_sign_in" android:textAllCaps="true" - android:textColor="@color/light_active_color" - android:textSize="@dimen/fre_button_text_size" /> + android:textColor="@android:color/white" + android:textSize="15sp" + chrome:buttonColor="@color/light_active_color" /> + + <View + android:id="@+id/positive_button_end_padding" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" + android:visibility="gone"/> </LinearLayout> </org.chromium.chrome.browser.firstrun.AccountFirstRunView>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 3dede14..895151e 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -163,7 +163,7 @@ <dimen name="badge_border_size">1.3dp</dimen> <!-- First Run Experience and Welcome Page dimensions --> - <dimen name="fre_button_padding">16dp</dimen> + <dimen name="fre_button_padding">12dp</dimen> <dimen name="fre_margin">24dp</dimen> <dimen name="fre_title_text_size">24sp</dimen> <dimen name="fre_button_text_size">14sp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSigninActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSigninActivity.java index f75af4d..c359b91e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSigninActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSigninActivity.java
@@ -131,6 +131,11 @@ } @Override + public void onAccountSelectionCancelled() { + finish(); + }; + + @Override public ProfileDataCache getProfileDataCache() { if (mProfileDataCache == null) { mProfileDataCache = new ProfileDataCache(this, Profile.getLastUsedProfile());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java index 034fd89..8e57330 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java
@@ -85,13 +85,13 @@ if (titles.length == 1) { mSnackbarManager.showSnackbar(Snackbar.make(titles[0], this, Snackbar.TYPE_ACTION) .setTemplateText(mContext.getString(R.string.undo_bar_delete_message)) - .setAction(mContext.getString(R.string.undo_bar_button_text), null)); + .setAction(mContext.getString(R.string.undo), null)); } else { mSnackbarManager.showSnackbar( Snackbar.make(String.format(Locale.getDefault(), "%d", titles.length), this, Snackbar.TYPE_ACTION) .setTemplateText(mContext.getString(R.string.undo_bar_multiple_delete_message)) - .setAction(mContext.getString(R.string.undo_bar_button_text), null)); + .setAction(mContext.getString(R.string.undo), null)); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunFragment.java index db5f742..be16f4c3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunFragment.java
@@ -38,11 +38,6 @@ mView.setListener(new AccountFirstRunView.Listener() { @Override - public void onAccountSelectionConfirmed(String accountName) { - mView.switchToSignedMode(); - } - - @Override public void onAccountSelectionCanceled() { getPageDelegate().refuseSignIn(); advanceToNextPage(); @@ -54,14 +49,17 @@ } @Override - public void onSigningInCompleted(String accountName) { + public void onAccountSelected(String accountName) { getPageDelegate().acceptSignIn(accountName); + } + + @Override + public void onDoneClicked() { advanceToNextPage(); } @Override - public void onSettingsButtonClicked(String accountName) { - getPageDelegate().acceptSignIn(accountName); + public void onSettingsClicked() { getPageDelegate().askToOpenSyncSettings(); advanceToNextPage(); } @@ -72,6 +70,7 @@ // The user would have to go through the FRE again. getPageDelegate().abortFirstRunExperience(); } + }); mView.init(getPageDelegate().getProfileDataCache()); @@ -88,7 +87,6 @@ @Override public void onStart() { super.onStart(); - mView.setButtonsEnabled(true); mView.setProfileDataCache(getPageDelegate().getProfileDataCache()); getPageDelegate().onSigninDialogShown(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java index 002cd2e..856c7d2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java
@@ -6,11 +6,13 @@ import android.content.Context; import android.graphics.Bitmap; -import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.text.TextPaint; import android.text.TextUtils; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; import android.util.AttributeSet; -import android.view.Gravity; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; @@ -27,7 +29,8 @@ import org.chromium.chrome.browser.profiles.ProfileDownloader; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.sync.signin.AccountManagerHelper; -import org.chromium.ui.widget.ButtonCompat; +import org.chromium.ui.text.SpanApplier; +import org.chromium.ui.text.SpanApplier.SpanInfo; import java.util.List; @@ -45,12 +48,6 @@ */ public interface Listener { /** - * The user selected an account. - * @param accountName The name of the account - */ - public void onAccountSelectionConfirmed(String accountName); - - /** * The user canceled account selection. */ public void onAccountSelectionCanceled(); @@ -61,16 +58,24 @@ public void onNewAccount(); /** - * The user has been signed in and pressed 'Done' button. + * The user selected an account. + * This call will be followed by either {@link #onSettingsClicked} or + * {@link #onDoneClicked}. * @param accountName The name of the account */ - public void onSigningInCompleted(String accountName); + public void onAccountSelected(String accountName); /** - * The user has signed in and pressed 'Settings' button. - * @param accountName The name of the account + * The user has completed the dialog flow. + * This will only be called after {@link #onAccountSelected} and should exit the View. */ - public void onSettingsButtonClicked(String accountName); + public void onDoneClicked(); + + /** + * The user has selected to view sync settings. + * This will only be called after {@link #onAccountSelected} and should exit the View. + */ + public void onSettingsClicked(); /** * Failed to set the forced account because it wasn't found. @@ -102,20 +107,27 @@ } } + private static final String TAG = "AccountFirstRunView"; + private static final int EXPERIMENT_TITLE_VARIANT_MASK = 1; private static final int EXPERIMENT_SUMMARY_VARIANT_MASK = 2; private static final int EXPERIMENT_LAYOUT_VARIANT_MASK = 4; private static final int EXPERIMENT_MAX_VALUE = 7; + private static final String SETTINGS_LINK_OPEN = "<LINK1>"; + private static final String SETTINGS_LINK_CLOSE = "</LINK1>"; + private AccountManagerHelper mAccountManagerHelper; private List<String> mAccountNames; private ArrayAdapter<CharSequence> mArrayAdapter; private ImageCarousel mImageCarousel; private Button mPositiveButton; private Button mNegativeButton; + private TextView mTitle; private TextView mDescriptionText; private Listener mListener; private Spinner mSpinner; + private Drawable mSpinnerBackground; private String mForcedAccountName; private String mAccountName; private String mAddAnotherAccount; @@ -123,11 +135,14 @@ private boolean mSignedIn; private boolean mPositionSetProgrammatically; private int mDescriptionTextId; + private int mCancelButtonTextId; private boolean mIsChildAccount; private boolean mHorizontalModeEnabled = true; + private boolean mShowSettingsSpan = true; public AccountFirstRunView(Context context, AttributeSet attrs) { super(context, attrs); + mAccountManagerHelper = AccountManagerHelper.get(getContext().getApplicationContext()); } /** @@ -157,30 +172,32 @@ mPositiveButton = (Button) findViewById(R.id.positive_button); mNegativeButton = (Button) findViewById(R.id.negative_button); - mNegativeButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - setButtonsEnabled(false); - mListener.onAccountSelectionCanceled(); - } - }); // A workaround for Android support library ignoring padding set in XML. b/20307607 int padding = getResources().getDimensionPixelSize(R.dimen.fre_button_padding); ApiCompatibilityUtils.setPaddingRelative(mPositiveButton, padding, 0, padding, 0); ApiCompatibilityUtils.setPaddingRelative(mNegativeButton, padding, 0, padding, 0); + mTitle = (TextView) findViewById(R.id.title); mDescriptionText = (TextView) findViewById(R.id.description); + // For the spans to be clickable. + mDescriptionText.setMovementMethod(LinkMovementMethod.getInstance()); mDescriptionTextId = R.string.fre_account_choice_description; + // TODO(peconn): Ensure this is changed to R.string.cancel when used in Settings > Sign In. + mCancelButtonTextId = R.string.fre_skip_text; + + // Set the invisible TextView to contain the longest text the visible TextView can hold. + // It assumes that the signed in description for child accounts is the longest text. + ((TextView) findViewById(R.id.longest_description)).setText(getSignedInDescription(true)); + mAddAnotherAccount = getResources().getString(R.string.fre_add_account); mSpinner = (Spinner) findViewById(R.id.google_accounts_spinner); + mSpinnerBackground = mSpinner.getBackground(); mArrayAdapter = new ArrayAdapter<CharSequence>( getContext().getApplicationContext(), R.layout.fre_spinner_text); - updateAccounts(); - mArrayAdapter.setDropDownViewResource(R.layout.fre_spinner_dropdown); mSpinner.setAdapter(mArrayAdapter); mSpinner.setOnItemSelectedListener(new SpinnerOnItemSelectedListener()); @@ -201,6 +218,8 @@ return super.performAccessibilityAction(host, action, args); } }); + + showSignInPage(); } @Override @@ -213,7 +232,12 @@ public void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); if (visibility == View.VISIBLE) { - updateAccounts(); + if (updateAccounts()) { + // A new account has been added and the visibility has returned to us. + // The updateAccounts function will have selected the new account. + // Shortcut to confirm sign in page. + showConfirmSignInPage(); + } } } @@ -244,33 +268,20 @@ /** * Changes the visuals slightly for when this view appears in the recent tabs page instead of * in first run. For example, the title text is changed as well as the button style. + * This is currently used in the Recent Tabs Promo and the Enhanced Bookmark page. */ - public void configureForRecentTabsPage() { + public void configureForRecentTabsOrBookmarksPage() { mHorizontalModeEnabled = false; + mShowSettingsSpan = false; setBackgroundResource(R.color.ntp_bg); - TextView title = (TextView) findViewById(R.id.title); - title.setText(R.string.sign_in_to_chrome); + mTitle.setText(R.string.sign_in_to_chrome); - // Remove the border above the button, swap in a new button with a blue material background, - // and center the button. - View buttonBarSeparator = findViewById(R.id.button_bar_separator); - buttonBarSeparator.setVisibility(View.GONE); + mCancelButtonTextId = R.string.cancel; + setUpCancelButton(); - LinearLayout buttonContainer = (LinearLayout) findViewById(R.id.button_bar); - buttonContainer.setGravity(Gravity.CENTER_HORIZONTAL); - setPadding(0, 0, 0, getResources().getDimensionPixelOffset( - R.dimen.sign_in_promo_padding_bottom)); - - ButtonCompat positiveButton = new ButtonCompat(getContext(), - ApiCompatibilityUtils.getColor(getResources(), R.color.light_active_color)); - positiveButton.setTextColor(Color.WHITE); - positiveButton.setLayoutParams(new LinearLayout.LayoutParams( - LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); - - buttonContainer.removeView(mPositiveButton); - buttonContainer.addView(positiveButton); - mPositiveButton = positiveButton; + setPadding(0, 0, 0, + getResources().getDimensionPixelOffset(R.dimen.sign_in_promo_padding_bottom)); } /** @@ -281,9 +292,8 @@ int experimentGroup = SigninManager.getAndroidSigninPromoExperimentGroup(); assert experimentGroup >= 0 && experimentGroup <= EXPERIMENT_MAX_VALUE; - TextView title = (TextView) findViewById(R.id.title); if ((experimentGroup & EXPERIMENT_TITLE_VARIANT_MASK) != 0) { - title.setText(R.string.make_chrome_yours); + mTitle.setText(R.string.make_chrome_yours); } mDescriptionTextId = (experimentGroup & EXPERIMENT_SUMMARY_VARIANT_MASK) != 0 @@ -322,36 +332,21 @@ } /** - * Tell the view whether or not the user can cancel account selection. In - * wizards, it makes sense to allow the user to skip account selection. - * However, in other settings-type contexts it does not make sense to allow - * this. - * - * @param canCancel Whether or not account selection can be canceled. - */ - public void setCanCancel(boolean canCancel) { - mNegativeButton.setVisibility(canCancel ? View.VISIBLE : View.GONE); - mPositiveButton.setGravity( - canCancel ? Gravity.END | Gravity.CENTER_VERTICAL : Gravity.CENTER); - } - - /** * Refresh the list of available system account. + * @return Whether any new accounts were added (the first newly added account will now be + * selected). */ - private void updateAccounts() { - if (mSignedIn) return; - setButtonsEnabled(true); - - mAccountManagerHelper = AccountManagerHelper.get(getContext().getApplicationContext()); + private boolean updateAccounts() { + if (mSignedIn) return false; List<String> oldAccountNames = mAccountNames; mAccountNames = mAccountManagerHelper.getGoogleAccountNames(); int accountToSelect = 0; - if (mForcedAccountName != null) { + if (isInForcedAccountMode()) { accountToSelect = mAccountNames.indexOf(mForcedAccountName); if (accountToSelect < 0) { mListener.onFailedToSetForcedAccount(mForcedAccountName); - return; + return false; } } else { accountToSelect = getIndexOfNewElement( @@ -363,24 +358,14 @@ mSpinner.setVisibility(View.VISIBLE); mArrayAdapter.addAll(mAccountNames); mArrayAdapter.add(mAddAnotherAccount); - mPositiveButton.setText(R.string.choose_account_sign_in); - mPositiveButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mListener.onAccountSelectionConfirmed(mAccountName); - } - }); + + setUpSignInButton(true); mDescriptionText.setText(mDescriptionTextId); + } else { mSpinner.setVisibility(View.GONE); mArrayAdapter.add(mAddAnotherAccount); - mPositiveButton.setText(R.string.fre_no_accounts); - mPositiveButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mListener.onNewAccount(); - } - }); + setUpSignInButton(false); mDescriptionText.setText(R.string.fre_no_account_choice_description); } @@ -390,6 +375,10 @@ mSpinner.setSelection(accountToSelect); mAccountName = mArrayAdapter.getItem(accountToSelect).toString(); mImageCarousel.scrollTo(accountToSelect, false, false); + + return oldAccountNames != null + && !(oldAccountNames.size() == mAccountNames.size() + && oldAccountNames.containsAll(mAccountNames)); } /** @@ -444,45 +433,146 @@ if (!mSignedIn) return; String name = null; - if (mIsChildAccount) name = mProfileData.getGivenName(mAccountName); - if (name == null) name = mProfileData.getFullName(mAccountName); + if (mProfileData != null) { + if (mIsChildAccount) name = mProfileData.getGivenName(mAccountName); + if (name == null) name = mProfileData.getFullName(mAccountName); + } if (name == null) name = mAccountName; String text = String.format(getResources().getString(R.string.fre_hi_name), name); - ((TextView) findViewById(R.id.title)).setText(text); + mTitle.setText(text); } /** * Updates the view to show that sign in has completed. */ public void switchToSignedMode() { + showConfirmSignInPage(); + } + + private void showSignInPage() { + mSignedIn = false; + mTitle.setText(R.string.sign_in_to_chrome); + + mSpinner.setEnabled(true); + mSpinner.setBackground(mSpinnerBackground); + mImageCarousel.setVisibility(VISIBLE); + + setUpCancelButton(); + updateAccounts(); + + mImageCarousel.setSignedInMode(false); + } + + private void showConfirmSignInPage() { mSignedIn = true; updateProfileName(); mSpinner.setEnabled(false); mSpinner.setBackground(null); - mPositiveButton.setText(getResources().getText(R.string.fre_done)); - mPositiveButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mListener.onSigningInCompleted(mAccountName); - } - }); - mNegativeButton.setText(getResources().getText(R.string.fre_settings)); + setUpConfirmButton(); + setUpUndoButton(); + + if (mShowSettingsSpan) { + ClickableSpan settingsSpan = new ClickableSpan() { + @Override + public void onClick(View widget) { + mListener.onAccountSelected(mAccountName); + mListener.onSettingsClicked(); + } + + @Override + public void updateDrawState(TextPaint textPaint) { + textPaint.setColor(textPaint.linkColor); + textPaint.setUnderlineText(false); + } + }; + mDescriptionText.setText(SpanApplier.applySpans(getSignedInDescription(mIsChildAccount), + new SpanInfo(SETTINGS_LINK_OPEN, SETTINGS_LINK_CLOSE, settingsSpan))); + } else { + // If we aren't showing the span, get rid of the LINK1 annotations. + mDescriptionText.setText(getSignedInDescription(mIsChildAccount) + .replace(SETTINGS_LINK_OPEN, "") + .replace(SETTINGS_LINK_CLOSE, "")); + } + + mImageCarousel.setVisibility(VISIBLE); + mImageCarousel.setSignedInMode(true); + } + + private void setUpCancelButton() { + setNegativeButtonVisible(true); + + mNegativeButton.setText(getResources().getText(mCancelButtonTextId)); mNegativeButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - mListener.onSettingsButtonClicked(mAccountName); + setButtonsEnabled(false); + mListener.onAccountSelectionCanceled(); } }); - setButtonsEnabled(true); - String text = getResources().getString(R.string.fre_signed_in_description); - if (mIsChildAccount) { - text += "\n" + getResources().getString( - R.string.fre_signed_in_description_uca_addendum); + } + + private void setUpSignInButton(boolean hasAccounts) { + if (hasAccounts) { + mPositiveButton.setText(R.string.choose_account_sign_in); + mPositiveButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + showConfirmSignInPage(); + } + }); + } else { + mPositiveButton.setText(R.string.fre_no_accounts); + mPositiveButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mListener.onNewAccount(); + } + }); } - mDescriptionText.setText(text); - mImageCarousel.setVisibility(VISIBLE); - mImageCarousel.setSignedInMode(); + } + + private void setUpUndoButton() { + setNegativeButtonVisible(!isInForcedAccountMode()); + if (isInForcedAccountMode()) return; + + mNegativeButton.setText(getResources().getText(R.string.undo)); + mNegativeButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + showSignInPage(); + } + }); + } + + private void setUpConfirmButton() { + mPositiveButton.setText(getResources().getText(R.string.fre_accept)); + mPositiveButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mListener.onAccountSelected(mAccountName); + mListener.onDoneClicked(); + } + }); + } + + private void setNegativeButtonVisible(boolean enabled) { + if (enabled) { + mNegativeButton.setVisibility(View.VISIBLE); + findViewById(R.id.positive_button_end_padding).setVisibility(View.GONE); + } else { + mNegativeButton.setVisibility(View.GONE); + findViewById(R.id.positive_button_end_padding).setVisibility(View.INVISIBLE); + } + } + + private String getSignedInDescription(boolean childAccount) { + if (childAccount) { + return getResources().getString(R.string.fre_signed_in_description) + '\n' + + getResources().getString(R.string.fre_signed_in_description_uca_addendum); + } else { + return getResources().getString(R.string.fre_signed_in_description); + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ImageCarousel.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ImageCarousel.java index df5a61f..499bac2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ImageCarousel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ImageCarousel.java
@@ -151,6 +151,7 @@ private float mPosition = 0f; private ImageCarouselPositionChangeListener mListener; + private ImageView mCheckmark; private int mLastPosition = 0; private boolean mNeedsPositionUpdates = true; @@ -221,24 +222,33 @@ } /** - * Sets the ImageCarousel to signed in mode that disables scrolling, animates away the - * background images, and displays a checkmark next to the account image that was chosen. + * Sets whether the ImageCarousel is in signed in mode. This mode disables scrolling, animates + * away the background images, and displays a checkmark next to the chosen account image. + * @param isSignedIn Whether the ImageCarousel should in signed in mode or not. */ - public void setSignedInMode() { - mScrollingDisabled = true; - mAccountSelected = true; + public void setSignedInMode(boolean isSignedIn) { + if (isSignedIn == mAccountSelected) return; + + mScrollingDisabled = isSignedIn; + mAccountSelected = isSignedIn; setPosition(getCenterPosition()); - ImageView checkmark = new ImageView(getContext()); - checkmark.setImageResource(R.drawable.verify_checkmark); - setLayoutParamsForCheckmark(checkmark); - addView(checkmark); + if (mCheckmark == null) { + mCheckmark = new ImageView(getContext()); + mCheckmark.setImageResource(R.drawable.verify_checkmark); + setLayoutParamsForCheckmark(mCheckmark); + addView(mCheckmark); + } if (mFadeInOutAnimator != null) mFadeInOutAnimator.cancel(); AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.playTogether( - ObjectAnimator.ofFloat(this, BACKGROUND_IMAGE_ALPHA, 0), - ObjectAnimator.ofFloat(checkmark, View.ALPHA, 0.0f, 1.0f)); + if (isSignedIn) { + animatorSet.playTogether(ObjectAnimator.ofFloat(this, BACKGROUND_IMAGE_ALPHA, 0), + ObjectAnimator.ofFloat(mCheckmark, View.ALPHA, 0.0f, 1.0f)); + } else { + animatorSet.playTogether(ObjectAnimator.ofFloat(this, BACKGROUND_IMAGE_ALPHA, 1), + ObjectAnimator.ofFloat(mCheckmark, View.ALPHA, 1.0f, 0.0f)); + } mFadeInOutAnimator = animatorSet; mFadeInOutAnimator.setDuration(ACCOUNT_SIGNED_IN_ANIMATION_DURATION_MS); mFadeInOutAnimator.start();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ProfileDataCache.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ProfileDataCache.java index 21b87a8..25b590b8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ProfileDataCache.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ProfileDataCache.java
@@ -142,7 +142,7 @@ Bitmap bitmap) { bitmap = getCroppedBitmap(bitmap); mCacheEntries.put(accountId, new CacheEntry(bitmap, fullName, givenName)); - if (mObserver != null) mObserver.onProfileDownloaded(accountId, givenName, fullName, + if (mObserver != null) mObserver.onProfileDownloaded(accountId, fullName, givenName, bitmap); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index c88469a..813a0dce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -616,7 +616,7 @@ Context context = mNewTabPageView.getContext(); Snackbar snackbar = Snackbar.make(context.getString(R.string.most_visited_item_removed), mMostVisitedItemRemovedController, Snackbar.TYPE_ACTION) - .setAction(context.getString(R.string.undo_bar_button_text), url); + .setAction(context.getString(R.string.undo), url); mTab.getSnackbarManager().showSnackbar(snackbar); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java index c598cfa..54bff39 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
@@ -5,7 +5,9 @@ package org.chromium.chrome.browser.ntp; import android.content.Context; +import android.content.SharedPreferences; import android.graphics.Bitmap; +import android.preference.PreferenceManager; import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils; @@ -52,6 +54,8 @@ } private static final int RECENTLY_CLOSED_MAX_TAB_COUNT = 5; + private static final String PREF_SIGNIN_PROMO_DECLINED = + "recent_tabs_signin_promo_declined"; private final Profile mProfile; private final Tab mTab; @@ -386,10 +390,25 @@ return false; } + if (PreferenceManager.getDefaultSharedPreferences(mContext).getBoolean( + PREF_SIGNIN_PROMO_DECLINED, false)) { + return false; + } + return !AndroidSyncSettings.isSyncEnabled(mContext) || mForeignSessions.isEmpty(); } /** + * Save that user tapped "No" button on the signin promo. + */ + public void setSigninPromoDeclined() { + SharedPreferences.Editor sharedPreferencesEditor = + PreferenceManager.getDefaultSharedPreferences(mContext).edit(); + sharedPreferencesEditor.putBoolean(PREF_SIGNIN_PROMO_DECLINED, true); + sharedPreferencesEditor.apply(); + } + + /** * Collapse the sync promo. * * @param isCollapsed Whether the sync promo is collapsed.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPromoView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPromoView.java index 3ef19806..f84cdee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPromoView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPromoView.java
@@ -93,6 +93,11 @@ * Called when user attempts to create a new account. */ void onNewAccount(); + + /** + * Called when a user cancels the account sign in process. + */ + void onAccountSelectionCancelled(); } private static final int PROMO_TYPE_SIGN_IN = 0; @@ -249,18 +254,14 @@ signInPromoView.init(mModel.getProfileDataCache()); signInPromoView.getLayoutParams().height = LayoutParams.WRAP_CONTENT; ((FrameLayout.LayoutParams) signInPromoView.getLayoutParams()).gravity = Gravity.CENTER; - signInPromoView.configureForRecentTabsPage(); - signInPromoView.setCanCancel(false); + signInPromoView.configureForRecentTabsOrBookmarksPage(); signInPromoView.setListener(new AccountFirstRunView.Listener() { - @Override - public void onAccountSelectionConfirmed(String accountName) { - if (mUserActionListener != null) mUserActionListener.onAccountSelectionConfirmed(); - SigninManager.get(mActivity).signIn(accountName, mActivity, null); - } + private String mAccountName; @Override public void onAccountSelectionCanceled() { - assert false : "Button should be hidden"; + assert mUserActionListener != null; + mUserActionListener.onAccountSelectionCancelled(); } @Override @@ -271,12 +272,18 @@ } @Override - public void onSigningInCompleted(String accountName) { - assert false : "Button should be hidden"; + public void onAccountSelected(String accountName) { + mAccountName = accountName; } @Override - public void onSettingsButtonClicked(String accountName) { + public void onDoneClicked() { + if (mUserActionListener != null) mUserActionListener.onAccountSelectionConfirmed(); + SigninManager.get(mActivity).signIn(mAccountName, mActivity, null); + } + + @Override + public void onSettingsClicked() { assert false : "Button should be hidden"; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java index 2b70b635..6afa1e0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -603,6 +603,11 @@ public void onNewAccount() { RecordUserAction.record("Signin_AddAccountToDevice"); } + @Override + public void onAccountSelectionCancelled() { + mRecentTabsManager.setSigninPromoDeclined(); + notifyDataSetChanged(); + } }); } if (!mRecentTabsManager.isSignedIn()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoScreen.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoScreen.java index 96ac59b..b72e672 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoScreen.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoScreen.java
@@ -35,6 +35,7 @@ extends AlwaysDismissedDialog implements AccountFirstRunView.Listener { private AccountFirstRunView mAccountFirstRunView; private ProfileDataCache mProfileDataCache; + private String mAccountName; /** * Launches the signin promo if it needs to be displayed. @@ -98,26 +99,6 @@ mProfileDataCache.destroy(); mProfileDataCache = null; } - - @Override - public void onAccountSelectionConfirmed(String accountName) { - Activity activity = getOwnerActivity(); - RecordUserAction.record("Signin_Signin_FromSigninPromo"); - SigninManager.get(activity).signIn(accountName, activity, new SignInCallback() { - @Override - public void onSignInComplete() { - mAccountFirstRunView.switchToSignedMode(); - SigninPromoUma.recordAction(SigninPromoUma.SIGNIN_PROMO_ACCEPTED); - } - - @Override - public void onSignInAborted() { - SigninPromoUma.recordAction(SigninPromoUma.SIGNIN_PROMO_DECLINED); - dismiss(); - } - }); - } - @Override public void onAccountSelectionCanceled() { SigninPromoUma.recordAction(SigninPromoUma.SIGNIN_PROMO_DECLINED); @@ -130,17 +111,36 @@ } @Override - public void onSigningInCompleted(String accountName) { - dismiss(); + public void onAccountSelected(String accountName) { + mAccountName = accountName; } @Override - public void onSettingsButtonClicked(String accountName) { + public void onDoneClicked() { + Activity activity = getOwnerActivity(); + RecordUserAction.record("Signin_Signin_FromSigninPromo"); + SigninManager.get(activity).signIn(mAccountName, activity, new SignInCallback() { + @Override + public void onSignInComplete() { + SigninManager.get(getOwnerActivity()).logInSignedInUser(); + SigninPromoUma.recordAction(SigninPromoUma.SIGNIN_PROMO_ACCEPTED); + } + + @Override + public void onSignInAborted() { + SigninPromoUma.recordAction(SigninPromoUma.SIGNIN_PROMO_DECLINED); + dismiss(); + } + }); + } + + @Override + public void onSettingsClicked() { if (ProfileSyncService.get() != null) { Intent intent = PreferencesLauncher.createIntentForSettingsPage(getContext(), SyncCustomizationFragment.class.getName()); Bundle args = new Bundle(); - args.putString(SyncCustomizationFragment.ARGUMENT_ACCOUNT, accountName); + args.putString(SyncCustomizationFragment.ARGUMENT_ACCOUNT, mAccountName); intent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, args); getContext().startActivity(intent); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/undo/UndoBarPopupController.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/undo/UndoBarPopupController.java index d77aaef..fe35884d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/undo/UndoBarPopupController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/undo/UndoBarPopupController.java
@@ -129,7 +129,7 @@ TAB_CLOSE_UNDO_TOAST_COUNT); mSnackbarManager.showSnackbar(Snackbar.make(content, this, Snackbar.TYPE_ACTION) .setTemplateText(mContext.getString(R.string.undo_bar_close_message)) - .setAction(mContext.getString(R.string.undo_bar_button_text), tabId)); + .setAction(mContext.getString(R.string.undo), tabId)); } /** @@ -144,7 +144,7 @@ String content = String.format(Locale.getDefault(), "%d", closedTabIds.size()); mSnackbarManager.showSnackbar(Snackbar.make(content, this, Snackbar.TYPE_ACTION) .setTemplateText(mContext.getString(R.string.undo_bar_close_all_message)) - .setAction(mContext.getString(R.string.undo_bar_button_text), closedTabIds)); + .setAction(mContext.getString(R.string.undo), closedTabIds)); }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 9b71ce5..dbae249 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -170,6 +170,9 @@ <message name="IDS_NEXT" desc="Generic label for a button to advance to the next item. [CHAR-LIMIT=20]"> Next </message> + <message name="IDS_UNDO" desc="Generic label for a button to undo the previous action."> + Undo + </message> <!-- Main Preferences --> <message name="IDS_PREFERENCES" desc="Title for Chrome's Settings."> @@ -1586,7 +1589,10 @@ Set up Chrome </message> <message name="IDS_FRE_ACCOUNT_CHOICE_DESCRIPTION" desc="Text for account chooser page"> - Select an account to get your bookmarks, history, passwords, and other settings on all your devices. + Sign in to get your bookmarks, history, passwords, and other settings on all your devices. + </message> + <message name="IDS_FRE_ACCEPT" desc="Text for button to accept being signed in"> + OK, got it </message> <message name="IDS_FRE_SKIP_TEXT" desc="Text for second page skip button"> No thanks @@ -1619,7 +1625,7 @@ Hi, <ph name="FULL_NAME">%1$s<ex>John Smith</ex></ph> </message> <message name="IDS_FRE_SIGNED_IN_DESCRIPTION" desc="Explanation of what gets synced after the user signed in"> - Your bookmarks, history, passwords, and other settings will be synced to your Google Account. + Your bookmarks, history, passwords, and other settings will be synced to your Google Account so you can use them on all your devices. You can choose what to sync in <ph name="BEGIN_LINK1"><LINK1></ph>Settings<ph name="END_LINK1"></LINK1></ph>. </message> <message name="IDS_FRE_SIGNED_IN_DESCRIPTION_UCA_ADDENDUM" desc="Additional explanation for child accounts that synced settings are managed by parents."> Your parents help manage these settings. @@ -2262,9 +2268,6 @@ <message name="IDS_UNDO_BAR_MULTIPLE_DELETE_MESSAGE" desc="Message shown when you can undo several bookmark delete actions."> <ph name="NUMBER_OF_BOOKMARKS">%1$s<ex>3</ex></ph> bookmarks deleted </message> - <message name="IDS_UNDO_BAR_BUTTON_TEXT" desc="Button text to undo closing a tab."> - Undo - </message> <!-- MultiWindow --> <message name="IDS_UNSUPPORTED_NUMBER_OF_WINDOWS" desc="Popup message for when the user has tried to start too many concurrent versions of Chrome.">
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 69aacd6..cf1dd246 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -247,7 +247,6 @@ <structure type="chrome_scaled_image" name="IDR_ENABLE_DEBUGGING_FAILURE" file="cros/enable_debugging_failure.png" /> <structure type="chrome_scaled_image" name="IDR_ENABLE_DEBUGGING_SUCCESS" file="cros/enable_debugging_success.png" /> </if> - <structure type="chrome_scaled_image" name="IDR_ERROR_NETWORK_GENERIC" file="common/error_network_generic.png" /> <structure type="chrome_scaled_image" name="IDR_ERROR_NETWORK_OFFLINE" file="common/error_network_offline.png" /> <if expr="enable_extensions"> <structure type="chrome_scaled_image" name="IDR_EXTENSIONS_FAVICON" file="common/favicon_extensions.png" /> @@ -500,7 +499,6 @@ <structure type="chrome_scaled_image" name="IDR_OMNIBOX_POPUP_BORDER_AND_SHADOW_TOP" file="common/omnibox_popup_border_and_shadow_top.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_POPUP_BORDER_AND_SHADOW_TOP_LEFT" file="common/omnibox_popup_border_and_shadow_top_left.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_POPUP_BORDER_AND_SHADOW_TOP_RIGHT" file="common/omnibox_popup_border_and_shadow_top_right.png" /> - <structure type="chrome_scaled_image" name="IDR_OMNIBOX_SEARCH_BUTTON_LOUPE" file="common/omnibox_search_button_loupe.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_SEARCH_SELECTED" file="common/omnibox_search_selected.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_SELECTED_KEYWORD_BUBBLE_BOTTOM" file="common/omnibox_selected_keyword_bubble_bottom.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_SELECTED_KEYWORD_BUBBLE_BOTTOM_LEFT" file="common/omnibox_selected_keyword_bubble_bottom_left.png" />
diff --git a/chrome/browser/android/profiles/profile_downloader_android.cc b/chrome/browser/android/profiles/profile_downloader_android.cc index 635689d7..eba72f1 100644 --- a/chrome/browser/android/profiles/profile_downloader_android.cc +++ b/chrome/browser/android/profiles/profile_downloader_android.cc
@@ -193,6 +193,15 @@ AccountTrackerService* account_tracker_service = AccountTrackerServiceFactory::GetForProfile(profile); + AccountInfo account_info = + account_tracker_service->FindAccountInfoByEmail(email); + + if (account_info.account_id.empty()) { + LOG(ERROR) << "Attempted to get AccountInfo for account not in the " + << "AccountTrackerService"; + return; + } + AccountInfoRetriever* retriever = new AccountInfoRetriever( profile, account_tracker_service->FindAccountInfoByEmail(email).account_id, email,
diff --git a/chrome/browser/chrome_browser_field_trials.cc b/chrome/browser/chrome_browser_field_trials.cc index 5c8b4af..533ccee 100644 --- a/chrome/browser/chrome_browser_field_trials.cc +++ b/chrome/browser/chrome_browser_field_trials.cc
@@ -29,15 +29,15 @@ // create an appropriate allocator for such if so. void InstantiatePersistentHistograms() { if (base::FeatureList::IsEnabled(base::kPersistentHistogramsFeature)) { - const std::string allocator_name("BrowserMetrics"); + const char kAllocatorName[] = "BrowserMetrics"; // Create persistent/shared memory and allow histograms to be stored in it. // TODO(bcwhite): Update this with correct allocator and memory size. base::SetPersistentHistogramMemoryAllocator( - new base::LocalPersistentMemoryAllocator(1 << 20, // 1 MiB - 0x4D5B9953, // SHA1(B..M..A..) - allocator_name)); + new base::LocalPersistentMemoryAllocator(2 << 20, // 2 MiB + 0x935DDD43, // SHA1(B...M...) + kAllocatorName)); base::GetPersistentHistogramMemoryAllocator()->CreateTrackingHistograms( - allocator_name); + kAllocatorName); } }
diff --git a/chrome/browser/resources/chromeos/neterror.css b/chrome/browser/resources/chromeos/neterror.css index 234c7cc..1b72f5d 100644 --- a/chrome/browser/resources/chromeos/neterror.css +++ b/chrome/browser/resources/chromeos/neterror.css
@@ -40,14 +40,14 @@ * renderer process, so embed the resource manually. */ content: -webkit-image-set( - url(../../../renderer/resources/default_100_percent/common/error_network_generic.png) 1x, - url(../../../renderer/resources/default_200_percent/common/error_network_generic.png) 2x); + url(../../../../components/resources/default_100_percent/neterror/error_network_generic.png) 1x, + url(../../../../components/resources/default_200_percent/neterror/error_network_generic.png) 2x); } .icon-offline { content: -webkit-image-set( - url(../../../renderer/resources/default_100_percent/offline/100-error-offline.png) 1x, - url(../../../renderer/resources/default_200_percent/offline/200-error-offline.png) 2x); + url(../../../../components/neterror/resources/default_100_percent/offline/100-error-offline.png) 1x, + url(../../../../components/neterror/resources/default_200_percent/offline/200-error-offline.png) 2x); } #help-box-outer {
diff --git a/chrome/browser/resources/md_history/history.js b/chrome/browser/resources/md_history/history.js index 50bf72dc..dc695a2 100644 --- a/chrome/browser/resources/md_history/history.js +++ b/chrome/browser/resources/md_history/history.js
@@ -76,6 +76,8 @@ */ function historyResult(info, results) { $('history-list').addNewResults(results); + if (info.finished) + $('history-list').disableResultLoading(); } /**
diff --git a/chrome/browser/resources/md_history/history_list.js b/chrome/browser/resources/md_history/history_list.js index 421e713..9375739 100644 --- a/chrome/browser/resources/md_history/history_list.js +++ b/chrome/browser/resources/md_history/history_list.js
@@ -27,6 +27,11 @@ menuIdentifier: { type: Number, value: 0 + }, + + resultLoadingDisabled_: { + type: Boolean, + value: false } }, @@ -69,6 +74,13 @@ }, /** + * Disables history result loading when there are no more history results. + */ + disableResultLoading: function() { + this.resultLoadingDisabled_ = true; + }, + + /** * Adds the newly updated history results into historyData. Adds new fields * for each result. * @param {!Array<!HistoryEntry>} historyResults The new history results. @@ -212,6 +224,9 @@ // Close overflow menu on scroll. this.closeMenu(); + if (this.resultLoadingDisabled_) + return; + // Requests the next list of results when the scrollbar is near the bottom // of the window. var scrollOffset = 10;
diff --git a/chrome/browser/resources_util_unittest.cc b/chrome/browser/resources_util_unittest.cc index 123b5790..c086aec 100644 --- a/chrome/browser/resources_util_unittest.cc +++ b/chrome/browser/resources_util_unittest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "build/build_config.h" +#include "grit/components_scaled_resources.h" #include "grit/theme_resources.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/resources/grit/ui_resources.h"
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 64299a9..b417e35e 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi
@@ -263,6 +263,7 @@ '../components/components.gyp:translate_content_renderer', '../components/components.gyp:visitedlink_renderer', '../components/components.gyp:web_cache_renderer', + '../components/components_resources.gyp:components_resources', '../content/app/resources/content_resources.gyp:content_resources', '../content/app/strings/content_strings.gyp:content_strings', '../content/content.gyp:content_renderer',
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index e1143ac6..e821ee12 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -48,6 +48,7 @@ "//components/password_manager/content/renderer", "//components/plugins/renderer", "//components/printing/renderer", + "//components/resources:components_resources", "//components/startup_metric_utils/common", "//components/translate/content/renderer", "//components/translate/core/common",
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc index 6d32ec07..937c4d3 100644 --- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -226,7 +226,6 @@ source_map->RegisterSource("chromeWebViewInternal", IDR_CHROME_WEB_VIEW_INTERNAL_CUSTOM_BINDINGS_JS); source_map->RegisterSource("chromeWebView", IDR_CHROME_WEB_VIEW_JS); - source_map->RegisterSource("injectAppTitlebar", IDR_INJECT_APP_TITLEBAR_JS); } void ChromeExtensionsDispatcherDelegate::RequireAdditionalModules(
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc index c813b33..ca58825 100644 --- a/chrome/renderer/net/net_error_helper.cc +++ b/chrome/renderer/net/net_error_helper.cc
@@ -16,7 +16,6 @@ #include "build/build_config.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/render_messages.h" -#include "chrome/grit/renderer_resources.h" #include "components/error_page/common/error_page_params.h" #include "components/error_page/common/localized_error.h" #include "components/error_page/common/net_error_info.h" @@ -28,6 +27,7 @@ #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/resource_fetcher.h" +#include "grit/components_resources.h" #include "ipc/ipc_message.h" #include "ipc/ipc_message_macros.h" #include "third_party/WebKit/public/platform/WebURL.h"
diff --git a/chrome/renderer/resources/extensions/inject_app_titlebar.js b/chrome/renderer/resources/extensions/inject_app_titlebar.js deleted file mode 100644 index 9f2ba37..0000000 --- a/chrome/renderer/resources/extensions/inject_app_titlebar.js +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright (c) 2012 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. - -exports.didCreateDocumentElement = function() { - var root = document.documentElement.createShadowRoot(); - root.appendChild(document.createElement('style')).innerText = - // TODO(jeremya): switch this to use automatic inlining once grit - // supports inlining into JS. See http://crbug.com/146319. - "x-titlebar { height: 24px; width: 100%; " + - "position: fixed; left: 0; top: 0; }\n" + - "div { margin-top: 24px; position: absolute; top: 0px; width: 100%; " + - "-webkit-widget-region: region(control rectangle); }\n" + - ":-webkit-full-screen * { display: none; }\n" + - ":-webkit-full-screen-document * { display: none; }\n" + - "div:-webkit-full-screen, div:-webkit-full-screen-document { " + - "margin-top: 0; }\n" + - "button { -webkit-widget-region: region(control rectangle); }\n" + - "button.close { border: 0; background-color: transparent; " + - "width: 16px; height: 16px; " + - "position: absolute; right: 4px; top: 4px; }\n" + - "button.close { background-image: url(data:image/png;base64," + - "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA9ElEQVQ4T7VTQQ6CMBCk0H" + - "AyIfAQbiZ+QHyDL/QLxqvx4MWDB+MvFAWMAuKsacmmSjkQSDbQ2Z3Z3WkQzsBHDOQ7owgs" + - "MdUacTGmi3BeIFYcNycgciGlfFRVtcd3qoojz/PmdV0XOD8RGy1iCoQgT5G8IyREjni7IC" + - "cg58ilwA7A8i4BwgMUxkKIV9M0PggTAoFlJpnwLhO5iEuFapq2s20CyoWIGbpeaRICyrI8" + - "89FtAtqwGxdQ65yYsV8NcwVN5obR/uTJW4mQsfp2fgToGjPqbBjWeoJVfNRsbSskSO7+7B" + - "sAiznZdgu6Qe97lH+htysv+AA10msRAt5JYQAAAABJRU5ErkJggg==); }\n" + - "button.close:hover { background-image: url(data:image/png;base64," + - "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABTElEQVQ4T2NkoBAwUqifAc" + - "WA////KwANFAPiV4yMjA+QDcclBzcApCA6Otpz2bJluQkJCf3z58/fDTMEnxyyAWZADQuA" + - "tj4B4ncpKSnbZs+efQjkCqjBmUDmMyD+ADSwD6j2FEgOxQWJiYmuCxYscIYawpWamnr89+" + - "/fHECxbKjmB2VlZbs6OzsvwFyHEQZATXZz5syxAGr4BMR8QCwJDYvn1dXVO1taWi4ihw9G" + - "LID8m5aWZgt0viXUEBaQAUDNh9E1o3gBFuIgA6Be8QKK3QXiLyA5oNMvIDsdph7DC9AASw" + - "cquI9sAJDNk5GRcX769OlHsXoBKapAoQ2KiQcgPwMDkbGrq8sGyP8DChNQwM6aNeswRiAC" + - "DYBF4yOgwnuwAAM5NTMz03rGjBnWsIAFql2ANxqB/l2B7F/kgCUYjUBbyEvKsFAllaY4Nw" + - "IAmJDPEd+LFvYAAAAASUVORK5CYII=); }\n" + - "button.close:active { background-image: url(data:image/png;base64," + - "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAZ0lEQVQ4T2NkoBAwUqifge" + - "oG2AFd1AfERUB8CM11WOXQXXAGSROyITDNMGkTGAPdAHSFIENAAOQqGEBxHbYwQDcE2ScY" + - "XsMViNgMwRYuOGOBIgMo8gLFgUi1aCQ7IZGcNaieF0h2AQCMABwRdsuhtQAAAABJRU5Erk" + - "Jggg==); }\n" - var titlebar = root.appendChild(document.createElement('x-titlebar')); - var closeButton = titlebar.appendChild(document.createElement('button')); - closeButton.className = 'close' - closeButton.addEventListener('click', function() { window.close(); }); - var container = root.appendChild(document.createElement('div')); - container.appendChild(document.createElement('content')); -}
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd index 731eead..732d4c6 100644 --- a/chrome/renderer/resources/renderer_resources.grd +++ b/chrome/renderer/resources/renderer_resources.grd
@@ -19,7 +19,6 @@ </if> <include name="IDR_BLOCKED_PLUGIN_HTML" file="plugins/blocked_plugin.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_DISABLED_PLUGIN_HTML" file="plugins/disabled_plugin.html" flattenhtml="true" type="BINDATA" /> - <include name="IDR_NET_ERROR_HTML" file="neterror.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_PLUGIN_POSTER_HTML" file="plugins/plugin_poster.html" flattenhtml="true" type="BINDATA" /> <!-- Searchbox API --> @@ -87,9 +86,6 @@ <include name="IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS" file="extensions\tts_engine_custom_bindings.js" type="BINDATA" /> <include name="IDR_WEBRTC_DESKTOP_CAPTURE_PRIVATE_CUSTOM_BINDINGS_JS" file="extensions\webrtc_desktop_capture_private_custom_bindings.js" type="BINDATA" /> <include name="IDR_WEBSTORE_CUSTOM_BINDINGS_JS" file="extensions\webstore_custom_bindings.js" type="BINDATA" /> - - <!-- Platform app support. --> - <include name="IDR_INJECT_APP_TITLEBAR_JS" file="extensions\inject_app_titlebar.js" type="BINDATA" /> </if> </includes> </release>
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index c178b5f7..998e476 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -7921.0.0 \ No newline at end of file +7925.0.0 \ No newline at end of file
diff --git a/components/neterror/OWNERS b/components/neterror/OWNERS new file mode 100644 index 0000000..0c27a2f --- /dev/null +++ b/components/neterror/OWNERS
@@ -0,0 +1,3 @@ +jar@chromium.org +mmenke@chromium.org +ttuttle@chromium.org
diff --git a/chrome/renderer/resources/default_100_percent/offline/100-disabled.png b/components/neterror/resources/default_100_percent/offline/100-disabled.png similarity index 100% rename from chrome/renderer/resources/default_100_percent/offline/100-disabled.png rename to components/neterror/resources/default_100_percent/offline/100-disabled.png Binary files differ
diff --git a/chrome/renderer/resources/default_100_percent/offline/100-error-offline.png b/components/neterror/resources/default_100_percent/offline/100-error-offline.png similarity index 100% rename from chrome/renderer/resources/default_100_percent/offline/100-error-offline.png rename to components/neterror/resources/default_100_percent/offline/100-error-offline.png Binary files differ
diff --git a/chrome/renderer/resources/default_100_percent/offline/100-offline-sprite.png b/components/neterror/resources/default_100_percent/offline/100-offline-sprite.png similarity index 100% rename from chrome/renderer/resources/default_100_percent/offline/100-offline-sprite.png rename to components/neterror/resources/default_100_percent/offline/100-offline-sprite.png Binary files differ
diff --git a/chrome/renderer/resources/default_200_percent/offline/200-disabled.png b/components/neterror/resources/default_200_percent/offline/200-disabled.png similarity index 100% rename from chrome/renderer/resources/default_200_percent/offline/200-disabled.png rename to components/neterror/resources/default_200_percent/offline/200-disabled.png Binary files differ
diff --git a/chrome/renderer/resources/default_200_percent/offline/200-error-offline.png b/components/neterror/resources/default_200_percent/offline/200-error-offline.png similarity index 100% rename from chrome/renderer/resources/default_200_percent/offline/200-error-offline.png rename to components/neterror/resources/default_200_percent/offline/200-error-offline.png Binary files differ
diff --git a/chrome/renderer/resources/default_200_percent/offline/200-offline-sprite.png b/components/neterror/resources/default_200_percent/offline/200-offline-sprite.png similarity index 100% rename from chrome/renderer/resources/default_200_percent/offline/200-offline-sprite.png rename to components/neterror/resources/default_200_percent/offline/200-offline-sprite.png Binary files differ
diff --git a/components/neterror/resources/neterror.css b/components/neterror/resources/neterror.css new file mode 100644 index 0000000..b9ba88b --- /dev/null +++ b/components/neterror/resources/neterror.css
@@ -0,0 +1,472 @@ +/* Copyright 2013 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. */ + +/* Don't use the main frame div when the error is in a subframe. */ +html[subframe] #main-frame-error { + display: none; +} + +/* Don't use the subframe error div when the error is in a main frame. */ +html:not([subframe]) #sub-frame-error { + display: none; +} + +#diagnose-button { + -webkit-margin-start: 0; + float: none; + margin-bottom: 10px; + margin-top: 20px; +} + +h1 { + margin-top: 0; + word-wrap: break-word; +} + +h1 span { + font-weight: 500; +} + +h2 { + color: #666; + font-size: 1.2em; + font-weight: normal; + margin: 10px 0; +} + +a { + color: rgb(17, 85, 204); + text-decoration: none; +} + +.icon { + -webkit-user-select: none; + display: inline-block; +} + +.icon-generic { + /** + * Can't access chrome://theme/IDR_ERROR_NETWORK_GENERIC from an untrusted + * renderer process, so embed the resource manually. + */ + content: -webkit-image-set( + url(../../resources/default_100_percent/neterror/error_network_generic.png) 1x, + url(../../resources/default_200_percent/neterror/error_network_generic.png) 2x); +} + +.icon-offline { + content: -webkit-image-set( + url(default_100_percent/offline/100-error-offline.png) 1x, + url(default_200_percent/offline/200-error-offline.png) 2x); + position: relative; +} + +.icon-disabled { + content: -webkit-image-set( + url(default_100_percent/offline/100-disabled.png) 1x, + url(default_200_percent/offline/200-disabled.png) 2x); + width: 112px; +} + +.error-code { + display: block; + font-size: .8em; +} + +#content-top { + margin: 20px; +} + +#help-box-inner { + background-color: #f9f9f9; + border-top: 1px solid #EEE; + color: #444; + padding: 20px; + text-align: start; +} + +.hidden { + display: none; +} + +#suggestion { + margin-top: 15px; +} + +#short-suggestion { + margin-top: 5px; +} + +#sub-frame-error-details { +<if expr="is_ios"> + font-size: 8pt; +</if> + color: #8F8F8F; +<if expr="not is_android and not is_ios"> + /* Not done on mobile for performance reasons. */ + text-shadow: 0 1px 0 rgba(255,255,255,0.3); +</if> +} + +[jscontent=failedUrl] { + overflow-wrap: break-word; +} + +#search-container { + /* Prevents a space between controls. */ + display: flex; + margin-top: 20px; +} + +#search-box { + border: 1px solid #cdcdcd; + flex-grow: 1; + font-size: 1em; + height: 26px; + margin-right: 0; + padding: 1px 9px; +} + +#search-box:focus { + border: 1px solid rgb(93, 154, 255); + outline: none; +} + +#search-button { + border: none; + border-bottom-left-radius: 0; + border-top-left-radius: 0; + box-shadow: none; + display: flex; + height: 30px; + margin: 0; + padding: 0; + width: 60px; +} + +#search-image { + content: + -webkit-image-set( + url(../../resources/default_100_percent/omnibox/omnibox_search_button_loupe.png) 1x, + url(../../resources/default_200_percent/omnibox/omnibox_search_button_loupe.png) 2x); + margin: auto; +} + +.secondary-button { + -webkit-margin-end: 16px; + background: #d9d9d9; + color: #696969; +} + +.snackbar { + background: #323232; + border-radius: 2px; + bottom: 24px; + box-sizing: border-box; + color: #fff; + font-size: .87em; + left: 24px; + max-width: 568px; + min-width: 288px; + opacity: 0; + padding: 16px 24px 12px; + position: fixed; + transform: translateY(90px); + will-change: opacity, transform; + z-index: 999; +} + +.snackbar-show { + -webkit-animation: + show-snackbar .25s cubic-bezier(0.0, 0.0, 0.2, 1) forwards, + hide-snackbar .25s cubic-bezier(0.4, 0.0, 1, 1) forwards 5s; +} + +@-webkit-keyframes show-snackbar { + 100% { + opacity: 1; + transform: translateY(0); + } +} + +@-webkit-keyframes hide-snackbar { + 0% { + opacity: 1; + transform: translateY(0); + } + 100% { + opacity: 0; + transform: translateY(90px); + } +} + +.suggestions { + margin-top: 18px; +} + +.suggestion-header { + font-weight: bold; + margin-bottom: 4px; +} + +.suggestion-body { + color: #777; +} + +/* Increase line height at higher resolutions. */ +@media (min-width: 641px) and (min-height: 641px) { + #help-box-inner { + line-height: 18px; + } +} + +/* Decrease padding at low sizes. */ +@media (max-width: 640px), (max-height: 640px) { + h1 { + margin: 0 0 15px; + } + #content-top { + margin: 15px; + } + #help-box-inner { + padding: 20px; + } + .suggestions { + margin-top: 10px; + } + .suggestion-header { + margin-bottom: 0; + } +} + +/* Don't allow overflow when in a subframe. */ +html[subframe] body { + overflow: hidden; +} + +#sub-frame-error { + -webkit-align-items: center; + background-color: #DDD; + display: -webkit-flex; + -webkit-flex-flow: column; + height: 100%; + -webkit-justify-content: center; + left: 0; + position: absolute; + top: 0; + transition: background-color .2s ease-in-out; + width: 100%; +} + +#sub-frame-error:hover { + background-color: #EEE; +} + +#sub-frame-error .icon-generic { + margin: 0 0 16px; +} + +#sub-frame-error-details { + margin: 0 10px; + text-align: center; + visibility: hidden; +} + +/* Show details only when hovering. */ +#sub-frame-error:hover #sub-frame-error-details { + visibility: visible; +} + +/* If the iframe is too small, always hide the error code. */ +/* TODO(mmenke): See if overflow: no-display works better, once supported. */ +@media (max-width: 200px), (max-height: 95px) { + #sub-frame-error-details { + display: none; + } +} + +/* Adjust icon for small embedded frames in apps. */ +@media (max-height: 100px) { + #sub-frame-error .icon-generic { + height: auto; + margin: 0; + padding-top: 0; + width: 25px; + } +} + +/* details-button is special; it's a <button> element that looks like a link. */ +#details-button { + box-shadow: none; + min-width: 0; +} + +/* Styles for platform dependent separation of controls and details button. */ +.suggested-left > #control-buttons, +.suggested-left #stale-load-button, +.suggested-right > #details-button { + float: left; +} + +.suggested-right > #control-buttons, +.suggested-right #stale-load-button, +.suggested-left > #details-button { + float: right; +} + +.suggested-left .secondary-button { + -webkit-margin-end: 0px; + -webkit-margin-start: 16px; +} + +#details-button.singular { + float: none; +} + +#buttons::after { + clear: both; + content: ''; + display: block; + width: 100%; +} + +/* Offline page */ +.offline { + transition: -webkit-filter 1.5s cubic-bezier(0.65, 0.05, 0.36, 1), + background-color 1.5s cubic-bezier(0.65, 0.05, 0.36, 1); + will-change: -webkit-filter, background-color; +} + +.offline.inverted { + -webkit-filter: invert(100%); + background-color: #000; +} + +.offline .interstitial-wrapper { + color: #2b2b2b; + font-size: 1em; + line-height: 1.55; + margin: 0 auto; + max-width: 600px; + padding-top: 100px; + width: 100%; +} + +.offline .runner-container { + height: 150px; + max-width: 600px; + overflow: hidden; + position: absolute; + top: 35px; + width: 44px; +} + +.offline .runner-canvas { + height: 150px; + max-width: 600px; + opacity: 1; + overflow: hidden; + position: absolute; + top: 0; + z-index: 2; +} + +.offline .controller { + background: rgba(247,247,247, .1); + height: 100vh; + left: 0; + position: absolute; + top: 0; + width: 100vw; + z-index: 1; +} + +#offline-resources { + display: none; +} + +@media (max-width: 420px) { + .suggested-left > #control-buttons, + .suggested-right > #control-buttons { + float: none; + } + + .snackbar { + left: 0; + bottom: 0; + width: 100%; + border-radius: 0; + } +} + +@media (max-height: 350px) { + h1 { + margin: 0 0 15px; + } + + .icon-offline { + margin: 0 0 10px; + } + + .interstitial-wrapper { + margin-top: 5%; + } + + .nav-wrapper { + margin-top: 30px; + } +} + +@media (min-width: 600px) and (max-width: 736px) and (orientation: landscape) { + .offline .interstitial-wrapper { + margin-left: 0; + margin-right: 0; + } +} + +@media (min-width: 420px) and (max-width: 736px) and + (min-height: 240px) and (max-height: 420px) and + (orientation:landscape) { + .interstitial-wrapper { + margin-bottom: 100px; + } +} + +@media (min-height: 240px) and (orientation: landscape) { + .offline .interstitial-wrapper { + margin-bottom: 90px; + } + + .icon-offline { + margin-bottom: 20px; + } +} + +@media (max-height: 320px) and (orientation: landscape) { + .icon-offline { + margin-bottom: 0; + } + + .offline .runner-container { + top: 10px; + } +} + +@media (max-width: 240px) { + button { + padding-left: 12px; + padding-right: 12px; + } + + .interstitial-wrapper { + overflow: inherit; + padding: 0 8px; + } +} + +@media (max-width: 120px) { + button { + width: auto; + } +}
diff --git a/chrome/renderer/resources/neterror.html b/components/neterror/resources/neterror.html similarity index 94% rename from chrome/renderer/resources/neterror.html rename to components/neterror/resources/neterror.html index f8f53ea..5615447 100644 --- a/chrome/renderer/resources/neterror.html +++ b/components/neterror/resources/neterror.html
@@ -5,9 +5,9 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title i18n-content="title"></title> - <link rel="stylesheet" href="../../../components/security_interstitials/core/browser/resources/interstitial_v2.css"> + <link rel="stylesheet" href="../../security_interstitials/core/browser/resources/interstitial_v2.css"> <link rel="stylesheet" href="neterror.css"> - <script src="../../../components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js"></script> + <script src="../../security_interstitials/core/browser/resources/interstitial_v2_mobile.js"></script> <script src="neterror.js"></script> <script src="offline.js"></script> </head>
diff --git a/chrome/renderer/resources/neterror.js b/components/neterror/resources/neterror.js similarity index 100% rename from chrome/renderer/resources/neterror.js rename to components/neterror/resources/neterror.js
diff --git a/chrome/renderer/resources/offline.js b/components/neterror/resources/offline.js similarity index 100% rename from chrome/renderer/resources/offline.js rename to components/neterror/resources/offline.js
diff --git a/chrome/renderer/resources/sounds/button-press.mp3 b/components/neterror/resources/sounds/button-press.mp3 similarity index 100% rename from chrome/renderer/resources/sounds/button-press.mp3 rename to components/neterror/resources/sounds/button-press.mp3 Binary files differ
diff --git a/chrome/renderer/resources/sounds/hit.mp3 b/components/neterror/resources/sounds/hit.mp3 similarity index 100% rename from chrome/renderer/resources/sounds/hit.mp3 rename to components/neterror/resources/sounds/hit.mp3 Binary files differ
diff --git a/chrome/renderer/resources/sounds/score-reached.mp3 b/components/neterror/resources/sounds/score-reached.mp3 similarity index 100% rename from chrome/renderer/resources/sounds/score-reached.mp3 rename to components/neterror/resources/sounds/score-reached.mp3 Binary files differ
diff --git a/components/resources/OWNERS b/components/resources/OWNERS index a247c17..83609568 100644 --- a/components/resources/OWNERS +++ b/components/resources/OWNERS
@@ -18,6 +18,8 @@ per-file gcm_driver_resources.grdp=jianli@chromium.org per-file gcm_driver_resources.grdp=peter@chromium.org per-file gcm_driver_resources.grdp=zea@chromium.org +per-file neterror*=mmenke@chromium.org +per-file neterror*=ttuttle@chromium.org per-file proximity_auth*=isherman@chromium.org per-file proximity_auth*=tengs@chromium.org per-file version_ui*=bauerb@chromium.org
diff --git a/components/resources/components_resources.grd b/components/resources/components_resources.grd index 466ae2e..3793a19 100644 --- a/components/resources/components_resources.grd +++ b/components/resources/components_resources.grd
@@ -15,6 +15,7 @@ <part file="flags_ui_resources.grdp" /> <part file="gcm_driver_resources.grdp" /> <part file="net_log_resources.grdp" /> + <part file="neterror_resources.grdp" /> <part file="printing_resources.grdp" /> <part file="proximity_auth_resources.grdp" /> <part file="security_interstitials_resources.grdp" />
diff --git a/components/resources/components_scaled_resources.grd b/components/resources/components_scaled_resources.grd index 82fc3fd..5be1c8c 100644 --- a/components/resources/components_scaled_resources.grd +++ b/components/resources/components_scaled_resources.grd
@@ -17,6 +17,7 @@ <part file="autofill_scaled_resources.grdp" /> <part file="crash_scaled_resources.grdp" /> <part file="flags_ui_scaled_resources.grdp" /> + <part file="neterror_scaled_resources.grdp" /> <part file="omnibox_scaled_resources.grdp" /> <part file="version_ui_scaled_resources.grdp" />
diff --git a/chrome/app/theme/default_100_percent/common/error_network_generic.png b/components/resources/default_100_percent/neterror/error_network_generic.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/error_network_generic.png rename to components/resources/default_100_percent/neterror/error_network_generic.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/omnibox_search_button_loupe.png b/components/resources/default_100_percent/omnibox/omnibox_search_button_loupe.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/omnibox_search_button_loupe.png rename to components/resources/default_100_percent/omnibox/omnibox_search_button_loupe.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/error_network_generic.png b/components/resources/default_200_percent/neterror/error_network_generic.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/error_network_generic.png rename to components/resources/default_200_percent/neterror/error_network_generic.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/omnibox_search_button_loupe.png b/components/resources/default_200_percent/omnibox/omnibox_search_button_loupe.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/omnibox_search_button_loupe.png rename to components/resources/default_200_percent/omnibox/omnibox_search_button_loupe.png Binary files differ
diff --git a/components/resources/neterror_resources.grdp b/components/resources/neterror_resources.grdp new file mode 100644 index 0000000..298f85ac --- /dev/null +++ b/components/resources/neterror_resources.grdp
@@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit-part> + <include name="IDR_NET_ERROR_HTML" file="../neterror/resources/neterror.html" flattenhtml="true" type="BINDATA" /> +</grit-part>
diff --git a/components/resources/neterror_scaled_resources.grdp b/components/resources/neterror_scaled_resources.grdp new file mode 100644 index 0000000..1e2cad3 --- /dev/null +++ b/components/resources/neterror_scaled_resources.grdp
@@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit-part> + <structure type="chrome_scaled_image" name="IDR_ERROR_NETWORK_GENERIC" file="neterror/error_network_generic.png" /> +</grit-part>
diff --git a/components/resources/omnibox_scaled_resources.grdp b/components/resources/omnibox_scaled_resources.grdp index b8890f8d..46a18f3 100644 --- a/components/resources/omnibox_scaled_resources.grdp +++ b/components/resources/omnibox_scaled_resources.grdp
@@ -3,6 +3,7 @@ <structure type="chrome_scaled_image" name="IDR_OMNIBOX_CALCULATOR" file="omnibox/omnibox_calculator.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_EXTENSION_APP" file="omnibox/omnibox_extension_app.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_HTTPS_POLICY_WARNING" file="omnibox/controlled_setting_mandatory.png" /> + <structure type="chrome_scaled_image" name="IDR_OMNIBOX_SEARCH_BUTTON_LOUPE" file="omnibox/omnibox_search_button_loupe.png" /> <if expr="is_ios"> <structure type="chrome_scaled_image" name="IDR_LOCATION_BAR_HTTP" file="omnibox/ios/location_bar_http.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_HISTORY" file="omnibox/ios/omnibox_history.png" />
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc index f7ff1907..bb2a918 100644 --- a/content/browser/loader/async_resource_handler.cc +++ b/content/browser/loader/async_resource_handler.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/containers/hash_tables.h" #include "base/debug/alias.h" +#include "base/feature_list.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/shared_memory.h" @@ -26,6 +27,7 @@ #include "content/common/resource_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" +#include "content/public/common/content_features.h" #include "content/public/common/resource_response.h" #include "net/base/io_buffer.h" #include "net/base/load_flags.h" @@ -45,6 +47,14 @@ // The interval for calls to ReportUploadProgress. static int kUploadProgressIntervalMsec = 10; +// Used when kOptimizeIPCForSmallResource is enabled. +// Small resource typically issues two Read call: one for the content itself +// and another for getting zero response to detect EOF. +// Inline these two into the IPC message to avoid allocating an expensive +// SharedMemory for small resources. +const int kNumLeadingChunk = 2; +const int kInlinedLeadingChunkSize = 2048; + void GetNumericArg(const std::string& name, int* result) { const std::string& value = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(name); @@ -65,6 +75,111 @@ } // namespace +// Used when kOptimizeIPCForSmallResource is enabled. +// The instance hooks the buffer allocation of AsyncResourceHandler, and +// determine if we should use SharedMemory or should inline the data into +// the IPC message. +class AsyncResourceHandler::InliningHelper { + public: + + InliningHelper() {} + ~InliningHelper() {} + + void OnResponseReceived(const ResourceResponse& response) { + InliningStatus status = IsInliningApplicable(response); + UMA_HISTOGRAM_ENUMERATION( + "Net.ResourceLoader.InliningStatus", + static_cast<int>(status), + static_cast<int>(InliningStatus::INLINING_STATUS_COUNT)); + inlining_applicable_ = status == InliningStatus::APPLICABLE; + } + + // Returns true if InliningHelper allocates the buffer for inlining. + bool PrepareInlineBufferIfApplicable(scoped_refptr<net::IOBuffer>* buf, + int* buf_size) { + ++num_allocation_; + + // If the server sends the resource in multiple small chunks, + // |num_allocation_| may exceed |kNumLeadingChunk|. Disable inlining and + // fall back to the regular resource loading path in that case. + if (!inlining_applicable_ || + num_allocation_ > kNumLeadingChunk || + !base::FeatureList::IsEnabled(features::kOptimizeIPCForSmallResource)) { + return false; + } + + leading_chunk_buffer_ = new net::IOBuffer(kInlinedLeadingChunkSize); + *buf = leading_chunk_buffer_; + *buf_size = kInlinedLeadingChunkSize; + return true; + } + + // Returns true if the received data is sent to the consumer. + bool SendInlinedDataIfApplicable(int bytes_read, + int encoded_data_length, + IPC::Sender* sender, + int request_id) { + DCHECK(sender); + if (!leading_chunk_buffer_) + return false; + + std::vector<char> data( + leading_chunk_buffer_->data(), + leading_chunk_buffer_->data() + bytes_read); + leading_chunk_buffer_ = nullptr; + + sender->Send(new ResourceMsg_InlinedDataChunkReceived( + request_id, data, encoded_data_length)); + return true; + } + + void RecordHistogram(int64_t elapsed_time) { + if (inlining_applicable_) { + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Net.ResourceLoader.ResponseStartToEnd.InliningApplicable", + elapsed_time, 1, 100000, 100); + } + } + + private: + enum class InliningStatus : int { + APPLICABLE = 0, + EARLY_ALLOCATION = 1, + UNKNOWN_CONTENT_LENGTH = 2, + LARGE_CONTENT = 3, + HAS_TRANSFER_ENCODING = 4, + HAS_CONTENT_ENCODING = 5, + INLINING_STATUS_COUNT, + }; + + InliningStatus IsInliningApplicable(const ResourceResponse& response) { + // Disable if the leading chunk is already arrived. + if (num_allocation_) + return InliningStatus::EARLY_ALLOCATION; + + // Disable if the content is known to be large. + if (response.head.content_length > kInlinedLeadingChunkSize) + return InliningStatus::LARGE_CONTENT; + + // Disable if the length of the content is unknown. + if (response.head.content_length < 0) + return InliningStatus::UNKNOWN_CONTENT_LENGTH; + + if (response.head.headers) { + if (response.head.headers->HasHeader("Transfer-Encoding")) + return InliningStatus::HAS_TRANSFER_ENCODING; + if (response.head.headers->HasHeader("Content-Encoding")) + return InliningStatus::HAS_CONTENT_ENCODING; + } + + return InliningStatus::APPLICABLE; + } + + int num_allocation_ = 0; + bool inlining_applicable_ = false; + scoped_refptr<net::IOBuffer> leading_chunk_buffer_; +}; + class DependentIOBuffer : public net::WrappedIOBuffer { public: DependentIOBuffer(ResourceBuffer* backing, char* memory) @@ -87,7 +202,8 @@ did_defer_(false), has_checked_for_sufficient_resources_(false), sent_received_response_msg_(false), - sent_first_data_msg_(false), + sent_data_buffer_msg_(false), + inlining_helper_(new InliningHelper), last_upload_position_(0), waiting_for_upload_progress_ack_(false), reported_transfer_size_(0) { @@ -266,6 +382,7 @@ copy)); } + inlining_helper_->OnResponseReceived(*response); return true; } @@ -294,6 +411,11 @@ if (!CheckForSufficientResource()) return false; + // Return early if InliningHelper allocates the buffer, so that we should + // inline the data into the IPC message without allocating SharedMemory. + if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) + return true; + if (!EnsureResourceBufferIsInitialized()) return false; @@ -317,9 +439,16 @@ if (!filter) return false; + int encoded_data_length = CalculateEncodedDataLengthToReport(); + + // Return early if InliningHelper handled the received data. + if (inlining_helper_->SendInlinedDataIfApplicable( + bytes_read, encoded_data_length, filter, GetRequestID())) + return true; + buffer_->ShrinkLastAllocation(bytes_read); - if (!sent_first_data_msg_) { + if (!sent_data_buffer_msg_) { base::SharedMemoryHandle handle; int size; if (!buffer_->ShareToProcess(filter->PeerHandle(), &handle, &size)) @@ -329,11 +458,10 @@ CHECK_LE(size, kBufferSize); filter->Send(new ResourceMsg_SetDataBuffer( GetRequestID(), handle, size, filter->peer_pid())); - sent_first_data_msg_ = true; + sent_data_buffer_msg_ = true; } int data_offset = buffer_->GetLastAllocationOffset(); - int encoded_data_length = CalculateEncodedDataLengthToReport(); // TODO(erikchen): Temporary debugging. http://crbug.com/527588. CHECK_LE(data_offset, kBufferSize); @@ -415,7 +543,8 @@ info->filter()->Send( new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); - RecordHistogram(); + if (status.is_success()) + RecordHistogram(); } bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { @@ -483,6 +612,8 @@ "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", elapsed_time, 1, 100000, 100); } + + inlining_helper_->RecordHistogram(elapsed_time); } } // namespace content
diff --git a/content/browser/loader/async_resource_handler.h b/content/browser/loader/async_resource_handler.h index f46fef96..5097413 100644 --- a/content/browser/loader/async_resource_handler.h +++ b/content/browser/loader/async_resource_handler.h
@@ -14,6 +14,7 @@ #include "base/timer/timer.h" #include "content/browser/loader/resource_handler.h" #include "content/browser/loader/resource_message_delegate.h" +#include "net/base/io_buffer.h" #include "url/gurl.h" namespace net { @@ -55,6 +56,8 @@ void OnDataDownloaded(int bytes_downloaded) override; private: + class InliningHelper; + // IPC message handlers: void OnFollowRedirect(int request_id); void OnDataReceivedACK(int request_id); @@ -82,8 +85,9 @@ bool has_checked_for_sufficient_resources_; bool sent_received_response_msg_; - bool sent_first_data_msg_; + bool sent_data_buffer_msg_; + scoped_ptr<InliningHelper> inlining_helper_; base::TimeTicks response_started_ticks_; uint64_t last_upload_position_;
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc index 9341fcf..79a8f80 100644 --- a/content/browser/loader/resource_dispatcher_host_unittest.cc +++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -7,6 +7,7 @@ #include <vector> #include "base/bind.h" +#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/location.h" @@ -41,6 +42,7 @@ #include "content/public/browser/web_contents_observer.h" #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/child_process_host.h" +#include "content/public/common/content_features.h" #include "content/public/common/process_type.h" #include "content/public/common/resource_response.h" #include "content/public/test/test_browser_context.h" @@ -126,6 +128,7 @@ case ResourceMsg_ReceivedRedirect::ID: case ResourceMsg_SetDataBuffer::ID: case ResourceMsg_DataReceived::ID: + case ResourceMsg_InlinedDataChunkReceived::ID: case ResourceMsg_DataDownloaded::ID: case ResourceMsg_RequestComplete::ID: { bool result = base::PickleIterator(msg).ReadInt(&request_id); @@ -828,7 +831,12 @@ net::UploadProgress upload_progress; }; -class ResourceDispatcherHostTest : public testing::Test, +enum class TestConfig { + kDefault, + kOptimizeIPCForSmallResourceEnabled, +}; + +class ResourceDispatcherHostTest : public testing::TestWithParam<TestConfig>, public IPC::Sender { public: typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo; @@ -899,6 +907,22 @@ browser_context_->GetResourceContext(), web_contents_->GetRenderProcessHost()->GetID()); child_ids_.insert(web_contents_->GetRenderProcessHost()->GetID()); + + base::FeatureList::ClearInstanceForTesting(); + switch (GetParam()) { + case TestConfig::kDefault: + base::FeatureList::InitializeInstance(); + break; + case TestConfig::kOptimizeIPCForSmallResourceEnabled: { + scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); + feature_list->InitializeFromCommandLine( + features::kOptimizeIPCForSmallResource.name, std::string()); + base::FeatureList::SetInstance(std::move(feature_list)); + ASSERT_TRUE(base::FeatureList::IsEnabled( + features::kOptimizeIPCForSmallResource)); + break; + } + } } void TearDown() override { @@ -1193,6 +1217,22 @@ ASSERT_EQ(expected_error_code, error_code); } +testing::AssertionResult ExtractInlinedChunkData( + const IPC::Message& message, + std::string* leading_chunk_data) { + base::PickleIterator iter(message); + int request_id; + if (!IPC::ReadParam(&message, &iter, &request_id)) + return testing::AssertionFailure() << "Could not read request_id"; + + std::vector<char> data; + if (!IPC::ReadParam(&message, &iter, &data)) + return testing::AssertionFailure() << "Could not read data"; + leading_chunk_data->assign(data.begin(), data.end()); + + return testing::AssertionSuccess(); +} + testing::AssertionResult ExtractDataOffsetAndLength(const IPC::Message& message, int* data_offset, int* data_length) { @@ -1207,10 +1247,39 @@ return testing::AssertionSuccess(); } +void CheckSuccessfulRequestWithErrorCodeForInlinedCase( + const std::vector<IPC::Message>& messages, + const std::string& reference_data, + int expected_error) { + // A successful request on the inlined case will have received 3 messages: + // ReceivedResponse (indicates headers received) + // InlinedDataChunkReceived (contains the content) + // RequestComplete (request is done) + + ASSERT_EQ(3U, messages.size()); + + // The first messages should be received response + ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type()); + ASSERT_EQ(ResourceMsg_InlinedDataChunkReceived::ID, messages[1].type()); + + std::string leading_chunk_data; + ASSERT_TRUE(ExtractInlinedChunkData(messages[1], &leading_chunk_data)); + ASSERT_EQ(reference_data, leading_chunk_data); + CheckRequestCompleteErrorCode(messages[2], expected_error); +} + void CheckSuccessfulRequestWithErrorCode( const std::vector<IPC::Message>& messages, const std::string& reference_data, int expected_error) { + ASSERT_LT(2U, messages.size()); + if (base::FeatureList::IsEnabled(features::kOptimizeIPCForSmallResource) && + messages[1].type() == ResourceMsg_InlinedDataChunkReceived::ID) { + CheckSuccessfulRequestWithErrorCodeForInlinedCase( + messages, reference_data, expected_error); + return; + } + // A successful request will have received 4 messages: // ReceivedResponse (indicates headers received) // SetDataBuffer (contains shared memory handle) @@ -1286,7 +1355,7 @@ } // Tests whether many messages get dispatched properly. -TEST_F(ResourceDispatcherHostTest, TestMany) { +TEST_P(ResourceDispatcherHostTest, TestMany) { MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); @@ -1319,7 +1388,7 @@ // Tests whether messages get canceled properly. We issue four requests, // cancel two of them, and make sure that each sent the proper notifications. -TEST_F(ResourceDispatcherHostTest, Cancel) { +TEST_P(ResourceDispatcherHostTest, Cancel) { MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); @@ -1374,7 +1443,7 @@ // Shows that detachable requests will timeout if the request takes too long to // complete. -TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) { +TEST_P(ResourceDispatcherHostTest, DetachedResourceTimesOut) { MakeTestRequestWithResourceType(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_PREFETCH); // detachable type @@ -1416,7 +1485,7 @@ // If the filter has disappeared then detachable resources should continue to // load. -TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) { +TEST_P(ResourceDispatcherHostTest, DeletedFilterDetached) { // test_url_1's data is available synchronously, so use 2 and 3. ResourceHostMsg_Request request_prefetch = CreateResourceRequest( "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_2()); @@ -1468,7 +1537,7 @@ // If the filter has disappeared (original process dies) then detachable // resources should continue to load, even when redirected. -TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) { +TEST_P(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) { ResourceHostMsg_Request request = CreateResourceRequest( "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_redirect_to_url_2()); @@ -1515,7 +1584,7 @@ EXPECT_EQ(0, network_delegate()->error_count()); } -TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) { +TEST_P(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) { bool was_deleted = false; // Arrange to have requests deferred before starting. @@ -1539,7 +1608,7 @@ EXPECT_TRUE(was_deleted); } -TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) { +TEST_P(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) { bool was_deleted = false; // Arrange to have requests deferred before starting. @@ -1581,7 +1650,7 @@ // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the // URLRequest will not be started. -TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) { +TEST_P(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) { TestResourceDispatcherHostDelegate delegate; delegate.set_flags(CANCEL_BEFORE_START); host_.SetDelegate(&delegate); @@ -1603,7 +1672,7 @@ EXPECT_EQ(0, job_factory_->url_request_jobs_created_count()); } -TEST_F(ResourceDispatcherHostTest, PausedStartError) { +TEST_P(ResourceDispatcherHostTest, PausedStartError) { // Arrange to have requests deferred before processing response headers. TestResourceDispatcherHostDelegate delegate; delegate.set_flags(DEFER_PROCESSING_RESPONSE); @@ -1621,7 +1690,7 @@ } // Test the WillStartUsingNetwork throttle. -TEST_F(ResourceDispatcherHostTest, ThrottleNetworkStart) { +TEST_P(ResourceDispatcherHostTest, ThrottleNetworkStart) { // Arrange to have requests deferred before processing response headers. TestResourceDispatcherHostDelegate delegate; delegate.set_flags(DEFER_NETWORK_START); @@ -1647,7 +1716,7 @@ EXPECT_EQ(0, host_.pending_requests()); } -TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) { +TEST_P(ResourceDispatcherHostTest, ThrottleAndResumeTwice) { // Arrange to have requests deferred before starting. TestResourceDispatcherHostDelegate delegate; delegate.set_flags(DEFER_STARTING_REQUEST); @@ -1685,7 +1754,7 @@ // Tests that the delegate can cancel a request and provide a error code. -TEST_F(ResourceDispatcherHostTest, CancelInDelegate) { +TEST_P(ResourceDispatcherHostTest, CancelInDelegate) { TestResourceDispatcherHostDelegate delegate; delegate.set_flags(CANCEL_BEFORE_START); delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED); @@ -1709,7 +1778,7 @@ } // Tests CancelRequestsForProcess -TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { +TEST_P(ResourceDispatcherHostTest, TestProcessCancel) { scoped_refptr<TestFilter> test_filter = new TestFilter( browser_context_->GetResourceContext()); child_ids_.insert(test_filter->child_id()); @@ -1786,7 +1855,7 @@ // Tests whether the correct requests get canceled when a RenderViewHost is // deleted. -TEST_F(ResourceDispatcherHostTest, CancelRequestsOnRenderFrameDeleted) { +TEST_P(ResourceDispatcherHostTest, CancelRequestsOnRenderFrameDeleted) { // Requests all hang once started. This prevents requests from being // destroyed due to completion. job_factory_->SetHangAfterStartJobGeneration(true); @@ -1836,7 +1905,7 @@ EXPECT_EQ(0U, msgs.size()); } -TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) { +TEST_P(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) { MakeTestRequestWithResourceType(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_4(), RESOURCE_TYPE_PREFETCH); // detachable type @@ -1882,7 +1951,7 @@ } // Tests blocking and resuming requests. -TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) { +TEST_P(ResourceDispatcherHostTest, TestBlockingResumingRequests) { host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 11)); host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 12)); host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 13)); @@ -1950,7 +2019,7 @@ } // Tests blocking and canceling requests. -TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { +TEST_P(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 11)); MakeTestRequestWithRenderFrame(0, 10, 1, net::URLRequestTestJob::test_url_1(), @@ -1991,7 +2060,7 @@ } // Tests that blocked requests are canceled if their associated process dies. -TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { +TEST_P(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { // This second filter is used to emulate a second process. scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter(); @@ -2038,7 +2107,7 @@ // away. Note that we rely on Purify for finding the leaks if any. // If this test turns the Purify bot red, check the ResourceDispatcherHost // destructor to make sure the blocked requests are deleted. -TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { +TEST_P(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { // This second filter is used to emulate a second process. scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter(); @@ -2080,7 +2149,7 @@ } // Test the private helper method "CalculateApproximateMemoryCost()". -TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) { +TEST_P(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) { net::URLRequestContext context; scoped_ptr<net::URLRequest> req(context.CreateRequest( GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL)); @@ -2111,7 +2180,7 @@ // Test that too much memory for outstanding requests for a particular // render_process_host_id causes requests to fail. -TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) { +TEST_P(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) { // Expected cost of each request as measured by // ResourceDispatcherHost::CalculateApproximateMemoryCost(). int kMemoryCostOfTest2Req = @@ -2188,7 +2257,7 @@ // Test that when too many requests are outstanding for a particular // render_process_host_id, any subsequent request from it fails. Also verify // that the global limit is honored. -TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) { +TEST_P(ResourceDispatcherHostTest, TooManyOutstandingRequests) { // Tighten the bound on the ResourceDispatcherHost, to speed things up. const size_t kMaxRequestsPerProcess = 2; host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess); @@ -2251,7 +2320,7 @@ } // Tests that we sniff the mime type for a simple request. -TEST_F(ResourceDispatcherHostTest, MimeSniffed) { +TEST_P(ResourceDispatcherHostTest, MimeSniffed) { std::string raw_headers("HTTP/1.1 200 OK\n\n"); std::string response_data("<html><title>Test One</title></html>"); SetResponse(raw_headers, response_data); @@ -2273,7 +2342,7 @@ } // Tests that we don't sniff the mime type when the server provides one. -TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) { +TEST_P(ResourceDispatcherHostTest, MimeNotSniffed) { std::string raw_headers("HTTP/1.1 200 OK\n" "Content-type: image/jpeg\n\n"); std::string response_data("<html><title>Test One</title></html>"); @@ -2296,7 +2365,7 @@ } // Tests that we don't sniff the mime type when there is no message body. -TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) { +TEST_P(ResourceDispatcherHostTest, MimeNotSniffed2) { SetResponse("HTTP/1.1 304 Not Modified\n\n"); HandleScheme("http"); @@ -2315,7 +2384,7 @@ ASSERT_EQ("", response_head.mime_type); } -TEST_F(ResourceDispatcherHostTest, MimeSniff204) { +TEST_P(ResourceDispatcherHostTest, MimeSniff204) { SetResponse("HTTP/1.1 204 No Content\n\n"); HandleScheme("http"); @@ -2334,7 +2403,7 @@ ASSERT_EQ("text/plain", response_head.mime_type); } -TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) { +TEST_P(ResourceDispatcherHostTest, MimeSniffEmpty) { SetResponse("HTTP/1.1 200 OK\n\n"); HandleScheme("http"); @@ -2354,7 +2423,7 @@ } // Tests for crbug.com/31266 (Non-2xx + application/octet-stream). -TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) { +TEST_P(ResourceDispatcherHostTest, ForbiddenDownload) { std::string raw_headers("HTTP/1.1 403 Forbidden\n" "Content-disposition: attachment; filename=blah\n" "Content-type: application/octet-stream\n\n"); @@ -2388,7 +2457,7 @@ // Test for http://crbug.com/76202 . We don't want to destroy a // download request prematurely when processing a cancellation from // the renderer. -TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) { +TEST_P(ResourceDispatcherHostTest, IgnoreCancelForDownloads) { EXPECT_EQ(0, host_.pending_requests()); int render_view_id = 0; @@ -2428,7 +2497,7 @@ while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} } -TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) { +TEST_P(ResourceDispatcherHostTest, CancelRequestsForContext) { EXPECT_EQ(0, host_.pending_requests()); int render_view_id = 0; @@ -2469,7 +2538,7 @@ EXPECT_EQ(0, host_.pending_requests()); } -TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) { +TEST_P(ResourceDispatcherHostTest, CancelRequestsForContextDetached) { EXPECT_EQ(0, host_.pending_requests()); int render_view_id = 0; @@ -2498,7 +2567,7 @@ // Test the cancelling of requests that are being transferred to a new renderer // due to a redirection. -TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) { +TEST_P(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) { EXPECT_EQ(0, host_.pending_requests()); int request_id = 1; @@ -2537,7 +2606,7 @@ // Test transferred navigations with text/html, which doesn't trigger any // content sniffing. -TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) { +TEST_P(ResourceDispatcherHostTest, TransferNavigationHtml) { if (IsBrowserSideNavigationEnabled()) { SUCCEED() << "Test is not applicable with browser side navigation enabled"; return; @@ -2611,7 +2680,7 @@ // Test transferring two navigations with text/html, to ensure the resource // accounting works. -TEST_F(ResourceDispatcherHostTest, TransferTwoNavigationsHtml) { +TEST_P(ResourceDispatcherHostTest, TransferTwoNavigationsHtml) { if (IsBrowserSideNavigationEnabled()) { SUCCEED() << "Test is not applicable with browser side navigation enabled"; return; @@ -2698,7 +2767,7 @@ // Test transferred navigations with text/plain, which causes // MimeTypeResourceHandler to buffer the response to sniff the content before // the transfer occurs. -TEST_F(ResourceDispatcherHostTest, TransferNavigationText) { +TEST_P(ResourceDispatcherHostTest, TransferNavigationText) { if (IsBrowserSideNavigationEnabled()) { SUCCEED() << "Test is not applicable with browser side navigation enabled"; return; @@ -2772,7 +2841,7 @@ CheckSuccessfulRequest(msgs[1], kResponseBody); } -TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { +TEST_P(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { if (IsBrowserSideNavigationEnabled()) { SUCCEED() << "Test is not applicable with browser side navigation enabled"; return; @@ -2862,7 +2931,7 @@ CheckSuccessfulRequest(msgs[1], kResponseBody); } -TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { +TEST_P(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { if (IsBrowserSideNavigationEnabled()) { SUCCEED() << "Test is not applicable with browser side navigation enabled"; return; @@ -2956,7 +3025,7 @@ CheckSuccessfulRequest(msgs[1], kResponseBody); } -TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) { +TEST_P(ResourceDispatcherHostTest, UnknownURLScheme) { EXPECT_EQ(0, host_.pending_requests()); HandleScheme("http"); @@ -2980,7 +3049,7 @@ CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME); } -TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) { +TEST_P(ResourceDispatcherHostTest, DataReceivedACKs) { EXPECT_EQ(0, host_.pending_requests()); SendDataReceivedACKs(true); @@ -3005,7 +3074,7 @@ // Request a very large detachable resource and cancel part way. Some of the // data should have been sent to the renderer, but not all. -TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) { +TEST_P(ResourceDispatcherHostTest, DataSentBeforeDetach) { EXPECT_EQ(0, host_.pending_requests()); int render_view_id = 0; @@ -3061,7 +3130,7 @@ net::ERR_ABORTED); } -TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) { +TEST_P(ResourceDispatcherHostTest, DelayedDataReceivedACKs) { EXPECT_EQ(0, host_.pending_requests()); HandleScheme("big-job"); @@ -3110,7 +3179,7 @@ // Flakyness of this test might indicate memory corruption issues with // for example the ResourceBuffer of AsyncResourceHandler. -TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) { +TEST_P(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) { EXPECT_EQ(0, host_.pending_requests()); HandleScheme("big-job"); @@ -3163,7 +3232,7 @@ } // Tests the dispatcher host's temporary file management. -TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFile) { +TEST_P(ResourceDispatcherHostTest, RegisterDownloadedTempFile) { const int kRequestID = 1; // Create a temporary file. @@ -3210,7 +3279,7 @@ // Tests that temporary files held on behalf of child processes are released // when the child process dies. -TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) { +TEST_P(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) { const int kRequestID = 1; // Create a temporary file. @@ -3241,7 +3310,7 @@ EXPECT_FALSE(base::PathExists(file_path)); } -TEST_F(ResourceDispatcherHostTest, DownloadToFile) { +TEST_P(ResourceDispatcherHostTest, DownloadToFile) { // Make a request which downloads to file. ResourceHostMsg_Request request = CreateResourceRequest( "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); @@ -3315,14 +3384,14 @@ } // Tests GetLoadInfoForAllRoutes when there are no pending requests. -TEST_F(ResourceDispatcherHostTest, LoadInfoNoRequests) { +TEST_P(ResourceDispatcherHostTest, LoadInfoNoRequests) { scoped_ptr<LoadInfoMap> load_info_map = RunLoadInfoTest(nullptr, 0); EXPECT_EQ(0u, load_info_map->size()); } // Tests GetLoadInfoForAllRoutes when there are 3 requests from the same // RenderView. The second one is farthest along. -TEST_F(ResourceDispatcherHostTest, LoadInfo) { +TEST_P(ResourceDispatcherHostTest, LoadInfo) { const GlobalRoutingID kId(filter_->child_id(), 0); LoadInfoTestRequestInfo request_info[] = { {kId.route_id, @@ -3351,7 +3420,7 @@ // Tests GetLoadInfoForAllRoutes when there are 2 requests with the same // priority. The first one (Which will have the lowest ID) should be returned. -TEST_F(ResourceDispatcherHostTest, LoadInfoSamePriority) { +TEST_P(ResourceDispatcherHostTest, LoadInfoSamePriority) { const GlobalRoutingID kId(filter_->child_id(), 0); LoadInfoTestRequestInfo request_info[] = { {kId.route_id, @@ -3374,7 +3443,7 @@ } // Tests GetLoadInfoForAllRoutes when a request is uploading a body. -TEST_F(ResourceDispatcherHostTest, LoadInfoUploadProgress) { +TEST_P(ResourceDispatcherHostTest, LoadInfoUploadProgress) { const GlobalRoutingID kId(filter_->child_id(), 0); LoadInfoTestRequestInfo request_info[] = { {kId.route_id, @@ -3412,7 +3481,7 @@ // Tests GetLoadInfoForAllRoutes when there are 4 requests from 2 different // RenderViews. Also tests the case where the first / last requests are the // most interesting ones. -TEST_F(ResourceDispatcherHostTest, LoadInfoTwoRenderViews) { +TEST_P(ResourceDispatcherHostTest, LoadInfoTwoRenderViews) { const GlobalRoutingID kId1(filter_->child_id(), 0); const GlobalRoutingID kId2(filter_->child_id(), 1); LoadInfoTestRequestInfo request_info[] = { @@ -3454,7 +3523,7 @@ // Confirm that resource response started notifications are correctly // transmitted to the WebContents. -TEST_F(ResourceDispatcherHostTest, TransferResponseStarted) { +TEST_P(ResourceDispatcherHostTest, TransferResponseStarted) { int initial_count = web_contents_observer_->resource_response_start_count(); MakeWebContentsAssociatedTestRequest(1, net::URLRequestTestJob::test_url_1()); @@ -3466,7 +3535,7 @@ // Confirm that request redirected notifications are correctly // transmitted to the WebContents. -TEST_F(ResourceDispatcherHostTest, TransferRequestRedirected) { +TEST_P(ResourceDispatcherHostTest, TransferRequestRedirected) { int initial_count = web_contents_observer_->resource_request_redirect_count(); MakeWebContentsAssociatedTestRequest( @@ -3478,7 +3547,7 @@ } // Confirm that DidChangePriority messages are respected. -TEST_F(ResourceDispatcherHostTest, DidChangePriority) { +TEST_P(ResourceDispatcherHostTest, DidChangePriority) { // ResourceScheduler only throttles http and https requests. HandleScheme("http"); @@ -3515,7 +3584,7 @@ // Confirm that resource response started notifications for downloads are not // transmitted to the WebContents. -TEST_F(ResourceDispatcherHostTest, TransferResponseStartedDownload) { +TEST_P(ResourceDispatcherHostTest, TransferResponseStartedDownload) { int initial_count(web_contents_observer_->resource_response_start_count()); MakeWebContentsAssociatedDownloadRequest( @@ -3527,7 +3596,7 @@ // Confirm that request redirected notifications for downloads are not // transmitted to the WebContents. -TEST_F(ResourceDispatcherHostTest, TransferRequestRedirectedDownload) { +TEST_P(ResourceDispatcherHostTest, TransferRequestRedirectedDownload) { int initial_count(web_contents_observer_->resource_request_redirect_count()); MakeWebContentsAssociatedDownloadRequest( @@ -3601,4 +3670,10 @@ return nullptr; } +INSTANTIATE_TEST_CASE_P( + ResourceDispatcherHostTests, + ResourceDispatcherHostTest, + testing::Values(TestConfig::kDefault, + TestConfig::kOptimizeIPCForSmallResourceEnabled)); + } // namespace content
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index bf48eb7..6d94b930 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc
@@ -13,6 +13,7 @@ #include "base/debug/alias.h" #include "base/debug/dump_without_crashing.h" #include "base/debug/stack_trace.h" +#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/memory/shared_memory.h" #include "base/message_loop/message_loop.h" @@ -33,6 +34,7 @@ #include "content/public/child/fixed_received_data.h" #include "content/public/child/request_peer.h" #include "content/public/child/resource_dispatcher_delegate.h" +#include "content/public/common/content_features.h" #include "content/public/common/resource_response.h" #include "content/public/common/resource_type.h" #include "net/base/net_errors.h" @@ -245,6 +247,36 @@ } } +void ResourceDispatcher::OnReceivedInlinedDataChunk( + int request_id, + const std::vector<char>& data, + int encoded_data_length) { + TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedInlinedDataChunk"); + DCHECK(!data.empty()); + DCHECK(base::FeatureList::IsEnabled(features::kOptimizeIPCForSmallResource)); + + PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); + if (!request_info || data.empty()) + return; + + // Check whether this response data is compliant with our cross-site + // document blocking policy. We only do this for the first chunk of data. + if (request_info->site_isolation_metadata.get()) { + SiteIsolationStatsGatherer::OnReceivedFirstChunk( + request_info->site_isolation_metadata, data.data(), data.size()); + request_info->site_isolation_metadata.reset(); + } + + // ThreadedDataProvider should not be attached at this point since |buffer| + // is not yet set up here. + DCHECK(!request_info->buffer.get()); + CHECK(!request_info->threaded_data_provider); + + scoped_ptr<RequestPeer::ReceivedData> received_data( + new content::FixedReceivedData(data, encoded_data_length)); + request_info->peer->OnReceivedData(std::move(received_data)); +} + void ResourceDispatcher::OnReceivedData(int request_id, int data_offset, int data_length, @@ -572,6 +604,8 @@ IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBuffer, OnSetDataBuffer) IPC_MESSAGE_HANDLER(ResourceMsg_DataReceivedDebug, OnReceivedDataDebug) IPC_MESSAGE_HANDLER(ResourceMsg_DataReceivedDebug2, OnReceivedDataDebug2) + IPC_MESSAGE_HANDLER(ResourceMsg_InlinedDataChunkReceived, + OnReceivedInlinedDataChunk) IPC_MESSAGE_HANDLER(ResourceMsg_DataReceived, OnReceivedData) IPC_MESSAGE_HANDLER(ResourceMsg_DataDownloaded, OnDownloadedData) IPC_MESSAGE_HANDLER(ResourceMsg_RequestComplete, OnRequestComplete) @@ -753,6 +787,7 @@ case ResourceMsg_SetDataBuffer::ID: case ResourceMsg_DataReceivedDebug::ID: case ResourceMsg_DataReceivedDebug2::ID: + case ResourceMsg_InlinedDataChunkReceived::ID: case ResourceMsg_DataReceived::ID: case ResourceMsg_DataDownloaded::ID: case ResourceMsg_RequestComplete::ID:
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h index a2aada8..0c33d65 100644 --- a/content/child/resource_dispatcher.h +++ b/content/child/resource_dispatcher.h
@@ -206,6 +206,9 @@ int data_offset, int data_length, int encoded_data_length); + void OnReceivedInlinedDataChunk(int request_id, + const std::vector<char>& data, + int encoded_data_length); void OnReceivedData(int request_id, int data_offset, int data_length,
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h index f300673..20b0475 100644 --- a/content/common/resource_messages.h +++ b/content/common/resource_messages.h
@@ -376,6 +376,14 @@ int /* data_length */, int /* encoded_data_length */) +// Sent when a chunk of data from a resource request is ready, and the resource +// is expected to be small enough to fit in the inlined buffer. +// The data is sent as a part of IPC message. +IPC_MESSAGE_CONTROL3(ResourceMsg_InlinedDataChunkReceived, + int /* request_id */, + std::vector<char> /* data */, + int /* encoded_data_length */) + // Sent when some data from a resource request is ready. The data offset and // length specify a byte range into the shared memory buffer provided by the // SetDataBuffer message.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 9022adb8..9a396b5 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -23,6 +23,12 @@ const base::Feature kExperimentalFramework{"ExperimentalFramework", base::FEATURE_DISABLED_BY_DEFAULT}; +// An experiment to optimize resource loading IPC for small resources. +// http://crbug.com/580928 +const base::Feature kOptimizeIPCForSmallResource{ + "OptimizeForSmallResource", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Scrolls to compensate for layout movements (bit.ly/scroll-anchoring). const base::Feature kScrollAnchoring{"ScrollAnchoring", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 509ffb7..ace7c61 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -19,6 +19,7 @@ CONTENT_EXPORT extern const base::Feature kBrotliEncoding; CONTENT_EXPORT extern const base::Feature kDownloadResumption; CONTENT_EXPORT extern const base::Feature kExperimentalFramework; +CONTENT_EXPORT extern const base::Feature kOptimizeIPCForSmallResource; CONTENT_EXPORT extern const base::Feature kScrollAnchoring; CONTENT_EXPORT extern const base::Feature kTokenBinding; CONTENT_EXPORT extern const base::Feature kUpdateRendererPriorityOnStartup;
diff --git a/extensions/browser/api/app_window/app_window_api.cc b/extensions/browser/api/app_window/app_window_api.cc index d7def0f..3e9f45f 100644 --- a/extensions/browser/api/app_window/app_window_api.cc +++ b/extensions/browser/api/app_window/app_window_api.cc
@@ -75,8 +75,6 @@ } // namespace app_window_constants const char kNoneFrameOption[] = "none"; - // TODO(benwells): Remove HTML titlebar injection. -const char kHtmlFrameOption[] = "experimental-html"; namespace { @@ -124,8 +122,7 @@ } // namespace -AppWindowCreateFunction::AppWindowCreateFunction() - : inject_html_titlebar_(false) {} +AppWindowCreateFunction::AppWindowCreateFunction() {} bool AppWindowCreateFunction::RunAsync() { // Don't create app window if the system is shutting down. @@ -198,8 +195,6 @@ result->Set("frameId", new base::FundamentalValue(frame_id)); existing_window->GetSerializedState(result); result->SetBoolean("existingWindow", true); - // TODO(benwells): Remove HTML titlebar injection. - result->SetBoolean("injectTitlebar", false); SetResult(result); SendResponse(true); return true; @@ -360,8 +355,6 @@ base::DictionaryValue* result = new base::DictionaryValue; result->Set("frameId", new base::FundamentalValue(frame_id)); - result->Set("injectTitlebar", - new base::FundamentalValue(inject_html_titlebar_)); result->Set("id", new base::StringValue(app_window->window_key())); app_window->GetSerializedState(result); SetResult(result); @@ -503,15 +496,6 @@ AppWindow::Frame AppWindowCreateFunction::GetFrameFromString( const std::string& frame_string) { - if (frame_string == kHtmlFrameOption && - (extension()->permissions_data()->HasAPIPermission( - APIPermission::kExperimental) || - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExperimentalExtensionApis))) { - inject_html_titlebar_ = true; - return AppWindow::FRAME_NONE; - } - if (frame_string == kNoneFrameOption) return AppWindow::FRAME_NONE;
diff --git a/extensions/browser/api/app_window/app_window_api.h b/extensions/browser/api/app_window/app_window_api.h index f70aecb3..f10ec98 100644 --- a/extensions/browser/api/app_window/app_window_api.h +++ b/extensions/browser/api/app_window/app_window_api.h
@@ -36,8 +36,6 @@ const extensions::api::app_window::CreateWindowOptions& options, AppWindow::CreateParams* create_params); void UpdateFrameOptionsForChannel(AppWindow::CreateParams* create_params); - - bool inject_html_titlebar_; }; } // namespace extensions
diff --git a/extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc b/extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc index 015eca3..08957fe3 100644 --- a/extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc +++ b/extensions/browser/api/display_source/wifi_display/wifi_display_session_service_impl.cc
@@ -62,7 +62,7 @@ DCHECK(client_); // We support only one Wi-Fi Display session at a time. if (delegate_->connection()) { - client_->OnError(ERROR_TYPE_EXCEEDED_SESSION_LIMIT_ERROR, + client_->OnError(ERROR_TYPE_SESSION_LIMIT_ERROR, kErrorCannotHaveMultipleSessions); return; } @@ -72,8 +72,7 @@ sinks.begin(), sinks.end(), [sink_id](DisplaySourceSinkInfoPtr ptr) { return ptr->id == sink_id; }); if (found == sinks.end() || (*found)->state != SINK_STATE_DISCONNECTED) { - client_->OnError(ERROR_TYPE_ESTABLISH_CONNECTION_ERROR, - kErrorSinkNotAvailable); + client_->OnError(ERROR_TYPE_CONNECTION_ERROR, kErrorSinkNotAvailable); return; } AuthenticationInfo auth_info; @@ -182,7 +181,7 @@ if (sink_id != sink_id_) return; DCHECK(client_); - client_->OnError(ERROR_TYPE_ESTABLISH_CONNECTION_ERROR, message); + client_->OnError(ERROR_TYPE_CONNECTION_ERROR, message); } void WiFiDisplaySessionServiceImpl::OnDisconnectFailed(
diff --git a/extensions/common/api/display_source.idl b/extensions/common/api/display_source.idl index 83cfa0de..00434a6 100644 --- a/extensions/common/api/display_source.idl +++ b/extensions/common/api/display_source.idl
@@ -6,31 +6,22 @@ // session using WebMediaStreamTrack as sources. namespace displaySource { enum ErrorType { - // Cannot create media pipeline from the given media stream which could be - // appropriate for a Display session (e.g., necessary codecs are missing - // on the platform). - create_media_pipeline_error, - // A new Display session cannot be started before the existing one is // terminated. - exceeded_session_limit_error, + session_limit_error, - // Could not establish connection to the sink. - establish_connection_error, + // The connection with sink cannot be established or has dropped + // unexpectedly. + connection_error, // The capabilities of this Display Source and the connected // sink do not fit (e.g. the sink cannot play the media content of // the formats given by the source). capabilities_negotiation_error, - // There was an error while packetizing and sending the media content. - media_send_error, - - // The TCP connection with sink has dropped unexpectedly. - connection_error, - - // An unexpected message has arrived from the sink. - unexpected_message_error, + // There was an error in media pipeline: while encoding, packetizing or + // sending the media content. + media_pipeline_error, // The sink became unresponsive. timeout_error,
diff --git a/extensions/common/mojo/wifi_display_session_service.mojom b/extensions/common/mojo/wifi_display_session_service.mojom index 637a1f0..025ed7f 100644 --- a/extensions/common/mojo/wifi_display_session_service.mojom +++ b/extensions/common/mojo/wifi_display_session_service.mojom
@@ -10,6 +10,8 @@ SetClient(WiFiDisplaySessionServiceClient client); // Requires connection to a sink using the given authentication information. + // Note: 'auth_method' values must correspond to 'enum AuthenticationMethod' + // from display_source.idl Connect(int32 sink_id, int32 auth_method, string auth_data); // Drops the established connection to the connected sink. @@ -27,6 +29,8 @@ OnTerminated(); // Notification of an error occurred during the session. + // Note: 'type' values must correspond to 'enum ErrorType' + // from display_source.idl OnError(int32 type, string description); // Invoked to transmit a controlling message from
diff --git a/extensions/renderer/app_window_custom_bindings.cc b/extensions/renderer/app_window_custom_bindings.cc index b61c384..04e45a1 100644 --- a/extensions/renderer/app_window_custom_bindings.cc +++ b/extensions/renderer/app_window_custom_bindings.cc
@@ -4,19 +4,14 @@ #include "extensions/renderer/app_window_custom_bindings.h" -#include <string> - #include "base/command_line.h" -#include "base/macros.h" #include "content/public/child/v8_value_converter.h" #include "content/public/renderer/render_frame.h" -#include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "extensions/common/extension_messages.h" #include "extensions/common/switches.h" #include "extensions/renderer/script_context.h" -#include "extensions/renderer/script_context_set.h" #include "grit/extensions_renderer_resources.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebView.h" @@ -25,39 +20,8 @@ namespace extensions { -class DidCreateDocumentElementObserver : public content::RenderFrameObserver { - public: - DidCreateDocumentElementObserver(content::RenderFrame* frame, - const ScriptContextSet* script_context_set) - : content::RenderFrameObserver(frame), - script_context_set_(script_context_set) { - DCHECK(script_context_set_); - } - - void DidCreateDocumentElement() override { - blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame(); - // Don't attempt to inject the titlebar into iframes. - if (web_frame->parent()) - return; - ScriptContext* script_context = script_context_set_->GetByV8Context( - web_frame->mainWorldScriptContext()); - if (!script_context) - return; - script_context->module_system()->CallModuleMethod( - "injectAppTitlebar", "didCreateDocumentElement"); - } - - private: - const ScriptContextSet* script_context_set_; - - DISALLOW_COPY_AND_ASSIGN(DidCreateDocumentElementObserver); -}; - -AppWindowCustomBindings::AppWindowCustomBindings( - const ScriptContextSet* script_context_set, - ScriptContext* context) - : ObjectBackedNativeHandler(context), - script_context_set_(script_context_set) { +AppWindowCustomBindings::AppWindowCustomBindings(ScriptContext* context) + : ObjectBackedNativeHandler(context) { RouteFunction("GetFrame", base::Bind(&AppWindowCustomBindings::GetFrame, base::Unretained(this))); @@ -70,19 +34,14 @@ const v8::FunctionCallbackInfo<v8::Value>& args) { // TODO(jeremya): convert this to IDL nocompile to get validation, and turn // these argument checks into CHECK(). - if (args.Length() != 2) + if (args.Length() != 1) return; if (!args[0]->IsInt32()) return; - if (!args[1]->IsBoolean()) - return; - int frame_id = args[0]->Int32Value(); - bool inject_titlebar = args[1]->BooleanValue(); - if (frame_id == MSG_ROUTING_NONE) return; @@ -99,9 +58,6 @@ if (!context_render_frame) return; - if (inject_titlebar) - new DidCreateDocumentElementObserver(app_frame, script_context_set_); - blink::WebFrame* opener = context_render_frame->GetWebFrame(); blink::WebLocalFrame* app_web_frame = app_frame->GetWebFrame(); app_web_frame->setOpener(opener);
diff --git a/extensions/renderer/app_window_custom_bindings.h b/extensions/renderer/app_window_custom_bindings.h index 26e02c72..3fbab04 100644 --- a/extensions/renderer/app_window_custom_bindings.h +++ b/extensions/renderer/app_window_custom_bindings.h
@@ -14,8 +14,7 @@ // Implements custom bindings for the app.window API. class AppWindowCustomBindings : public ObjectBackedNativeHandler { public: - AppWindowCustomBindings(const ScriptContextSet* script_context_set, - ScriptContext* context); + AppWindowCustomBindings(ScriptContext* context); private: void GetFrame(const v8::FunctionCallbackInfo<v8::Value>& args); @@ -25,9 +24,6 @@ void GetWindowControlsHtmlTemplate( const v8::FunctionCallbackInfo<v8::Value>& args); - // ScriptContextSet handle. Not owned. - const ScriptContextSet* script_context_set_; - DISALLOW_COPY_AND_ASSIGN(AppWindowCustomBindings); };
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index a8a2b3e..2c6ad7d1 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -807,13 +807,9 @@ scoped_ptr<NativeHandler>(new FileSystemNatives(context))); // Custom bindings. - // |dispatcher| is null in unit tests. - const ScriptContextSet* script_context_set = dispatcher ? - &dispatcher->script_context_set() : nullptr; module_system->RegisterNativeHandler( "app_window_natives", - scoped_ptr<NativeHandler>(new AppWindowCustomBindings( - script_context_set, context))); + scoped_ptr<NativeHandler>(new AppWindowCustomBindings(context))); module_system->RegisterNativeHandler( "blob_natives", scoped_ptr<NativeHandler>(new BlobNativeHandler(context)));
diff --git a/extensions/renderer/resources/app_window_custom_bindings.js b/extensions/renderer/resources/app_window_custom_bindings.js index 63f1eae..3800beac 100644 --- a/extensions/renderer/resources/app_window_custom_bindings.js +++ b/extensions/renderer/resources/app_window_custom_bindings.js
@@ -118,10 +118,8 @@ var view = null; // When window creation fails, |windowParams| will be undefined. - if (windowParams && windowParams.frameId) { - view = appWindowNatives.GetFrame( - windowParams.frameId, windowParams.injectTitlebar); - } + if (windowParams && windowParams.frameId) + view = appWindowNatives.GetFrame(windowParams.frameId); if (!view) { // No route to created window. If given a callback, trigger it with an
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 63447f1..b602ed42 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -60,6 +60,8 @@ "gles2_conform_support/egl/egl.cc", "gles2_conform_support/egl/surface.cc", "gles2_conform_support/egl/surface.h", + "gles2_conform_support/egl/test_support.cc", + "gles2_conform_support/egl/test_support.h", ] deps = [ @@ -81,6 +83,43 @@ } } +# GYP version: //gpu/gpu.gyp:command_buffer_gles2_tests +test("command_buffer_gles2_tests") { + sources = [ + "command_buffer/tests/command_buffer_gles2_tests_main.cc", + "command_buffer/tests/egl_test.cc", + ] + + deps = [ + ":command_buffer_gles2", + "//base", + "//base/test:test_support", + "//base/third_party/dynamic_annotations", + "//testing/gmock", + "//testing/gtest", + ] + + defines = [ + "COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY", + "EGLAPIENTRY=", + ] + if (current_os == "win") { + defines += [ "EGLAPI=__declspec(dllimport)" ] + } else { + defines += [ "EGLAPI=" ] + } + + libs = [] + + if (is_android) { + libs += [ "android" ] + deps += [ "//ui/android:ui_java" ] + } + if (!is_component_build) { + configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ] + } +} + source_set("test_support") { testonly = true sources = [
diff --git a/gpu/command_buffer/tests/command_buffer_gles2_tests_main.cc b/gpu/command_buffer/tests/command_buffer_gles2_tests_main.cc new file mode 100644 index 0000000..f945390 --- /dev/null +++ b/gpu/command_buffer/tests/command_buffer_gles2_tests_main.cc
@@ -0,0 +1,67 @@ +// Copyright (c) 2012 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 "base/bind.h" +#include "base/message_loop/message_loop.h" +#if defined(OS_MACOSX) +#include "base/mac/scoped_nsautorelease_pool.h" +#endif +#include "base/test/launcher/unit_test_launcher.h" +#include "base/test/test_suite.h" +#include "gpu/gles2_conform_support/egl/test_support.h" +#include "testing/gmock/include/gmock/gmock.h" + +// This file implements the main entry point for tests for command_buffer_gles2, +// the mode of command buffer where the code is compiled as a standalone dynamic +// library and exposed through EGL API. +namespace { + +int RunHelper(base::TestSuite* testSuite) { +#if defined(USE_OZONE) + base::MessageLoopForUI main_loop; +#else + base::MessageLoopForIO message_loop; +#endif + return testSuite->Run(); +} + +} // namespace + +int main(int argc, char** argv) { +// NOTE: we initialize globals through TestSuite constructor or through JNI +// library registration process on Android. + +// However, when the system is compiled with component build, +// command_buffer_gles2 library and this test runner share the globals, such +// as AtExitManager and JVM references. When command_buffer_gles2 is run with +// the test runner, the globals may be populated. Any other app linking to +// command_buffer_gles2 of course can not provide the globals. + +// When the system is compiled without component build, command_buffer_gles2 +// gets its own globals, while the test runner gets its own. The runner +// initialize different global variables than the ones command_buffer_gles2 +// library uses. For example, there should be a global AtExitManager for the +// test runner, and there should be a global AtExitManager that the library +// uses. Similarly, if the test runner would use JNI, it should have global +// reference to the JNI environent. If the command_buffer_gles2 library would +// use JNI, it should have its own global reference to the JNI that always +// remains null. The reference of the library should always stay null, since +// JNI is not part of command_buffer_gles2 exported API (EGL API), and thus +// there is no way for the client of the library to populate the JNI +// pointer. The client may not even be a Java app. + +// We signify that the globals have been initialized when running +// the component build. +#if defined(COMPONENT_BUILD) + g_command_buffer_gles_has_atexit_manager = true; +#endif + + base::TestSuite test_suite(argc, argv); +#if defined(OS_MACOSX) + base::mac::ScopedNSAutoreleasePool pool; +#endif + testing::InitGoogleMock(&argc, argv); + return base::LaunchUnitTestsSerially( + argc, argv, base::Bind(&RunHelper, base::Unretained(&test_suite))); +}
diff --git a/gpu/command_buffer/tests/egl_test.cc b/gpu/command_buffer/tests/egl_test.cc new file mode 100644 index 0000000..bf7e30e5 --- /dev/null +++ b/gpu/command_buffer/tests/egl_test.cc
@@ -0,0 +1,36 @@ +// Copyright 2015 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 "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +#include <EGL/egl.h> + +// This file tests EGL basic interface for command_buffer_gles2, the mode of +// command buffer where the code is compiled as a standalone dynamic library and +// exposed through EGL API. +namespace gpu { + +using testing::Test; + +TEST_F(Test, BasicEGLInitialization) { + EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + ASSERT_NE(display, EGL_NO_DISPLAY); + + // Test for no crash even though passing nullptrs for major, minor. + EGLBoolean success = eglInitialize(display, nullptr, nullptr); + ASSERT_TRUE(success); + + EGLint major = 0; + EGLint minor = 0; + success = eglInitialize(display, &major, &minor); + ASSERT_TRUE(success); + ASSERT_EQ(major, 1); + ASSERT_EQ(minor, 4); + + success = eglTerminate(display); + ASSERT_TRUE(success); +} + +} // namespace gpu
diff --git a/gpu/command_buffer_gles2_tests_apk.isolate b/gpu/command_buffer_gles2_tests_apk.isolate new file mode 100644 index 0000000..aeae953 --- /dev/null +++ b/gpu/command_buffer_gles2_tests_apk.isolate
@@ -0,0 +1,18 @@ +# 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. +{ + 'includes': [ + '../build/android/android.isolate', + ], + 'variables': { + 'command': [ + '<(PRODUCT_DIR)/bin/run_command_buffer_gles2_tests', + '--logcat-output-dir', '${ISOLATED_OUTDIR}/logcats', + ], + 'files': [ + '<(PRODUCT_DIR)/bin/run_command_buffer_gles2_tests', + '<(PRODUCT_DIR)/command_buffer_gles2_tests_apk/', + ] + }, +}
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 9df0095..bf63108 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc
@@ -23,6 +23,7 @@ #include "gpu/command_buffer/service/valuebuffer_manager.h" #include "gpu/gles2_conform_support/egl/config.h" #include "gpu/gles2_conform_support/egl/surface.h" +#include "gpu/gles2_conform_support/egl/test_support.h" namespace { const int32_t kCommandBufferSize = 1024 * 1024; @@ -40,6 +41,11 @@ base::AtExitManager* g_exit_manager; void RefAtExitManager() { base::AutoLock lock(g_exit_manager_lock.Get()); +#if defined(COMPONENT_BUILD) + if (g_command_buffer_gles_has_atexit_manager) { + return; + } +#endif if (g_exit_manager_use_count == 0) { g_exit_manager = new base::AtExitManager; } @@ -47,6 +53,11 @@ } void ReleaseAtExitManager() { base::AutoLock lock(g_exit_manager_lock.Get()); +#if defined(COMPONENT_BUILD) + if (g_command_buffer_gles_has_atexit_manager) { + return; + } +#endif --g_exit_manager_use_count; if (g_exit_manager_use_count == 0) { delete g_exit_manager;
diff --git a/gpu/gles2_conform_support/egl/egl.cc b/gpu/gles2_conform_support/egl/egl.cc index a61bf53..5a81954b 100644 --- a/gpu/gles2_conform_support/egl/egl.cc +++ b/gpu/gles2_conform_support/egl/egl.cc
@@ -143,9 +143,10 @@ gfx::GLSurface::InitializeOneOff(); } - - *major = 1; - *minor = 4; + if (major) + *major = 1; + if (minor) + *minor = 4; return EglSuccess(EGL_TRUE); }
diff --git a/gpu/gles2_conform_support/egl/test_support.cc b/gpu/gles2_conform_support/egl/test_support.cc new file mode 100644 index 0000000..938abcfd4 --- /dev/null +++ b/gpu/gles2_conform_support/egl/test_support.cc
@@ -0,0 +1,9 @@ +// Copyright (c) 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 "test_support.h" + +#if defined(COMPONENT_BUILD) && defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY) +bool g_command_buffer_gles_has_atexit_manager; +#endif
diff --git a/gpu/gles2_conform_support/egl/test_support.h b/gpu/gles2_conform_support/egl/test_support.h new file mode 100644 index 0000000..b1a70885 --- /dev/null +++ b/gpu/gles2_conform_support/egl/test_support.h
@@ -0,0 +1,19 @@ +// Copyright (c) 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 GPU_GLES2_CONFORM_SUPPORT_EGL_TEST_SUPPORT_H_ +#define GPU_GLES2_CONFORM_SUPPORT_EGL_TEST_SUPPORT_H_ + +#if defined(COMPONENT_BUILD) && defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY) +// A variable used for communicating whether the app has initialized the global +// variables. +// On component build, the dynamic library and the Chromium test +// runner executable refer to the same global variables. Any non-Chromium client +// of the dynamic library will not initialize the globabl variables. +// On non-component (static) build, the library and the runner have distinct +// global variables. +EGLAPI extern EGLAPIENTRY bool g_command_buffer_gles_has_atexit_manager; +#endif + +#endif
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 25487b09..2b529e1 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp
@@ -437,23 +437,63 @@ 'gles2_conform_support/egl/egl.cc', 'gles2_conform_support/egl/surface.cc', 'gles2_conform_support/egl/surface.h', + 'gles2_conform_support/egl/test_support.cc', + 'gles2_conform_support/egl/test_support.h', + ], + 'defines': [ + 'COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY', + 'EGLAPIENTRY=', + ], + 'conditions': [ + ['OS=="win"', { + 'defines': [ + 'EGLAPI=__declspec(dllexport)', + ], + }, { # OS!="win" + 'defines': [ + 'EGLAPI=__attribute__((visibility(\"default\")))' + ], + }], + ], + }, + { + # GN version: //gpu:command_buffer_gles2_tests + 'target_name': 'command_buffer_gles2_tests', + 'type': '<(gtest_target_type)', + 'dependencies': [ + '../base/base.gyp:base', + '../base/base.gyp:test_support_base', + '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', + 'command_buffer_gles2', + ], + 'sources': [ + # Note: sources list duplicated in GN build. + 'command_buffer/tests/command_buffer_gles2_tests_main.cc', + 'command_buffer/tests/egl_test.cc', + ], + 'defines': [ + 'COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY', + 'EGLAPIENTRY=', ], 'conditions': [ ['OS=="win"', { 'defines': [ - 'COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY', - 'EGLAPIENTRY=', - 'EGLAPI=__declspec(dllexport)', + 'EGLAPI=__declspec(dllimport)', ], }, { # OS!="win" - 'defines': [ - 'COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY', - 'EGLAPIENTRY=', - 'EGLAPI=__attribute__((visibility(\"default\")))' + 'defines': [ + 'EGLAPI=', ], - }, ], + }], + ['OS == "android"', { + 'dependencies': [ + '../testing/android/native_test.gyp:native_test_native_code', + ], + }], ], - } + }, ], 'conditions': [ ['component=="static_library"', { @@ -753,6 +793,19 @@ }, 'includes': [ '../build/apk_test.gypi' ], }, + { + 'target_name': 'command_buffer_gles2_tests_apk', + 'type': 'none', + 'dependencies': [ + 'command_buffer_gles2_tests', + ], + 'variables': { + 'test_suite_name': 'command_buffer_gles2_tests', + }, + 'includes': [ + '../build/apk_test.gypi', + ], + }, ], }], ['OS == "win" or (OS == "linux" and use_x11==1) or OS == "mac"', { @@ -880,6 +933,19 @@ { 'targets': [ { + 'target_name': 'command_buffer_gles2_tests_apk_run', + 'type': 'none', + 'dependencies': [ + 'command_buffer_gles2_tests_apk', + ], + 'includes': [ + '../build/isolate.gypi', + ], + 'sources': [ + 'command_buffer_gles2_apk.isolate', + ], + }, + { 'target_name': 'gl_tests_apk_run', 'type': 'none', 'dependencies': [
diff --git a/ios/chrome/BUILD.gn b/ios/chrome/BUILD.gn index 59a9731..f59a480 100644 --- a/ios/chrome/BUILD.gn +++ b/ios/chrome/BUILD.gn
@@ -23,6 +23,8 @@ "browser/net/image_fetcher_unittest.mm", "browser/net/metrics_network_client_unittest.mm", "browser/net/retryable_url_fetcher_unittest.mm", + "browser/reading_list/reading_list_entry_unittest.cc", + "browser/reading_list/reading_list_model_unittest.cc", "browser/signin/chrome_identity_service_observer_bridge_unittest.mm", "browser/signin/gaia_auth_fetcher_ios_unittest.mm", "browser/snapshots/lru_cache_unittest.mm",
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index 648375c..8469be43 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -292,6 +292,15 @@ "prefs/pref_observer_bridge.h", "prefs/pref_observer_bridge.mm", "procedural_block_types.h", + "reading_list/reading_list_entry.cc", + "reading_list/reading_list_entry.h", + "reading_list/reading_list_model.cc", + "reading_list/reading_list_model.h", + "reading_list/reading_list_model_factory.cc", + "reading_list/reading_list_model_factory.h", + "reading_list/reading_list_model_memory.cc", + "reading_list/reading_list_model_memory.h", + "reading_list/reading_list_model_observer.h", "search/search_util.cc", "search/search_util.h", "search_engines/search_engines_util.cc",
diff --git a/ios/chrome/browser/reading_list/OWNERS b/ios/chrome/browser/reading_list/OWNERS new file mode 100644 index 0000000..bf1620f --- /dev/null +++ b/ios/chrome/browser/reading_list/OWNERS
@@ -0,0 +1 @@ +noyau@chromium.org
diff --git a/ios/chrome/browser/reading_list/reading_list_entry.cc b/ios/chrome/browser/reading_list/reading_list_entry.cc new file mode 100644 index 0000000..15c0dea --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_entry.cc
@@ -0,0 +1,32 @@ +// 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 "ios/chrome/browser/reading_list/reading_list_entry.h" + +ReadingListEntry::ReadingListEntry(const GURL& url, const std::string& title) + : url_(url), title_(title) { + DCHECK(!url.is_empty()); + DCHECK(url.is_valid()); +} +ReadingListEntry::ReadingListEntry(const ReadingListEntry& entry) + : url_(entry.url()), title_(entry.title()) {} +ReadingListEntry::~ReadingListEntry() {} + +const GURL& ReadingListEntry::url() const { + return url_; +} + +const std::string ReadingListEntry::title() const { + return title_; +} + +ReadingListEntry& ReadingListEntry::operator=(const ReadingListEntry& other) { + url_ = other.url_; + title_ = other.title_; + return *this; +} + +bool ReadingListEntry::operator==(const ReadingListEntry& other) const { + return url_ == other.url_; +}
diff --git a/ios/chrome/browser/reading_list/reading_list_entry.h b/ios/chrome/browser/reading_list/reading_list_entry.h new file mode 100644 index 0000000..f7287b71 --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_entry.h
@@ -0,0 +1,32 @@ +// 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 IOS_CHROME_BROWSER_READING_LIST_READING_LIST_ENTRY_H_ +#define IOS_CHROME_BROWSER_READING_LIST_READING_LIST_ENTRY_H_ + +#include <string> + +#include "url/gurl.h" + +// An entry in the reading list. The URL is a unique identifier for an entry, as +// such it should not be empty and is the only thing considered when comparing +// entries. +class ReadingListEntry { + public: + ReadingListEntry(const GURL& url, const std::string& title); + ReadingListEntry(const ReadingListEntry& entry); + ~ReadingListEntry(); + + const GURL& url() const; + const std::string title() const; + + ReadingListEntry& operator=(const ReadingListEntry& other); + bool operator==(const ReadingListEntry& other) const; + + private: + GURL url_; + std::string title_; +}; + +#endif // IOS_CHROME_BROWSER_READING_LIST_READING_LIST_ENTRY_H_
diff --git a/ios/chrome/browser/reading_list/reading_list_entry_unittest.cc b/ios/chrome/browser/reading_list/reading_list_entry_unittest.cc new file mode 100644 index 0000000..1bb920b9 --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_entry_unittest.cc
@@ -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. + +#include "ios/chrome/browser/reading_list/reading_list_entry.h" + +#include "testing/gtest/include/gtest/gtest.h" + +TEST(ReadingListEntry, CompareIgnoreTitle) { + const ReadingListEntry e1(GURL("http://example.com"), "bar"); + const ReadingListEntry e2(GURL("http://example.com"), "foo"); + + EXPECT_EQ(e1, e2); +} + +TEST(ReadingListEntry, CompareFailureIgnoreTitle) { + const ReadingListEntry e1(GURL("http://example.com"), "bar"); + const ReadingListEntry e2(GURL("http://example.org"), "bar"); + + EXPECT_FALSE(e1 == e2); +} + +TEST(ReadingListEntry, CopyAreEquals) { + const ReadingListEntry e1(GURL("http://example.com"), "bar"); + const ReadingListEntry e2(e1); + + EXPECT_EQ(e1, e2); + EXPECT_EQ(e1.title(), e2.title()); +}
diff --git a/ios/chrome/browser/reading_list/reading_list_model.cc b/ios/chrome/browser/reading_list/reading_list_model.cc new file mode 100644 index 0000000..bdc26516 --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_model.cc
@@ -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. + +#include "ios/chrome/browser/reading_list/reading_list_model.h" + +ReadingListModel::ReadingListModel() {} +ReadingListModel::~ReadingListModel() {} + +// Observer methods. +void ReadingListModel::AddObserver(ReadingListModelObserver* observer) { + DCHECK(observer); + observers_.AddObserver(observer); + if (loaded()) { + observer->ReadingListModelLoaded(this); + } +} + +void ReadingListModel::RemoveObserver(ReadingListModelObserver* observer) { + observers_.RemoveObserver(observer); +}
diff --git a/ios/chrome/browser/reading_list/reading_list_model.h b/ios/chrome/browser/reading_list/reading_list_model.h new file mode 100644 index 0000000..196476e --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_model.h
@@ -0,0 +1,76 @@ +// 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 IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_H_ +#define IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/observer_list.h" +#include "ios/chrome/browser/reading_list/reading_list_model_observer.h" + +class GURL; +class ReadingListEntry; +class ReadingListModel; + +namespace ios { +class ChromeBrowserState; +} + +// The reading list model contains two list of entries: one of unread urls, the +// other of read ones. This object should only be accessed from one thread +// (Usually the main thread). The observers callbacks are also sent on the main +// thread. +class ReadingListModel { + public: + // Returns true if the model finished loading. Until this returns true the + // reading list is not ready for use. + virtual bool loaded() const = 0; + + // Returns the size of read and unread entries. + virtual size_t unread_size() const = 0; + virtual size_t read_size() const = 0; + + // Returns true if there are entries in the model that were not seen by the + // user yet. Reset to true when new unread entries are added. Reset to false + // when ResetUnseenEntries is called. + virtual bool HasUnseenEntries() const = 0; + virtual void ResetUnseenEntries() = 0; + + // Returns a specific entry. + virtual const ReadingListEntry& GetUnreadEntryAtIndex(size_t index) const = 0; + virtual const ReadingListEntry& GetReadEntryAtIndex(size_t index) const = 0; + + // Adds |url| at the top of the unread entries, and removes entries with the + // same |url| from everywhere else if they exist. The addition may be + // asynchronous, and the data will be available only once the observers are + // notified. + virtual const ReadingListEntry& AddEntry(const GURL& url, + const std::string& title) = 0; + + // Removes an entry. The removal may be asynchronous, and not happen + // immediately. + virtual void RemoveEntryByUrl(const GURL& url) = 0; + + // If the |url| is in the reading list and unread, mark it read. If it is in + // the reading list and read, move it to the top of unread if it is not here + // already. This may trigger deletion of old read entries. + virtual void MarkReadByURL(const GURL& url) = 0; + + // Observer registration methods. + void AddObserver(ReadingListModelObserver* observer); + void RemoveObserver(ReadingListModelObserver* observer); + + protected: + ReadingListModel(); + virtual ~ReadingListModel(); + // The observers. + base::ObserverList<ReadingListModelObserver> observers_; + + DISALLOW_COPY_AND_ASSIGN(ReadingListModel); +}; + +#endif // IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_H_
diff --git a/ios/chrome/browser/reading_list/reading_list_model_factory.cc b/ios/chrome/browser/reading_list/reading_list_model_factory.cc new file mode 100644 index 0000000..dcf6c2bc --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_model_factory.cc
@@ -0,0 +1,51 @@ +// 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 "ios/chrome/browser/reading_list/reading_list_model_factory.h" + +#include <utility> + +#include "base/memory/singleton.h" +#include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/reading_list/reading_list_model_memory.h" + +// static +ReadingListModel* ReadingListModelFactory::GetForBrowserState( + ios::ChromeBrowserState* browser_state) { + return static_cast<ReadingListModelMemory*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +// static +ReadingListModel* ReadingListModelFactory::GetForBrowserStateIfExists( + ios::ChromeBrowserState* browser_state) { + return static_cast<ReadingListModelMemory*>( + GetInstance()->GetServiceForBrowserState(browser_state, false)); +} + +// static +ReadingListModelFactory* ReadingListModelFactory::GetInstance() { + return base::Singleton<ReadingListModelFactory>::get(); +} + +ReadingListModelFactory::ReadingListModelFactory() + : BrowserStateKeyedServiceFactory( + "ReadingListModel", + BrowserStateDependencyManager::GetInstance()) {} + +ReadingListModelFactory::~ReadingListModelFactory() {} + +scoped_ptr<KeyedService> ReadingListModelFactory::BuildServiceInstanceFor( + web::BrowserState* context) const { + scoped_ptr<ReadingListModelMemory> reading_list_model( + new ReadingListModelMemory()); + return std::move(reading_list_model); +} + +web::BrowserState* ReadingListModelFactory::GetBrowserStateToUse( + web::BrowserState* context) const { + return GetBrowserStateRedirectedInIncognito(context); +}
diff --git a/ios/chrome/browser/reading_list/reading_list_model_factory.h b/ios/chrome/browser/reading_list/reading_list_model_factory.h new file mode 100644 index 0000000..96a6638 --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_model_factory.h
@@ -0,0 +1,46 @@ +// 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 IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_FACTORY_H_ +#define IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_FACTORY_H_ + +#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +namespace base { +template <typename T> +struct DefaultSingletonTraits; +} // namespace base + +class ReadingListModel; + +namespace ios { +class ChromeBrowserState; +} + +// Singleton that owns the ReadingListModel and associates it with +// ios::ChromeBrowserState. +class ReadingListModelFactory : public BrowserStateKeyedServiceFactory { + public: + static ReadingListModel* GetForBrowserState( + ios::ChromeBrowserState* browser_state); + static ReadingListModel* GetForBrowserStateIfExists( + ios::ChromeBrowserState* browser_state); + static ReadingListModelFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<ReadingListModelFactory>; + + ReadingListModelFactory(); + ~ReadingListModelFactory() override; + + // BrowserStateKeyedServiceFactory implementation. + scoped_ptr<KeyedService> BuildServiceInstanceFor( + web::BrowserState* context) const override; + web::BrowserState* GetBrowserStateToUse( + web::BrowserState* context) const override; + + DISALLOW_COPY_AND_ASSIGN(ReadingListModelFactory); +}; + +#endif // IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_FACTORY_H_
diff --git a/ios/chrome/browser/reading_list/reading_list_model_memory.cc b/ios/chrome/browser/reading_list/reading_list_model_memory.cc new file mode 100644 index 0000000..40f9224 --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_model_memory.cc
@@ -0,0 +1,117 @@ +// 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 "ios/chrome/browser/reading_list/reading_list_model_memory.h" + +#include "url/gurl.h" + +ReadingListModelMemory::ReadingListModelMemory() + : hasUnseen_(false), loaded_(true) {} +ReadingListModelMemory::~ReadingListModelMemory() {} + +void ReadingListModelMemory::Shutdown() { + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListModelBeingDeleted(this)); + loaded_ = false; +} + +bool ReadingListModelMemory::loaded() const { + return loaded_; +} + +size_t ReadingListModelMemory::unread_size() const { + DCHECK(loaded()); + return unread_.size(); +} + +size_t ReadingListModelMemory::read_size() const { + DCHECK(loaded()); + return read_.size(); +} + +bool ReadingListModelMemory::HasUnseenEntries() const { + DCHECK(loaded()); + return unread_size() && hasUnseen_; +} + +void ReadingListModelMemory::ResetUnseenEntries() { + DCHECK(loaded()); + hasUnseen_ = false; +} + +// Returns a specific entry. +const ReadingListEntry& ReadingListModelMemory::GetUnreadEntryAtIndex( + size_t index) const { + DCHECK(loaded()); + return unread_[index]; +} +const ReadingListEntry& ReadingListModelMemory::GetReadEntryAtIndex( + size_t index) const { + DCHECK(loaded()); + return read_[index]; +} + +void ReadingListModelMemory::RemoveEntryByUrl(const GURL& url) { + DCHECK(loaded()); + const ReadingListEntry entry(url, std::string()); + + auto result = std::find(unread_.begin(), unread_.end(), entry); + if (result != unread_.end()) { + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListWillRemoveUnreadEntry( + this, std::distance(unread_.begin(), result))); + unread_.erase(result); + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListDidApplyChanges(this)); + return; + } + + result = std::find(read_.begin(), read_.end(), entry); + if (result != read_.end()) { + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListWillRemoveReadEntry( + this, std::distance(read_.begin(), result))); + read_.erase(result); + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListDidApplyChanges(this)); + return; + } +} + +const ReadingListEntry& ReadingListModelMemory::AddEntry( + const GURL& url, + const std::string& title) { + DCHECK(loaded()); + RemoveEntryByUrl(url); + const ReadingListEntry entry(url, title); + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListWillAddUnreadEntry(this, entry)); + unread_.insert(unread_.begin(), entry); + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListDidApplyChanges(this)); + + hasUnseen_ = true; + return *unread_.begin(); +} + +void ReadingListModelMemory::MarkReadByURL(const GURL& url) { + DCHECK(loaded()); + const ReadingListEntry entry(url, std::string()); + + auto result = std::find(unread_.begin(), unread_.end(), entry); + if (result == unread_.end()) { + return; + } + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListWillRemoveUnreadEntry( + this, std::distance(unread_.begin(), result))); + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListWillAddReadEntry(this, entry)); + + read_.insert(read_.begin(), *result); + unread_.erase(result); + + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, + ReadingListDidApplyChanges(this)); +}
diff --git a/ios/chrome/browser/reading_list/reading_list_model_memory.h b/ios/chrome/browser/reading_list/reading_list_model_memory.h new file mode 100644 index 0000000..1dda495 --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_model_memory.h
@@ -0,0 +1,44 @@ +// 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 IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_MEMORY_H_ +#define IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_MEMORY_H_ + +#include "components/keyed_service/core/keyed_service.h" +#include "ios/chrome/browser/reading_list/reading_list_entry.h" +#include "ios/chrome/browser/reading_list/reading_list_model.h" + +// Concrete implementation of a reading list model using in memory lists. +class ReadingListModelMemory : public ReadingListModel, public KeyedService { + public: + ReadingListModelMemory(); + ~ReadingListModelMemory() override; + void Shutdown() override; + + bool loaded() const override; + size_t unread_size() const override; + size_t read_size() const override; + + bool HasUnseenEntries() const override; + void ResetUnseenEntries() override; + + // Returns a specific entry. + const ReadingListEntry& GetUnreadEntryAtIndex(size_t index) const override; + const ReadingListEntry& GetReadEntryAtIndex(size_t index) const override; + + void RemoveEntryByUrl(const GURL& url) override; + + const ReadingListEntry& AddEntry(const GURL& url, + const std::string& title) override; + + void MarkReadByURL(const GURL& url) override; + + private: + std::vector<ReadingListEntry> unread_; + std::vector<ReadingListEntry> read_; + bool hasUnseen_; + bool loaded_; +}; + +#endif // IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_MEMORY_H_
diff --git a/ios/chrome/browser/reading_list/reading_list_model_observer.h b/ios/chrome/browser/reading_list/reading_list_model_observer.h new file mode 100644 index 0000000..4881d3932 --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_model_observer.h
@@ -0,0 +1,55 @@ +// 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 IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_OBSERVER_H_ +#define IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_OBSERVER_H_ + +#import <set> +#import <vector> + +class ReadingListModel; +class ReadingListEntry; + +// Observer for the Reading List model. In the observer methods care should be +// taken to not modify the model. +class ReadingListModelObserver { + public: + // Invoked when the model has finished loading. Until this method is called it + // is unsafe to use the model. + virtual void ReadingListModelLoaded(const ReadingListModel* model) = 0; + + // Invoked from the destructor of the model. The model is no longer valid + // after this call. + virtual void ReadingListModelBeingDeleted(const ReadingListModel* model) {} + + // Invoked when elements are about to be removed from the read or unread list. + virtual void ReadingListWillRemoveUnreadEntry(const ReadingListModel* model, + size_t index) {} + virtual void ReadingListWillRemoveReadEntry(const ReadingListModel* model, + size_t index) {} + + // Invoked when elements are added to the read or the unread list. The new + // entries are always added at the beginning. these methods may be called + // multiple time (to process changes coming from a synchronization for + // example) and they will be executed in call order, the last call will end up + // in first position. + virtual void ReadingListWillAddUnreadEntry(const ReadingListModel* model, + const ReadingListEntry& entry) {} + + virtual void ReadingListWillAddReadEntry(const ReadingListModel* model, + const ReadingListEntry& entry) {} + + // Called after all th"e changes signaled by calls to the "Will" methods are + // done. All the "Will" methods are called as necessary, then the changes + // are applied and then this method is called. + virtual void ReadingListDidApplyChanges(ReadingListModel* model) {} + + protected: + ReadingListModelObserver() {} + virtual ~ReadingListModelObserver() {} + + DISALLOW_COPY_AND_ASSIGN(ReadingListModelObserver); +}; + +#endif // IOS_CHROME_BROWSER_READING_LIST_READING_LIST_MODEL_OBSERVER_H_
diff --git a/ios/chrome/browser/reading_list/reading_list_model_unittest.cc b/ios/chrome/browser/reading_list/reading_list_model_unittest.cc new file mode 100644 index 0000000..a863707 --- /dev/null +++ b/ios/chrome/browser/reading_list/reading_list_model_unittest.cc
@@ -0,0 +1,123 @@ +// 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 "ios/chrome/browser/reading_list/reading_list_model_memory.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class ReadingListModelTest : public ReadingListModelObserver, + public testing::Test { + public: + ReadingListModelTest() : model_(new ReadingListModelMemory()) { + ClearCounts(); + model_->AddObserver(this); + } + ~ReadingListModelTest() override {} + + void ClearCounts() { + observer_loaded_ = observer_deleted_ = observer_remove_unread_ = + observer_remove_read_ = observer_add_unread_ = observer_add_read_ = + observer_did_apply_ = 0; + } + + void AssertObserverCount(int observer_loaded, + int observer_deleted, + int observer_remove_unread, + int observer_remove_read, + int observer_add_unread, + int observer_add_read, + int observer_did_apply) { + ASSERT_EQ(observer_loaded, observer_loaded_); + ASSERT_EQ(observer_deleted, observer_deleted_); + ASSERT_EQ(observer_remove_unread, observer_remove_unread_); + ASSERT_EQ(observer_remove_read, observer_remove_read_); + ASSERT_EQ(observer_add_unread, observer_add_unread_); + ASSERT_EQ(observer_add_read, observer_add_read_); + ASSERT_EQ(observer_did_apply, observer_did_apply_); + } + + // ReadingListModelObserver + void ReadingListModelLoaded(const ReadingListModel* model) override { + observer_loaded_ += 1; + } + void ReadingListModelBeingDeleted(const ReadingListModel* model) override { + observer_deleted_ += 1; + } + void ReadingListWillRemoveUnreadEntry(const ReadingListModel* model, + size_t index) override { + observer_remove_unread_ += 1; + } + void ReadingListWillRemoveReadEntry(const ReadingListModel* model, + size_t index) override { + observer_remove_read_ += 1; + } + void ReadingListWillAddUnreadEntry(const ReadingListModel* model, + const ReadingListEntry& entry) override { + observer_add_unread_ += 1; + } + void ReadingListWillAddReadEntry(const ReadingListModel* model, + const ReadingListEntry& entry) override { + observer_add_read_ += 1; + } + void ReadingListDidApplyChanges(ReadingListModel* model) override { + observer_did_apply_ += 1; + } + + protected: + int observer_loaded_; + int observer_deleted_; + int observer_remove_unread_; + int observer_remove_read_; + int observer_add_unread_; + int observer_add_read_; + int observer_did_apply_; + + scoped_ptr<ReadingListModelMemory> model_; +}; + +TEST_F(ReadingListModelTest, EmptyLoaded) { + EXPECT_TRUE(model_->loaded()); + AssertObserverCount(1, 0, 0, 0, 0, 0, 0); + EXPECT_EQ(0ul, model_->unread_size()); + EXPECT_EQ(0ul, model_->read_size()); + model_->Shutdown(); + EXPECT_FALSE(model_->loaded()); + AssertObserverCount(1, 1, 0, 0, 0, 0, 0); +} + +TEST_F(ReadingListModelTest, AddEntry) { + ClearCounts(); + const ReadingListEntry entry = + model_->AddEntry(GURL("http://example.com"), "sample"); + EXPECT_EQ(GURL("http://example.com"), entry.url()); + EXPECT_EQ("sample", entry.title()); + + AssertObserverCount(0, 0, 0, 0, 1, 0, 1); + EXPECT_EQ(1ul, model_->unread_size()); + EXPECT_EQ(0ul, model_->read_size()); + EXPECT_TRUE(model_->HasUnseenEntries()); + + const ReadingListEntry other_entry = model_->GetUnreadEntryAtIndex(0); + EXPECT_EQ(GURL("http://example.com"), other_entry.url()); + EXPECT_EQ("sample", other_entry.title()); +} + +TEST_F(ReadingListModelTest, ReadEntry) { + const ReadingListEntry entry = + model_->AddEntry(GURL("http://example.com"), "sample"); + + ClearCounts(); + model_->MarkReadByURL(GURL("http://example.com")); + AssertObserverCount(0, 0, 1, 0, 0, 1, 1); + EXPECT_EQ(0ul, model_->unread_size()); + EXPECT_EQ(1ul, model_->read_size()); + EXPECT_FALSE(model_->HasUnseenEntries()); + + const ReadingListEntry other_entry = model_->GetReadEntryAtIndex(0); + EXPECT_EQ(GURL("http://example.com"), other_entry.url()); + EXPECT_EQ("sample", other_entry.title()); +} + +} // namespace
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp index a1ac53d..50af6e1 100644 --- a/ios/chrome/ios_chrome.gyp +++ b/ios/chrome/ios_chrome.gyp
@@ -447,6 +447,15 @@ 'browser/prefs/pref_observer_bridge.h', 'browser/prefs/pref_observer_bridge.mm', 'browser/procedural_block_types.h', + 'browser/reading_list/reading_list_entry.cc', + 'browser/reading_list/reading_list_entry.h', + 'browser/reading_list/reading_list_model.cc', + 'browser/reading_list/reading_list_model.h', + 'browser/reading_list/reading_list_model_factory.cc', + 'browser/reading_list/reading_list_model_factory.h', + 'browser/reading_list/reading_list_model_memory.cc', + 'browser/reading_list/reading_list_model_memory.h', + 'browser/reading_list/reading_list_model_observer.h', 'browser/search/search_util.cc', 'browser/search/search_util.h', 'browser/search_engines/search_engines_util.cc',
diff --git a/ios/chrome/ios_chrome_tests.gyp b/ios/chrome/ios_chrome_tests.gyp index 70012fe..d72f00e 100644 --- a/ios/chrome/ios_chrome_tests.gyp +++ b/ios/chrome/ios_chrome_tests.gyp
@@ -55,6 +55,8 @@ 'browser/net/image_fetcher_unittest.mm', 'browser/net/metrics_network_client_unittest.mm', 'browser/net/retryable_url_fetcher_unittest.mm', + 'browser/reading_list/reading_list_entry_unittest.cc', + 'browser/reading_list/reading_list_model_unittest.cc', 'browser/signin/chrome_identity_service_observer_bridge_unittest.mm', 'browser/signin/gaia_auth_fetcher_ios_unittest.mm', 'browser/snapshots/lru_cache_unittest.mm',
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc index 62854b9..5f4507ad 100644 --- a/media/audio/mac/audio_low_latency_input_mac.cc +++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -30,6 +30,12 @@ // if input callbacks have started, and false otherwise. const int kInputCallbackStartTimeoutInSeconds = 5; +// Returns true if the format flags in |format_flags| has the "non-interleaved" +// flag (kAudioFormatFlagIsNonInterleaved) cleared (set to 0). +static bool FormatIsInterleaved(UInt32 format_flags) { + return !(format_flags & kAudioFormatFlagIsNonInterleaved); +} + static std::ostream& operator<<(std::ostream& os, const AudioStreamBasicDescription& format) { // The 32-bit integer format.mFormatID is actually a non-terminated 4 byte @@ -46,10 +52,26 @@ << "bytes per frame : " << format.mBytesPerFrame << std::endl << "channels per frame: " << format.mChannelsPerFrame << std::endl << "bits per channel : " << format.mBitsPerChannel << std::endl - << "reserved : " << format.mReserved; + << "reserved : " << format.mReserved << std::endl + << "interleaved : " + << (FormatIsInterleaved(format.mFormatFlags) ? "yes" : "no"); return os; } +static OSStatus GetInputDeviceStreamFormat( + AudioUnit audio_unit, + AudioStreamBasicDescription* format) { + DCHECK(audio_unit); + UInt32 property_size = sizeof(*format); + // Get the audio stream data format on the input scope of the input element + // since it is connected to the current input device. + OSStatus result = + AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, 1, format, &property_size); + DVLOG(1) << "Input device stream format: " << *format; + return result; +} + // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit" // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html // for more details and background regarding this implementation. @@ -70,7 +92,8 @@ kNumberOfBlocksBufferInFifo), input_callback_is_active_(false), start_was_deferred_(false), - buffer_size_was_changed_(false) { + buffer_size_was_changed_(false), + audio_unit_render_has_worked_(false) { DCHECK(manager_); // Set up the desired (output) format specified by the client. @@ -78,6 +101,7 @@ format_.mFormatID = kAudioFormatLinearPCM; format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; + DCHECK(FormatIsInterleaved(format_.mFormatFlags)); format_.mBitsPerChannel = input_params.bits_per_sample(); format_.mChannelsPerFrame = input_params.channels(); format_.mFramesPerPacket = 1; // uncompressed audio @@ -91,10 +115,6 @@ DVLOG(1) << "buffer size : " << number_of_frames_; DVLOG(1) << "channels : " << input_params.channels(); DVLOG(1) << "desired output format: " << format_; - // Ensure that the output format is interleaved. - const bool interleaved = - !(format_.mFormatFlags & kAudioFormatFlagIsNonInterleaved); - DCHECK(interleaved); // Derive size (in bytes) of the buffers that we will render to. UInt32 data_byte_size = number_of_frames_ * format_.mBytesPerFrame; @@ -248,11 +268,7 @@ // in the AUHAL, only *simple* conversions, e.g., 32-bit float to 16-bit // signed integer format. AudioStreamBasicDescription input_device_format = {0}; - UInt32 property_size = sizeof(input_device_format); - result = AudioUnitGetProperty(audio_unit_, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, 1, &input_device_format, - &property_size); - DVLOG(1) << "Input device format: " << input_device_format; + GetInputDeviceStreamFormat(audio_unit_, &input_device_format); if (input_device_format.mSampleRate != format_.mSampleRate) { LOG(ERROR) << "Input device's sample rate does not match the client's sample rate"; @@ -285,7 +301,7 @@ // perfect match. Any such mismatch will be compensated for in // OnDataIsAvailable(). UInt32 buffer_frame_size = 0; - property_size = sizeof(buffer_frame_size); + UInt32 property_size = sizeof(buffer_frame_size); result = AudioUnitGetProperty( audio_unit_, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, 0, &buffer_frame_size, &property_size); @@ -354,6 +370,7 @@ sink_ = callback; last_success_time_ = base::TimeTicks::Now(); + audio_unit_render_has_worked_ = false; StartAgc(); OSStatus result = AudioOutputUnitStart(audio_unit_); if (result == noErr) { @@ -605,7 +622,9 @@ // See crbug/428706 for details. UInt32 new_size = number_of_frames * format_.mBytesPerFrame; AudioBuffer* audio_buffer = audio_buffer_list_.mBuffers; + bool new_buffer_size_detected = false; if (new_size != audio_buffer->mDataByteSize) { + new_buffer_size_detected = true; DVLOG(1) << "New size of number_of_frames detected: " << number_of_frames; io_buffer_frame_size_ = static_cast<size_t>(number_of_frames); if (new_size > audio_buffer->mDataByteSize) { @@ -628,6 +647,9 @@ // renders into. OSStatus result = AudioUnitRender(audio_unit_, flags, time_stamp, bus_number, number_of_frames, &audio_buffer_list_); + if (result == noErr) { + audio_unit_render_has_worked_ = true; + } if (result) { UMA_HISTOGRAM_SPARSE_SLOWLY("Media.AudioInputCbErrorMac", result); OSSTATUS_LOG(ERROR, result) << "AudioUnitRender() failed "; @@ -654,6 +676,15 @@ LOG(ERROR) << "Too long sequence of " << err << " errors!"; HandleError(result); } + + // Add some extra UMA stat to track down if we see this particular error + // in combination with a previous change of buffer size "on the fly". + if (result == kAudioUnitErr_CannotDoInCurrentContext) { + UMA_HISTOGRAM_BOOLEAN("Media.Audio.RenderFailsWhenBufferSizeChangesMac", + new_buffer_size_detected); + UMA_HISTOGRAM_BOOLEAN("Media.Audio.AudioUnitRenderHasWorkedMac", + audio_unit_render_has_worked_); + } } else { // We have also seen kAudioUnitErr_NoConnection in some cases. Bailing // out for this error for now. @@ -919,16 +950,16 @@ // (by the client) number of audio frames per I/O buffer connected to the // selected input device. Ideally, this size will be the same as the native // I/O buffer size given by |io_buffer_frame_size_|. - UMA_HISTOGRAM_COUNTS("Media.Audio.RequestedInputBufferFrameSizeMac", - number_of_frames_); + UMA_HISTOGRAM_SPARSE_SLOWLY("Media.Audio.RequestedInputBufferFrameSizeMac", + number_of_frames_); DVLOG(1) << "number_of_frames_: " << number_of_frames_; // This value indicates the number of frames in the IO buffers connected to // the selected input device. It has been set by the audio manger in Open() // and can be the same as |number_of_frames_|, which is the desired buffer // size. These two values might differ if other streams are using the same // device and any of these streams have asked for a smaller buffer size. - UMA_HISTOGRAM_COUNTS("Media.Audio.ActualInputBufferFrameSizeMac", - io_buffer_frame_size_); + UMA_HISTOGRAM_SPARSE_SLOWLY("Media.Audio.ActualInputBufferFrameSizeMac", + io_buffer_frame_size_); DVLOG(1) << "io_buffer_frame_size_: " << io_buffer_frame_size_; // TODO(henrika): this value will currently always report true. It should be // fixed when we understand the problem better.
diff --git a/media/audio/mac/audio_low_latency_input_mac.h b/media/audio/mac/audio_low_latency_input_mac.h index 7067985..6d2d8f5 100644 --- a/media/audio/mac/audio_low_latency_input_mac.h +++ b/media/audio/mac/audio_low_latency_input_mac.h
@@ -215,6 +215,9 @@ // called. bool buffer_size_was_changed_; + // Set to true once when AudioUnitRender() succeeds for the first time. + bool audio_unit_render_has_worked_; + DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream); };
diff --git a/media/capture/video/video_capture_device_unittest.cc b/media/capture/video/video_capture_device_unittest.cc index 2b6ef438..97b48356 100644 --- a/media/capture/video/video_capture_device_unittest.cc +++ b/media/capture/video/video_capture_device_unittest.cc
@@ -447,7 +447,9 @@ return; } #if defined(OS_WIN) - if (base::win::GetVersion() == base::win::VERSION_WIN10) { + base::win::Version version = base::win::GetVersion(); + VLOG(1) << "Windows version: " << (int)version; + if (version >= base::win::VERSION_WIN10) { VLOG(1) << "Skipped on Win10: http://crbug.com/570604."; return; }
diff --git a/mojo/edk/system/channel_win.cc b/mojo/edk/system/channel_win.cc index 77a19a68..3678835 100644 --- a/mojo/edk/system/channel_win.cc +++ b/mojo/edk/system/channel_win.cc
@@ -4,6 +4,7 @@ #include "mojo/edk/system/channel.h" +#include <stdint.h> #include <windows.h> #include <algorithm> @@ -77,6 +78,8 @@ self_(this), handle_(std::move(handle)), io_task_runner_(io_task_runner) { + sentinel_ = ~reinterpret_cast<uintptr_t>(this); + CHECK(handle_.is_valid()); memset(&read_context_, 0, sizeof(read_context_)); read_context_.handler = this; @@ -134,7 +137,13 @@ private: // May run on any thread. - ~ChannelWin() override {} + ~ChannelWin() override { + // This is intentionally not 0. If another object is constructed on top of + // this memory, it is likely to initialise values to 0. Using a non-zero + // value lets us detect the difference between just destroying, and + // re-allocating the memory. + sentinel_ = UINTPTR_MAX; + } void StartOnIOThread() { base::MessageLoop::current()->AddDestructionObserver(this); @@ -158,6 +167,9 @@ void ShutDownOnIOThread() { base::MessageLoop::current()->RemoveDestructionObserver(this); + // BUG(crbug.com/583525): This function is expected to be called once, and + // |handle_| should be valid at this point. + CHECK(handle_.is_valid()); CancelIo(handle_.get().handle); handle_.reset(); @@ -167,6 +179,7 @@ // base::MessageLoop::DestructionObserver: void WillDestroyCurrentMessageLoop() override { + CheckValid(); DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); if (self_) ShutDownOnIOThread(); @@ -176,6 +189,7 @@ void OnIOCompleted(base::MessageLoopForIO::IOContext* context, DWORD bytes_transfered, DWORD error) override { + CheckValid(); if (error != ERROR_SUCCESS) { OnError(); } else if (context == &read_context_) { @@ -270,6 +284,10 @@ return WriteNoLock(outgoing_messages_.front()); } + void CheckValid() const { + CHECK_EQ(reinterpret_cast<uintptr_t>(this), ~sentinel_); + } + // Keeps the Channel alive at least until explicit shutdown on the IO thread. scoped_refptr<Channel> self_; @@ -287,6 +305,12 @@ bool reject_writes_ = false; std::deque<MessageView> outgoing_messages_; + // A value that is unlikely to be valid if this object is destroyed and the + // memory overwritten by something else. When this is valid, its value will be + // ~|this|. + // TODO(amistry): Remove before M50 branch point. + uintptr_t sentinel_; + DISALLOW_COPY_AND_ASSIGN(ChannelWin); };
diff --git a/mojo/shell/BUILD.gn b/mojo/shell/BUILD.gn index 1adf800..c0154a72 100644 --- a/mojo/shell/BUILD.gn +++ b/mojo/shell/BUILD.gn
@@ -121,8 +121,8 @@ mojom("test_bindings") { sources = [ "application_manager_apptests.mojom", - "application_package_apptest.mojom", "capability_filter_unittest.mojom", + "package_test.mojom", "test.mojom", ] } @@ -133,7 +133,7 @@ sources = [ "application_manager_apptest.cc", - "application_package_apptest.cc", + "package_apptest.cc", ] deps = [ @@ -151,12 +151,43 @@ data_deps = [ ":application_manager_apptest_driver", ":application_manager_apptest_target", + ":package_test_package", ] } mojo_application_manifest("apptests_manifest") { application_name = "mojo_shell_apptests" source = "application_manager_apptest_manifest.json" +} + +mojo_application_manifest("package_test_a_manifest") { + application_name = "package_test_a" + source = "package_test_app_a_manifest.json" +} + +mojo_application_manifest("package_test_b_manifest") { + application_name = "package_test_b" + source = "package_test_app_b_manifest.json" +} + +mojo_native_application("package_test_package") { + testonly = true + sources = [ + "package_test_package.cc", + ] + deps = [ + ":package_test_package_manifest", + ":test_bindings", + "//base", + "//mojo/common:common_base", + "//mojo/shell/public/cpp:sources", + "//mojo/shell/public/interfaces", + ] +} + +mojo_application_manifest("package_test_package_manifest") { + application_name = "package_test_package" + source = "package_test_package_manifest.json" deps = [ ":package_test_a_manifest", ":package_test_b_manifest", @@ -167,16 +198,6 @@ ] } -mojo_application_manifest("package_test_a_manifest") { - application_name = "package_test_a" - source = "application_package_apptest_app_a_manifest.json" -} - -mojo_application_manifest("package_test_b_manifest") { - application_name = "package_test_b" - source = "application_package_apptest_app_b_manifest.json" -} - executable("application_manager_apptest_driver") { testonly = true
diff --git a/mojo/shell/application_package_apptest.cc b/mojo/shell/application_package_apptest.cc deleted file mode 100644 index 333ab70..0000000 --- a/mojo/shell/application_package_apptest.cc +++ /dev/null
@@ -1,210 +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 <stddef.h> -#include <stdint.h> - -#include <utility> - -#include "base/bind.h" -#include "base/macros.h" -#include "base/run_loop.h" -#include "base/threading/simple_thread.h" -#include "mojo/public/cpp/bindings/weak_binding_set.h" -#include "mojo/shell/application_package_apptest.mojom.h" -#include "mojo/shell/public/cpp/application_runner.h" -#include "mojo/shell/public/cpp/application_test_base.h" -#include "mojo/shell/public/cpp/interface_factory.h" -#include "mojo/shell/public/interfaces/content_handler.mojom.h" - -// Tests that multiple applications can be packaged in a single Mojo application -// implementing ContentHandler; that these applications can be specified by -// the package's manifest and are thus registered with the PackageManager. - -namespace mojo { -namespace shell { -namespace { - -using GetNameCallback = - test::mojom::ApplicationPackageApptestService::GetNameCallback; - -class ProvidedApplicationDelegate - : public ShellClient, - public InterfaceFactory<test::mojom::ApplicationPackageApptestService>, - public test::mojom::ApplicationPackageApptestService, - public base::SimpleThread { - public: - ProvidedApplicationDelegate(const std::string& name, - InterfaceRequest<mojom::ShellClient> request, - const Callback<void()>& destruct_callback) - : base::SimpleThread(name), - name_(name), - request_(std::move(request)), - destruct_callback_(destruct_callback) { - Start(); - } - ~ProvidedApplicationDelegate() override { - Join(); - destruct_callback_.Run(); - } - - private: - // mojo::ShellClient: - void Initialize(Shell* shell, const std::string& url, uint32_t id) override {} - bool AcceptConnection(Connection* connection) override { - connection->AddInterface<test::mojom::ApplicationPackageApptestService>( - this); - return true; - } - - // InterfaceFactory<test::mojom::ApplicationPackageApptestService>: - void Create( - Connection* connection, - InterfaceRequest<test::mojom::ApplicationPackageApptestService> request) - override { - bindings_.AddBinding(this, std::move(request)); - } - - // test::mojom::ApplicationPackageApptestService: - void GetName(const GetNameCallback& callback) override { - callback.Run(name_); - } - - // base::SimpleThread: - void Run() override { - ApplicationRunner(this).Run(request_.PassMessagePipe().release().value(), - false); - delete this; - } - - const std::string name_; - InterfaceRequest<mojom::ShellClient> request_; - const Callback<void()> destruct_callback_; - WeakBindingSet<test::mojom::ApplicationPackageApptestService> bindings_; - - DISALLOW_COPY_AND_ASSIGN(ProvidedApplicationDelegate); -}; - -class ApplicationPackageApptestDelegate - : public ShellClient, - public InterfaceFactory<mojom::ContentHandler>, - public InterfaceFactory<test::mojom::ApplicationPackageApptestService>, - public mojom::ContentHandler, - public test::mojom::ApplicationPackageApptestService { - public: - ApplicationPackageApptestDelegate() {} - ~ApplicationPackageApptestDelegate() override {} - - private: - // mojo::ShellClient: - void Initialize(Shell* shell, const std::string& url, uint32_t id) override {} - bool AcceptConnection(Connection* connection) override { - connection->AddInterface<ContentHandler>(this); - connection->AddInterface<test::mojom::ApplicationPackageApptestService>( - this); - return true; - } - - // InterfaceFactory<mojom::ContentHandler>: - void Create(Connection* connection, - InterfaceRequest<mojom::ContentHandler> request) override { - content_handler_bindings_.AddBinding(this, std::move(request)); - } - - // InterfaceFactory<test::mojom::ApplicationPackageApptestService>: - void Create(Connection* connection, - InterfaceRequest<test::mojom::ApplicationPackageApptestService> - request) override { - bindings_.AddBinding(this, std::move(request)); - } - - // mojom::ContentHandler: - void StartApplication(InterfaceRequest<mojom::ShellClient> request, - URLResponsePtr response, - const Callback<void()>& destruct_callback) override { - const std::string url = response->url; - if (url == "mojo://package_test_a/") { - new ProvidedApplicationDelegate("A", std::move(request), - destruct_callback); - } else if (url == "mojo://package_test_b/") { - new ProvidedApplicationDelegate("B", std::move(request), - destruct_callback); - } - } - - // test::mojom::ApplicationPackageApptestService: - void GetName(const GetNameCallback& callback) override { - callback.Run("ROOT"); - } - - std::vector<scoped_ptr<ShellClient>> delegates_; - WeakBindingSet<mojom::ContentHandler> content_handler_bindings_; - WeakBindingSet<test::mojom::ApplicationPackageApptestService> bindings_; - - DISALLOW_COPY_AND_ASSIGN(ApplicationPackageApptestDelegate); -}; - -void ReceiveName(std::string* out_name, - base::RunLoop* loop, - const String& name) { - *out_name = name; - loop->Quit(); -} - -} // namespace - -class ApplicationPackageApptest : public mojo::test::ApplicationTestBase { - public: - ApplicationPackageApptest() : delegate_(nullptr) {} - ~ApplicationPackageApptest() override {} - - private: - // test::ApplicationTestBase: - ShellClient* GetShellClient() override { - delegate_ = new ApplicationPackageApptestDelegate; - return delegate_; - } - - ApplicationPackageApptestDelegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(ApplicationPackageApptest); -}; - -TEST_F(ApplicationPackageApptest, Basic) { - { - // We need to do this to force the shell to read the test app's manifest and - // register aliases. - test::mojom::ApplicationPackageApptestServicePtr root_service; - shell()->ConnectToInterface("mojo:mojo_shell_apptests", &root_service); - base::RunLoop run_loop; - std::string root_name; - root_service->GetName(base::Bind(&ReceiveName, &root_name, &run_loop)); - run_loop.Run(); - } - - { - // Now subsequent connects to applications provided by the root app will be - // resolved correctly. - test::mojom::ApplicationPackageApptestServicePtr service_a; - shell()->ConnectToInterface("mojo:package_test_a", &service_a); - base::RunLoop run_loop; - std::string a_name; - service_a->GetName(base::Bind(&ReceiveName, &a_name, &run_loop)); - run_loop.Run(); - EXPECT_EQ("A", a_name); - } - - { - test::mojom::ApplicationPackageApptestServicePtr service_b; - shell()->ConnectToInterface("mojo:package_test_b", &service_b); - base::RunLoop run_loop; - std::string b_name; - service_b->GetName(base::Bind(&ReceiveName, &b_name, &run_loop)); - run_loop.Run(); - EXPECT_EQ("B", b_name); - } -} - -} // namespace shell -} // namespace mojo
diff --git a/mojo/shell/package_apptest.cc b/mojo/shell/package_apptest.cc new file mode 100644 index 0000000..5e2db9b --- /dev/null +++ b/mojo/shell/package_apptest.cc
@@ -0,0 +1,84 @@ +// 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 <stddef.h> +#include <stdint.h> + +#include <utility> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "mojo/shell/package_test.mojom.h" +#include "mojo/shell/public/cpp/application_test_base.h" +#include "mojo/shell/public/interfaces/application_manager.mojom.h" + +// Tests that multiple applications can be packaged in a single Mojo application +// implementing ContentHandler; that these applications can be specified by +// the package's manifest and are thus registered with the PackageManager. + +namespace mojo { +namespace shell { +namespace { +void ReceiveName(std::string* out_name, + base::RunLoop* loop, + const String& name) { + *out_name = name; + loop->Quit(); +} +} // namespace + +using PackageApptest = mojo::test::ApplicationTestBase; + +TEST_F(PackageApptest, Basic) { + std::set<uint32_t> ids; + { + // We need to do this to force the shell to read the test app's manifest and + // register aliases. + test::mojom::PackageTestServicePtr root_service; + scoped_ptr<Connection> connection = + shell()->Connect("mojo:package_test_package"); + connection->GetInterface(&root_service); + base::RunLoop run_loop; + std::string root_name; + root_service->GetName(base::Bind(&ReceiveName, &root_name, &run_loop)); + run_loop.Run(); + uint32_t id = mojom::Shell::kInvalidApplicationID; + EXPECT_TRUE(connection->GetRemoteApplicationID(&id)); + ids.insert(id); + } + + { + // Now subsequent connects to applications provided by the root app will be + // resolved correctly. + test::mojom::PackageTestServicePtr service_a; + scoped_ptr<Connection> connection = shell()->Connect("mojo:package_test_a"); + connection->GetInterface(&service_a); + base::RunLoop run_loop; + std::string a_name; + service_a->GetName(base::Bind(&ReceiveName, &a_name, &run_loop)); + run_loop.Run(); + EXPECT_EQ("A", a_name); + uint32_t id = mojom::Shell::kInvalidApplicationID; + EXPECT_TRUE(connection->GetRemoteApplicationID(&id)); + ids.insert(id); + } + + { + test::mojom::PackageTestServicePtr service_b; + scoped_ptr<Connection> connection = shell()->Connect("mojo:package_test_b"); + connection->GetInterface(&service_b); + base::RunLoop run_loop; + std::string b_name; + service_b->GetName(base::Bind(&ReceiveName, &b_name, &run_loop)); + run_loop.Run(); + EXPECT_EQ("B", b_name); + uint32_t id = mojom::Shell::kInvalidApplicationID; + EXPECT_TRUE(connection->GetRemoteApplicationID(&id)); + ids.insert(id); + } +} + +} // namespace shell +} // namespace mojo
diff --git a/mojo/shell/application_package_apptest.mojom b/mojo/shell/package_test.mojom similarity index 83% rename from mojo/shell/application_package_apptest.mojom rename to mojo/shell/package_test.mojom index 88cbeead..1bcebcb29 100644 --- a/mojo/shell/application_package_apptest.mojom +++ b/mojo/shell/package_test.mojom
@@ -4,6 +4,6 @@ module mojo.shell.test.mojom; -interface ApplicationPackageApptestService { +interface PackageTestService { GetName() => (string name); };
diff --git a/mojo/shell/application_package_apptest_app_a_manifest.json b/mojo/shell/package_test_app_a_manifest.json similarity index 100% rename from mojo/shell/application_package_apptest_app_a_manifest.json rename to mojo/shell/package_test_app_a_manifest.json
diff --git a/mojo/shell/application_package_apptest_app_b_manifest.json b/mojo/shell/package_test_app_b_manifest.json similarity index 100% rename from mojo/shell/application_package_apptest_app_b_manifest.json rename to mojo/shell/package_test_app_b_manifest.json
diff --git a/mojo/shell/package_test_package.cc b/mojo/shell/package_test_package.cc new file mode 100644 index 0000000..2c932689 --- /dev/null +++ b/mojo/shell/package_test_package.cc
@@ -0,0 +1,173 @@ +// 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 <stddef.h> +#include <stdint.h> + +#include <utility> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/threading/simple_thread.h" +#include "mojo/public/c/system/main.h" +#include "mojo/public/cpp/bindings/weak_binding_set.h" +#include "mojo/shell/package_test.mojom.h" +#include "mojo/shell/public/cpp/application_runner.h" +#include "mojo/shell/public/cpp/interface_factory.h" +#include "mojo/shell/public/cpp/shell.h" +#include "mojo/shell/public/cpp/shell_client.h" +#include "mojo/shell/public/interfaces/content_handler.mojom.h" + +// Tests that multiple applications can be packaged in a single Mojo application +// implementing ContentHandler; that these applications can be specified by +// the package's manifest and are thus registered with the PackageManager. + +namespace mojo { +namespace shell { + +using GetNameCallback = test::mojom::PackageTestService::GetNameCallback; + +class ProvidedShellClient + : public ShellClient, + public InterfaceFactory<test::mojom::PackageTestService>, + public test::mojom::PackageTestService, + public base::SimpleThread { + public: + ProvidedShellClient(const std::string& name, + mojom::ShellClientRequest request, + const Callback<void()>& destruct_callback) + : base::SimpleThread(name), + name_(name), + request_(std::move(request)), + destruct_callback_(destruct_callback), + shell_(nullptr) { + Start(); + } + ~ProvidedShellClient() override { + Join(); + destruct_callback_.Run(); + } + + private: + // mojo::ShellClient: + void Initialize(Shell* shell, const std::string& url, uint32_t id) override { + shell_ = shell; + bindings_.set_connection_error_handler( + base::Bind(&ProvidedShellClient::OnConnectionError, + base::Unretained(this))); + } + bool AcceptConnection(Connection* connection) override { + connection->AddInterface<test::mojom::PackageTestService>( + this); + return true; + } + + // InterfaceFactory<test::mojom::PackageTestService>: + void Create(Connection* connection, + test::mojom::PackageTestServiceRequest request) override { + bindings_.AddBinding(this, std::move(request)); + } + + // test::mojom::PackageTestService: + void GetName(const GetNameCallback& callback) override { + callback.Run(name_); + } + + // base::SimpleThread: + void Run() override { + ApplicationRunner(this).Run(request_.PassMessagePipe().release().value(), + false); + delete this; + } + + void OnConnectionError() { + if (bindings_.empty()) + shell_->Quit(); + } + + const std::string name_; + mojom::ShellClientRequest request_; + const Callback<void()> destruct_callback_; + Shell* shell_; + WeakBindingSet<test::mojom::PackageTestService> bindings_; + + DISALLOW_COPY_AND_ASSIGN(ProvidedShellClient); +}; + +class PackageTestShellClient + : public ShellClient, + public InterfaceFactory<mojom::ContentHandler>, + public InterfaceFactory<test::mojom::PackageTestService>, + public mojom::ContentHandler, + public test::mojom::PackageTestService { + public: + PackageTestShellClient() : shell_(nullptr) {} + ~PackageTestShellClient() override {} + + private: + // mojo::ShellClient: + void Initialize(Shell* shell, const std::string& url, uint32_t id) override { + shell_ = shell; + bindings_.set_connection_error_handler( + base::Bind(&PackageTestShellClient::OnConnectionError, + base::Unretained(this))); + } + bool AcceptConnection(Connection* connection) override { + connection->AddInterface<ContentHandler>(this); + connection->AddInterface<test::mojom::PackageTestService>( + this); + return true; + } + + // InterfaceFactory<mojom::ContentHandler>: + void Create(Connection* connection, + mojom::ContentHandlerRequest request) override { + content_handler_bindings_.AddBinding(this, std::move(request)); + } + + // InterfaceFactory<test::mojom::PackageTestService>: + void Create(Connection* connection, + test::mojom::PackageTestServiceRequest request) override { + bindings_.AddBinding(this, std::move(request)); + } + + // mojom::ContentHandler: + void StartApplication(mojom::ShellClientRequest request, + URLResponsePtr response, + const Callback<void()>& destruct_callback) override { + const std::string url = response->url; + if (url == "mojo://package_test_a/") + new ProvidedShellClient("A", std::move(request), destruct_callback); + else if (url == "mojo://package_test_b/") + new ProvidedShellClient("B", std::move(request), destruct_callback); + } + + // test::mojom::PackageTestService: + void GetName(const GetNameCallback& callback) override { + callback.Run("ROOT"); + } + + void OnConnectionError() { + if (bindings_.empty()) + shell_->Quit(); + } + + Shell* shell_; + std::vector<scoped_ptr<ShellClient>> delegates_; + WeakBindingSet<mojom::ContentHandler> content_handler_bindings_; + WeakBindingSet<test::mojom::PackageTestService> bindings_; + + DISALLOW_COPY_AND_ASSIGN(PackageTestShellClient); +}; + +} // namespace shell +} // namespace mojo + + +MojoResult MojoMain(MojoHandle shell_handle) { + MojoResult rv = mojo::ApplicationRunner( + new mojo::shell::PackageTestShellClient).Run(shell_handle); + return rv; +}
diff --git a/mojo/shell/package_test_package_manifest.json b/mojo/shell/package_test_package_manifest.json new file mode 100644 index 0000000..d4825b26 --- /dev/null +++ b/mojo/shell/package_test_package_manifest.json
@@ -0,0 +1,5 @@ +{ + "url": "mojo://package_test_package/", + "name": "Package Test Package", + "capabilities": { } +}
diff --git a/mojo/shell/public/cpp/lib/application_runner.cc b/mojo/shell/public/cpp/lib/application_runner.cc index c4aba6d..de4bfe96 100644 --- a/mojo/shell/public/cpp/lib/application_runner.cc +++ b/mojo/shell/public/cpp/lib/application_runner.cc
@@ -72,7 +72,12 @@ } MojoResult ApplicationRunner::Run(MojoHandle shell_client_request_handle) { - return Run(shell_client_request_handle, true); + bool init_base = true; + if (base::CommandLine::InitializedForCurrentProcess()) { + init_base = + !base::CommandLine::ForCurrentProcess()->HasSwitch("single-process"); + } + return Run(shell_client_request_handle, init_base); } } // namespace mojo
diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc index b65018e8..cdaadf0 100644 --- a/remoting/host/basic_desktop_environment.cc +++ b/remoting/host/basic_desktop_environment.cc
@@ -10,7 +10,9 @@ #include "build/build_config.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/client_session_control.h" +#include "remoting/host/desktop_capturer_proxy.h" #include "remoting/host/input_injector.h" +#include "remoting/host/mouse_cursor_monitor_proxy.h" #include "remoting/host/screen_controls.h" #include "remoting/host/security_key/gnubby_auth_handler.h" #include "remoting/protocol/capability_names.h" @@ -52,12 +54,16 @@ scoped_ptr<webrtc::MouseCursorMonitor> BasicDesktopEnvironment::CreateMouseCursorMonitor() { + scoped_ptr<webrtc::MouseCursorMonitor> cursor_monitor; + #if defined(OS_CHROMEOS) - return make_scoped_ptr(new MouseCursorMonitorAura()); + cursor_monitor.reset(new MouseCursorMonitorAura()); #else - return make_scoped_ptr(webrtc::MouseCursorMonitor::CreateForScreen( + cursor_monitor.reset(webrtc::MouseCursorMonitor::CreateForScreen( *desktop_capture_options_, webrtc::kFullDesktopScreenId)); #endif + return make_scoped_ptr(new MouseCursorMonitorProxy( + video_capture_task_runner_, std::move(cursor_monitor))); } std::string BasicDesktopEnvironment::GetCapabilities() const { @@ -79,27 +85,30 @@ BasicDesktopEnvironment::CreateVideoCapturer() { DCHECK(caller_task_runner_->BelongsToCurrentThread()); + scoped_ptr<webrtc::DesktopCapturer> capturer; + #if defined(OS_CHROMEOS) - return scoped_ptr<webrtc::DesktopCapturer>(new AuraDesktopCapturer()); + capturer.reset(new AuraDesktopCapturer()); #else // !defined(OS_CHROMEOS) - // The basic desktop environment does not use X DAMAGE, since it is - // broken on many systems - see http://crbug.com/73423. - return make_scoped_ptr( - webrtc::ScreenCapturer::Create(*desktop_capture_options_)); + capturer.reset(webrtc::ScreenCapturer::Create(*desktop_capture_options_)); #endif // !defined(OS_CHROMEOS) + + return make_scoped_ptr(new DesktopCapturerProxy(video_capture_task_runner_, + std::move(capturer))); } BasicDesktopEnvironment::BasicDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, bool supports_touch_events) : caller_task_runner_(caller_task_runner), + video_capture_task_runner_(video_capture_task_runner), input_task_runner_(input_task_runner), ui_task_runner_(ui_task_runner), - desktop_capture_options_( - new webrtc::DesktopCaptureOptions( - webrtc::DesktopCaptureOptions::CreateDefault())), + desktop_capture_options_(new webrtc::DesktopCaptureOptions( + webrtc::DesktopCaptureOptions::CreateDefault())), supports_touch_events_(supports_touch_events) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); #if defined(USE_X11) @@ -109,16 +118,16 @@ BasicDesktopEnvironmentFactory::BasicDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) : caller_task_runner_(caller_task_runner), + video_capture_task_runner_(video_capture_task_runner), input_task_runner_(input_task_runner), ui_task_runner_(ui_task_runner), - supports_touch_events_(false) { -} + supports_touch_events_(false) {} -BasicDesktopEnvironmentFactory::~BasicDesktopEnvironmentFactory() { -} +BasicDesktopEnvironmentFactory::~BasicDesktopEnvironmentFactory() {} bool BasicDesktopEnvironmentFactory::SupportsAudioCapture() const { DCHECK(caller_task_runner_->BelongsToCurrentThread());
diff --git a/remoting/host/basic_desktop_environment.h b/remoting/host/basic_desktop_environment.h index c99c831..8530061 100644 --- a/remoting/host/basic_desktop_environment.h +++ b/remoting/host/basic_desktop_environment.h
@@ -45,6 +45,7 @@ BasicDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, bool supports_touch_events); @@ -53,6 +54,11 @@ return caller_task_runner_; } + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner() + const { + return video_capture_task_runner_; + } + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner() const { return input_task_runner_; } @@ -70,6 +76,9 @@ // called. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; + // Used to run video capturer. + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; + // Used to run input-related tasks. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; @@ -94,6 +103,7 @@ public: BasicDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); ~BasicDesktopEnvironmentFactory() override; @@ -110,6 +120,11 @@ return caller_task_runner_; } + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner() + const { + return video_capture_task_runner_; + } + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner() const { return input_task_runner_; } @@ -125,6 +140,9 @@ // be called. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; + // Used to run video capture tasks. + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; + // Used to run input-related tasks. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 885f2e9..81ccacfb 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc
@@ -68,26 +68,16 @@ scoped_ptr<protocol::SessionManager> session_manager, scoped_refptr<protocol::TransportContext> transport_context, scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner) : desktop_environment_factory_(desktop_environment_factory), session_manager_(std::move(session_manager)), transport_context_(transport_context), audio_task_runner_(audio_task_runner), - input_task_runner_(input_task_runner), - video_capture_task_runner_(video_capture_task_runner), video_encode_task_runner_(video_encode_task_runner), - network_task_runner_(network_task_runner), - ui_task_runner_(ui_task_runner), started_(false), login_backoff_(&kDefaultBackoffPolicy), enable_curtaining_(false), weak_factory_(this) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); } @@ -142,7 +132,7 @@ } void ChromotingHost::SetEnableCurtaining(bool enable) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); + DCHECK(CalledOnValidThread()); if (enable_curtaining_ == enable) return; @@ -285,11 +275,10 @@ } // Create a ClientSession object. - ClientSession* client = new ClientSession( - this, audio_task_runner_, input_task_runner_, video_capture_task_runner_, - video_encode_task_runner_, network_task_runner_, ui_task_runner_, - std::move(connection), desktop_environment_factory_, - max_session_duration_, pairing_registry_, extensions_.get()); + ClientSession* client = + new ClientSession(this, audio_task_runner_, std::move(connection), + desktop_environment_factory_, max_session_duration_, + pairing_registry_, extensions_.get()); clients_.push_back(client); }
diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index 3b1a1fa..78ae1e4 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h
@@ -72,11 +72,7 @@ scoped_ptr<protocol::SessionManager> session_manager, scoped_refptr<protocol::TransportContext> transport_context, scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); + scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner); ~ChromotingHost() override; // Asynchronously starts the host. @@ -160,11 +156,7 @@ scoped_ptr<protocol::SessionManager> session_manager_; scoped_refptr<protocol::TransportContext> transport_context_; scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; // Must be used on the network thread only. base::ObserverList<HostStatusObserver> status_observers_;
diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index f033eee..1b94ed5 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc
@@ -67,11 +67,7 @@ desktop_environment_factory_.get(), make_scoped_ptr(session_manager_), protocol::TransportContext::ForTests(protocol::TransportRole::SERVER), task_runner_, // Audio - task_runner_, // Input - task_runner_, // Video capture - task_runner_, // Video encode - task_runner_, // Network - task_runner_)); // UI + task_runner_)); // Video encode host_->AddStatusObserver(&host_status_observer_); xmpp_login_ = "host@domain"; @@ -129,13 +125,7 @@ (connection_index == 0) ? owned_connection1_ : owned_connection2_); protocol::ConnectionToClient* connection_ptr = connection.get(); scoped_ptr<ClientSession> client(new ClientSession( - host_.get(), - task_runner_, // Audio - task_runner_, // Input - task_runner_, // Video capture - task_runner_, // Video encode - task_runner_, // Network - task_runner_, // UI + host_.get(), task_runner_ /* audio_task_runner */, std::move(connection), desktop_environment_factory_.get(), base::TimeDelta(), nullptr, std::vector<HostExtension*>())); ClientSession* client_ptr = client.get();
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index e51db407..8aa6997ac 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc
@@ -18,11 +18,9 @@ #include "remoting/codec/audio_encoder_verbatim.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/audio_pump.h" -#include "remoting/host/desktop_capturer_proxy.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/host_extension_session.h" #include "remoting/host/input_injector.h" -#include "remoting/host/mouse_cursor_monitor_proxy.h" #include "remoting/host/mouse_shape_pump.h" #include "remoting/host/screen_controls.h" #include "remoting/host/screen_resolution.h" @@ -65,11 +63,6 @@ ClientSession::ClientSession( EventHandler* event_handler, scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, scoped_ptr<protocol::ConnectionToClient> connection, DesktopEnvironmentFactory* desktop_environment_factory, const base::TimeDelta& max_duration, @@ -87,11 +80,6 @@ client_clipboard_factory_(clipboard_echo_filter_.client_filter()), max_duration_(max_duration), audio_task_runner_(audio_task_runner), - input_task_runner_(input_task_runner), - video_capture_task_runner_(video_capture_task_runner), - video_encode_task_runner_(video_encode_task_runner), - network_task_runner_(network_task_runner), - ui_task_runner_(ui_task_runner), pairing_registry_(pairing_registry), is_authenticated_(false), pause_video_(false), @@ -455,21 +443,13 @@ return; // Create MouseShapePump to send mouse cursor shape. - // TODO(sergeyu): Move MouseCursorMonitorProxy creation to DesktopEnvironment. - // When using IpcDesktopCapturer the capture thread is not useful. mouse_shape_pump_.reset( - new MouseShapePump(make_scoped_ptr(new MouseCursorMonitorProxy( - video_capture_task_runner_, - desktop_environment_->CreateMouseCursorMonitor())), + new MouseShapePump(desktop_environment_->CreateMouseCursorMonitor(), connection_->client_stub())); // Create a VideoStream to pump frames from the capturer to the client. - // TODO(sergeyu): Move DesktopCapturerProxy creation to DesktopEnvironment. - // When using IpcDesktopCapturer the capture thread is not useful. - scoped_ptr<webrtc::DesktopCapturer> capturer_proxy(new DesktopCapturerProxy( - video_capture_task_runner_, std::move(video_capturer))); + video_stream_ = connection_->StartVideoStream(std::move(video_capturer)); - video_stream_ = connection_->StartVideoStream(std::move(capturer_proxy)); video_stream_->SetSizeCallback( base::Bind(&ClientSession::OnScreenSizeChanged, base::Unretained(this)));
diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index 750a8af7..03965919 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h
@@ -86,19 +86,13 @@ // |event_handler| and |desktop_environment_factory| must outlive |this|. // All |HostExtension|s in |extensions| must outlive |this|. - ClientSession( - EventHandler* event_handler, - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, - scoped_ptr<protocol::ConnectionToClient> connection, - DesktopEnvironmentFactory* desktop_environment_factory, - const base::TimeDelta& max_duration, - scoped_refptr<protocol::PairingRegistry> pairing_registry, - const std::vector<HostExtension*>& extensions); + ClientSession(EventHandler* event_handler, + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, + scoped_ptr<protocol::ConnectionToClient> connection, + DesktopEnvironmentFactory* desktop_environment_factory, + const base::TimeDelta& max_duration, + scoped_refptr<protocol::PairingRegistry> pairing_registry, + const std::vector<HostExtension*>& extensions); ~ClientSession() override; // Returns the set of capabilities negotiated between client and host. @@ -203,11 +197,6 @@ base::OneShotTimer max_duration_timer_; scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; // Objects responsible for sending video, audio and mouse shape. // |video_stream_| and |mouse_shape_pump_| may be nullptr if the video
diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index dade4725..3e7eacb 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc
@@ -188,11 +188,6 @@ client_session_.reset(new ClientSession( &session_event_handler_, task_runner_, // Audio thread. - task_runner_, // Input thread. - task_runner_, // Capture thread. - task_runner_, // Encode thread. - task_runner_, // Network thread. - task_runner_, // UI thread. std::move(connection), desktop_environment_factory_.get(), base::TimeDelta(), nullptr, extensions_)); }
diff --git a/remoting/host/desktop_process.cc b/remoting/host/desktop_process.cc index 749fd65..b0afa8e 100644 --- a/remoting/host/desktop_process.cc +++ b/remoting/host/desktop_process.cc
@@ -121,16 +121,10 @@ AutoThread::CreateWithType( "I/O thread", caller_task_runner_, base::MessageLoop::TYPE_IO); - // Launch the video capture thread. - scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner = - AutoThread::Create("Video capture thread", caller_task_runner_); - // Create a desktop agent. - desktop_agent_ = new DesktopSessionAgent(audio_task_runner, - caller_task_runner_, - input_task_runner_, - io_task_runner, - video_capture_task_runner); + desktop_agent_ = + new DesktopSessionAgent(audio_task_runner, caller_task_runner_, + input_task_runner_, io_task_runner); // Start the agent and create an IPC channel to talk to it. IPC::PlatformFileForTransit desktop_pipe;
diff --git a/remoting/host/desktop_process_main.cc b/remoting/host/desktop_process_main.cc index 95242c9..794128c 100644 --- a/remoting/host/desktop_process_main.cc +++ b/remoting/host/desktop_process_main.cc
@@ -40,6 +40,10 @@ new AutoThreadTaskRunner(message_loop.task_runner(), run_loop.QuitClosure()); + // Launch the video capture thread. + scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner = + AutoThread::Create("Video capture thread", ui_task_runner); + // Launch the input thread. scoped_refptr<AutoThreadTaskRunner> input_task_runner = AutoThread::CreateWithType( @@ -52,17 +56,13 @@ // Create a platform-dependent environment factory. scoped_ptr<DesktopEnvironmentFactory> desktop_environment_factory; #if defined(OS_WIN) - desktop_environment_factory.reset( - new SessionDesktopEnvironmentFactory( - ui_task_runner, - input_task_runner, - ui_task_runner, - base::Bind(&DesktopProcess::InjectSas, - desktop_process.AsWeakPtr()))); + desktop_environment_factory.reset(new SessionDesktopEnvironmentFactory( + ui_task_runner, video_capture_task_runner, input_task_runner, + ui_task_runner, + base::Bind(&DesktopProcess::InjectSas, desktop_process.AsWeakPtr()))); #else // !defined(OS_WIN) desktop_environment_factory.reset(new Me2MeDesktopEnvironmentFactory( - ui_task_runner, - input_task_runner, + ui_task_runner, video_capture_task_runner, input_task_runner, ui_task_runner)); #endif // !defined(OS_WIN)
diff --git a/remoting/host/desktop_process_unittest.cc b/remoting/host/desktop_process_unittest.cc index 55aac14..97d0249 100644 --- a/remoting/host/desktop_process_unittest.cc +++ b/remoting/host/desktop_process_unittest.cc
@@ -25,6 +25,7 @@ #include "remoting/base/auto_thread_task_runner.h" #include "remoting/host/chromoting_messages.h" #include "remoting/host/desktop_process.h" +#include "remoting/host/fake_mouse_cursor_monitor.h" #include "remoting/host/host_exit_codes.h" #include "remoting/host/host_mock_objects.h" #include "remoting/host/screen_resolution.h" @@ -123,6 +124,10 @@ // DesktopEnvironment::CreateVideoCapturer(). webrtc::DesktopCapturer* CreateVideoCapturer(); + // Creates a fake webrtc::MouseCursorMonitor, to mock + // DesktopEnvironment::CreateMouseCursorMonitor(). + webrtc::MouseCursorMonitor* CreateMouseCursorMonitor(); + // Disconnects the daemon-to-desktop channel causing the desktop process to // exit. void DisconnectChannels(); @@ -207,6 +212,9 @@ EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr()) .Times(AtMost(1)) .WillOnce(Invoke(this, &DesktopProcessTest::CreateVideoCapturer)); + EXPECT_CALL(*desktop_environment, CreateMouseCursorMonitorPtr()) + .Times(AtMost(1)) + .WillOnce(Invoke(this, &DesktopProcessTest::CreateMouseCursorMonitor)); EXPECT_CALL(*desktop_environment, GetCapabilities()) .Times(AtMost(1)); EXPECT_CALL(*desktop_environment, SetCapabilities(_)) @@ -227,6 +235,10 @@ return new protocol::FakeDesktopCapturer(); } +webrtc::MouseCursorMonitor* DesktopProcessTest::CreateMouseCursorMonitor() { + return new FakeMouseCursorMonitor(); +} + void DesktopProcessTest::DisconnectChannels() { daemon_channel_.reset(); network_channel_.reset();
diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc index d8ac3e7..ed594d4 100644 --- a/remoting/host/desktop_session_agent.cc +++ b/remoting/host/desktop_session_agent.cc
@@ -158,13 +158,11 @@ scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner, scoped_refptr<AutoThreadTaskRunner> caller_task_runner, scoped_refptr<AutoThreadTaskRunner> input_task_runner, - scoped_refptr<AutoThreadTaskRunner> io_task_runner, - scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner) + scoped_refptr<AutoThreadTaskRunner> io_task_runner) : audio_capture_task_runner_(audio_capture_task_runner), caller_task_runner_(caller_task_runner), input_task_runner_(input_task_runner), io_task_runner_(io_task_runner), - video_capture_task_runner_(video_capture_task_runner), weak_factory_(this) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); } @@ -315,14 +313,16 @@ // Start the video capturer and mouse cursor monitor. video_capturer_ = desktop_environment_->CreateVideoCapturer(); + video_capturer_->Start(this); + video_capturer_->SetSharedMemoryFactory( + rtc_make_scoped_ptr(new SharedMemoryFactoryImpl( + base::Bind(&DesktopSessionAgent::SendToNetwork, this)))); mouse_cursor_monitor_ = desktop_environment_->CreateMouseCursorMonitor(); - video_capture_task_runner_->PostTask( - FROM_HERE, base::Bind( - &DesktopSessionAgent::StartVideoCapturerAndMouseMonitor, this)); + mouse_cursor_monitor_->Init(this, webrtc::MouseCursorMonitor::SHAPE_ONLY); } void DesktopSessionAgent::OnCaptureCompleted(webrtc::DesktopFrame* frame) { - DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); last_frame_.reset(frame); @@ -345,7 +345,7 @@ } void DesktopSessionAgent::OnMouseCursor(webrtc::MouseCursor* cursor) { - DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); scoped_ptr<webrtc::MouseCursor> owned_cursor(cursor); @@ -440,19 +440,14 @@ FROM_HERE, base::Bind(&DesktopSessionAgent::StopAudioCapturer, this)); // Stop the video capturer. - video_capture_task_runner_->PostTask( - FROM_HERE, base::Bind( - &DesktopSessionAgent::StopVideoCapturerAndMouseMonitor, this)); + video_capturer_.reset(); + last_frame_.reset(); + mouse_cursor_monitor_.reset(); } } void DesktopSessionAgent::OnCaptureFrame() { - if (!video_capture_task_runner_->BelongsToCurrentThread()) { - video_capture_task_runner_->PostTask( - FROM_HERE, - base::Bind(&DesktopSessionAgent::OnCaptureFrame, this)); - return; - } + DCHECK(caller_task_runner_->BelongsToCurrentThread()); mouse_cursor_monitor_->Capture(); @@ -583,27 +578,4 @@ audio_capturer_.reset(); } -void DesktopSessionAgent::StartVideoCapturerAndMouseMonitor() { - DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); - - if (video_capturer_) { - video_capturer_->Start(this); - video_capturer_->SetSharedMemoryFactory( - rtc_make_scoped_ptr(new SharedMemoryFactoryImpl( - base::Bind(&DesktopSessionAgent::SendToNetwork, this)))); - } - - if (mouse_cursor_monitor_) { - mouse_cursor_monitor_->Init(this, webrtc::MouseCursorMonitor::SHAPE_ONLY); - } -} - -void DesktopSessionAgent::StopVideoCapturerAndMouseMonitor() { - DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); - - video_capturer_.reset(); - last_frame_.reset(); - mouse_cursor_monitor_.reset(); -} - } // namespace remoting
diff --git a/remoting/host/desktop_session_agent.h b/remoting/host/desktop_session_agent.h index 8004bcd..358bfce 100644 --- a/remoting/host/desktop_session_agent.h +++ b/remoting/host/desktop_session_agent.h
@@ -70,8 +70,7 @@ scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner, scoped_refptr<AutoThreadTaskRunner> caller_task_runner, scoped_refptr<AutoThreadTaskRunner> input_task_runner, - scoped_refptr<AutoThreadTaskRunner> io_task_runner, - scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner); + scoped_refptr<AutoThreadTaskRunner> io_task_runner); // IPC::Listener implementation. bool OnMessageReceived(const IPC::Message& message) override; @@ -142,14 +141,6 @@ // Posted to |audio_capture_task_runner_| to stop the audio capturer. void StopAudioCapturer(); - // Posted to |video_capture_task_runner_| to start the video capturer and the - // mouse cursor monitor. - void StartVideoCapturerAndMouseMonitor(); - - // Posted to |video_capture_task_runner_| to stop the video capturer and the - // mouse cursor monitor. - void StopVideoCapturerAndMouseMonitor(); - private: // Task runner dedicated to running methods of |audio_capturer_|. scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner_; @@ -163,9 +154,6 @@ // Task runner used by the IPC channel. scoped_refptr<AutoThreadTaskRunner> io_task_runner_; - // Task runner dedicated to running methods of |video_capturer_|. - scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner_; - // Captures audio output. scoped_ptr<AudioCapturer> audio_capturer_;
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc index a7bfdba..4dbe639 100644 --- a/remoting/host/desktop_session_proxy.cc +++ b/remoting/host/desktop_session_proxy.cc
@@ -90,7 +90,6 @@ scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, base::WeakPtr<ClientSessionControl> client_session_control, base::WeakPtr<DesktopSessionConnector> desktop_session_connector, bool virtual_terminal, @@ -98,7 +97,6 @@ : audio_capture_task_runner_(audio_capture_task_runner), caller_task_runner_(caller_task_runner), io_task_runner_(io_task_runner), - video_capture_task_runner_(video_capture_task_runner), client_session_control_(client_session_control), desktop_session_connector_(desktop_session_connector), pending_capture_frame_requests_(0), @@ -276,7 +274,7 @@ // Generate fake responses to keep the video capturer in sync. while (pending_capture_frame_requests_) { --pending_capture_frame_requests_; - PostCaptureCompleted(nullptr); + video_capturer_->OnCaptureCompleted(nullptr); } } @@ -288,30 +286,26 @@ } void DesktopSessionProxy::CaptureFrame() { - if (!caller_task_runner_->BelongsToCurrentThread()) { - caller_task_runner_->PostTask( - FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this)); - return; - } + DCHECK(caller_task_runner_->BelongsToCurrentThread()); if (desktop_channel_) { ++pending_capture_frame_requests_; SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame()); } else { - PostCaptureCompleted(nullptr); + video_capturer_->OnCaptureCompleted(nullptr); } } void DesktopSessionProxy::SetVideoCapturer( const base::WeakPtr<IpcVideoFrameCapturer> video_capturer) { - DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); video_capturer_ = video_capturer; } void DesktopSessionProxy::SetMouseCursorMonitor( const base::WeakPtr<IpcMouseCursorMonitor>& mouse_cursor_monitor) { - DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); mouse_cursor_monitor_ = mouse_cursor_monitor; } @@ -507,13 +501,17 @@ } --pending_capture_frame_requests_; - PostCaptureCompleted(std::move(frame)); + video_capturer_->OnCaptureCompleted(std::move(frame)); } void DesktopSessionProxy::OnMouseCursor( const webrtc::MouseCursor& mouse_cursor) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); - PostMouseCursor(make_scoped_ptr(webrtc::MouseCursor::CopyOf(mouse_cursor))); + + if (mouse_cursor_monitor_) { + mouse_cursor_monitor_->OnMouseCursor( + make_scoped_ptr(webrtc::MouseCursor::CopyOf(mouse_cursor))); + } } void DesktopSessionProxy::OnInjectClipboardEvent( @@ -531,26 +529,6 @@ } } -void DesktopSessionProxy::PostCaptureCompleted( - scoped_ptr<webrtc::DesktopFrame> frame) { - DCHECK(caller_task_runner_->BelongsToCurrentThread()); - - video_capture_task_runner_->PostTask( - FROM_HERE, - base::Bind(&IpcVideoFrameCapturer::OnCaptureCompleted, video_capturer_, - base::Passed(&frame))); -} - -void DesktopSessionProxy::PostMouseCursor( - scoped_ptr<webrtc::MouseCursor> mouse_cursor) { - DCHECK(caller_task_runner_->BelongsToCurrentThread()); - - video_capture_task_runner_->PostTask( - FROM_HERE, - base::Bind(&IpcMouseCursorMonitor::OnMouseCursor, mouse_cursor_monitor_, - base::Passed(&mouse_cursor))); -} - void DesktopSessionProxy::SendToDesktop(IPC::Message* message) { DCHECK(caller_task_runner_->BelongsToCurrentThread());
diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h index 52fa521..f54713f 100644 --- a/remoting/host/desktop_session_proxy.h +++ b/remoting/host/desktop_session_proxy.h
@@ -76,7 +76,6 @@ scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, base::WeakPtr<ClientSessionControl> client_session_control, base::WeakPtr<DesktopSessionConnector> desktop_session_connector, bool virtual_terminal, @@ -169,14 +168,6 @@ // Handles InjectClipboardEvent request from the desktop integration process. void OnInjectClipboardEvent(const std::string& serialized_event); - // Posts OnCaptureCompleted() to |video_capturer_| on the video thread, - // passing |frame|. - void PostCaptureCompleted(scoped_ptr<webrtc::DesktopFrame> frame); - - // Posts OnMouseCursor() to |mouse_cursor_monitor_| on the video thread, - // passing |mouse_cursor|. - void PostMouseCursor(scoped_ptr<webrtc::MouseCursor> mouse_cursor); - // Sends a message to the desktop session agent. The message is silently // deleted if the channel is broken. void SendToDesktop(IPC::Message* message); @@ -186,11 +177,9 @@ // - public methods of this class (with some exceptions) are called on // |caller_task_runner_|. // - background I/O is served on |io_task_runner_|. - // - |video_capturer_| is called back on |video_capture_task_runner_|. scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; // Points to the audio capturer receiving captured audio packets. base::WeakPtr<IpcAudioCapturer> audio_capturer_;
diff --git a/remoting/host/ipc_desktop_environment.cc b/remoting/host/ipc_desktop_environment.cc index 129a584..25dd9dc 100644 --- a/remoting/host/ipc_desktop_environment.cc +++ b/remoting/host/ipc_desktop_environment.cc
@@ -28,7 +28,6 @@ IpcDesktopEnvironment::IpcDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, base::WeakPtr<ClientSessionControl> client_session_control, base::WeakPtr<DesktopSessionConnector> desktop_session_connector, @@ -36,18 +35,13 @@ bool supports_touch_events) { DCHECK(caller_task_runner->BelongsToCurrentThread()); - desktop_session_proxy_ = new DesktopSessionProxy(audio_task_runner, - caller_task_runner, - io_task_runner, - capture_task_runner, - client_session_control, - desktop_session_connector, - virtual_terminal, - supports_touch_events); + desktop_session_proxy_ = new DesktopSessionProxy( + audio_task_runner, caller_task_runner, io_task_runner, + client_session_control, desktop_session_connector, virtual_terminal, + supports_touch_events); } -IpcDesktopEnvironment::~IpcDesktopEnvironment() { -} +IpcDesktopEnvironment::~IpcDesktopEnvironment() {} scoped_ptr<AudioCapturer> IpcDesktopEnvironment::CreateAudioCapturer() { return desktop_session_proxy_->CreateAudioCapturer(); @@ -87,36 +81,24 @@ IpcDesktopEnvironmentFactory::IpcDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, IPC::Sender* daemon_channel) : audio_task_runner_(audio_task_runner), caller_task_runner_(caller_task_runner), - capture_task_runner_(capture_task_runner), io_task_runner_(io_task_runner), - curtain_enabled_(false), daemon_channel_(daemon_channel), - next_id_(0), - connector_factory_(this), - supports_touch_events_(false) { -} + connector_factory_(this) {} -IpcDesktopEnvironmentFactory::~IpcDesktopEnvironmentFactory() { -} +IpcDesktopEnvironmentFactory::~IpcDesktopEnvironmentFactory() {} scoped_ptr<DesktopEnvironment> IpcDesktopEnvironmentFactory::Create( base::WeakPtr<ClientSessionControl> client_session_control) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); - return make_scoped_ptr( - new IpcDesktopEnvironment(audio_task_runner_, - caller_task_runner_, - capture_task_runner_, - io_task_runner_, - client_session_control, - connector_factory_.GetWeakPtr(), - curtain_enabled_, - supports_touch_events_)); + return make_scoped_ptr(new IpcDesktopEnvironment( + audio_task_runner_, caller_task_runner_, io_task_runner_, + client_session_control, connector_factory_.GetWeakPtr(), curtain_enabled_, + supports_touch_events_)); } void IpcDesktopEnvironmentFactory::SetEnableCurtaining(bool enable) {
diff --git a/remoting/host/ipc_desktop_environment.h b/remoting/host/ipc_desktop_environment.h index c874337e..6d8cb7a 100644 --- a/remoting/host/ipc_desktop_environment.h +++ b/remoting/host/ipc_desktop_environment.h
@@ -41,7 +41,6 @@ IpcDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, base::WeakPtr<ClientSessionControl> client_session_control, base::WeakPtr<DesktopSessionConnector> desktop_session_connector, @@ -77,7 +76,6 @@ IpcDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, IPC::Sender* daemon_channel); ~IpcDesktopEnvironmentFactory() override; @@ -114,14 +112,11 @@ // be called. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; - // Used to run the video capturer. - scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_; - // Task runner used for running background I/O. scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; // True if curtain mode is enabled. - bool curtain_enabled_; + bool curtain_enabled_ = false; // IPC channel connected to the daemon process. IPC::Sender* daemon_channel_; @@ -133,15 +128,15 @@ // Next desktop session ID. IDs are allocated sequentially starting from 0. // This gives us more than 67 years of unique IDs assuming a new ID is // allocated every second. - int next_id_; + int next_id_ = 0; + + // Defines whether desktop environments created by this factory will support + // touch events by default. + bool supports_touch_events_ = false; // Factory for weak pointers to DesktopSessionConnector interface. base::WeakPtrFactory<DesktopSessionConnector> connector_factory_; - // If true then the newly Create()ed desktop environments support touch - // events. - bool supports_touch_events_; - DISALLOW_COPY_AND_ASSIGN(IpcDesktopEnvironmentFactory); };
diff --git a/remoting/host/ipc_desktop_environment_unittest.cc b/remoting/host/ipc_desktop_environment_unittest.cc index 1a32693..86b9c80 100644 --- a/remoting/host/ipc_desktop_environment_unittest.cc +++ b/remoting/host/ipc_desktop_environment_unittest.cc
@@ -294,11 +294,7 @@ // Create a desktop environment instance. desktop_environment_factory_.reset(new IpcDesktopEnvironmentFactory( - task_runner_, - task_runner_, - task_runner_, - io_task_runner_, - &daemon_channel_)); + task_runner_, task_runner_, io_task_runner_, &daemon_channel_)); desktop_environment_ = desktop_environment_factory_->Create( client_session_control_factory_.GetWeakPtr());
diff --git a/remoting/host/it2me/it2me_host.cc b/remoting/host/it2me/it2me_host.cc index 3fc19d0a..f3a32a2 100644 --- a/remoting/host/it2me/it2me_host.cc +++ b/remoting/host/it2me/it2me_host.cc
@@ -77,8 +77,8 @@ desktop_environment_factory_.reset(new It2MeDesktopEnvironmentFactory( host_context_->network_task_runner(), - host_context_->input_task_runner(), - host_context_->ui_task_runner())); + host_context_->video_capture_task_runner(), + host_context_->input_task_runner(), host_context_->ui_task_runner())); // Start monitoring configured policies. policy_watcher_->StartWatching( @@ -255,13 +255,10 @@ session_manager->set_protocol_config(std::move(protocol_config)); // Create the host. - host_.reset(new ChromotingHost( - desktop_environment_factory_.get(), std::move(session_manager), - transport_context, host_context_->audio_task_runner(), - host_context_->input_task_runner(), - host_context_->video_capture_task_runner(), - host_context_->video_encode_task_runner(), - host_context_->network_task_runner(), host_context_->ui_task_runner())); + host_.reset(new ChromotingHost(desktop_environment_factory_.get(), + std::move(session_manager), transport_context, + host_context_->audio_task_runner(), + host_context_->video_encode_task_runner())); host_->AddStatusObserver(this); host_status_logger_.reset( new HostStatusLogger(host_->AsWeakPtr(), ServerLogEntry::IT2ME,
diff --git a/remoting/host/it2me_desktop_environment.cc b/remoting/host/it2me_desktop_environment.cc index 511f4cc..f2f7cf05 100644 --- a/remoting/host/it2me_desktop_environment.cc +++ b/remoting/host/it2me_desktop_environment.cc
@@ -27,11 +27,13 @@ It2MeDesktopEnvironment::It2MeDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, base::WeakPtr<ClientSessionControl> client_session_control, bool supports_touch_events) : BasicDesktopEnvironment(caller_task_runner, + video_capture_task_runner, input_task_runner, ui_task_runner, supports_touch_events) { @@ -72,25 +74,23 @@ It2MeDesktopEnvironmentFactory::It2MeDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) : BasicDesktopEnvironmentFactory(caller_task_runner, + video_capture_task_runner, input_task_runner, - ui_task_runner) { -} + ui_task_runner) {} -It2MeDesktopEnvironmentFactory::~It2MeDesktopEnvironmentFactory() { -} +It2MeDesktopEnvironmentFactory::~It2MeDesktopEnvironmentFactory() {} scoped_ptr<DesktopEnvironment> It2MeDesktopEnvironmentFactory::Create( base::WeakPtr<ClientSessionControl> client_session_control) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); - return make_scoped_ptr(new It2MeDesktopEnvironment(caller_task_runner(), - input_task_runner(), - ui_task_runner(), - client_session_control, - supports_touch_events())); + return make_scoped_ptr(new It2MeDesktopEnvironment( + caller_task_runner(), video_capture_task_runner(), input_task_runner(), + ui_task_runner(), client_session_control, supports_touch_events())); } } // namespace remoting
diff --git a/remoting/host/it2me_desktop_environment.h b/remoting/host/it2me_desktop_environment.h index 218187b..54118ba 100644 --- a/remoting/host/it2me_desktop_environment.h +++ b/remoting/host/it2me_desktop_environment.h
@@ -25,6 +25,7 @@ friend class It2MeDesktopEnvironmentFactory; It2MeDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, base::WeakPtr<ClientSessionControl> client_session_control, @@ -48,6 +49,7 @@ public: It2MeDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); ~It2MeDesktopEnvironmentFactory() override;
diff --git a/remoting/host/me2me_desktop_environment.cc b/remoting/host/me2me_desktop_environment.cc index 6e278b3..c3b2568 100644 --- a/remoting/host/me2me_desktop_environment.cc +++ b/remoting/host/me2me_desktop_environment.cc
@@ -52,15 +52,20 @@ Me2MeDesktopEnvironment::Me2MeDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, bool supports_touch_events) : BasicDesktopEnvironment(caller_task_runner, + video_capture_task_runner, input_task_runner, ui_task_runner, - supports_touch_events), - gnubby_auth_enabled_(false) { + supports_touch_events) { DCHECK(caller_task_runner->BelongsToCurrentThread()); + + // X DAMAGE is not enabled by default, since it is broken on many systems - + // see http://crbug.com/73423. It's safe to enable it here because it works + // properly under Xvfb. desktop_capture_options()->set_use_update_notifications(true); } @@ -132,13 +137,13 @@ Me2MeDesktopEnvironmentFactory::Me2MeDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) : BasicDesktopEnvironmentFactory(caller_task_runner, + video_capture_task_runner, input_task_runner, - ui_task_runner), - curtain_enabled_(false) { -} + ui_task_runner) {} Me2MeDesktopEnvironmentFactory::~Me2MeDesktopEnvironmentFactory() { } @@ -148,10 +153,9 @@ DCHECK(caller_task_runner()->BelongsToCurrentThread()); scoped_ptr<Me2MeDesktopEnvironment> desktop_environment( - new Me2MeDesktopEnvironment(caller_task_runner(), - input_task_runner(), - ui_task_runner(), - supports_touch_events())); + new Me2MeDesktopEnvironment( + caller_task_runner(), video_capture_task_runner(), + input_task_runner(), ui_task_runner(), supports_touch_events())); if (!desktop_environment->InitializeSecurity(client_session_control, curtain_enabled_)) { return nullptr;
diff --git a/remoting/host/me2me_desktop_environment.h b/remoting/host/me2me_desktop_environment.h index 7faf9a5..6d9969f 100644 --- a/remoting/host/me2me_desktop_environment.h +++ b/remoting/host/me2me_desktop_environment.h
@@ -30,6 +30,7 @@ friend class Me2MeDesktopEnvironmentFactory; Me2MeDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, bool supports_touch_events); @@ -54,7 +55,7 @@ scoped_ptr<LocalInputMonitor> local_input_monitor_; // True if gnubby auth is enabled. - bool gnubby_auth_enabled_; + bool gnubby_auth_enabled_ = false; DISALLOW_COPY_AND_ASSIGN(Me2MeDesktopEnvironment); }; @@ -64,6 +65,7 @@ public: Me2MeDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); ~Me2MeDesktopEnvironmentFactory() override; @@ -79,10 +81,10 @@ private: // True if curtain mode is enabled. - bool curtain_enabled_; + bool curtain_enabled_ = false; // True if gnubby auth is enabled. - bool gnubby_auth_enabled_; + bool gnubby_auth_enabled_ = false; DISALLOW_COPY_AND_ASSIGN(Me2MeDesktopEnvironmentFactory); };
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index b664dd2..a80ef55b 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc
@@ -897,27 +897,19 @@ #if defined(REMOTING_MULTI_PROCESS) IpcDesktopEnvironmentFactory* desktop_environment_factory = new IpcDesktopEnvironmentFactory( - context_->audio_task_runner(), - context_->network_task_runner(), - context_->video_capture_task_runner(), - context_->network_task_runner(), - daemon_channel_.get()); + context_->audio_task_runner(), context_->network_task_runner(), + context_->network_task_runner(), daemon_channel_.get()); desktop_session_connector_ = desktop_environment_factory; #else // !defined(REMOTING_MULTI_PROCESS) BasicDesktopEnvironmentFactory* desktop_environment_factory; if (enable_window_capture_) { - desktop_environment_factory = - new SingleWindowDesktopEnvironmentFactory( - context_->network_task_runner(), - context_->input_task_runner(), - context_->ui_task_runner(), - window_id_); + desktop_environment_factory = new SingleWindowDesktopEnvironmentFactory( + context_->network_task_runner(), context_->video_capture_task_runner(), + context_->input_task_runner(), context_->ui_task_runner(), window_id_); } else { - desktop_environment_factory = - new Me2MeDesktopEnvironmentFactory( - context_->network_task_runner(), - context_->input_task_runner(), - context_->ui_task_runner()); + desktop_environment_factory = new Me2MeDesktopEnvironmentFactory( + context_->network_task_runner(), context_->video_capture_task_runner(), + context_->input_task_runner(), context_->ui_task_runner()); } #endif // !defined(REMOTING_MULTI_PROCESS) desktop_environment_factory->set_supports_touch_events( @@ -1543,12 +1535,10 @@ } session_manager->set_protocol_config(std::move(protocol_config)); - host_.reset(new ChromotingHost( - desktop_environment_factory_.get(), std::move(session_manager), - transport_context, context_->audio_task_runner(), - context_->input_task_runner(), context_->video_capture_task_runner(), - context_->video_encode_task_runner(), context_->network_task_runner(), - context_->ui_task_runner())); + host_.reset(new ChromotingHost(desktop_environment_factory_.get(), + std::move(session_manager), transport_context, + context_->audio_task_runner(), + context_->video_encode_task_runner())); if (frame_recorder_buffer_size_ > 0) { scoped_ptr<VideoFrameRecorderHostExtension> frame_recorder_extension(
diff --git a/remoting/host/single_window_desktop_environment.cc b/remoting/host/single_window_desktop_environment.cc index d120932..0f2b1480 100644 --- a/remoting/host/single_window_desktop_environment.cc +++ b/remoting/host/single_window_desktop_environment.cc
@@ -29,6 +29,7 @@ friend class SingleWindowDesktopEnvironmentFactory; SingleWindowDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, webrtc::WindowId window_id, @@ -70,27 +71,29 @@ SingleWindowDesktopEnvironment::SingleWindowDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, webrtc::WindowId window_id, bool supports_touch_events) : BasicDesktopEnvironment(caller_task_runner, + video_capture_task_runner, input_task_runner, ui_task_runner, supports_touch_events), - window_id_(window_id) { -} + window_id_(window_id) {} SingleWindowDesktopEnvironmentFactory::SingleWindowDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, webrtc::WindowId window_id) : BasicDesktopEnvironmentFactory(caller_task_runner, + video_capture_task_runner, input_task_runner, ui_task_runner), - window_id_(window_id) { -} + window_id_(window_id) {} SingleWindowDesktopEnvironmentFactory:: ~SingleWindowDesktopEnvironmentFactory() { @@ -100,13 +103,9 @@ base::WeakPtr<ClientSessionControl> client_session_control) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); - scoped_ptr<SingleWindowDesktopEnvironment> desktop_environment( - new SingleWindowDesktopEnvironment(caller_task_runner(), - input_task_runner(), - ui_task_runner(), - window_id_, - supports_touch_events())); - return std::move(desktop_environment); + return make_scoped_ptr(new SingleWindowDesktopEnvironment( + caller_task_runner(), video_capture_task_runner(), input_task_runner(), + ui_task_runner(), window_id_, supports_touch_events())); } } // namespace remoting
diff --git a/remoting/host/single_window_desktop_environment.h b/remoting/host/single_window_desktop_environment.h index a446cc9..c4e84ea 100644 --- a/remoting/host/single_window_desktop_environment.h +++ b/remoting/host/single_window_desktop_environment.h
@@ -18,6 +18,7 @@ public: SingleWindowDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, webrtc::WindowId window_id);
diff --git a/remoting/host/win/session_desktop_environment.cc b/remoting/host/win/session_desktop_environment.cc index 045562f..9d9f8b2 100644 --- a/remoting/host/win/session_desktop_environment.cc +++ b/remoting/host/win/session_desktop_environment.cc
@@ -29,40 +29,43 @@ SessionDesktopEnvironment::SessionDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, const base::Closure& inject_sas, bool supports_touch_events) : Me2MeDesktopEnvironment(caller_task_runner, + video_capture_task_runner, input_task_runner, ui_task_runner, supports_touch_events), - inject_sas_(inject_sas) { -} + inject_sas_(inject_sas) {} SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, const base::Closure& inject_sas) : Me2MeDesktopEnvironmentFactory(caller_task_runner, + video_capture_task_runner, input_task_runner, ui_task_runner), inject_sas_(inject_sas) { DCHECK(caller_task_runner->BelongsToCurrentThread()); } -SessionDesktopEnvironmentFactory::~SessionDesktopEnvironmentFactory() { -} +SessionDesktopEnvironmentFactory::~SessionDesktopEnvironmentFactory() {} scoped_ptr<DesktopEnvironment> SessionDesktopEnvironmentFactory::Create( base::WeakPtr<ClientSessionControl> client_session_control) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); scoped_ptr<SessionDesktopEnvironment> desktop_environment( - new SessionDesktopEnvironment(caller_task_runner(), input_task_runner(), - ui_task_runner(), inject_sas_, - supports_touch_events())); + new SessionDesktopEnvironment(caller_task_runner(), + video_capture_task_runner(), + input_task_runner(), ui_task_runner(), + inject_sas_, supports_touch_events())); if (!desktop_environment->InitializeSecurity(client_session_control, curtain_enabled())) { return nullptr;
diff --git a/remoting/host/win/session_desktop_environment.h b/remoting/host/win/session_desktop_environment.h index cc4b187..96fd493 100644 --- a/remoting/host/win/session_desktop_environment.h +++ b/remoting/host/win/session_desktop_environment.h
@@ -26,6 +26,7 @@ friend class SessionDesktopEnvironmentFactory; SessionDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, const base::Closure& inject_sas, @@ -42,6 +43,7 @@ public: SessionDesktopEnvironmentFactory( scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, const base::Closure& inject_sas);
diff --git a/remoting/test/protocol_perftest.cc b/remoting/test/protocol_perftest.cc index b936479b..fa1a325 100644 --- a/remoting/test/protocol_perftest.cc +++ b/remoting/test/protocol_perftest.cc
@@ -331,9 +331,7 @@ host_.reset(new ChromotingHost( &desktop_environment_factory_, std::move(session_manager), transport_context, host_thread_.task_runner(), - host_thread_.task_runner(), capture_thread_.task_runner(), - encode_thread_.task_runner(), host_thread_.task_runner(), - host_thread_.task_runner())); + encode_thread_.task_runner())); base::FilePath certs_dir(net::GetTestCertsDirectory());
diff --git a/third_party/WebKit/LayoutTests/fast/css/variables/css-supports-supports-variables.html b/third_party/WebKit/LayoutTests/fast/css/variables/css-supports-supports-variables.html new file mode 100644 index 0000000..b0d2b37 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/variables/css-supports-supports-variables.html
@@ -0,0 +1,82 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<style> +#testElem { + --foo:pretty much anything; + --space: space at start; + --bar:including this(</style> +<style> +#testElem { + --far\ :this is OK too (); + --foo\ \ :and this \(; +} +</style> +<style> +#testElem { + --wow: wow!; +} +</style> +<style> +#testElem { + --yay: yay :-); +} +</style> +<style> +#testElem { + --n: +</style> +<style> +#testElem { + --wrong: ' +</style> +<div id='testElem'></div> +<script> +test(function() { + assert_true(CSS.supports('--foo', 'pretty much anything')); + assert_true(CSS.supports('--bar', 'including this(')); + assert_true(CSS.supports('--far ', 'this is OK too ()')); + assert_true(CSS.supports('--foo ', 'and this \\(')); + assert_false(CSS.supports('--wow', 'wow!')); + assert_false(CSS.supports('--yay', 'yay :-)')); + assert_true(CSS.supports('--n', '\n')); + assert_false(CSS.supports('--wrong', "'\n")); + assert_true(CSS.supports('--space', ' space at start')); + + assert_false(CSS.supports('--width', '100px) and (width: 100px'), + "it's tempting to implement this supports function in terms of the other one. Don't."); +}, "Test that CSS.supports(prop, val) returns true for custom properties."); + +test(function() { + assert_equals(getComputedStyle(testElem).getPropertyValue('--foo'), 'pretty much anything'); + assert_equals(getComputedStyle(testElem).getPropertyValue('--bar'), 'including this('); + assert_equals(getComputedStyle(testElem).getPropertyValue('--far '), 'this is OK too ()'); + assert_equals(getComputedStyle(testElem).getPropertyValue('--foo '), 'and this \\('); + assert_equals(getComputedStyle(testElem).getPropertyValue('--wow'), ''); + assert_equals(getComputedStyle(testElem).getPropertyValue('--yay'), ''); + assert_equals(getComputedStyle(testElem).getPropertyValue('--n'), ' '); + assert_equals(getComputedStyle(testElem).getPropertyValue('--wrong'), ''); + assert_equals(getComputedStyle(testElem).getPropertyValue('--space'), ' space at start'); +}, "Test that above CSS.supports values can be specified in style."); + +test(function() { + testElem.style.setProperty('--foo', 'pretty much anything'); + testElem.style.setProperty('--bar', 'including this('); + testElem.style.setProperty('--far ', 'this is OK too ()'); + testElem.style.setProperty('--foo ', 'and this \\('); + testElem.style.setProperty('--wow', 'wow!'); + testElem.style.setProperty('--yay', 'yay :-)'); + testElem.style.setProperty('--n', '\n'); + testElem.style.setProperty('--wrong', "'\n"); + testElem.style.setProperty('--space', ' space at start'); + assert_equals(testElem.style.getPropertyValue('--foo'), 'pretty much anything'); + assert_equals(testElem.style.getPropertyValue('--bar'), 'including this('); + assert_equals(testElem.style.getPropertyValue('--far '), 'this is OK too ()'); + assert_equals(testElem.style.getPropertyValue('--foo '), 'and this \\('); + assert_equals(testElem.style.getPropertyValue('--wow'), ''); + assert_equals(testElem.style.getPropertyValue('--yay'), ''); + assert_equals(testElem.style.getPropertyValue('--n'), ' '); + assert_equals(testElem.style.getPropertyValue('--wrong'), ''); + assert_equals(testElem.style.getPropertyValue('--space'), ' space at start'); +}, "Test that above CSS.supports values can be written into inline style via CSSOM API"); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/content-reprojection-recalc-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/shadow/content-reprojection-recalc-expected.txt new file mode 100644 index 0000000..f7e9dbb --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/content-reprojection-recalc-expected.txt
@@ -0,0 +1,11 @@ +Redistribution into same position should not cause style recalc + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS window.internals is defined. +PASS internals.updateStyleAndReturnAffectedElementCount() is 1 +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/content-reprojection-recalc.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/content-reprojection-recalc.html new file mode 100644 index 0000000..a486de2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/content-reprojection-recalc.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<script src="../../../resources/js-test.js"></script> +<div id="host"> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> +</div> +<script> +description("Redistribution into same position should not cause style recalc"); + +shouldBeDefined("window.internals"); + +var root = host.createShadowRoot(); +root.innerHTML = "<content></content>"; + +host.offsetTop; + +host.appendChild(document.createElement("div")); + +shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "1"); + +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-dynamic.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-dynamic.html new file mode 100644 index 0000000..5d51a08 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-dynamic.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<script src='../../../resources/testharness.js'></script> +<script src='../../../resources/testharnessreport.js'></script> +<script src='resources/shadow-dom.js'></script> +<div id='d1'> + <template data-mode='open' data-expose-as='d1_shadow'> + <div id='d1-d1'> + <template data-mode='open' data-expose-as='d1_d1_shadow'> + <slot name='d1-d1-s1'></slot> + </template> + <slot name='d1-s1' slot='d1-d1-s1'></slot> + </div> + </template> + <div id='d2' slot='d1-s1'></div> +</div> +<script> +'use strict'; +convertTemplatesToShadowRootsWithin(d1); +removeWhiteSpaceOnlyTextNodes(d1); + +test(() => { + const d1_s1 = d1_shadow.querySelector('slot'); + const d1_d1_s1 = d1_d1_shadow.querySelector('slot'); + + assert_array_equals(d1_s1.getAssignedNodes(), [d2]); + assert_array_equals(d1_s1.getAssignedNodes({'flatten': true}), [d2]); + + assert_array_equals(d1_d1_s1.getAssignedNodes(), [d1_s1]); + assert_array_equals(d1_d1_s1.getAssignedNodes({'flatten': true}), [d2]); + + const d3 = document.createElement('div'); + d3.setAttribute('id', 'd3'); + d3.setAttribute('slot', 'd1-s1'); + d1.appendChild(d3); + + assert_array_equals(d1_s1.getAssignedNodes(), [d2, d3]); + assert_array_equals(d1_s1.getAssignedNodes({'flatten': true}), [d2, d3]); + + assert_array_equals(d1_d1_s1.getAssignedNodes(), [d1_s1]); + assert_array_equals(d1_d1_s1.getAssignedNodes({'flatten': true}), [d2, d3]); +}, "Distribution should be re-calcualted when assigned nodes of a slot in the parent tree is changed"); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors-preflight.js b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors-preflight.js index fea9e4d..c2b1389d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors-preflight.js +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors-preflight.js
@@ -12,94 +12,110 @@ var checkMethod = checkJsonpMethod.bind(this, method); TEST_TARGETS.push( // Tests for Access-Control-Allow-Headers header. - [OTHER_BASE_URL + 'mode=cors&method=' + method + '&headers=CUSTOM', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM&ACAOrigin=*', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM&ACAOrigin=' + BASE_ORIGIN, [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM&ACAOrigin=*&ACAHeaders=x-serviceworker-test', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM&ACAOrigin=' + BASE_ORIGIN + '&ACAHeaders=x-serviceworker-test', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&ACAHeaders=x-serviceworker-test&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&ACAHeaders=x-serviceworker-test' + + '&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM&ACAOrigin=' + BASE_ORIGIN + - '&ACAHeaders=x-serviceworker-test&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', + '&ACAHeaders=x-serviceworker-test' + + '&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], // Test that Access-Control-Allow-Headers is checked in // CORS preflight fetch. - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-serviceworker-test&PreflightTest=200', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-serviceworker-test&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&ACAHeaders=x-serviceworker-test&PreflightTest=200', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*' + + '&ACAHeaders=x-serviceworker-test&PreflightTest=200', [fetchRejected]], // Test that CORS check is done in both preflight and main fetch. - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAHeaders=x-serviceworker-test&PreflightTest=200', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAHeaders=x-serviceworker-test' + + '&PreflightTest=200', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&PACAOrigin=*&PACAHeaders=x-serviceworker-test&PreflightTest=200', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&PACAOrigin=*&PACAHeaders=x-serviceworker-test' + + '&PreflightTest=200', [fetchRejected]], // Test that Access-Control-Expose-Headers of CORS preflight is ignored. - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-serviceworker-test&PACEHeaders=Content-Length, X-ServiceWorker-ServerHeader&PreflightTest=200', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-serviceworker-test&PACEHeaders=Content-Length, X-ServiceWorker-ServerHeader&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], // Test that CORS preflight with Status 2XX succeeds. - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-serviceworker-test&PreflightTest=201', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-serviceworker-test&PreflightTest=201', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], // Test that CORS preflight with Status other than 2XX fails. // https://crbug.com/452394 - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-serviceworker-test&PreflightTest=301', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-serviceworker-test&PreflightTest=301', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-serviceworker-test&PreflightTest=401', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-serviceworker-test&PreflightTest=401', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-serviceworker-test&PreflightTest=500', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-serviceworker-test&PreflightTest=500', [fetchRejected]], // Test CORS preflight with multiple request headers. - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM2&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-servicEworker-u, x-servicEworker-ua, x-servicewOrker-test, x-sErviceworker-s, x-sErviceworker-v&PreflightTest=200', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM2&ACAOrigin=*' + + '&PACAOrigin=*&PACAHeaders=x-servicEworker-u, x-servicEworker-ua, x-servicewOrker-test, x-sErviceworker-s, x-sErviceworker-v&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader2]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM2&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-servicewOrker-test&PreflightTest=200', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM2&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-servicewOrker-test&PreflightTest=200', [fetchRejected]], // Test request headers sent in CORS preflight requests. - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-serviceworker-test&PACRMethod=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-serviceworker-test&PACRMethod=' + method + '&PACRHeaders=x-serviceworker-test&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], // Test Access-Control-Request-Headers is sorted https://crbug.com/452391 - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&headers=CUSTOM2&ACAOrigin=*&PACAOrigin=*&PACAHeaders=x-servicEworker-u, x-servicEworker-ua, x-servicewOrker-test, x-sErviceworker-s, x-sErviceworker-v&PACRMethod=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&headers=CUSTOM2&ACAOrigin=*&PACAOrigin=*' + + '&PACAHeaders=x-servicEworker-u, x-servicEworker-ua, x-servicewOrker-test, x-sErviceworker-s, x-sErviceworker-v&PACRMethod=' + method + '&PACRHeaders=x-serviceworker-s, x-serviceworker-test, x-serviceworker-u, x-serviceworker-ua, x-serviceworker-v&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader2]]);
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors-preflight2.js b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors-preflight2.js index b09bd7f8..ec49232e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors-preflight2.js +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors-preflight2.js
@@ -18,149 +18,157 @@ // https://fetch.spec.whatwg.org/#cors-preflight-fetch // Tests for Access-Control-Allow-Methods header. // Tests for Access-Control-Allow-Headers header. - [OTHER_BASE_URL + 'mode=cors&method=' + method, + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method, [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + '&ACAMethods=' + method, + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&ACAMethods=' + method, [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + '&ACAOrigin=*', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&ACAOrigin=*', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&ACAMethods=' + method, [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&headers=CUSTOM&ACAMethods=' + method, [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&headers=CUSTOM&ACAMethods=' + method + '&ACAHeaders=x-serviceworker-test', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&headers=CUSTOM&ACAMethods=' + method + + '&ACAHeaders=x-serviceworker-test' + + '&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', + [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], + [checkMethod, hasCustomHeader]], + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&ACAOrigin=*&headers=CUSTOM&ACAMethods=PUT, XXX', + [fetchRejected]], + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&ACAOrigin=*&headers=CUSTOM&ACAMethods=PUT, XXX' + + '&ACAHeaders=x-serviceworker-test', + [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], + [checkMethod, hasCustomHeader]], + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + + '&ACAOrigin=*&headers=CUSTOM&ACAMethods=PUT, XXX' + '&ACAHeaders=x-serviceworker-test&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&ACAOrigin=*&headers=CUSTOM&ACAMethods=PUT, XXX', - [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&ACAOrigin=*&headers=CUSTOM&ACAMethods=PUT, XXX&ACAHeaders=x-serviceworker-test', - [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], - [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + - '&ACAOrigin=*&headers=CUSTOM&ACAMethods=PUT, XXX&ACAHeaders=x-serviceworker-test&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', - [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], - [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=' + BASE_ORIGIN, [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=' + BASE_ORIGIN + '&ACAMethods=' + method, [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=' + BASE_ORIGIN + '&headers=CUSTOM&ACAMethods=' + method, [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=' + BASE_ORIGIN + '&headers=CUSTOM&ACAMethods=' + method + '&ACAHeaders=x-serviceworker-test', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=' + BASE_ORIGIN + '&headers=CUSTOM&ACAMethods=' + method + - '&ACAHeaders=x-serviceworker-test&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', + '&ACAHeaders=x-serviceworker-test' + + '&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=' + BASE_ORIGIN + '&headers=CUSTOM&ACAMethods=PUT, XXX', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=' + BASE_ORIGIN + '&headers=CUSTOM&ACAMethods=PUT, XXX&ACAHeaders=x-serviceworker-test', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=' + BASE_ORIGIN + - '&headers=CUSTOM&ACAMethods=PUT, XXX&ACAHeaders=x-serviceworker-test&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', + '&headers=CUSTOM&ACAMethods=PUT, XXX&ACAHeaders=x-serviceworker-test' + + '&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], // Test that Access-Control-Allow-Methods is checked in // CORS preflight fetch. - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&PACAOrigin=*&ACAMethods=' + method + '&PreflightTest=200', [fetchRejected]], // Test that Access-Control-Allow-Headers is checked in // CORS preflight fetch. - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PACAHeaders=x-serviceworker-test&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&ACAHeaders=x-serviceworker-test&PreflightTest=200', [fetchRejected]], // Test that CORS check is done in both preflight and main fetch. - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&PACAMethods=' + method + '&PreflightTest=200', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&PACAOrigin=*&PACAMethods=' + method + '&PreflightTest=200', [fetchRejected]], // Test that Access-Control-Expose-Headers of CORS preflight is ignored. - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + - '&PACEHeaders=Content-Length, X-ServiceWorker-ServerHeader&PreflightTest=200', + '&PACEHeaders=Content-Length, X-ServiceWorker-ServerHeader' + + '&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod]], // Test that CORS preflight with Status 2XX succeeds. - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PreflightTest=201', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod]], // Test that CORS preflight with Status other than 2XX fails. // https://crbug.com/452394 - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PreflightTest=301', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PreflightTest=401', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PreflightTest=500', [fetchRejected]], // Test CORS preflight with multiple request headers. - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM2&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PACAHeaders=x-servicEworker-u, x-servicEworker-ua, x-servicewOrker-test, x-sErviceworker-s, x-sErviceworker-v&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader2]], - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM2&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PACAHeaders=x-servicewOrker-test&PreflightTest=200', [fetchRejected]], // Test request headers sent in CORS preflight requests. - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PACAHeaders=x-serviceworker-test&PACRMethod=' + method + '&PACRHeaders=x-serviceworker-test&PreflightTest=200', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [checkMethod, hasCustomHeader]], // Test Access-Control-Request-Headers is sorted https://crbug.com/452391 - [OTHER_BASE_URL + 'mode=cors&method=' + method + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=' + method + '&headers=CUSTOM2&ACAOrigin=*&PACAOrigin=*&PACAMethods=' + method + '&PACAHeaders=x-servicEworker-u, x-servicEworker-ua, x-servicewOrker-test, x-sErviceworker-s, x-sErviceworker-v&PACRMethod=' + method + '&PACRHeaders=x-serviceworker-s, x-serviceworker-test, x-serviceworker-u, x-serviceworker-ua, x-serviceworker-v&PreflightTest=200',
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors.js b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors.js index 409cf6a..93b153c3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors.js +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/cors.js
@@ -18,34 +18,40 @@ // CORS check // https://fetch.spec.whatwg.org/#concept-cors-check // Tests for Access-Control-Allow-Origin header. - [OTHER_BASE_URL + 'mode=cors&method=GET', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=GET&ACAOrigin=*', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], - [OTHER_BASE_URL + 'mode=cors&method=GET&ACAOrigin=' + BASE_ORIGIN, + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET' + + '&ACAOrigin=' + BASE_ORIGIN, [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], - [OTHER_BASE_URL + 'mode=cors&method=GET&ACAOrigin=' + BASE_ORIGIN + - ',http://www.example.com', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET&' + + 'ACAOrigin=' + BASE_ORIGIN + ',http://www.example.com', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=GET&ACAOrigin=http://www.example.com', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET' + + '&ACAOrigin=http://www.example.com', [fetchRejected]], // CORS filtered response // https://fetch.spec.whatwg.org/#concept-filtered-response-cors // Tests for Access-Control-Expose-Headers header. - [OTHER_BASE_URL + 'mode=cors&method=GET&ACAOrigin=*&ACEHeaders=X-ServiceWorker-ServerHeader', - [fetchResolved, noContentLength, hasServerHeader, hasBody, typeCors], - [methodIsGET]], - [OTHER_BASE_URL + 'mode=cors&method=GET&ACAOrigin=' + BASE_ORIGIN + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET&ACAOrigin=*' + '&ACEHeaders=X-ServiceWorker-ServerHeader', [fetchResolved, noContentLength, hasServerHeader, hasBody, typeCors], [methodIsGET]], - [OTHER_BASE_URL + 'mode=cors&method=GET&ACAOrigin=*&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET' + + '&ACAOrigin=' + BASE_ORIGIN + + '&ACEHeaders=X-ServiceWorker-ServerHeader', + [fetchResolved, noContentLength, hasServerHeader, hasBody, typeCors], + [methodIsGET]], + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET' + + '&ACAOrigin=*&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [methodIsGET]], - [OTHER_BASE_URL + 'mode=cors&method=GET&ACAOrigin=' + BASE_ORIGIN + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=GET' + + '&ACAOrigin=' + BASE_ORIGIN + '&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [methodIsGET]], @@ -55,34 +61,40 @@ // CORS check // https://fetch.spec.whatwg.org/#concept-cors-check // Tests for Access-Control-Allow-Origin header. - [OTHER_BASE_URL + 'mode=cors&method=POST', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=POST&ACAOrigin=*', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST&ACAOrigin=*', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsPOST]], - [OTHER_BASE_URL + 'mode=cors&method=POST&ACAOrigin=' + BASE_ORIGIN, + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST' + + '&ACAOrigin=' + BASE_ORIGIN, [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsPOST]], - [OTHER_BASE_URL + 'mode=cors&method=POST&ACAOrigin=' + BASE_ORIGIN + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST' + + '&ACAOrigin=' + BASE_ORIGIN + ',http://www.example.com', [fetchRejected]], - [OTHER_BASE_URL + 'mode=cors&method=POST&ACAOrigin=http://www.example.com', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST' + + '&ACAOrigin=http://www.example.com', [fetchRejected]], // CORS filtered response // https://fetch.spec.whatwg.org/#concept-filtered-response-cors // Tests for Access-Control-Expose-Headers header. - [OTHER_BASE_URL + 'mode=cors&method=POST&ACAOrigin=*&ACEHeaders=X-ServiceWorker-ServerHeader', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST' + + '&ACAOrigin=*&ACEHeaders=X-ServiceWorker-ServerHeader', [fetchResolved, noContentLength, hasServerHeader, hasBody, typeCors], [methodIsPOST]], - [OTHER_BASE_URL + 'mode=cors&method=POST&ACAOrigin=' + BASE_ORIGIN + - '&ACEHeaders=X-ServiceWorker-ServerHeader', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST' + + '&ACAOrigin=' + BASE_ORIGIN + '&ACEHeaders=X-ServiceWorker-ServerHeader', [fetchResolved, noContentLength, hasServerHeader, hasBody, typeCors], [methodIsPOST]], - [OTHER_BASE_URL + 'mode=cors&method=POST&ACAOrigin=*&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST' + + '&ACAOrigin=*&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [methodIsPOST]], - [OTHER_BASE_URL + 'mode=cors&method=POST&ACAOrigin=' + BASE_ORIGIN + + [OTHER_BASE_URL + 'mode=cors&credentials=same-origin&method=POST' + + '&ACAOrigin=' + BASE_ORIGIN + '&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [methodIsPOST]],
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect-loop.js b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect-loop.js index 31bdae0..6b413a62d2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect-loop.js +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect-loop.js
@@ -5,42 +5,44 @@ var TEST_TARGETS = [ // Redirect loop: same origin -> same origin - [REDIRECT_LOOP_URL + encodeURIComponent(BASE_URL) + '&Count=20&mode=cors', + [REDIRECT_LOOP_URL + encodeURIComponent(BASE_URL) + '&Count=20&mode=cors' + + '&credentials=same-origin', [fetchResolved, hasContentLength, hasBody, typeBasic], [methodIsGET, authCheck1]], - [REDIRECT_LOOP_URL + encodeURIComponent(BASE_URL) + '&Count=21&mode=cors', + [REDIRECT_LOOP_URL + encodeURIComponent(BASE_URL) + '&Count=21&mode=cors' + + '&credentials=same-origin', [fetchRejected]], // Redirect loop: same origin -> other origin [REDIRECT_LOOP_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - '&Count=20&mode=cors&method=GET', + '&Count=20&mode=cors&credentials=same-origin&method=GET', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], // FIXME: due to the current implementation of Chromium, // Count=21 is resolved, Count=22 is rejected. // https://crbug.com/353768 [REDIRECT_LOOP_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - '&Count=22&mode=cors&method=GET', + '&Count=22&mode=cors&credentials=same-origin&method=GET', [fetchRejected]], // Redirect loop: other origin -> same origin [OTHER_REDIRECT_LOOP_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*') + - '&Count=20&mode=cors&method=GET&ACAOrigin=*', + '&Count=20&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], [OTHER_REDIRECT_LOOP_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*') + - '&Count=21&mode=cors&method=GET&ACAOrigin=*', + '&Count=21&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchRejected]], // Redirect loop: other origin -> other origin [OTHER_REDIRECT_LOOP_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - '&Count=20&mode=cors&method=GET&ACAOrigin=*', + '&Count=20&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], [OTHER_REDIRECT_LOOP_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - '&Count=21&mode=cors&method=GET&ACAOrigin=*', + '&Count=21&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchRejected]], ];
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect.js b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect.js index f34a736a..7f33e95b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect.js +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect.js
@@ -59,76 +59,77 @@ // Do not redirect for other status even if Location header exists. [REDIRECT_URL + encodeURIComponent(BASE_URL) + - '&mode=same-origin&method=POST&Status=201&NoRedirectTest=true', + '&mode=same-origin&credentials=same-origin&method=POST&Status=201&' + + 'NoRedirectTest=true', [fetchResolved, hasBody, typeBasic], [checkJsonpNoRedirect]], [REDIRECT_URL + encodeURIComponent(BASE_URL) + - '&mode=same-origin&method=PUT', + '&mode=same-origin&credentials=same-origin&method=PUT', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeBasic], [methodIsPUT, authCheck1]], [REDIRECT_URL + encodeURIComponent(BASE_URL) + - '&mode=cors&method=GET&headers=CUSTOM', + '&mode=cors&credentials=same-origin&method=GET&headers=CUSTOM', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeBasic], [methodIsGET, hasCustomHeader, authCheck1]], // Redirect: same origin -> other origin [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL) + - '&mode=same-origin&method=GET', + '&mode=same-origin&credentials=same-origin&method=GET', [fetchRejected]], [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL) + - '&mode=same-origin&method=POST', + '&mode=same-origin&credentials=same-origin&method=POST', [fetchRejected]], [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL) + - '&mode=same-origin&method=PUT', + '&mode=same-origin&credentials=same-origin&method=PUT', [fetchRejected]], [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL) + - '&mode=cors&method=GET', + '&mode=cors&credentials=same-origin&method=GET', [fetchRejected]], [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL) + - '&mode=cors&method=PUT', + '&mode=cors&credentials=same-origin&method=PUT', [fetchRejected]], [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - '&mode=cors&method=GET', + '&mode=cors&credentials=same-origin&method=GET', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - '&mode=cors&method=PUT', + '&mode=cors&credentials=same-origin&method=PUT', [fetchRejected]], [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*&ACAMethods=PUT') + - '&mode=cors&method=PUT', + '&mode=cors&credentials=same-origin&method=PUT', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsPUT, noCustomHeader, authCheckNone]], // Status code tests for mode="cors" // The 301 redirect response MAY change the request method from POST to GET. [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - '&mode=cors&method=POST&Status=301', + '&mode=cors&credentials=same-origin&method=POST&Status=301', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // The 302 redirect response MAY change the request method from POST to GET. [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - '&mode=cors&method=POST&Status=302', + '&mode=cors&credentials=same-origin&method=POST&Status=302', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // GET method must be used for 303 redirect. [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - '&mode=cors&method=POST&Status=303', + '&mode=cors&credentials=same-origin&method=POST&Status=303', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // The 307 redirect response MUST NOT change the method. [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - '&mode=cors&method=POST&Status=307', + '&mode=cors&credentials=same-origin&method=POST&Status=307', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsPOST]], // The 308 redirect response MUST NOT change the method. // FIXME: disabled due to https://crbug.com/451938 // [REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + '&ACAOrigin=*') + - // '&mode=cors&method=POST&Status=308', + // '&mode=cors&credentials=same-origin&method=POST&Status=308', // [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], // [methodIsPOST]], @@ -138,54 +139,54 @@ OTHER_BASE_URL + '&ACAOrigin=' + BASE_ORIGIN + '&ACEHeaders=Content-Length, X-ServiceWorker-ServerHeader') + - '&mode=cors&method=GET', + '&mode=cors&credentials=same-origin&method=GET', [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], // Redirect: other origin -> same origin [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL) + - '&mode=same-origin&method=GET', + '&mode=same-origin&credentials=same-origin&method=GET', [fetchRejected]], [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL) + - '&mode=same-origin&method=POST', + '&mode=same-origin&credentials=same-origin&method=POST', [fetchRejected]], [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL) + - '&mode=cors&method=GET', + '&mode=cors&credentials=same-origin&method=GET', [fetchRejected]], [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL) + - '&mode=cors&method=GET&ACAOrigin=*', + '&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchRejected]], [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=GET&ACAOrigin=*', + '&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], // Status code tests for mode="cors" // The 301 redirect response MAY change the request method from POST to GET. [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=post&ACAOrigin=*&Status=301', + '&mode=cors&credentials=same-origin&method=post&ACAOrigin=*&Status=301', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // The 302 redirect response MAY change the request method from POST to GET. [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=post&ACAOrigin=*&Status=302', + '&mode=cors&credentials=same-origin&method=post&ACAOrigin=*&Status=302', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // GET method must be used for 303 redirect. [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=post&ACAOrigin=*&Status=303', + '&mode=cors&credentials=same-origin&method=post&ACAOrigin=*&Status=303', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // The 307 redirect response MUST NOT change the method. [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=post&ACAOrigin=*&Status=307', + '&mode=cors&credentials=same-origin&method=post&ACAOrigin=*&Status=307', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsPOST]], // The 308 redirect response MUST NOT change the method. // FIXME: disabled due to https://crbug.com/451938 // [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*') + - // '&mode=cors&method=post&ACAOrigin=*&Status=308', + // '&mode=cors&credentials=same-origin&method=post&ACAOrigin=*&Status=308', // [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], // [methodIsPOST]], @@ -194,14 +195,14 @@ // Custom method [OTHER_REDIRECT_URL + encodeURIComponent(BASE_URL + 'ACAOrigin=*&ACAMethods=PUT') + - '&mode=cors&method=PUT&ACAOrigin=*&ACAMethods=PUT', + '&mode=cors&credentials=same-origin&method=PUT&ACAOrigin=*&ACAMethods=PUT', [fetchRejected]], // Custom header [OTHER_REDIRECT_URL + encodeURIComponent( BASE_URL + 'ACAOrigin=' + BASE_ORIGIN + '&ACAHeaders=x-serviceworker-test') + - '&mode=cors&method=GET&headers=CUSTOM&ACAOrigin=*', + '&mode=cors&credentials=same-origin&method=GET&headers=CUSTOM&ACAOrigin=*', [fetchRejected]], // Redirect: other origin -> other origin @@ -209,55 +210,57 @@ '&mode=same-origin&method=GET', [fetchRejected]], [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL) + - '&mode=cors&method=GET', + '&mode=cors&credentials=same-origin&method=GET', [fetchRejected]], [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL) + - '&mode=cors&method=GET&ACAOrigin=*', + '&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchRejected]], [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=GET&ACAOrigin=*', + '&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=' + BASE_ORIGIN + '') + - '&mode=cors&method=GET&ACAOrigin=*', + '&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=GET&ACAOrigin=' + BASE_ORIGIN + '', + '&mode=cors&credentials=same-origin&method=GET' + + '&ACAOrigin=' + BASE_ORIGIN + '', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=' + BASE_ORIGIN + '') + - '&mode=cors&method=GET&ACAOrigin=' + BASE_ORIGIN + '', + '&mode=cors&credentials=same-origin&method=GET' + + '&ACAOrigin=' + BASE_ORIGIN + '', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], // Status code tests for mode="cors" // The 301 redirect response MAY change the request method from POST to GET. [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=POST&ACAOrigin=*&Status=301', + '&mode=cors&credentials=same-origin&method=POST&ACAOrigin=*&Status=301', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // The 302 redirect response MAY change the request method from POST to GET. [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=POST&ACAOrigin=*&Status=302', + '&mode=cors&credentials=same-origin&method=POST&ACAOrigin=*&Status=302', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // GET method must be used for 303 redirect. [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=POST&ACAOrigin=*&Status=303', + '&mode=cors&credentials=same-origin&method=POST&ACAOrigin=*&Status=303', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsGET]], // The 307 redirect response MUST NOT change the method. [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - '&mode=cors&method=POST&ACAOrigin=*&Status=307', + '&mode=cors&credentials=same-origin&method=POST&ACAOrigin=*&Status=307', [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], [methodIsPOST]], // The 308 redirect response MUST NOT change the method. // FIXME: disabled due to https://crbug.com/451938 // [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*') + - // '&mode=cors&method=POST&ACAOrigin=*&Status=308', + // '&mode=cors&credentials=same-origin&method=POST&ACAOrigin=*&Status=308', // [fetchResolved, noContentLength, noServerHeader, hasBody, typeCors], // [methodIsPOST]], @@ -265,7 +268,7 @@ [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*&ACEHeaders=X-ServiceWorker-ServerHeader') + - '&mode=cors&method=GET&ACAOrigin=*', + '&mode=cors&credentials=same-origin&method=GET&ACAOrigin=*', [fetchResolved, noContentLength, hasServerHeader, hasBody, typeCors], [methodIsGET, authCheckNone]], @@ -274,14 +277,14 @@ // Custom method [OTHER_REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*&ACAMethods=PUT') + - '&mode=cors&method=PUT&ACAOrigin=*&ACAMethods=PUT', + '&mode=cors&credentials=same-origin&method=PUT&ACAOrigin=*&ACAMethods=PUT', [fetchRejected]], // Custom header [OTHER_REDIRECT_URL + encodeURIComponent( OTHER_BASE_URL + 'ACAOrigin=' + BASE_ORIGIN + '&ACAHeaders=x-serviceworker-test') + - '&mode=cors&method=GET&headers=CUSTOM' + + '&mode=cors&credentials=same-origin&method=GET&headers=CUSTOM' + '&ACAOrigin=' + BASE_ORIGIN + '&ACAHeaders=x-serviceworker-test', [fetchRejected]], ];
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-resources.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-resources.html index 3ee299c..7b7947a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-resources.html +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-resources.html
@@ -12,7 +12,6 @@ expected_mode, expected_credentials) { var actual_url = url + (++url_count); expected_results[actual_url] = { - cross_origin: cross_origin, mode: expected_mode, credentials: expected_credentials, redirect: 'follow', @@ -26,7 +25,6 @@ expected_mode, expected_credentials) { var actual_url = url + (++url_count); expected_results[actual_url] = { - cross_origin: cross_origin, mode: expected_mode, credentials: expected_credentials, redirect: 'follow', @@ -40,7 +38,6 @@ expected_mode, expected_credentials) { var actual_url = url + (++url_count); expected_results[actual_url] = { - cross_origin: cross_origin, mode: expected_mode, credentials: expected_credentials, redirect: 'follow', @@ -89,6 +86,33 @@ return frame.contentWindow.load_css_image_set(actual_url, type); } +function fetch_test(frame, url, mode, credentials, + expected_mode, expected_credentials) { + var actual_url = url + (++url_count); + expected_results[actual_url] = { + mode: expected_mode, + credentials: expected_credentials, + redirect: 'follow', + message: 'fetch (url:' + actual_url + ' mode:' + mode + ' credentials:' + + credentials + ')' + }; + return frame.contentWindow.fetch( + new Request(actual_url, {mode: mode, credentials: credentials})); +} + +function audio_test(frame, url, cross_origin, + expected_mode, expected_credentials) { + var actual_url = url + (++url_count); + expected_results[actual_url] = { + mode: expected_mode, + credentials: expected_credentials, + redirect: 'follow', + message: 'Audio load (url:' + actual_url + ' cross_origin:' + + cross_origin + ')' + }; + return frame.contentWindow.load_audio(actual_url, cross_origin); +} + async_test(function(t) { var SCOPE = 'resources/fetch-request-resources-iframe.html'; var SCRIPT = 'resources/fetch-request-resources-worker.js'; @@ -143,45 +167,69 @@ .then(function() { return with_iframe(SCOPE); }) .then(function(f) { frame = f; - image_test(f, LOCAL_URL, '', 'no-cors', 'same-origin'); + image_test(f, LOCAL_URL, '', 'no-cors', 'include'); image_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin'); image_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include'); - image_test(f, REMOTE_URL, '', 'no-cors', 'same-origin'); + image_test(f, REMOTE_URL, '', 'no-cors', 'include'); image_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin'); image_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include'); - script_test(f, LOCAL_URL, '', 'no-cors', 'same-origin'); + script_test(f, LOCAL_URL, '', 'no-cors', 'include'); script_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin'); script_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include'); - script_test(f, REMOTE_URL, '', 'no-cors', 'same-origin'); + script_test(f, REMOTE_URL, '', 'no-cors', 'include'); script_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin'); script_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include'); - css_test(f, LOCAL_URL, '', 'no-cors', 'same-origin'); + css_test(f, LOCAL_URL, '', 'no-cors', 'include'); css_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin'); css_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include'); - css_test(f, REMOTE_URL, '', 'no-cors', 'same-origin'); + css_test(f, REMOTE_URL, '', 'no-cors', 'include'); css_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin'); css_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include'); font_face_test(f, LOCAL_URL, 'cors', 'same-origin'); font_face_test(f, REMOTE_URL, 'cors', 'same-origin'); - css_image_test(f, LOCAL_URL, 'backgroundImage', - 'no-cors', 'same-origin'); - css_image_test(f, REMOTE_URL, 'backgroundImage', - 'no-cors', 'same-origin'); + css_image_test(f, LOCAL_URL, 'backgroundImage', 'no-cors', 'include'); + css_image_test(f, REMOTE_URL, 'backgroundImage', 'no-cors', 'include'); css_image_test(f, LOCAL_URL, 'shapeOutside', 'cors', 'same-origin'); css_image_test(f, REMOTE_URL, 'shapeOutside', 'cors', 'same-origin'); css_image_set_test(f, LOCAL_URL, 'backgroundImage', - 'no-cors', 'same-origin'); + 'no-cors', 'include'); css_image_set_test(f, REMOTE_URL, 'backgroundImage', - 'no-cors', 'same-origin'); + 'no-cors', 'include'); css_image_set_test(f, LOCAL_URL, 'shapeOutside', 'cors', 'same-origin'); css_image_set_test(f, REMOTE_URL, 'shapeOutside', 'cors', 'same-origin'); + fetch_test(f, LOCAL_URL, 'same-origin', 'omit', 'same-origin', 'omit'); + fetch_test(f, LOCAL_URL, 'same-origin', 'same-origin', + 'same-origin', 'same-origin'); + fetch_test(f, LOCAL_URL, 'same-origin', 'include', + 'same-origin', 'include'); + fetch_test(f, LOCAL_URL, 'no-cors', 'omit', 'no-cors', 'omit'); + fetch_test(f, LOCAL_URL, 'no-cors', 'same-origin', + 'no-cors', 'same-origin'); + fetch_test(f, LOCAL_URL, 'no-cors', 'include', 'no-cors', 'include'); + fetch_test(f, LOCAL_URL, 'cors', 'omit', 'cors', 'omit'); + fetch_test(f, LOCAL_URL, 'cors', 'same-origin', 'cors', 'same-origin'); + fetch_test(f, LOCAL_URL, 'cors', 'include', 'cors', 'include'); + fetch_test(f, REMOTE_URL, 'no-cors', 'omit', 'no-cors', 'omit'); + fetch_test(f, REMOTE_URL, 'no-cors', 'same-origin', + 'no-cors', 'same-origin'); + fetch_test(f, REMOTE_URL, 'no-cors', 'include', 'no-cors', 'include'); + fetch_test(f, REMOTE_URL, 'cors', 'omit', 'cors', 'omit'); + fetch_test(f, REMOTE_URL, 'cors', 'same-origin', 'cors', 'same-origin'); + fetch_test(f, REMOTE_URL, 'cors', 'include', 'cors', 'include'); + + audio_test(f, LOCAL_URL, '', 'no-cors', 'include'); + audio_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin'); + audio_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include'); + audio_test(f, REMOTE_URL, '', 'no-cors', 'include'); + audio_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin'); + audio_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include'); }) .catch(unreached_rejection(t)); }, 'Verify FetchEvent for resources.');
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-resources-iframe.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-resources-iframe.html index 00c58386d..f13129c5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-resources-iframe.html +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-resources-iframe.html
@@ -48,5 +48,13 @@ div.style[type] = '-webkit-image-set(url(' + url + ') 1x)'; } +function load_audio(url, cross_origin) { + var audio = document.createElement('audio'); + if (cross_origin != '') { + audio.crossOrigin = cross_origin; + } + audio.src = url; + document.body.appendChild(audio); +} </script> </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-xhr-iframe.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-xhr-iframe.html index c16cc5dc..b485ee2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-xhr-iframe.html +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-xhr-iframe.html
@@ -133,7 +133,7 @@ return xhr_send(host_info['HTTP_ORIGIN'], 'GET', '', false) .then(function(response){ assert_equals(response.mode, 'cors'); - assert_equals(response.credentials, 'same-origin'); + assert_equals(response.credentials, 'include'); return xhr_send(host_info['HTTP_ORIGIN'], 'GET', '', true); }) .then(function(response){
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp index 9a1e604..b3e921af 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
@@ -32,7 +32,7 @@ #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8RecursionScope.h" #include "bindings/core/v8/V8ScriptRunner.h" -#include "core/frame/UseCounter.h" +#include "core/frame/Deprecation.h" #include "core/inspector/MainThreadDebugger.h" #include "public/platform/Platform.h" #include "wtf/LeakAnnotations.h" @@ -114,7 +114,7 @@ return; } if (deprecated) - UseCounter::countDeprecation(currentExecutionContext(isolate), blinkFeature); + Deprecation::countDeprecation(currentExecutionContext(isolate), blinkFeature); else UseCounter::count(currentExecutionContext(isolate), blinkFeature); }
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py index 5312a76..2987967d 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
@@ -94,6 +94,9 @@ if cached_attribute_validation_method or keep_alive_for_gc: includes.add('bindings/core/v8/V8HiddenValue.h') + if 'RuntimeEnabled' in extended_attributes: + includes.add('platform/RuntimeEnabledFeatures.h') + if 'OriginTrialEnabled' in extended_attributes: includes.add('core/inspector/ConsoleMessage.h') includes.add('core/origin_trials/OriginTrials.h')
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_interface.py b/third_party/WebKit/Source/bindings/scripts/v8_interface.py index 6565fc7b..f003601 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_interface.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
@@ -63,10 +63,7 @@ 'bindings/core/v8/ExceptionState.h', 'bindings/core/v8/V8DOMConfiguration.h', 'bindings/core/v8/V8ObjectConstructor.h', - 'core/dom/ContextFeatures.h', 'core/dom/Document.h', - 'platform/RuntimeEnabledFeatures.h', - 'platform/TraceEvent.h', 'wtf/GetPtr.h', 'wtf/RefPtr.h', ]) @@ -162,6 +159,9 @@ cpp_class_name_or_partial = cpp_name_or_partial(interface) v8_class_name_or_partial = v8_utilities.v8_class_name_or_partial(interface) + if 'RuntimeEnabled' in extended_attributes: + includes.add('platform/RuntimeEnabledFeatures.h') + if 'OriginTrialEnabled' in extended_attributes: includes.add('core/inspector/ConsoleMessage.h') includes.add('core/origin_trials/OriginTrials.h')
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_methods.py b/third_party/WebKit/Source/bindings/scripts/v8_methods.py index ea6486c..a3d4232 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_methods.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_methods.py
@@ -118,6 +118,9 @@ if 'LenientThis' in extended_attributes: raise Exception('[LenientThis] is not supported for operations.') + if 'RuntimeEnabled' in extended_attributes: + includes.add('platform/RuntimeEnabledFeatures.h') + if 'OriginTrialEnabled' in extended_attributes: includes.add('core/inspector/ConsoleMessage.h') includes.add('core/origin_trials/OriginTrials.h')
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_utilities.py b/third_party/WebKit/Source/bindings/scripts/v8_utilities.py index 7ec15f2e..88580d90 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_utilities.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_utilities.py
@@ -223,7 +223,7 @@ extended_attributes = member.extended_attributes if 'DeprecateAs' not in extended_attributes: return None - includes.add('core/frame/UseCounter.h') + includes.add('core/frame/Deprecation.h') return extended_attributes['DeprecateAs']
diff --git a/third_party/WebKit/Source/bindings/templates/attributes.cpp b/third_party/WebKit/Source/bindings/templates/attributes.cpp index 2cce9c177..68b988c 100644 --- a/third_party/WebKit/Source/bindings/templates/attributes.cpp +++ b/third_party/WebKit/Source/bindings/templates/attributes.cpp
@@ -171,7 +171,7 @@ {%- endif %}) { {% if attribute.deprecate_as %} - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}}); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}}); {% endif %} {% if attribute.measure_as %} UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as('AttributeGetter')}}); @@ -203,7 +203,7 @@ static void {{attribute.name}}ConstructorGetterCallback{{world_suffix}}(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { {% if attribute.deprecate_as %} - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}}); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}}); {% endif %} {% if attribute.measure_as %} UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as('ConstructorGetter')}}); @@ -362,7 +362,7 @@ v8::Local<v8::Value> v8Value = info[0]; {% endif %} {% if attribute.deprecate_as %} - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}}); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}}); {% endif %} {% if attribute.measure_as %} UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as('AttributeSetter')}});
diff --git a/third_party/WebKit/Source/bindings/templates/constants.cpp b/third_party/WebKit/Source/bindings/templates/constants.cpp index 2ed818f..a0020c6be 100644 --- a/third_party/WebKit/Source/bindings/templates/constants.cpp +++ b/third_party/WebKit/Source/bindings/templates/constants.cpp
@@ -5,7 +5,7 @@ static void {{constant.name}}ConstantGetterCallback(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info) { {% if constant.deprecate_as %} - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{constant.deprecate_as}}); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{constant.deprecate_as}}); {% endif %} {% if constant.measure_as %} UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{constant.measure_as('ConstantGetter')}});
diff --git a/third_party/WebKit/Source/bindings/templates/dictionary_v8.cpp b/third_party/WebKit/Source/bindings/templates/dictionary_v8.cpp index 459bec61..3a0d8274 100644 --- a/third_party/WebKit/Source/bindings/templates/dictionary_v8.cpp +++ b/third_party/WebKit/Source/bindings/templates/dictionary_v8.cpp
@@ -66,7 +66,7 @@ {% endif %} } else { {% if member.deprecate_as %} - UseCounter::countDeprecationIfNotPrivateScript(isolate, currentExecutionContext(isolate), UseCounter::{{member.deprecate_as}}); + Deprecation::countDeprecationIfNotPrivateScript(isolate, currentExecutionContext(isolate), UseCounter::{{member.deprecate_as}}); {% endif %} {{v8_value_to_local_cpp_value(member) | indent(12)}} {% if member.is_interface_type %}
diff --git a/third_party/WebKit/Source/bindings/templates/methods.cpp b/third_party/WebKit/Source/bindings/templates/methods.cpp index 584d770..e59be03 100644 --- a/third_party/WebKit/Source/bindings/templates/methods.cpp +++ b/third_party/WebKit/Source/bindings/templates/methods.cpp
@@ -400,7 +400,7 @@ UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{overloads.measure_all_as}}); {% endif %} {% if overloads.deprecate_all_as %} - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{overloads.deprecate_all_as}}); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{overloads.deprecate_all_as}}); {% endif %} {# First resolve by length #} {# 2. Initialize argcount to be min(maxarg, n). #} @@ -419,7 +419,7 @@ UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as('Method')}}); {% endif %} {% if method.deprecate_as and not overloads.deprecate_all_as %} - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}}); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}}); {% endif %} {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info); return; @@ -504,7 +504,7 @@ UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as('Method')}}); {% endif %} {% if method.deprecate_as %} - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}}); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}}); {% endif %} {% if method.is_origin_trial_enabled %} {{check_origin_trial(method) | indent}}
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBuffer.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBuffer.cpp index ad1d619..7a5b3d6c 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBuffer.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBuffer.cpp
@@ -11,10 +11,7 @@ #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8SharedArrayBuffer.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.cpp index 8416289..395989c 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.cpp
@@ -22,10 +22,7 @@ #include "bindings/core/v8/V8Uint32Array.h" #include "bindings/core/v8/V8Uint8Array.h" #include "bindings/core/v8/V8Uint8ClampedArray.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.cpp index 1fb4a91..4dad8a53 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.cpp
@@ -11,10 +11,7 @@ #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8SharedArrayBuffer.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8SVGTestInterface.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8SVGTestInterface.cpp index 56afd4c..3655d18 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8SVGTestInterface.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8SVGTestInterface.cpp
@@ -10,11 +10,8 @@ #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "core/SVGNames.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/dom/custom/CustomElementProcessingStack.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp index 6f5cc7f4..99c61ae 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
@@ -20,7 +20,7 @@ #include "bindings/core/v8/V8TestInterfaceWillBeGarbageCollected.h" #include "bindings/core/v8/V8Uint8Array.h" #include "core/dom/FlexibleArrayBufferView.h" -#include "core/frame/UseCounter.h" +#include "core/frame/Deprecation.h" namespace blink { @@ -95,7 +95,7 @@ if (deprecatedCreateMemberValue.IsEmpty() || deprecatedCreateMemberValue->IsUndefined()) { // Do nothing. } else { - UseCounter::countDeprecationIfNotPrivateScript(isolate, currentExecutionContext(isolate), UseCounter::CreateMember); + Deprecation::countDeprecationIfNotPrivateScript(isolate, currentExecutionContext(isolate), UseCounter::CreateMember); bool deprecatedCreateMember = toBoolean(isolate, deprecatedCreateMemberValue, exceptionState); if (exceptionState.hadException()) return;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.cpp index e491557..137b2451 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.cpp
@@ -9,11 +9,8 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.cpp index d0a12d0..de8714b 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.cpp
@@ -11,10 +11,7 @@ #include "bindings/core/v8/V8Document.h" #include "bindings/core/v8/V8Node.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.cpp index 072d0f3b..9785e31 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.cpp
@@ -11,10 +11,7 @@ #include "bindings/core/v8/V8Document.h" #include "bindings/core/v8/V8Node.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.cpp index fbe76861..c6544bc9 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.cpp
@@ -11,10 +11,7 @@ #include "bindings/core/v8/V8Document.h" #include "bindings/core/v8/V8Node.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp index a210e1a..1c98240 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp
@@ -27,7 +27,6 @@ #include "bindings/tests/idls/core/TestImplements3Implementation.h" #include "bindings/tests/idls/core/TestPartialInterface.h" #include "bindings/tests/idls/core/TestPartialInterfaceImplementation.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalFrame.h" #include "core/frame/UseCounter.h" @@ -35,7 +34,6 @@ #include "core/origin_trials/OriginTrials.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/ScriptForbiddenScope.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp index dd15d9c6..7b7c596 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp
@@ -14,12 +14,9 @@ #include "bindings/core/v8/V8Iterator.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestInterfaceEmpty.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/dom/Element.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface3.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface3.cpp index c3b889e6..28a2d8e 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface3.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface3.cpp
@@ -14,10 +14,8 @@ #include "bindings/core/v8/V8Iterator.h" #include "bindings/core/v8/V8Node.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp index 0c24619..745fc95 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp
@@ -10,10 +10,7 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp index ecdf110..6b0df0c 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp
@@ -13,12 +13,9 @@ #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestDictionary.h" #include "bindings/core/v8/V8TestInterfaceEmpty.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" #include "core/frame/UseCounter.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp index d1d6260..9c8dec4 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp
@@ -11,11 +11,8 @@ #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestInterfaceEmpty.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor3.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor3.cpp index 47b1d67..10ec66a 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor3.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor3.cpp
@@ -9,11 +9,8 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor4.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor4.cpp index 2523108e..83353aa 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor4.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor4.cpp
@@ -10,11 +10,8 @@ #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestInterfaceConstructor4.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCustomConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCustomConstructor.cpp index 8117563..5173a81 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCustomConstructor.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCustomConstructor.cpp
@@ -9,11 +9,8 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceDocument.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceDocument.cpp index 83be05e..a303cea 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceDocument.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceDocument.cpp
@@ -12,13 +12,10 @@ #include "bindings/core/v8/V8ObjectConstructor.h" #include "core/animation/DocumentAnimation.h" #include "core/css/DocumentFontFaceSet.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/dom/DocumentFullscreen.h" #include "core/svg/SVGDocumentExtensions.h" #include "core/xml/DocumentXPathEvaluator.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEmpty.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEmpty.cpp index ce34377..d9b66ba7 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEmpty.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEmpty.cpp
@@ -9,10 +9,7 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInitConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInitConstructor.cpp index 80a80b1..b3f2af97 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInitConstructor.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInitConstructor.cpp
@@ -10,11 +10,9 @@ #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestInterfaceEventInit.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" #include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp index 603fc98..70a2cfce 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp
@@ -9,11 +9,8 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceGarbageCollected.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceGarbageCollected.cpp index a2f23fe..7ff47a7 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceGarbageCollected.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceGarbageCollected.cpp
@@ -13,11 +13,8 @@ #include "bindings/core/v8/V8Iterator.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestInterfaceGarbageCollected.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp index 865074dd..c1b2103 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
@@ -9,11 +9,8 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp index 266618f..f91fa7e 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp
@@ -9,11 +9,8 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNode.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNode.cpp index 99538e4..a2335d7 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNode.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNode.cpp
@@ -13,11 +13,8 @@ #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestInterfaceEmpty.h" #include "core/HTMLNames.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/dom/custom/CustomElementProcessingStack.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceWillBeGarbageCollected.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceWillBeGarbageCollected.cpp index ea891f6..2dd0572af 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceWillBeGarbageCollected.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceWillBeGarbageCollected.cpp
@@ -10,11 +10,8 @@ #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestInterfaceWillBeGarbageCollected.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestNode.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestNode.cpp index d1ab744e..92a966c6 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestNode.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestNode.cpp
@@ -9,11 +9,8 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp index 856f721..0d7656e 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -53,13 +53,13 @@ #include "bindings/core/v8/V8XPathNSResolver.h" #include "core/HTMLNames.h" #include "core/dom/ClassCollection.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/DOMArrayBuffer.h" #include "core/dom/Document.h" #include "core/dom/FlexibleArrayBufferView.h" #include "core/dom/MessagePort.h" #include "core/dom/TagCollection.h" #include "core/dom/custom/CustomElementProcessingStack.h" +#include "core/frame/Deprecation.h" #include "core/frame/ImageBitmap.h" #include "core/frame/LocalFrame.h" #include "core/frame/UseCounter.h" @@ -72,7 +72,6 @@ #include "core/origin_trials/OriginTrials.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/ScriptForbiddenScope.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h" @@ -98,7 +97,7 @@ static void DEPRECATED_CONSTANTConstantGetterCallback(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info) { - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::Constant); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::Constant); v8SetReturnValueInt(info, 1); } @@ -2381,7 +2380,7 @@ static void testInterfaceEmptyConstructorAttributeAttributeSetterCallback(v8::Local<v8::Name>, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info) { - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::deprecatedTestInterfaceEmptyConstructorAttribute); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::deprecatedTestInterfaceEmptyConstructorAttribute); TestObjectV8Internal::testInterfaceEmptyConstructorAttributeAttributeSetter(v8Value, info); } @@ -2474,7 +2473,7 @@ static void deprecatedLongAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::LongAttribute); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::LongAttribute); TestObjectV8Internal::deprecatedLongAttributeAttributeGetter(info); } @@ -2492,7 +2491,7 @@ static void deprecatedLongAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Local<v8::Value> v8Value = info[0]; - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::LongAttribute); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::LongAttribute); TestObjectV8Internal::deprecatedLongAttributeAttributeSetter(v8Value, info); } @@ -5221,7 +5220,7 @@ static void testInterfaceEmptyConstructorAttributeConstructorGetterCallback(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::deprecatedTestInterfaceEmptyConstructorAttribute); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::deprecatedTestInterfaceEmptyConstructorAttribute); v8ConstructorAttributeGetter(property, info); } @@ -9668,7 +9667,7 @@ static void deprecatedVoidMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::voidMethod); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::voidMethod); TestObjectV8Internal::deprecatedVoidMethodMethod(info); } @@ -10025,14 +10024,14 @@ switch (std::min(1, info.Length())) { case 0: if (true) { - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureA); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureA); DeprecateAsOverloadedMethod1Method(info); return; } break; case 1: if (true) { - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureB); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureB); DeprecateAsOverloadedMethod2Method(info); return; } @@ -10072,7 +10071,7 @@ static void DeprecateAsSameValueOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) { ExceptionState exceptionState(ExceptionState::ExecutionContext, "DeprecateAsSameValueOverloadedMethod", "TestObject", info.Holder(), info.GetIsolate()); - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeature); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeature); switch (std::min(1, info.Length())) { case 0: if (true) { @@ -10225,7 +10224,7 @@ case 0: if (true) { UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeature); - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureA); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureA); deprecateAsMeasureAsSameValueOverloadedMethod1Method(info); return; } @@ -10233,7 +10232,7 @@ case 1: if (true) { UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeature); - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureB); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureB); deprecateAsMeasureAsSameValueOverloadedMethod2Method(info); return; } @@ -10273,7 +10272,7 @@ static void deprecateAsSameValueMeasureAsOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) { ExceptionState exceptionState(ExceptionState::ExecutionContext, "deprecateAsSameValueMeasureAsOverloadedMethod", "TestObject", info.Holder(), info.GetIsolate()); - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeature); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeature); switch (std::min(1, info.Length())) { case 0: if (true) { @@ -10324,7 +10323,7 @@ static void deprecateAsSameValueMeasureAsSameValueOverloadedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) { ExceptionState exceptionState(ExceptionState::ExecutionContext, "deprecateAsSameValueMeasureAsSameValueOverloadedMethod", "TestObject", info.Holder(), info.GetIsolate()); - UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureA); + Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExecutionContext(info.GetIsolate()), UseCounter::TestFeatureA); switch (std::min(1, info.Length())) { case 0: if (true) {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperations.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperations.cpp index 78ca243d..ed732e562 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperations.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperations.cpp
@@ -12,14 +12,11 @@ #include "bindings/core/v8/V8Node.h" #include "bindings/core/v8/V8NodeList.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/dom/NameNodeList.h" #include "core/dom/NodeList.h" #include "core/dom/StaticNodeList.h" #include "core/html/LabelsNodeList.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperationsNotEnumerable.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperationsNotEnumerable.cpp index f08e79e..2d08668a 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperationsNotEnumerable.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperationsNotEnumerable.cpp
@@ -9,10 +9,7 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp index 0dea0892..77f97fa 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
@@ -13,11 +13,8 @@ #include "bindings/core/v8/V8TestCallbackInterface.h" #include "bindings/core/v8/V8TestInterface.h" #include "bindings/core/v8/V8TestInterfaceEmpty.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.cpp index 6fb4ec0..5a3427a 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.cpp
@@ -11,10 +11,7 @@ #include "bindings/core/v8/V8DOMConfiguration.h" #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8SharedArrayBuffer.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" -#include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.cpp b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.cpp index ad3c2e84..8105f624 100644 --- a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.cpp
@@ -15,10 +15,8 @@ #include "bindings/core/v8/V8TestInterfaceEmpty.h" #include "bindings/modules/v8/UnionTypesModules.h" #include "bindings/modules/v8/V8TestInterface5.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "platform/RuntimeEnabledFeatures.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp index 65e31cc..93b652e 100644 --- a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp
@@ -15,14 +15,12 @@ #include "bindings/core/v8/V8ObjectConstructor.h" #include "bindings/core/v8/V8TestInterface.h" #include "bindings/tests/idls/modules/TestPartialInterfaceImplementation3.h" -#include "core/dom/ContextFeatures.h" #include "core/dom/Document.h" #include "core/frame/LocalFrame.h" #include "core/inspector/ConsoleMessage.h" #include "core/origin_trials/OriginTrials.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/ScriptForbiddenScope.h" -#include "platform/TraceEvent.h" #include "wtf/GetPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/build/scripts/templates/InternalSettingsGenerated.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/InternalSettingsGenerated.cpp.tmpl index 03a6198f..bec4e08 100644 --- a/third_party/WebKit/Source/build/scripts/templates/InternalSettingsGenerated.cpp.tmpl +++ b/third_party/WebKit/Source/build/scripts/templates/InternalSettingsGenerated.cpp.tmpl
@@ -34,4 +34,9 @@ } {% endfor %} +DEFINE_TRACE(InternalSettingsGenerated) +{ + visitor->trace(m_page); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/build/scripts/templates/InternalSettingsGenerated.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/InternalSettingsGenerated.h.tmpl index 9a02e16..b5fea91 100644 --- a/third_party/WebKit/Source/build/scripts/templates/InternalSettingsGenerated.h.tmpl +++ b/third_party/WebKit/Source/build/scripts/templates/InternalSettingsGenerated.h.tmpl
@@ -25,10 +25,7 @@ void set{{setting.name|upper_first}}({{setting.type|to_passing_type}} {{setting.name}}); {% endfor %} - DEFINE_INLINE_VIRTUAL_TRACE() - { - visitor->trace(m_page); - } + DECLARE_VIRTUAL_TRACE(); private: RawPtrWillBeMember<Page> m_page;
diff --git a/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp b/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp index 2aba4cd..f0eb22e 100644 --- a/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp +++ b/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
@@ -34,7 +34,7 @@ #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" #include "core/dom/Node.h" -#include "core/frame/UseCounter.h" +#include "core/frame/Deprecation.h" #include "core/html/HTMLStyleElement.h" #include "core/inspector/InspectorInstrumentation.h" #include "core/svg/SVGStyleElement.h" @@ -313,7 +313,7 @@ unsigned CSSStyleSheet::insertRule(const String& rule, ExceptionState& exceptionState) { - UseCounter::countDeprecation(currentExecutionContext(V8PerIsolateData::mainThreadIsolate()), UseCounter::CSSStyleSheetInsertRuleOptionalArg); + Deprecation::countDeprecation(currentExecutionContext(V8PerIsolateData::mainThreadIsolate()), UseCounter::CSSStyleSheetInsertRuleOptionalArg); return insertRule(rule, 0, exceptionState); }
diff --git a/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp b/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp index 8c70fee04..a94ee84 100644 --- a/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp +++ b/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp
@@ -33,6 +33,7 @@ #include "core/css/CSSPropertyMetadata.h" #include "core/css/StylePropertySet.h" #include "core/css/parser/CSSParser.h" +#include "core/css/parser/CSSVariableParser.h" #include "wtf/text/StringBuilder.h" #include "wtf/text/WTFString.h" @@ -41,8 +42,14 @@ bool DOMWindowCSS::supports(const String& property, const String& value) { CSSPropertyID unresolvedProperty = unresolvedCSSPropertyID(property); - if (unresolvedProperty == CSSPropertyInvalid) + if (unresolvedProperty == CSSPropertyInvalid) { + if (RuntimeEnabledFeatures::cssVariablesEnabled() && CSSVariableParser::isValidVariableName(property)) { + RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create(HTMLStandardMode); + return CSSParser::parseValueForCustomProperty(dummyStyle.get(), "--valid", value, false, 0); + } return false; + } + ASSERT(CSSPropertyMetadata::isEnabledProperty(unresolvedProperty)); // This will return false when !important is present
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp index 2738219..b8aeae9 100644 --- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp +++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -346,7 +346,7 @@ case CSSSelector::ShadowPseudo: { if (!m_isUARule && context.selector->pseudoType() == CSSSelector::PseudoShadow) - UseCounter::countDeprecation(context.element->document(), UseCounter::CSSSelectorPseudoShadow); + Deprecation::countDeprecation(context.element->document(), UseCounter::CSSSelectorPseudoShadow); // If we're in the same tree-scope as the scoping element, then following a shadow descendant combinator would escape that and thus the scope. if (context.scope && context.scope->shadowHost() && context.scope->shadowHost()->treeScope() == context.element->treeScope()) return SelectorFailsCompletely; @@ -361,7 +361,7 @@ case CSSSelector::ShadowDeep: { if (!m_isUARule) - UseCounter::countDeprecation(context.element->document(), UseCounter::CSSDeepCombinator); + Deprecation::countDeprecation(context.element->document(), UseCounter::CSSDeepCombinator); if (ShadowRoot* root = context.element->containingShadowRoot()) { if (root->type() == ShadowRootType::UserAgent) return SelectorFailsCompletely;
diff --git a/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp b/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp index 7e6f913..3a2a9e3 100644 --- a/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp +++ b/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
@@ -30,7 +30,7 @@ #include "core/dom/ElementTraversal.h" #include "core/dom/NodeTraversal.h" #include "core/dom/shadow/DistributedNodes.h" -#include "core/frame/UseCounter.h" +#include "core/frame/Deprecation.h" #include "core/html/HTMLContentElement.h" #include "core/html/HTMLShadowElement.h" #include "core/inspector/InspectorInstrumentation.h" @@ -156,9 +156,9 @@ shadowHost.willAddFirstAuthorShadowRoot(); } else if (m_shadowRoots.head()->type() == ShadowRootType::UserAgent) { shadowHost.willAddFirstAuthorShadowRoot(); - UseCounter::countDeprecation(shadowHost.document(), UseCounter::ElementCreateShadowRootMultipleWithUserAgentShadowRoot); + Deprecation::countDeprecation(shadowHost.document(), UseCounter::ElementCreateShadowRootMultipleWithUserAgentShadowRoot); } else { - UseCounter::countDeprecation(shadowHost.document(), UseCounter::ElementCreateShadowRootMultiple); + Deprecation::countDeprecation(shadowHost.document(), UseCounter::ElementCreateShadowRootMultiple); } } else if (type == ShadowRootType::Open || type == ShadowRootType::Closed) { shadowHost.willAddFirstAuthorShadowRoot();
diff --git a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp index 6ee8312c..16ad5ad 100644 --- a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp +++ b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp
@@ -7,6 +7,7 @@ #include "core/HTMLNames.h" #include "core/dom/ElementTraversal.h" #include "core/dom/NodeTraversal.h" +#include "core/dom/shadow/ElementShadow.h" #include "core/dom/shadow/InsertionPoint.h" #include "core/dom/shadow/ShadowRoot.h" #include "core/html/HTMLSlotElement.h" @@ -86,6 +87,8 @@ slot.appendDistributedNodesFrom(toHTMLSlotElement(hostChild)); else slot.appendDistributedNode(hostChild); + if (slot.isChildOfV1ShadowHost()) + slot.parentElementShadow()->setNeedsDistributionRecalc(); } DEFINE_TRACE(SlotAssignment)
diff --git a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp index cd04d73..639f888 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp +++ b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp
@@ -155,6 +155,23 @@ EXPECT_EQ_SELECTED_TEXT("Baz"); } +TEST_F(FrameSelectionTest, ModifyExtendWithFlatTree) +{ + setBodyContent("<span id=host></span>one"); + setShadowContent("two<content></content>", "host"); + updateLayoutAndStyleForPainting(); + RefPtrWillBeRawPtr<Element> host = document().getElementById("host"); + Node* const two = FlatTreeTraversal::firstChild(*host); + // Select "two" for selection in DOM tree + // Select "twoone" for selection in Flat tree + selection().setSelection(VisibleSelectionInFlatTree(PositionInFlatTree(host.get(), 0), PositionInFlatTree(document().body(), 2))); + selection().modify(FrameSelection::AlterationExtend, DirectionForward, WordGranularity); + EXPECT_EQ(Position(two, 0), visibleSelectionInDOMTree().start()); + EXPECT_EQ(Position(two, 3), visibleSelectionInDOMTree().end()); + EXPECT_EQ(PositionInFlatTree(two, 0), visibleSelectionInFlatTree().start()); + EXPECT_EQ(PositionInFlatTree(two, 3), visibleSelectionInFlatTree().end()); +} + TEST_F(FrameSelectionTest, MoveRangeSelectionTest) { // "Foo Bar Baz,"
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp index 4660cdc1..ceb6aa9e 100644 --- a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp +++ b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
@@ -194,6 +194,7 @@ m_selection.setBase(end); m_selection.setExtent(start); } + SelectionAdjuster::adjustSelectionInFlatTree(&m_selectionInFlatTree, m_selection); } VisiblePosition SelectionEditor::positionForPlatform(bool isGetStart) const
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.h b/third_party/WebKit/Source/core/editing/SelectionEditor.h index 2a2dab49..bf3f70a 100644 --- a/third_party/WebKit/Source/core/editing/SelectionEditor.h +++ b/third_party/WebKit/Source/core/editing/SelectionEditor.h
@@ -90,9 +90,6 @@ LocalFrame* frame() const; - void adjustVisibleSelectionInFlatTree(); - void adjustVisibleSelectionInDOMTree(); - TextDirection directionOfEnclosingBlock(); TextDirection directionOfSelection();
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp index 3720339..6ba2c19 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
@@ -209,7 +209,9 @@ } // Apply any remaining styles to the inline elements. if (!m_style->isEmpty() || m_styledInlineElement || m_isInlineElementToRemoveFunction) { - applyRelativeFontStyleChange(m_style.get()); + applyRelativeFontStyleChange(m_style.get(), editingState); + if (editingState->isAborted()) + return; applyInlineStyle(m_style.get(), editingState); if (editingState->isAborted()) return; @@ -275,7 +277,9 @@ block = newBlock; } if (block && block->isHTMLElement()) { - removeCSSStyle(style, toHTMLElement(block)); + removeCSSStyle(style, toHTMLElement(block), editingState); + if (editingState->isAborted()) + return; if (!m_removeOnly) addBlockStyle(styleChange, toHTMLElement(block)); } @@ -304,7 +308,7 @@ return style->mutableCopy(); } -void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style) +void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style, EditingState* editingState) { static const float MinimumFontSize = 0.1f; @@ -402,7 +406,9 @@ // Last styled node was not parent node of this text node, but we wish to style this // text node. To make this possible, add a style span to surround this text node. RefPtrWillBeRawPtr<HTMLSpanElement> span = HTMLSpanElement::create(document()); - surroundNodeRangeWithElement(node, node, span.get(), ASSERT_NO_EDITING_ABORT); + surroundNodeRangeWithElement(node, node, span.get(), editingState); + if (editingState->isAborted()) + return; element = span.release(); } else { // Only handle HTML elements and text nodes. @@ -429,8 +435,11 @@ } } - for (const auto& unstyledSpan : unstyledSpans) - removeNodePreservingChildren(unstyledSpan.get()); + for (const auto& unstyledSpan : unstyledSpans) { + removeNodePreservingChildren(unstyledSpan.get(), editingState); + if (editingState->isAborted()) + return; + } } static ContainerNode* dummySpanAncestorForNode(const Node* node) @@ -441,7 +450,7 @@ return node ? node->parentNode() : 0; } -void ApplyStyleCommand::cleanupUnstyledAppleStyleSpans(ContainerNode* dummySpanAncestor) +void ApplyStyleCommand::cleanupUnstyledAppleStyleSpans(ContainerNode* dummySpanAncestor, EditingState* editingState) { if (!dummySpanAncestor) return; @@ -453,8 +462,11 @@ Node* next; for (Node* node = dummySpanAncestor->firstChild(); node; node = next) { next = node->nextSibling(); - if (isSpanWithoutAttributesOrUnstyledStyleSpan(node)) - removeNodePreservingChildren(node); + if (isSpanWithoutAttributesOrUnstyledStyleSpan(node)) { + removeNodePreservingChildren(node, editingState); + if (editingState->isAborted()) + return; + } } } @@ -509,7 +521,7 @@ return unsplitAncestor; } -void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, HTMLElement* unsplitAncestor) +void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, HTMLElement* unsplitAncestor, EditingState* editingState) { Element* block = enclosingBlock(node); if (!block) @@ -537,8 +549,11 @@ inlineStyle->setProperty(CSSPropertyUnicodeBidi, CSSValueNormal); inlineStyle->removeProperty(CSSPropertyDirection); setNodeAttribute(element, styleAttr, AtomicString(inlineStyle->asText())); - if (isSpanWithoutAttributesOrUnstyledStyleSpan(element)) - removeNodePreservingChildren(element); + if (isSpanWithoutAttributesOrUnstyledStyleSpan(element)) { + removeNodePreservingChildren(element, editingState); + if (editingState->isAborted()) + return; + } } } } @@ -620,8 +635,12 @@ // Leave alone an ancestor that provides the desired single level embedding, if there is one. HTMLElement* startUnsplitAncestor = splitAncestorsWithUnicodeBidi(start.anchorNode(), true, textDirection); HTMLElement* endUnsplitAncestor = splitAncestorsWithUnicodeBidi(end.anchorNode(), false, textDirection); - removeEmbeddingUpToEnclosingBlock(start.anchorNode(), startUnsplitAncestor); - removeEmbeddingUpToEnclosingBlock(end.anchorNode(), endUnsplitAncestor); + removeEmbeddingUpToEnclosingBlock(start.anchorNode(), startUnsplitAncestor, editingState); + if (editingState->isAborted()) + return; + removeEmbeddingUpToEnclosingBlock(end.anchorNode(), endUnsplitAncestor, editingState); + if (editingState->isAborted()) + return; // Avoid removing the dir attribute and the unicode-bidi and direction properties from the unsplit ancestors. Position embeddingRemoveStart = removeStart; @@ -636,24 +655,36 @@ styleWithoutEmbedding = style->copy(); embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDirection(); - if (comparePositions(embeddingRemoveStart, embeddingRemoveEnd) <= 0) - removeInlineStyle(embeddingStyle.get(), embeddingRemoveStart, embeddingRemoveEnd); + if (comparePositions(embeddingRemoveStart, embeddingRemoveEnd) <= 0) { + removeInlineStyle(embeddingStyle.get(), embeddingRemoveStart, embeddingRemoveEnd, editingState); + if (editingState->isAborted()) + return; + } } } - removeInlineStyle(styleWithoutEmbedding ? styleWithoutEmbedding.get() : style, removeStart, end); + removeInlineStyle(styleWithoutEmbedding ? styleWithoutEmbedding.get() : style, removeStart, end, editingState); + if (editingState->isAborted()) + return; start = startPosition(); end = endPosition(); if (start.isNull() || start.isOrphan() || end.isNull() || end.isOrphan()) return; - if (splitStart && mergeStartWithPreviousIfIdentical(start, end)) { - start = startPosition(); - end = endPosition(); + if (splitStart) { + bool mergeResult = mergeStartWithPreviousIfIdentical(start, end, editingState); + if (editingState->isAborted()) + return; + if (splitStart && mergeResult) { + start = startPosition(); + end = endPosition(); + } } if (splitEnd) { - mergeEndWithNextIfIdentical(start, end); + mergeEndWithNextIfIdentical(start, end, editingState); + if (editingState->isAborted()) + return; start = startPosition(); end = endPosition(); } @@ -691,9 +722,11 @@ return; // Remove dummy style spans created by splitting text elements. - cleanupUnstyledAppleStyleSpans(startDummySpanAncestor.get()); + cleanupUnstyledAppleStyleSpans(startDummySpanAncestor.get(), editingState); + if (editingState->isAborted()) + return; if (endDummySpanAncestor != startDummySpanAncestor) - cleanupUnstyledAppleStyleSpans(endDummySpanAncestor.get()); + cleanupUnstyledAppleStyleSpans(endDummySpanAncestor.get(), editingState); } void ApplyStyleCommand::fixRangeAndApplyInlineStyle(EditingStyle* style, const Position& start, const Position& end, EditingState* editingState) @@ -846,7 +879,9 @@ } for (auto& run : runs) { - removeConflictingInlineStyleFromRun(style, run.start, run.end, run.pastEndNode); + removeConflictingInlineStyleFromRun(style, run.start, run.end, run.pastEndNode, editingState); + if (editingState->isAborted()) + return; if (run.startAndEndAreStillInDocument()) run.positionForStyleComputation = positionToComputeInlineStyleChange(run.start, run.dummyElement); } @@ -894,7 +929,7 @@ return false; } -void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style, RefPtrWillBeMember<Node>& runStart, RefPtrWillBeMember<Node>& runEnd, PassRefPtrWillBeRawPtr<Node> pastEndNode) +void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style, RefPtrWillBeMember<Node>& runStart, RefPtrWillBeMember<Node>& runEnd, PassRefPtrWillBeRawPtr<Node> pastEndNode, EditingState* editingState) { ASSERT(runStart && runEnd); RefPtrWillBeRawPtr<Node> next = runStart; @@ -912,7 +947,9 @@ RefPtrWillBeRawPtr<Node> previousSibling = element.previousSibling(); RefPtrWillBeRawPtr<Node> nextSibling = element.nextSibling(); RefPtrWillBeRawPtr<ContainerNode> parent = element.parentNode(); - removeInlineStyleFromElement(style, &element, RemoveAlways); + removeInlineStyleFromElement(style, &element, editingState, RemoveAlways); + if (editingState->isAborted()) + return; if (!element.inDocument()) { // FIXME: We might need to update the start and the end of current selection here but need a test. if (runStart == element) @@ -923,7 +960,7 @@ } } -bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, PassRefPtrWillBeRawPtr<HTMLElement> element, InlineStyleRemovalMode mode, EditingStyle* extractedStyle) +bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, PassRefPtrWillBeRawPtr<HTMLElement> element, EditingState* editingState, InlineStyleRemovalMode mode, EditingStyle* extractedStyle) { ASSERT(element); @@ -935,34 +972,38 @@ return true; if (extractedStyle) extractedStyle->mergeInlineStyleOfElement(element.get(), EditingStyle::OverrideValues); - removeNodePreservingChildren(element); + removeNodePreservingChildren(element, editingState); + if (editingState->isAborted()) + return false; return true; } - bool removed = false; - if (removeImplicitlyStyledElement(style, element.get(), mode, extractedStyle)) - removed = true; + bool removed = removeImplicitlyStyledElement(style, element.get(), mode, extractedStyle, editingState); + if (editingState->isAborted()) + return false; if (!element->inDocument()) return removed; // If the node was converted to a span, the span may still contain relevant // styles which must be removed (e.g. <b style='font-weight: bold'>) - if (removeCSSStyle(style, element.get(), mode, extractedStyle)) + if (removeCSSStyle(style, element.get(), editingState, mode, extractedStyle)) removed = true; + if (editingState->isAborted()) + return false; return removed; } -void ApplyStyleCommand::replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement* elem) +void ApplyStyleCommand::replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement* elem, EditingState* editingState) { if (hasNoAttributeOrOnlyStyleAttribute(elem, StyleAttributeShouldBeEmpty)) - removeNodePreservingChildren(elem); + removeNodePreservingChildren(elem, editingState); else replaceElementWithSpanPreservingChildrenAndAttributes(elem); } -bool ApplyStyleCommand::removeImplicitlyStyledElement(EditingStyle* style, HTMLElement* element, InlineStyleRemovalMode mode, EditingStyle* extractedStyle) +bool ApplyStyleCommand::removeImplicitlyStyledElement(EditingStyle* style, HTMLElement* element, InlineStyleRemovalMode mode, EditingStyle* extractedStyle, EditingState* editingState) { ASSERT(style); if (mode == RemoveNone) { @@ -972,7 +1013,9 @@ ASSERT(mode == RemoveIfNeeded || mode == RemoveAlways); if (style->conflictsWithImplicitStyleOfElement(element, extractedStyle, mode == RemoveAlways ? EditingStyle::ExtractMatchingStyle : EditingStyle::DoNotExtractMatchingStyle)) { - replaceWithSpanOrRemoveIfWithoutAttributes(element); + replaceWithSpanOrRemoveIfWithoutAttributes(element, editingState); + if (editingState->isAborted()) + return false; return true; } @@ -985,13 +1028,16 @@ for (const auto& attribute : attributes) removeElementAttribute(element, attribute); - if (isEmptyFontTag(element) || isSpanWithoutAttributesOrUnstyledStyleSpan(element)) - removeNodePreservingChildren(element); + if (isEmptyFontTag(element) || isSpanWithoutAttributesOrUnstyledStyleSpan(element)) { + removeNodePreservingChildren(element, editingState); + if (editingState->isAborted()) + return false; + } return true; } -bool ApplyStyleCommand::removeCSSStyle(EditingStyle* style, HTMLElement* element, InlineStyleRemovalMode mode, EditingStyle* extractedStyle) +bool ApplyStyleCommand::removeCSSStyle(EditingStyle* style, HTMLElement* element, EditingState* editingState, InlineStyleRemovalMode mode, EditingStyle* extractedStyle) { ASSERT(style); ASSERT(element); @@ -1008,7 +1054,7 @@ removeCSSProperty(element, property); if (isSpanWithoutAttributesOrUnstyledStyleSpan(element)) - removeNodePreservingChildren(element); + removeNodePreservingChildren(element, editingState); return true; } @@ -1033,7 +1079,7 @@ return result; } -void ApplyStyleCommand::applyInlineStyleToPushDown(Node* node, EditingStyle* style) +void ApplyStyleCommand::applyInlineStyleToPushDown(Node* node, EditingStyle* style, EditingState* editingState) { ASSERT(node); @@ -1061,10 +1107,10 @@ // We can't wrap node with the styled element here because new styled element will never be removed if we did. // If we modified the child pointer in pushDownInlineStyleAroundNode to point to new style element // then we fall into an infinite loop where we keep removing and adding styled element wrapping node. - addInlineStyleIfNeeded(newInlineStyle.get(), node, node, DoNotAddStyledElement); + addInlineStyleIfNeeded(newInlineStyle.get(), node, node, editingState, DoNotAddStyledElement); } -void ApplyStyleCommand::pushDownInlineStyleAroundNode(EditingStyle* style, Node* targetNode) +void ApplyStyleCommand::pushDownInlineStyleAroundNode(EditingStyle* style, Node* targetNode, EditingState* editingState) { HTMLElement* highestAncestor = highestAncestorWithConflictingInlineStyle(style, targetNode); if (!highestAncestor) @@ -1085,8 +1131,11 @@ } RefPtrWillBeRawPtr<EditingStyle> styleToPushDown = EditingStyle::create(); - if (current->isHTMLElement()) - removeInlineStyleFromElement(style, toHTMLElement(current), RemoveIfNeeded, styleToPushDown.get()); + if (current->isHTMLElement()) { + removeInlineStyleFromElement(style, toHTMLElement(current), editingState, RemoveIfNeeded, styleToPushDown.get()); + if (editingState->isAborted()) + return; + } // The inner loop will go through children on each level // FIXME: we should aggregate inline child elements together so that we don't wrap each child separately. @@ -1108,8 +1157,11 @@ // Apply style to all nodes containing targetNode and their siblings but NOT to targetNode // But if we've removed styledElement then go ahead and always apply the style. - if (child != targetNode || styledElement) - applyInlineStyleToPushDown(child, styleToPushDown.get()); + if (child != targetNode || styledElement) { + applyInlineStyleToPushDown(child, styleToPushDown.get(), editingState); + if (editingState->isAborted()) + return; + } // We found the next node for the outer loop (contains targetNode) // When reached targetNode, stop the outer loop upon the completion of the current inner loop @@ -1119,7 +1171,7 @@ } } -void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &start, const Position &end) +void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &start, const Position &end, EditingState* editingState) { ASSERT(start.isNotNull()); ASSERT(end.isNotNull()); @@ -1144,8 +1196,12 @@ if (pushDownEndContainer && pushDownEndContainer->isTextNode() && !pushDownEnd.computeOffsetInContainerNode()) pushDownEnd = previousVisuallyDistinctCandidate(pushDownEnd); - pushDownInlineStyleAroundNode(style, pushDownStart.anchorNode()); - pushDownInlineStyleAroundNode(style, pushDownEnd.anchorNode()); + pushDownInlineStyleAroundNode(style, pushDownStart.anchorNode(), editingState); + if (editingState->isAborted()) + return; + pushDownInlineStyleAroundNode(style, pushDownEnd.anchorNode(), editingState); + if (editingState->isAborted()) + return; // The s and e variables store the positions used to set the ending selection after style removal // takes place. This will help callers to recognize when either the start node or the end node @@ -1180,7 +1236,9 @@ childNode = elem->firstChild(); } - removeInlineStyleFromElement(style, elem.get(), RemoveIfNeeded, styleToPushDown.get()); + removeInlineStyleFromElement(style, elem.get(), editingState, RemoveIfNeeded, styleToPushDown.get()); + if (editingState->isAborted()) + return; if (!elem->inDocument()) { if (s.anchorNode() == elem) { // Since elem must have been fully selected, and it is at the start @@ -1198,8 +1256,11 @@ } if (styleToPushDown) { - for (; childNode; childNode = childNode->nextSibling()) - applyInlineStyleToPushDown(childNode.get(), styleToPushDown.get()); + for (; childNode; childNode = childNode->nextSibling()) { + applyInlineStyleToPushDown(childNode.get(), styleToPushDown.get(), editingState); + if (editingState->isAborted()) + return; + } } } if (node == end.anchorNode()) @@ -1301,7 +1362,7 @@ return offsetInText > caretMinOffset(node) && offsetInText < caretMaxOffset(node); } -bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position& start, const Position& end) +bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position& start, const Position& end, EditingState* editingState) { Node* startNode = start.computeContainerNode(); int startOffset = start.computeOffsetInContainerNode(); @@ -1327,7 +1388,9 @@ Element* element = toElement(startNode); Node* startChild = element->firstChild(); ASSERT(startChild); - mergeIdenticalElements(previousElement, element); + mergeIdenticalElements(previousElement, element, editingState); + if (editingState->isAborted()) + return false; int startOffsetAdjustment = startChild->nodeIndex(); int endOffsetAdjustment = startNode == end.anchorNode() ? startOffsetAdjustment : 0; @@ -1339,7 +1402,7 @@ return false; } -bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const Position& end) +bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const Position& end, EditingState* editingState) { Node* endNode = end.computeContainerNode(); @@ -1363,7 +1426,9 @@ Element* element = toElement(endNode); Node* nextChild = nextElement->firstChild(); - mergeIdenticalElements(element, nextElement); + mergeIdenticalElements(element, nextElement, editingState); + if (editingState->isAborted()) + return false; bool shouldUpdateStart = start.computeContainerNode() == endNode; int endOffset = nextChild ? nextChild->nodeIndex() : nextElement->childNodes()->length(); @@ -1403,14 +1468,20 @@ RefPtrWillBeRawPtr<Node> nextSibling = element->nextSibling(); RefPtrWillBeRawPtr<Node> previousSibling = element->previousSibling(); if (nextSibling && nextSibling->isElementNode() && nextSibling->hasEditableStyle() - && areIdenticalElements(*element, toElement(*nextSibling))) - mergeIdenticalElements(element.get(), toElement(nextSibling)); + && areIdenticalElements(*element, toElement(*nextSibling))) { + mergeIdenticalElements(element.get(), toElement(nextSibling), editingState); + if (editingState->isAborted()) + return; + } if (previousSibling && previousSibling->isElementNode() && previousSibling->hasEditableStyle()) { Node* mergedElement = previousSibling->nextSibling(); if (mergedElement->isElementNode() && mergedElement->hasEditableStyle() - && areIdenticalElements(toElement(*previousSibling), toElement(*mergedElement))) - mergeIdenticalElements(toElement(previousSibling), toElement(mergedElement)); + && areIdenticalElements(toElement(*previousSibling), toElement(*mergedElement))) { + mergeIdenticalElements(toElement(previousSibling), toElement(mergedElement), editingState); + if (editingState->isAborted()) + return; + } } // FIXME: We should probably call updateStartEnd if the start or end was in the node @@ -1436,7 +1507,7 @@ setNodeAttribute(block, styleAttr, cssText.toAtomicString()); } -void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtrWillBeRawPtr<Node> passedStart, PassRefPtrWillBeRawPtr<Node> passedEnd, EAddStyledElement addStyledElement) +void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtrWillBeRawPtr<Node> passedStart, PassRefPtrWillBeRawPtr<Node> passedEnd, EditingState* editingState, EAddStyledElement addStyledElement) { if (!passedStart || !passedEnd || !passedStart->inDocument() || !passedEnd->inDocument()) return; @@ -1445,10 +1516,13 @@ RefPtrWillBeMember<HTMLSpanElement> dummyElement = nullptr; StyleChange styleChange(style, positionToComputeInlineStyleChange(start, dummyElement)); - if (dummyElement) - removeNode(dummyElement); + if (dummyElement) { + removeNode(dummyElement, editingState); + if (editingState->isAborted()) + return; + } - applyInlineStyleChange(start, passedEnd, styleChange, addStyledElement, ASSERT_NO_EDITING_ABORT); + applyInlineStyleChange(start, passedEnd, styleChange, addStyledElement, editingState); } Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtrWillBeRawPtr<Node> startNode, RefPtrWillBeMember<HTMLSpanElement>& dummyElement) @@ -1617,7 +1691,8 @@ newEnd = Position(childText, childText->length() + end.offsetInContainerNode()); String textToMove = nextText->data(); insertTextIntoNode(childText, childText->length(), textToMove); - removeNode(next); + // Removing a Text node doesn't dispatch synchronous events. + removeNode(next, ASSERT_NO_EDITING_ABORT); // don't move child node pointer. it may want to merge with more text nodes. }
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.h b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.h index 42452e74..782fa16 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.h
@@ -79,26 +79,28 @@ // style-removal helpers bool isStyledInlineElementToRemove(Element*) const; bool shouldApplyInlineStyleToRun(EditingStyle*, Node* runStart, Node* pastEndNode); - void removeConflictingInlineStyleFromRun(EditingStyle*, RefPtrWillBeMember<Node>& runStart, RefPtrWillBeMember<Node>& runEnd, PassRefPtrWillBeRawPtr<Node> pastEndNode); - bool removeInlineStyleFromElement(EditingStyle*, PassRefPtrWillBeRawPtr<HTMLElement>, InlineStyleRemovalMode = RemoveIfNeeded, EditingStyle* extractedStyle = nullptr); - inline bool shouldRemoveInlineStyleFromElement(EditingStyle* style, HTMLElement* element) {return removeInlineStyleFromElement(style, element, RemoveNone);} - void replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement*); - bool removeImplicitlyStyledElement(EditingStyle*, HTMLElement*, InlineStyleRemovalMode, EditingStyle* extractedStyle); - bool removeCSSStyle(EditingStyle*, HTMLElement*, InlineStyleRemovalMode = RemoveIfNeeded, EditingStyle* extractedStyle = nullptr); + void removeConflictingInlineStyleFromRun(EditingStyle*, RefPtrWillBeMember<Node>& runStart, RefPtrWillBeMember<Node>& runEnd, PassRefPtrWillBeRawPtr<Node> pastEndNode, EditingState*); + bool removeInlineStyleFromElement(EditingStyle*, PassRefPtrWillBeRawPtr<HTMLElement>, EditingState*, InlineStyleRemovalMode = RemoveIfNeeded, EditingStyle* extractedStyle = nullptr); + inline bool shouldRemoveInlineStyleFromElement(EditingStyle* style, HTMLElement* element) { return removeInlineStyleFromElement(style, element, ASSERT_NO_EDITING_ABORT, RemoveNone); } + void replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement*, EditingState*); + bool removeImplicitlyStyledElement(EditingStyle*, HTMLElement*, InlineStyleRemovalMode, EditingStyle* extractedStyle, EditingState*); + bool removeCSSStyle(EditingStyle*, HTMLElement*, EditingState*, InlineStyleRemovalMode = RemoveIfNeeded, EditingStyle* extractedStyle = nullptr); HTMLElement* highestAncestorWithConflictingInlineStyle(EditingStyle*, Node*); - void applyInlineStyleToPushDown(Node*, EditingStyle*); - void pushDownInlineStyleAroundNode(EditingStyle*, Node*); - void removeInlineStyle(EditingStyle* , const Position& start, const Position& end); + void applyInlineStyleToPushDown(Node*, EditingStyle*, EditingState*); + void pushDownInlineStyleAroundNode(EditingStyle*, Node*, EditingState*); + void removeInlineStyle(EditingStyle* , const Position& start, const Position& end, EditingState*); bool elementFullySelected(HTMLElement&, const Position& start, const Position& end) const; // style-application helpers void applyBlockStyle(EditingStyle*, EditingState*); - void applyRelativeFontStyleChange(EditingStyle*); + void applyRelativeFontStyleChange(EditingStyle*, EditingState*); void applyInlineStyle(EditingStyle*, EditingState*); void fixRangeAndApplyInlineStyle(EditingStyle*, const Position& start, const Position& end, EditingState*); void applyInlineStyleToNodeRange(EditingStyle*, PassRefPtrWillBeRawPtr<Node> startNode, PassRefPtrWillBeRawPtr<Node> pastEndNode, EditingState*); void addBlockStyle(const StyleChange&, HTMLElement*); - void addInlineStyleIfNeeded(EditingStyle*, PassRefPtrWillBeRawPtr<Node> start, PassRefPtrWillBeRawPtr<Node> end, EAddStyledElement = AddStyledElement); + // TODO(tkent): Remove the EAddStyledElement argument. It's always + // DoNotAddStyledElement. + void addInlineStyleIfNeeded(EditingStyle*, PassRefPtrWillBeRawPtr<Node> start, PassRefPtrWillBeRawPtr<Node> end, EditingState*, EAddStyledElement = AddStyledElement); Position positionToComputeInlineStyleChange(PassRefPtrWillBeRawPtr<Node>, RefPtrWillBeMember<HTMLSpanElement>& dummyElement); void applyInlineStyleChange(PassRefPtrWillBeRawPtr<Node> startNode, PassRefPtrWillBeRawPtr<Node> endNode, StyleChange&, EAddStyledElement, EditingState*); void splitTextAtStart(const Position& start, const Position& end); @@ -107,16 +109,16 @@ void splitTextElementAtEnd(const Position& start, const Position& end); bool shouldSplitTextElement(Element*, EditingStyle*); bool isValidCaretPositionInTextNode(const Position&); - bool mergeStartWithPreviousIfIdentical(const Position& start, const Position& end); - bool mergeEndWithNextIfIdentical(const Position& start, const Position& end); - void cleanupUnstyledAppleStyleSpans(ContainerNode* dummySpanAncestor); + bool mergeStartWithPreviousIfIdentical(const Position& start, const Position& end, EditingState*); + bool mergeEndWithNextIfIdentical(const Position& start, const Position& end, EditingState*); + void cleanupUnstyledAppleStyleSpans(ContainerNode* dummySpanAncestor, EditingState*); void surroundNodeRangeWithElement(PassRefPtrWillBeRawPtr<Node> start, PassRefPtrWillBeRawPtr<Node> end, PassRefPtrWillBeRawPtr<Element>, EditingState*); float computedFontSize(Node*); void joinChildTextNodes(ContainerNode*, const Position& start, const Position& end); HTMLElement* splitAncestorsWithUnicodeBidi(Node*, bool before, WritingDirection allowedDirection); - void removeEmbeddingUpToEnclosingBlock(Node*, HTMLElement* unsplitAncestor); + void removeEmbeddingUpToEnclosingBlock(Node*, HTMLElement* unsplitAncestor, EditingState*); void updateStartEnd(const Position& newStart, const Position& newEnd); Position startPosition();
diff --git a/third_party/WebKit/Source/core/editing/commands/BreakBlockquoteCommand.cpp b/third_party/WebKit/Source/core/editing/commands/BreakBlockquoteCommand.cpp index cea7493..b7bc276 100644 --- a/third_party/WebKit/Source/core/editing/commands/BreakBlockquoteCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/BreakBlockquoteCommand.cpp
@@ -72,14 +72,17 @@ { } -void BreakBlockquoteCommand::doApply(EditingState*) +void BreakBlockquoteCommand::doApply(EditingState* editingState) { if (endingSelection().isNone()) return; // Delete the current selection. - if (endingSelection().isRange()) - deleteSelection(ASSERT_NO_EDITING_ABORT, false, false); + if (endingSelection().isRange()) { + deleteSelection(editingState, false, false); + if (editingState->isAborted()) + return; + } // This is a scenario that should never happen, but we want to // make sure we don't dereference a null pointer below. @@ -191,11 +194,15 @@ setNodeAttribute(clonedChild, startAttr, AtomicString::number(toLayoutListItem(listChildNode->layoutObject())->value())); } - appendNode(clonedChild.get(), clonedAncestor.get()); + appendNode(clonedChild.get(), clonedAncestor.get(), editingState); + if (editingState->isAborted()) + return; clonedAncestor = clonedChild; } - moveRemainingSiblingsToNewParent(startNode, 0, clonedAncestor); + moveRemainingSiblingsToNewParent(startNode, 0, clonedAncestor, editingState); + if (editingState->isAborted()) + return; if (!ancestors.isEmpty()) { // Split the tree up the ancestor chain until the topBlockquote @@ -206,13 +213,19 @@ RefPtrWillBeRawPtr<Element> clonedParent = nullptr; for (ancestor = ancestors.first(), clonedParent = clonedAncestor->parentElement(); ancestor && ancestor != topBlockquote; - ancestor = ancestor->parentElement(), clonedParent = clonedParent->parentElement()) - moveRemainingSiblingsToNewParent(ancestor->nextSibling(), 0, clonedParent); + ancestor = ancestor->parentElement(), clonedParent = clonedParent->parentElement()) { + moveRemainingSiblingsToNewParent(ancestor->nextSibling(), 0, clonedParent, editingState); + if (editingState->isAborted()) + return; + } // If the startNode's original parent is now empty, remove it Element* originalParent = ancestors.first().get(); - if (!originalParent->hasChildren()) - removeNode(originalParent); + if (!originalParent->hasChildren()) { + removeNode(originalParent, editingState); + if (editingState->isAborted()) + return; + } } // Make sure the cloned block quote renders.
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp index 9968645..112f619 100644 --- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -388,7 +388,7 @@ applyCommandToComposite(AppendNodeCommand::create(parent, node)); } -void CompositeEditCommand::removeChildrenInRange(PassRefPtrWillBeRawPtr<Node> node, unsigned from, unsigned to) +void CompositeEditCommand::removeChildrenInRange(PassRefPtrWillBeRawPtr<Node> node, unsigned from, unsigned to, EditingState* editingState) { WillBeHeapVector<RefPtrWillBeMember<Node>> children; Node* child = NodeTraversal::childAt(*node, from); @@ -396,8 +396,11 @@ children.append(child); size_t size = children.size(); - for (size_t i = 0; i < size; ++i) - removeNode(children[i].release()); + for (size_t i = 0; i < size; ++i) { + removeNode(children[i].release(), editingState); + if (editingState->isAborted()) + return; + } } void CompositeEditCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, EditingState* editingState, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable) @@ -414,15 +417,17 @@ applyCommandToComposite(RemoveNodePreservingChildrenCommand::create(node, shouldAssumeContentIsAlwaysEditable), editingState); } -void CompositeEditCommand::removeNodeAndPruneAncestors(PassRefPtrWillBeRawPtr<Node> node, Node* excludeNode) +void CompositeEditCommand::removeNodeAndPruneAncestors(PassRefPtrWillBeRawPtr<Node> node, EditingState* editingState, Node* excludeNode) { ASSERT(node.get() != excludeNode); RefPtrWillBeRawPtr<ContainerNode> parent = node->parentNode(); - removeNode(node); - prune(parent.release(), excludeNode); + removeNode(node, editingState); + if (editingState->isAborted()) + return; + prune(parent.release(), editingState, excludeNode); } -void CompositeEditCommand::moveRemainingSiblingsToNewParent(Node* node, Node* pastLastNodeToMove, PassRefPtrWillBeRawPtr<Element> prpNewParent) +void CompositeEditCommand::moveRemainingSiblingsToNewParent(Node* node, Node* pastLastNodeToMove, PassRefPtrWillBeRawPtr<Element> prpNewParent, EditingState* editingState) { NodeVector nodesToRemove; RefPtrWillBeRawPtr<Element> newParent = prpNewParent; @@ -431,8 +436,12 @@ nodesToRemove.append(node); for (unsigned i = 0; i < nodesToRemove.size(); i++) { - removeNode(nodesToRemove[i]); - appendNode(nodesToRemove[i], newParent); + removeNode(nodesToRemove[i], editingState); + if (editingState->isAborted()) + return; + appendNode(nodesToRemove[i], newParent, editingState); + if (editingState->isAborted()) + return; } } @@ -459,10 +468,10 @@ return command->spanElement(); } -void CompositeEditCommand::prune(PassRefPtrWillBeRawPtr<Node> node, Node* excludeNode) +void CompositeEditCommand::prune(PassRefPtrWillBeRawPtr<Node> node, EditingState* editingState, Node* excludeNode) { if (RefPtrWillBeRawPtr<Node> highestNodeToRemove = highestNodeToRemoveInPruning(node.get(), excludeNode)) - removeNode(highestNodeToRemove.release()); + removeNode(highestNodeToRemove.release(), editingState); } void CompositeEditCommand::splitTextNode(PassRefPtrWillBeRawPtr<Text> node, unsigned offset) @@ -475,16 +484,18 @@ applyCommandToComposite(SplitElementCommand::create(element, atChild)); } -void CompositeEditCommand::mergeIdenticalElements(PassRefPtrWillBeRawPtr<Element> prpFirst, PassRefPtrWillBeRawPtr<Element> prpSecond) +void CompositeEditCommand::mergeIdenticalElements(PassRefPtrWillBeRawPtr<Element> prpFirst, PassRefPtrWillBeRawPtr<Element> prpSecond, EditingState* editingState) { RefPtrWillBeRawPtr<Element> first = prpFirst; RefPtrWillBeRawPtr<Element> second = prpSecond; ASSERT(!first->isDescendantOf(second.get()) && second != first); if (first->nextSibling() != second) { - removeNode(second); + removeNode(second, editingState); + if (editingState->isAborted()) + return; insertNodeAfter(second, first); } - applyCommandToComposite(MergeIdenticalElementsCommand::create(first, second)); + applyCommandToComposite(MergeIdenticalElementsCommand::create(first, second), editingState); } void CompositeEditCommand::wrapContentsInDummySpan(PassRefPtrWillBeRawPtr<Element> element) @@ -776,7 +787,8 @@ if (!box) { // whole text node is empty - removeNode(textNode); + // Removing a Text node won't dispatch synchronous events. + removeNode(textNode, ASSERT_NO_EDITING_ABORT); return; } @@ -917,7 +929,8 @@ // We are certain that the position is at a line break, but it may be a br or a preserved newline. if (isHTMLBRElement(*p.anchorNode())) { - removeNode(p.anchorNode()); + // Removing a BR element won't dispatch synchronous events. + removeNode(p.anchorNode(), ASSERT_NO_EDITING_ABORT); return; } @@ -1107,7 +1120,7 @@ // Deleting a paragraph will leave a placeholder. Remove it (and prune // empty or unrendered parents). -void CompositeEditCommand::cleanupAfterDeletion(VisiblePosition destination) +void CompositeEditCommand::cleanupAfterDeletion(EditingState* editingState, VisiblePosition destination) { VisiblePosition caretAfterDelete = endingSelection().visibleStart(); Node* destinationNode = destination.deepEquivalent().anchorNode(); @@ -1122,7 +1135,7 @@ // Normally deletion will leave a br as a placeholder. if (isHTMLBRElement(*node)) { - removeNodeAndPruneAncestors(node, destinationNode); + removeNodeAndPruneAncestors(node, editingState, destinationNode); // If the selection to move was empty and in an empty block that // doesn't require a placeholder to prop itself open (like a bordered @@ -1132,16 +1145,16 @@ // If caret position after deletion and destination position coincides, // node should not be removed. if (!rendersInDifferentPosition(position, destination.deepEquivalent())) { - prune(node, destinationNode); + prune(node, editingState, destinationNode); return; } - removeNodeAndPruneAncestors(node, destinationNode); + removeNodeAndPruneAncestors(node, editingState, destinationNode); } else if (lineBreakExistsAtPosition(position)) { // There is a preserved '\n' at caretAfterDelete. // We can safely assume this is a text node. Text* textNode = toText(node); if (textNode->length() == 1) - removeNodeAndPruneAncestors(node, destinationNode); + removeNodeAndPruneAncestors(node, editingState, destinationNode); else deleteTextFromNode(textNode, position.computeOffsetInContainerNode(), 1); } @@ -1180,7 +1193,9 @@ // It expands and removes the entire table/list, but will let content // before and after the table/list collapse onto one line. - cleanupAfterDeletion(); + cleanupAfterDeletion(editingState); + if (editingState->isAborted()) + return; // Add a br if pruning an empty block level element caused a collapse. For example: // foo^ @@ -1269,7 +1284,9 @@ return; ASSERT(destination.deepEquivalent().inDocument()); - cleanupAfterDeletion(destination); + cleanupAfterDeletion(editingState, destination); + if (editingState->isAborted()) + return; ASSERT(destination.deepEquivalent().inDocument()); // Add a br if pruning an empty block level element caused a collapse. For example: @@ -1326,7 +1343,7 @@ } // FIXME: Send an appropriate shouldDeleteRange call. -bool CompositeEditCommand::breakOutOfEmptyListItem() +bool CompositeEditCommand::breakOutOfEmptyListItem(EditingState* editingState) { RefPtrWillBeRawPtr<Node> emptyListItem = enclosingEmptyListItem(endingSelection().visibleStart()); if (!emptyListItem) @@ -1352,7 +1369,9 @@ // If listNode does NOT appear at the end, then we should consider it as a regular paragraph. // e.g. <ul><li> <ul><li><br></li></ul> hello</li></ul> should become <ul><li> <div><br></div> hello</li></ul> at the end splitElement(toElement(blockEnclosingList), listNode); - removeNodePreservingChildren(listNode->parentNode()); + removeNodePreservingChildren(listNode->parentNode(), editingState); + if (editingState->isAborted()) + return false; newBlock = HTMLLIElement::create(document()); } // If listNode does NOT appear at the end of the outer list item, then behave as if in a regular paragraph. @@ -1373,13 +1392,19 @@ // If emptyListItem is followed by other list item or nested list, then insert newBlock before the list node. // Because we have splitted the element, emptyListItem is the first element in the list node. // i.e. insert newBlock before ul or ol whose first element is emptyListItem - insertNodeBefore(newBlock, listNode); - removeNode(emptyListItem); + insertNodeBefore(newBlock, listNode, editingState); + if (editingState->isAborted()) + return false; + removeNode(emptyListItem, editingState); + if (editingState->isAborted()) + return false; } else { // When emptyListItem does not follow any list item or nested list, insert newBlock after the enclosing list node. // Remove the enclosing node if emptyListItem is the only child; otherwise just remove emptyListItem. insertNodeAfter(newBlock, listNode); - removeNode(isListItem(previousListNode.get()) || isHTMLListElement(previousListNode.get()) ? emptyListItem.get() : listNode.get()); + removeNode(isListItem(previousListNode.get()) || isHTMLListElement(previousListNode.get()) ? emptyListItem.get() : listNode.get(), editingState); + if (editingState->isAborted()) + return false; } appendBlockPlaceholder(newBlock); @@ -1394,7 +1419,7 @@ // If the caret is in an empty quoted paragraph, and either there is nothing before that // paragraph, or what is before is unquoted, and the user presses delete, unquote that paragraph. -bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph() +bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph(EditingState* editingState) { if (!endingSelection().isCaret()) return false; @@ -1415,12 +1440,17 @@ RefPtrWillBeRawPtr<HTMLBRElement> br = HTMLBRElement::create(document()); // We want to replace this quoted paragraph with an unquoted one, so insert a br // to hold the caret before the highest blockquote. - insertNodeBefore(br, highestBlockquote); + insertNodeBefore(br, highestBlockquote, editingState); + if (editingState->isAborted()) + return false; VisiblePosition atBR = createVisiblePosition(positionBeforeNode(br.get())); // If the br we inserted collapsed, for example foo<br><blockquote>...</blockquote>, insert // a second one. - if (!isStartOfParagraph(atBR)) - insertNodeBefore(HTMLBRElement::create(document()), br); + if (!isStartOfParagraph(atBR)) { + insertNodeBefore(HTMLBRElement::create(document()), br, editingState); + if (editingState->isAborted()) + return false; + } setEndingSelection(VisibleSelection(atBR, endingSelection().isDirectional())); // If this is an empty paragraph there must be a line break here. @@ -1432,7 +1462,9 @@ ASSERT(isHTMLBRElement(caretPos.anchorNode()) || (caretPos.anchorNode()->isTextNode() && caretPos.anchorNode()->layoutObject()->style()->preserveNewline())); if (isHTMLBRElement(*caretPos.anchorNode())) { - removeNodeAndPruneAncestors(caretPos.anchorNode()); + removeNodeAndPruneAncestors(caretPos.anchorNode(), editingState); + if (editingState->isAborted()) + return false; } else if (caretPos.anchorNode()->isTextNode()) { ASSERT(caretPos.computeOffsetInContainerNode() == 0); Text* textNode = toText(caretPos.anchorNode()); @@ -1440,7 +1472,9 @@ // The preserved newline must be the first thing in the node, since otherwise the previous // paragraph would be quoted, and we verified that it wasn't above. deleteTextFromNode(textNode, 0, 1); - prune(parentNode); + prune(parentNode, editingState); + if (editingState->isAborted()) + return false; } return true;
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h index 7bcefc8d..8c0270f 100644 --- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h
@@ -114,7 +114,7 @@ void insertNodeBefore(PassRefPtrWillBeRawPtr<Node>, PassRefPtrWillBeRawPtr<Node> refChild, EditingState* = ASSERT_NO_EDITING_ABORT, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable); void insertParagraphSeparator(bool useDefaultParagraphElement = false, bool pasteBlockqutoeIntoUnquotedArea = false); void insertTextIntoNode(PassRefPtrWillBeRawPtr<Text>, unsigned offset, const String& text); - void mergeIdenticalElements(PassRefPtrWillBeRawPtr<Element>, PassRefPtrWillBeRawPtr<Element>); + void mergeIdenticalElements(PassRefPtrWillBeRawPtr<Element>, PassRefPtrWillBeRawPtr<Element>, EditingState*); void rebalanceWhitespace(); void rebalanceWhitespaceAt(const Position&); void rebalanceWhitespaceOnTextSubstring(PassRefPtrWillBeRawPtr<Text>, int startOffset, int endOffset); @@ -124,14 +124,14 @@ bool shouldRebalanceLeadingWhitespaceFor(const String&) const; void removeCSSProperty(PassRefPtrWillBeRawPtr<Element>, CSSPropertyID); void removeElementAttribute(PassRefPtrWillBeRawPtr<Element>, const QualifiedName& attribute); - void removeChildrenInRange(PassRefPtrWillBeRawPtr<Node>, unsigned from, unsigned to); - virtual void removeNode(PassRefPtrWillBeRawPtr<Node>, EditingState* = ASSERT_NO_EDITING_ABORT, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable); + void removeChildrenInRange(PassRefPtrWillBeRawPtr<Node>, unsigned from, unsigned to, EditingState*); + virtual void removeNode(PassRefPtrWillBeRawPtr<Node>, EditingState*, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable); HTMLSpanElement* replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtrWillBeRawPtr<HTMLElement>); - void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node>, EditingState* = ASSERT_NO_EDITING_ABORT, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable); - void removeNodeAndPruneAncestors(PassRefPtrWillBeRawPtr<Node>, Node* excludeNode = nullptr); - void moveRemainingSiblingsToNewParent(Node*, Node* pastLastNodeToMove, PassRefPtrWillBeRawPtr<Element> prpNewParent); + void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node>, EditingState*, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable); + void removeNodeAndPruneAncestors(PassRefPtrWillBeRawPtr<Node>, EditingState*, Node* excludeNode = nullptr); + void moveRemainingSiblingsToNewParent(Node*, Node* pastLastNodeToMove, PassRefPtrWillBeRawPtr<Element> prpNewParent, EditingState*); void updatePositionForNodeRemovalPreservingChildren(Position&, Node&); - void prune(PassRefPtrWillBeRawPtr<Node>, Node* excludeNode = nullptr); + void prune(PassRefPtrWillBeRawPtr<Node>, EditingState*, Node* excludeNode = nullptr); void replaceTextInNode(PassRefPtrWillBeRawPtr<Text>, unsigned offset, unsigned count, const String& replacementText); Position replaceSelectedTextInNode(const String&); void replaceTextInNodePreservingMarkers(PassRefPtrWillBeRawPtr<Text>, unsigned offset, unsigned count, const String& replacementText); @@ -162,10 +162,10 @@ void moveParagraphs(const VisiblePosition&, const VisiblePosition&, const VisiblePosition&, EditingState*, bool preserveSelection = false, bool preserveStyle = true, Node* constrainingAncestor = nullptr); void moveParagraphWithClones(const VisiblePosition& startOfParagraphToMove, const VisiblePosition& endOfParagraphToMove, HTMLElement* blockElement, Node* outerNode, EditingState* = ASSERT_NO_EDITING_ABORT); void cloneParagraphUnderNewElement(const Position& start, const Position& end, Node* outerNode, Element* blockElement, EditingState*); - void cleanupAfterDeletion(VisiblePosition destination = VisiblePosition()); + void cleanupAfterDeletion(EditingState*, VisiblePosition destination = VisiblePosition()); - bool breakOutOfEmptyListItem(); - bool breakOutOfEmptyMailBlockquotedParagraph(); + bool breakOutOfEmptyListItem(EditingState*); + bool breakOutOfEmptyMailBlockquotedParagraph(EditingState*); Position positionAvoidingSpecialElementBoundary(const Position&, EditingState*);
diff --git a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp index cd8700f7..da914f13 100644 --- a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
@@ -300,7 +300,7 @@ m_deleteIntoBlockquoteStyle = nullptr; } -bool DeleteSelectionCommand::handleSpecialCaseBRDelete() +bool DeleteSelectionCommand::handleSpecialCaseBRDelete(EditingState* editingState) { Node* nodeAfterUpstreamStart = m_upstreamStart.computeNodeAfterPosition(); Node* nodeAfterDownstreamStart = m_downstreamStart.computeNodeAfterPosition(); @@ -315,7 +315,7 @@ bool downstreamStartIsBR = isHTMLBRElement(*nodeAfterDownstreamStart); bool isBROnLineByItself = upstreamStartIsBR && downstreamStartIsBR && nodeAfterDownstreamStart == nodeAfterUpstreamEnd; if (isBROnLineByItself) { - removeNode(nodeAfterDownstreamStart); + removeNode(nodeAfterDownstreamStart, editingState); return true; } @@ -431,7 +431,7 @@ CompositeEditCommand::deleteTextFromNode(node, offset, count); } -void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss() +void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(EditingState* editingState) { RefPtrWillBeRawPtr<Range> range = createRange(m_selectionToDelete.toNormalizedEphemeralRange()); RefPtrWillBeRawPtr<Node> node = range->firstNode(); @@ -441,8 +441,12 @@ nextNode = NodeTraversal::nextSkippingChildren(*node); RefPtrWillBeRawPtr<Element> rootEditableElement = node->rootEditableElement(); if (rootEditableElement.get()) { - removeNode(node); - appendNode(node, rootEditableElement); + removeNode(node, editingState); + if (editingState->isAborted()) + return; + appendNode(node, rootEditableElement, editingState); + if (editingState->isAborted()) + return; } } node = nextNode; @@ -458,7 +462,9 @@ Node* startNode = m_upstreamStart.anchorNode(); ASSERT(startNode); - makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(); + makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(editingState); + if (editingState->isAborted()) + return; // Never remove the start block unless it's a table, in which case we won't merge content in. if (startNode->isSameNode(m_startBlock.get()) && !startOffset && canHaveChildrenForEditing(startNode) && !isHTMLTableElement(*startNode)) { @@ -490,7 +496,9 @@ Text* text = toText(startNode); deleteTextFromNode(text, startOffset, m_downstreamEnd.computeOffsetInContainerNode() - startOffset); } else { - removeChildrenInRange(startNode, startOffset, m_downstreamEnd.computeEditingOffset()); + removeChildrenInRange(startNode, startOffset, m_downstreamEnd.computeEditingOffset(), editingState); + if (editingState->isAborted()) + return; m_endingPosition = m_upstreamStart; } } @@ -573,7 +581,9 @@ if (n) offset = n->nodeIndex() + 1; } - removeChildrenInRange(m_downstreamEnd.anchorNode(), offset, m_downstreamEnd.computeEditingOffset()); + removeChildrenInRange(m_downstreamEnd.anchorNode(), offset, m_downstreamEnd.computeEditingOffset(), editingState); + if (editingState->isAborted()) + return; m_downstreamEnd = Position::editingPositionOf(m_downstreamEnd.anchorNode(), offset); } } @@ -601,12 +611,14 @@ // If a selection starts in one block and ends in another, we have to merge to bring content before the // start together with content after the end. -void DeleteSelectionCommand::mergeParagraphs() +void DeleteSelectionCommand::mergeParagraphs(EditingState* editingState) { if (!m_mergeBlocksAfterDelete) { if (m_pruneStartBlockIfNecessary) { // We aren't going to merge into the start block, so remove it if it's empty. - prune(m_startBlock); + prune(m_startBlock, editingState); + if (editingState->isAborted()) + return; // Removing the start block during a deletion is usually an indication that we need // a placeholder, but not in this case. m_needPlaceholder = false; @@ -636,13 +648,15 @@ // move, so just remove it. Element* endBlock = enclosingBlock(m_downstreamEnd.anchorNode()); if (!endBlock || !endBlock->contains(startOfParagraphToMove.deepEquivalent().anchorNode()) || !startOfParagraphToMove.deepEquivalent().anchorNode()) { - removeNode(enclosingBlock(m_downstreamEnd.anchorNode())); + removeNode(enclosingBlock(m_downstreamEnd.anchorNode()), editingState); return; } // We need to merge into m_upstreamStart's block, but it's been emptied out and collapsed by deletion. if (!mergeDestination.deepEquivalent().anchorNode() || (!mergeDestination.deepEquivalent().anchorNode()->isDescendantOf(enclosingBlock(m_upstreamStart.computeContainerNode())) && (!mergeDestination.deepEquivalent().anchorNode()->hasChildren() || !m_upstreamStart.computeContainerNode()->hasChildren())) || (m_startsAtEmptyLine && mergeDestination.deepEquivalent() != startOfParagraphToMove.deepEquivalent())) { - insertNodeAt(HTMLBRElement::create(document()).get(), m_upstreamStart); + insertNodeAt(HTMLBRElement::create(document()).get(), m_upstreamStart, editingState); + if (editingState->isAborted()) + return; mergeDestination = createVisiblePosition(m_upstreamStart); } @@ -660,7 +674,9 @@ if (listItemInFirstParagraph && listItemInSecondParagraph && listItemInFirstParagraph->parentElement() != listItemInSecondParagraph->parentElement() && canMergeLists(listItemInFirstParagraph->parentElement(), listItemInSecondParagraph->parentElement())) { - mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listItemInSecondParagraph->parentElement()); + mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listItemInSecondParagraph->parentElement(), editingState); + if (editingState->isAborted()) + return; m_endingPosition = mergeDestination.deepEquivalent(); return; } @@ -669,7 +685,9 @@ // FIXME: Consider RTL. if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && absoluteCaretBoundsOf(startOfParagraphToMove).x() > absoluteCaretBoundsOf(mergeDestination).x()) { if (isHTMLBRElement(*mostForwardCaretPosition(mergeDestination.deepEquivalent()).anchorNode())) { - removeNodeAndPruneAncestors(mostForwardCaretPosition(mergeDestination.deepEquivalent()).anchorNode()); + removeNodeAndPruneAncestors(mostForwardCaretPosition(mergeDestination.deepEquivalent()).anchorNode(), editingState); + if (editingState->isAborted()) + return; m_endingPosition = startOfParagraphToMove.deepEquivalent(); return; } @@ -687,13 +705,15 @@ // removals that it does cause the insertion of *another* placeholder. bool needPlaceholder = m_needPlaceholder; bool paragraphToMergeIsEmpty = startOfParagraphToMove.deepEquivalent() == endOfParagraphToMove.deepEquivalent(); - moveParagraph(startOfParagraphToMove, endOfParagraphToMove, mergeDestination, ASSERT_NO_EDITING_ABORT, false, !paragraphToMergeIsEmpty); + moveParagraph(startOfParagraphToMove, endOfParagraphToMove, mergeDestination, editingState, false, !paragraphToMergeIsEmpty); + if (editingState->isAborted()) + return; m_needPlaceholder = needPlaceholder; // The endingPosition was likely clobbered by the move, so recompute it (moveParagraph selects the moved paragraph). m_endingPosition = endingSelection().start(); } -void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows() +void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows(EditingState* editingState) { if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_startTableRow) { Node* row = m_endTableRow->previousSibling(); @@ -703,7 +723,9 @@ // Use a raw removeNode, instead of DeleteSelectionCommand's, // because that won't remove rows, it only empties them in // preparation for this function. - CompositeEditCommand::removeNode(row); + CompositeEditCommand::removeNode(row, editingState); + if (editingState->isAborted()) + return; } row = previousRow.get(); } @@ -714,8 +736,11 @@ Node* row = m_startTableRow->nextSibling(); while (row && row != m_endTableRow) { RefPtrWillBeRawPtr<Node> nextRow = row->nextSibling(); - if (isTableRowEmpty(row)) - CompositeEditCommand::removeNode(row); + if (isTableRowEmpty(row)) { + CompositeEditCommand::removeNode(row, editingState); + if (editingState->isAborted()) + return; + } row = nextRow.get(); } } @@ -729,7 +754,9 @@ // fully selected, even if it is empty. We'll need to start // adjusting the selection endpoints during deletion to know // whether or not m_endTableRow was fully selected here. - CompositeEditCommand::removeNode(m_endTableRow.get()); + CompositeEditCommand::removeNode(m_endTableRow.get(), editingState); + if (editingState->isAborted()) + return; } } } @@ -842,7 +869,10 @@ // deleting just a BR is handled specially, at least because we do not // want to replace it with a placeholder BR! - if (handleSpecialCaseBRDelete()) { + bool brResult = handleSpecialCaseBRDelete(editingState); + if (editingState->isAborted()) + return; + if (brResult) { calculateTypingStyleAfterDelete(); setEndingSelection(VisibleSelection(m_endingPosition, affinity, endingSelection().isDirectional())); clearTransientState(); @@ -856,9 +886,13 @@ fixupWhitespace(); - mergeParagraphs(); + mergeParagraphs(editingState); + if (editingState->isAborted()) + return; - removePreviouslySelectedEmptyTableRows(); + removePreviouslySelectedEmptyTableRows(editingState); + if (editingState->isAborted()) + return; if (!m_needPlaceholder && rootWillStayOpenWithoutPlaceholder) { VisiblePosition visualEnding = createVisiblePosition(m_endingPosition);
diff --git a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h index 6e8ea714..af4e2c70b 100644 --- a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h
@@ -59,15 +59,15 @@ void setStartingSelectionOnSmartDelete(const Position&, const Position&); void initializePositionData(); void saveTypingStyleState(); - bool handleSpecialCaseBRDelete(); + bool handleSpecialCaseBRDelete(EditingState*); void handleGeneralDelete(EditingState*); void fixupWhitespace(); - void mergeParagraphs(); - void removePreviouslySelectedEmptyTableRows(); + void mergeParagraphs(EditingState*); + void removePreviouslySelectedEmptyTableRows(EditingState*); void calculateTypingStyleAfterDelete(); void clearTransientState(); - void makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(); - void removeNode(PassRefPtrWillBeRawPtr<Node>, EditingState* = ASSERT_NO_EDITING_ABORT, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable) override; + void makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(EditingState*); + void removeNode(PassRefPtrWillBeRawPtr<Node>, EditingState*, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable) override; void deleteTextFromNode(PassRefPtrWillBeRawPtr<Text>, unsigned, unsigned) override; void removeRedundantBlocks(EditingState*);
diff --git a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp index 6101908..b4044294 100644 --- a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp
@@ -66,7 +66,7 @@ { } -bool IndentOutdentCommand::tryIndentingAsListItem(const Position& start, const Position& end) +bool IndentOutdentCommand::tryIndentingAsListItem(const Position& start, const Position& end, EditingState* editingState) { // If our selection is not inside a list, bail out. RefPtrWillBeRawPtr<Node> lastNodeInSelectedParagraph = start.anchorNode(); @@ -89,22 +89,34 @@ // list element will change visibility of list item, e.g. :first-child // CSS selector. RefPtrWillBeRawPtr<HTMLElement> newList = toHTMLElement(document().createElement(listElement->tagQName(), false).get()); - insertNodeBefore(newList, selectedListItem.get()); + insertNodeBefore(newList, selectedListItem.get(), editingState); + if (editingState->isAborted()) + return false; // We should clone all the children of the list item for indenting purposes. However, in case the current // selection does not encompass all its children, we need to explicitally handle the same. The original // list item too would require proper deletion in that case. if (end.anchorNode() == selectedListItem.get() || end.anchorNode()->isDescendantOf(selectedListItem->lastChild())) { - moveParagraphWithClones(createVisiblePosition(start), createVisiblePosition(end), newList.get(), selectedListItem.get()); + moveParagraphWithClones(createVisiblePosition(start), createVisiblePosition(end), newList.get(), selectedListItem.get(), editingState); } else { - moveParagraphWithClones(createVisiblePosition(start), createVisiblePosition(positionAfterNode(selectedListItem->lastChild())), newList.get(), selectedListItem.get()); - removeNode(selectedListItem.get()); + moveParagraphWithClones(createVisiblePosition(start), createVisiblePosition(positionAfterNode(selectedListItem->lastChild())), newList.get(), selectedListItem.get(), editingState); + if (editingState->isAborted()) + return false; + removeNode(selectedListItem.get(), editingState); } + if (editingState->isAborted()) + return false; - if (canMergeLists(previousList.get(), newList.get())) - mergeIdenticalElements(previousList.get(), newList.get()); - if (canMergeLists(newList.get(), nextList.get())) - mergeIdenticalElements(newList.get(), nextList.get()); + if (canMergeLists(previousList.get(), newList.get())) { + mergeIdenticalElements(previousList.get(), newList.get(), editingState); + if (editingState->isAborted()) + return false; + } + if (canMergeLists(newList.get(), nextList.get())) { + mergeIdenticalElements(newList.get(), nextList.get(), editingState); + if (editingState->isAborted()) + return false; + } return true; } @@ -143,7 +155,7 @@ moveParagraphWithClones(startOfContents, endOfContents, targetBlockquote.get(), outerBlock.get(), editingState); } -void IndentOutdentCommand::outdentParagraph() +void IndentOutdentCommand::outdentParagraph(EditingState* editingState) { VisiblePosition visibleStartOfParagraph = startOfParagraph(endingSelection().visibleStart()); VisiblePosition visibleEndOfParagraph = endOfParagraph(visibleStartOfParagraph); @@ -154,11 +166,11 @@ // Use InsertListCommand to remove the selection from the list if (isHTMLOListElement(*enclosingElement)) { - applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::OrderedList)); + applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::OrderedList), editingState); return; } if (isHTMLUListElement(*enclosingElement)) { - applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::UnorderedList)); + applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::UnorderedList), editingState); return; } @@ -173,7 +185,9 @@ && visibleEndOfParagraph.deepEquivalent() == endOfEnclosingBlock.deepEquivalent()) { // The blockquote doesn't contain anything outside the paragraph, so it can be totally removed. Node* splitPoint = enclosingElement->nextSibling(); - removeNodePreservingChildren(enclosingElement); + removeNodePreservingChildren(enclosingElement, editingState); + if (editingState->isAborted()) + return; // outdentRegion() assumes it is operating on the first paragraph of an enclosing blockquote, but if there are multiply nested blockquotes and we've // just removed one, then this assumption isn't true. By splitting the next containing blockquote after this node, we keep this assumption true if (splitPoint) { @@ -188,11 +202,13 @@ document().updateLayoutIgnorePendingStylesheets(); visibleStartOfParagraph = createVisiblePosition(visibleStartOfParagraph.deepEquivalent()); visibleEndOfParagraph = createVisiblePosition(visibleEndOfParagraph.deepEquivalent()); - if (visibleStartOfParagraph.isNotNull() && !isStartOfParagraph(visibleStartOfParagraph)) - insertNodeAt(HTMLBRElement::create(document()), visibleStartOfParagraph.deepEquivalent()); + if (visibleStartOfParagraph.isNotNull() && !isStartOfParagraph(visibleStartOfParagraph)) { + insertNodeAt(HTMLBRElement::create(document()), visibleStartOfParagraph.deepEquivalent(), editingState); + if (editingState->isAborted()) + return; + } if (visibleEndOfParagraph.isNotNull() && !isEndOfParagraph(visibleEndOfParagraph)) - insertNodeAt(HTMLBRElement::create(document()), visibleEndOfParagraph.deepEquivalent()); - + insertNodeAt(HTMLBRElement::create(document()), visibleEndOfParagraph.deepEquivalent(), editingState); return; } RefPtrWillBeRawPtr<Node> splitBlockquoteNode = enclosingElement; @@ -210,18 +226,20 @@ if (startOfParagraphToMove.isNull() || endOfParagraphToMove.isNull()) return; RefPtrWillBeRawPtr<HTMLBRElement> placeholder = HTMLBRElement::create(document()); - insertNodeBefore(placeholder, splitBlockquoteNode); - moveParagraph(startOfParagraphToMove, endOfParagraphToMove, createVisiblePosition(positionBeforeNode(placeholder.get())), ASSERT_NO_EDITING_ABORT, true); + insertNodeBefore(placeholder, splitBlockquoteNode, editingState); + if (editingState->isAborted()) + return; + moveParagraph(startOfParagraphToMove, endOfParagraphToMove, createVisiblePosition(positionBeforeNode(placeholder.get())), editingState, true); } // FIXME: We should merge this function with ApplyBlockElementCommand::formatSelection -void IndentOutdentCommand::outdentRegion(const VisiblePosition& startOfSelection, const VisiblePosition& endOfSelection) +void IndentOutdentCommand::outdentRegion(const VisiblePosition& startOfSelection, const VisiblePosition& endOfSelection, EditingState* editingState) { VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection); VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection); if (endOfCurrentParagraph.deepEquivalent() == endOfLastParagraph.deepEquivalent()) { - outdentParagraph(); + outdentParagraph(editingState); return; } @@ -235,7 +253,9 @@ else setEndingSelection(endOfCurrentParagraph); - outdentParagraph(); + outdentParagraph(editingState); + if (editingState->isAborted()) + return; // outdentParagraph could move more than one paragraph if the paragraph // is in a list item. As a result, endAfterSelection and endOfNextParagraph @@ -256,12 +276,15 @@ if (m_typeOfAction == Indent) ApplyBlockElementCommand::formatSelection(startOfSelection, endOfSelection, editingState); else - outdentRegion(startOfSelection, endOfSelection); + outdentRegion(startOfSelection, endOfSelection, editingState); } void IndentOutdentCommand::formatRange(const Position& start, const Position& end, const Position&, RefPtrWillBeRawPtr<HTMLElement>& blockquoteForNextIndent, EditingState* editingState) { - if (tryIndentingAsListItem(start, end)) + bool indentingAsListItemResult = tryIndentingAsListItem(start, end, editingState); + if (editingState->isAborted()) + return; + if (indentingAsListItemResult) blockquoteForNextIndent = nullptr; else indentIntoBlockquote(start, end, blockquoteForNextIndent, editingState);
diff --git a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.h b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.h index 227aa6cf..45fe406a 100644 --- a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.h
@@ -46,9 +46,9 @@ EditAction editingAction() const override { return m_typeOfAction == Indent ? EditActionIndent : EditActionOutdent; } - void outdentRegion(const VisiblePosition&, const VisiblePosition&); - void outdentParagraph(); - bool tryIndentingAsListItem(const Position&, const Position&); + void outdentRegion(const VisiblePosition&, const VisiblePosition&, EditingState*); + void outdentParagraph(EditingState*); + bool tryIndentingAsListItem(const Position&, const Position&, EditingState*); void indentIntoBlockquote(const Position&, const Position&, RefPtrWillBeRawPtr<HTMLElement>&, EditingState*); void formatSelection(const VisiblePosition& startOfSelection, const VisiblePosition& endOfSelection, EditingState*) override;
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp index bdfaddb..76c69cd 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
@@ -50,21 +50,30 @@ return listChild; } -HTMLUListElement* InsertListCommand::fixOrphanedListChild(Node* node) +HTMLUListElement* InsertListCommand::fixOrphanedListChild(Node* node, EditingState* editingState) { RefPtrWillBeRawPtr<HTMLUListElement> listElement = HTMLUListElement::create(document()); - insertNodeBefore(listElement, node); - removeNode(node); - appendNode(node, listElement); + insertNodeBefore(listElement, node, editingState); + if (editingState->isAborted()) + return nullptr; + removeNode(node, editingState); + if (editingState->isAborted()) + return nullptr; + appendNode(node, listElement, editingState); + if (editingState->isAborted()) + return nullptr; return listElement.get(); } -PassRefPtrWillBeRawPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtrWillBeRawPtr<HTMLElement> passedList) +PassRefPtrWillBeRawPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtrWillBeRawPtr<HTMLElement> passedList, EditingState* editingState) { RefPtrWillBeRawPtr<HTMLElement> list = passedList; Element* previousList = ElementTraversal::previousSibling(*list); - if (canMergeLists(previousList, list.get())) - mergeIdenticalElements(previousList, list); + if (canMergeLists(previousList, list.get())) { + mergeIdenticalElements(previousList, list, editingState); + if (editingState->isAborted()) + return nullptr; + } if (!list) return nullptr; @@ -75,7 +84,9 @@ RefPtrWillBeRawPtr<HTMLElement> nextList = toHTMLElement(nextSibling); if (canMergeLists(list.get(), nextList.get())) { - mergeIdenticalElements(list, nextList); + mergeIdenticalElements(list, nextList, editingState); + if (editingState->isAborted()) + return nullptr; return nextList.release(); } return list.release(); @@ -237,8 +248,12 @@ } } if (!listElement) { - listElement = fixOrphanedListChild(listChildNode); - listElement = mergeWithNeighboringLists(listElement); + listElement = fixOrphanedListChild(listChildNode, editingState); + if (editingState->isAborted()) + return false; + listElement = mergeWithNeighboringLists(listElement, editingState); + if (editingState->isAborted()) + return false; } ASSERT(listElement->hasEditableStyle()); ASSERT(listElement->parentNode()->hasEditableStyle()); @@ -259,20 +274,29 @@ bool rangeEndIsInList = visiblePositionAfterNode(*listElement).deepEquivalent() == createVisiblePosition(currentSelection.endPosition()).deepEquivalent(); RefPtrWillBeRawPtr<HTMLElement> newList = createHTMLElement(document(), listTag); - insertNodeBefore(newList, listElement); + insertNodeBefore(newList, listElement, editingState); + if (editingState->isAborted()) + return false; Node* firstChildInList = enclosingListChild(createVisiblePosition(firstPositionInNode(listElement.get())).deepEquivalent().anchorNode(), listElement.get()); Element* outerBlock = firstChildInList && isBlockFlowElement(*firstChildInList) ? toElement(firstChildInList) : listElement.get(); - moveParagraphWithClones(createVisiblePosition(firstPositionInNode(listElement.get())), createVisiblePosition(lastPositionInNode(listElement.get())), newList.get(), outerBlock); + moveParagraphWithClones(createVisiblePosition(firstPositionInNode(listElement.get())), createVisiblePosition(lastPositionInNode(listElement.get())), newList.get(), outerBlock, editingState); + if (editingState->isAborted()) + return false; // Manually remove listNode because moveParagraphWithClones sometimes leaves it behind in the document. // See the bug 33668 and editing/execCommand/insert-list-orphaned-item-with-nested-lists.html. // FIXME: This might be a bug in moveParagraphWithClones or deleteSelection. - if (listElement && listElement->inDocument()) - removeNode(listElement); + if (listElement && listElement->inDocument()) { + removeNode(listElement, editingState); + if (editingState->isAborted()) + return false; + } - newList = mergeWithNeighboringLists(newList); + newList = mergeWithNeighboringLists(newList, editingState); + if (editingState->isAborted()) + return false; // Restore the start and the end of current selection if they started inside listNode // because moveParagraphWithClones could have removed them. @@ -401,7 +425,7 @@ return; if (canMergeLists(previousList, nextList)) - mergeIdenticalElements(previousList, nextList); + mergeIdenticalElements(previousList, nextList, editingState); return; } @@ -448,7 +472,7 @@ if (editingState->isAborted()) return; - mergeWithNeighboringLists(listElement); + mergeWithNeighboringLists(listElement, editingState); } void InsertListCommand::moveParagraphOverPositionIntoEmptyListItem(const VisiblePosition& pos, PassRefPtrWillBeRawPtr<HTMLLIElement> listItemElement, EditingState* editingState)
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.h b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.h index c70b5c8..6981ad0 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.h
@@ -52,9 +52,9 @@ void doApply(EditingState*) override; EditAction editingAction() const override { return EditActionInsertList; } - HTMLUListElement* fixOrphanedListChild(Node*); + HTMLUListElement* fixOrphanedListChild(Node*, EditingState*); bool selectionHasListOfType(const VisibleSelection&, const HTMLQualifiedName&); - PassRefPtrWillBeRawPtr<HTMLElement> mergeWithNeighboringLists(PassRefPtrWillBeRawPtr<HTMLElement>); + PassRefPtrWillBeRawPtr<HTMLElement> mergeWithNeighboringLists(PassRefPtrWillBeRawPtr<HTMLElement>, EditingState*); bool doApplyForSingleParagraph(bool forceCreateList, const HTMLQualifiedName&, Range& currentSelection, EditingState*); void unlistifyParagraph(const VisiblePosition& originalStart, HTMLElement* listNode, Node* listChildNode); void listifyParagraph(const VisiblePosition& originalStart, const HTMLQualifiedName& listTag, EditingState*);
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp index a2297835..36b5938 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp
@@ -148,7 +148,7 @@ return parent.release(); } -void InsertParagraphSeparatorCommand::doApply(EditingState*) +void InsertParagraphSeparatorCommand::doApply(EditingState* editingState) { if (!endingSelection().isNonOrphanedCaretOrRange()) return; @@ -193,7 +193,7 @@ //--------------------------------------------------------------------- // Handle special case of typing return on an empty list item - if (breakOutOfEmptyListItem()) + if (breakOutOfEmptyListItem(editingState) || editingState->isAborted()) return; //--------------------------------------------------------------------- @@ -410,7 +410,9 @@ } } - moveRemainingSiblingsToNewParent(n, blockToInsert.get(), blockToInsert); + moveRemainingSiblingsToNewParent(n, blockToInsert.get(), blockToInsert, editingState); + if (editingState->isAborted()) + return; } // Handle whitespace that occurs after the split
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp index b46dac6..81fca40 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
@@ -120,7 +120,7 @@ return true; } -void InsertTextCommand::doApply(EditingState*) +void InsertTextCommand::doApply(EditingState* editingState) { ASSERT(m_text.find('\n') == kNotFound); @@ -133,7 +133,9 @@ if (performTrivialReplace(m_text, m_selectInsertedText)) return; bool endOfSelectionWasAtStartOfBlock = isStartOfBlock(endingSelection().visibleEnd()); - deleteSelection(ASSERT_NO_EDITING_ABORT, false, true, false, false); + deleteSelection(editingState, false, true, false, false); + if (editingState->isAborted()) + return; // deleteSelection eventually makes a new endingSelection out of a Position. If that Position doesn't have // a layoutObject (e.g. it is on a <frameset> in the DOM), the VisibleSelection cannot be canonicalized to // anything other than NoSelection. The rest of this function requires a real endingSelection, so bail out. @@ -179,7 +181,9 @@ if (!isVisuallyEquivalentCandidate(startPosition)) startPosition = mostForwardCaretPosition(startPosition); - startPosition = positionAvoidingSpecialElementBoundary(startPosition, ASSERT_NO_EDITING_ABORT); + startPosition = positionAvoidingSpecialElementBoundary(startPosition, editingState); + if (editingState->isAborted()) + return; Position endPosition;
diff --git a/third_party/WebKit/Source/core/editing/commands/MoveSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/MoveSelectionCommand.cpp index c1d2518..4a3af35 100644 --- a/third_party/WebKit/Source/core/editing/commands/MoveSelectionCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/MoveSelectionCommand.cpp
@@ -36,7 +36,7 @@ ASSERT(m_fragment); } -void MoveSelectionCommand::doApply(EditingState*) +void MoveSelectionCommand::doApply(EditingState* editingState) { ASSERT(endingSelection().isNonOrphanedRange()); @@ -55,7 +55,9 @@ pos = Position(pos.computeContainerNode(), pos.offsetInContainerNode() + selectionStart.offsetInContainerNode()); } - deleteSelection(ASSERT_NO_EDITING_ABORT, m_smartDelete); + deleteSelection(editingState, m_smartDelete); + if (editingState->isAborted()) + return; // If the node for the destination has been removed as a result of the deletion, // set the destination to the ending point after the deletion. @@ -64,7 +66,9 @@ if (!pos.inDocument()) pos = endingSelection().start(); - cleanupAfterDeletion(createVisiblePosition(pos)); + cleanupAfterDeletion(editingState, createVisiblePosition(pos)); + if (editingState->isAborted()) + return; setEndingSelection(VisibleSelection(pos, endingSelection().affinity(), endingSelection().isDirectional())); if (!pos.inDocument()) { @@ -74,7 +78,7 @@ ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::PreventNesting; if (m_smartInsert) options |= ReplaceSelectionCommand::SmartReplace; - applyCommandToComposite(ReplaceSelectionCommand::create(document(), m_fragment, options)); + applyCommandToComposite(ReplaceSelectionCommand::create(document(), m_fragment, options), editingState); } EditAction MoveSelectionCommand::editingAction() const
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp index eb5383d70..2edc6e3 100644 --- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -482,7 +482,7 @@ // Style rules that match just inserted elements could change their appearance, like // a div inserted into a document with div { display:inline; }. -void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(InsertedNodes& insertedNodes) +void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(InsertedNodes& insertedNodes, EditingState* editingState) { RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); RefPtrWillBeRawPtr<Node> next = nullptr; @@ -532,7 +532,9 @@ if (!inlineStyle || newInlineStyle->isEmpty()) { if (isStyleSpanOrSpanWithOnlyStyleAttribute(element) || isEmptyFontTag(element, AllowNonEmptyStyleAttribute)) { insertedNodes.willRemoveNodePreservingChildren(*element); - removeNodePreservingChildren(element); + removeNodePreservingChildren(element, editingState); + if (editingState->isAborted()) + return; continue; } removeElementAttribute(element, styleAttr); @@ -545,7 +547,9 @@ && createVisiblePosition(firstPositionInNode(element->parentNode())).deepEquivalent() == createVisiblePosition(firstPositionInNode(element)).deepEquivalent() && createVisiblePosition(lastPositionInNode(element->parentNode())).deepEquivalent() == createVisiblePosition(lastPositionInNode(element)).deepEquivalent()) { insertedNodes.willRemoveNodePreservingChildren(*element); - removeNodePreservingChildren(element); + removeNodePreservingChildren(element, editingState); + if (editingState->isAborted()) + return; continue; } @@ -557,7 +561,9 @@ if (isLegacyAppleHTMLSpanElement(element)) { if (!element->hasChildren()) { insertedNodes.willRemoveNodePreservingChildren(*element); - removeNodePreservingChildren(element); + removeNodePreservingChildren(element, editingState); + if (editingState->isAborted()) + return; continue; } // There are other styles that style rules can give to style spans, @@ -633,7 +639,7 @@ return elements.contains(name); } -void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes& insertedNodes) +void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes& insertedNodes, EditingState* editingState) { RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); RefPtrWillBeRawPtr<Node> next = nullptr; @@ -649,18 +655,24 @@ HTMLElement& element = toHTMLElement(*node); if (isProhibitedParagraphChild(element.localName())) { - if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWithTag(positionInParentBeforeNode(element), pTag))) - moveElementOutOfAncestor(&element, paragraphElement); + if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWithTag(positionInParentBeforeNode(element), pTag))) { + moveElementOutOfAncestor(&element, paragraphElement, editingState); + if (editingState->isAborted()) + return; + } } if (isHTMLHeaderElement(&element)) { - if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(element), isHTMLHeaderElement))) - moveElementOutOfAncestor(&element, headerElement); + if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(element), isHTMLHeaderElement))) { + moveElementOutOfAncestor(&element, headerElement, editingState); + if (editingState->isAborted()) + return; + } } } } -void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<Element> prpElement, PassRefPtrWillBeRawPtr<Element> prpAncestor) +void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<Element> prpElement, PassRefPtrWillBeRawPtr<Element> prpAncestor, EditingState* editingState) { RefPtrWillBeRawPtr<Element> element = prpElement; RefPtrWillBeRawPtr<Element> ancestor = prpAncestor; @@ -671,18 +683,26 @@ VisiblePosition positionAtEndOfNode = createVisiblePosition(lastPositionInOrAfterNode(element.get())); VisiblePosition lastPositionInParagraph = createVisiblePosition(lastPositionInNode(ancestor.get())); if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEquivalent()) { - removeNode(element); + removeNode(element, editingState); + if (editingState->isAborted()) + return; if (ancestor->nextSibling()) - insertNodeBefore(element, ancestor->nextSibling()); + insertNodeBefore(element, ancestor->nextSibling(), editingState); else - appendNode(element, ancestor->parentNode()); + appendNode(element, ancestor->parentNode(), editingState); + if (editingState->isAborted()) + return; } else { RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(), ancestor.get(), true); - removeNode(element); - insertNodeBefore(element, nodeToSplitTo); + removeNode(element, editingState); + if (editingState->isAborted()) + return; + insertNodeBefore(element, nodeToSplitTo, editingState); + if (editingState->isAborted()) + return; } if (!ancestor->hasChildren()) - removeNode(ancestor.release()); + removeNode(ancestor.release(), editingState); } static inline bool nodeHasVisibleLayoutText(Text& text) @@ -699,7 +719,8 @@ && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted), selectTag) && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted), scriptTag)) { insertedNodes.willRemoveNode(*lastLeafInserted); - removeNode(lastLeafInserted); + // Removing a Text node won't dispatch synchronous events. + removeNode(lastLeafInserted, ASSERT_NO_EDITING_ABORT); } // We don't have to make sure that firstNodeInserted isn't inside a select or script element, because @@ -707,7 +728,8 @@ Node* firstNodeInserted = insertedNodes.firstNodeInserted(); if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleLayoutText(toText(*firstNodeInserted))) { insertedNodes.willRemoveNode(*firstNodeInserted); - removeNode(firstNodeInserted); + // Removing a Text node won't dispatch synchronous events. + removeNode(firstNodeInserted, ASSERT_NO_EDITING_ABORT); } } @@ -777,7 +799,7 @@ // We should remove the Apple-style-span class when we're done, see <rdar://problem/5685600>. // We should remove styles from spans that are overridden by all of their children, either here // or at copy time. -void ReplaceSelectionCommand::handleStyleSpans(InsertedNodes& insertedNodes) +void ReplaceSelectionCommand::handleStyleSpans(InsertedNodes& insertedNodes, EditingState* editingState) { HTMLSpanElement* wrappingStyleSpan = nullptr; // The style span that contains the source document's default style should be at @@ -819,7 +841,7 @@ if (style->isEmpty() || !wrappingStyleSpan->hasChildren()) { insertedNodes.willRemoveNodePreservingChildren(*wrappingStyleSpan); - removeNodePreservingChildren(wrappingStyleSpan); + removeNodePreservingChildren(wrappingStyleSpan, editingState); } else { setNodeAttribute(wrappingStyleSpan, styleAttr, AtomicString(style->style()->asText())); } @@ -932,7 +954,10 @@ return; ReplacementFragment fragment(&document(), m_documentFragment.get(), selection); - if (performTrivialReplace(fragment)) + bool trivialReplaceResult = performTrivialReplace(fragment, editingState); + if (editingState->isAborted()) + return; + if (trivialReplaceResult) return; // We can skip matching the style if the selection is plain text. @@ -1015,7 +1040,9 @@ ASSERT(isHTMLBRElement(br)); // Insert content between the two blockquotes, but remove the br (since it was just a placeholder). insertionPos = positionInParentBeforeNode(*br); - removeNode(br); + removeNode(br, editingState); + if (editingState->isAborted()) + return; } // Inserting content could cause whitespace to collapse, e.g. inserting <div>foo</div> into hello^ world. @@ -1148,8 +1175,11 @@ removeUnrenderedTextNodesAtEnds(insertedNodes); - if (!handledStyleSpans) - handleStyleSpans(insertedNodes); + if (!handledStyleSpans) { + handleStyleSpans(insertedNodes, editingState); + if (editingState->isAborted()) + return; + } // Mutation events (bug 20161) may have already removed the inserted content if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted()->inDocument()) @@ -1170,16 +1200,24 @@ if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosBeforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)))) { RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode(); insertedNodes.willRemoveNode(*endBR); - removeNode(endBR); + removeNode(endBR, editingState); + if (editingState->isAborted()) + return; if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { insertedNodes.willRemoveNode(*nodeToRemove); - removeNode(nodeToRemove); + removeNode(nodeToRemove, editingState); + if (editingState->isAborted()) + return; } } - makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes); + makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes, editingState); + if (editingState->isAborted()) + return; - removeRedundantStylesAndKeepStyleSpanInline(insertedNodes); + removeRedundantStylesAndKeepStyleSpanInline(insertedNodes, editingState); + if (editingState->isAborted()) + return; if (m_sanitizeFragment) applyCommandToComposite(SimplifyMarkupCommand::create(document(), insertedNodes.firstNodeInserted(), insertedNodes.pastLastLeaf())); @@ -1268,7 +1306,7 @@ if (plainTextFragment) m_matchStyle = false; - completeHTMLReplacement(lastPositionToSelect); + completeHTMLReplacement(lastPositionToSelect, editingState); } bool ReplaceSelectionCommand::shouldRemoveEndBR(HTMLBRElement* endBR, const VisiblePosition& originalVisPosBeforeEndBR) @@ -1362,7 +1400,7 @@ } } -void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositionToSelect) +void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositionToSelect, EditingState* editingState) { Position start = positionAtStartOfInsertedContent().deepEquivalent(); Position end = positionAtEndOfInsertedContent().deepEquivalent(); @@ -1381,7 +1419,9 @@ if (lastPositionToSelect.isNotNull()) end = lastPositionToSelect; - mergeTextNodesAroundPosition(start, end); + mergeTextNodesAroundPosition(start, end, editingState); + if (editingState->isAborted()) + return; } else if (lastPositionToSelect.isNotNull()) { start = end = lastPositionToSelect; } else { @@ -1397,7 +1437,7 @@ setEndingSelection(VisibleSelection(end, SelDefaultAffinity, endingSelection().isDirectional())); } -void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, Position& positionOnlyToBeUpdated) +void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, Position& positionOnlyToBeUpdated, EditingState* editingState) { bool positionIsOffsetInAnchor = position.isOffsetInAnchor(); bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOffsetInAnchor(); @@ -1435,7 +1475,9 @@ updatePositionForNodeRemoval(positionOnlyToBeUpdated, *previous); } - removeNode(previous); + removeNode(previous, editingState); + if (editingState->isAborted()) + return; } if (text->nextSibling() && text->nextSibling()->isTextNode()) { RefPtrWillBeRawPtr<Text> next = toText(text->nextSibling()); @@ -1450,7 +1492,9 @@ else updatePositionForNodeRemoval(positionOnlyToBeUpdated, *next); - removeNode(next); + removeNode(next, editingState); + if (editingState->isAborted()) + return; } } @@ -1517,7 +1561,7 @@ // directly into the text node that holds the selection. This is much faster than the generalized code in // ReplaceSelectionCommand, and works around <https://bugs.webkit.org/show_bug.cgi?id=6148> since we don't // split text nodes. -bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& fragment) +bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& fragment, EditingState* editingState) { if (!fragment.firstChild() || fragment.firstChild() != fragment.lastChild() || !fragment.firstChild()->isTextNode()) return false; @@ -1540,8 +1584,11 @@ return false; if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBRElement(*nodeAfterInsertionPos) - && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), createVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) - removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); + && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), createVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) { + removeNodeAndPruneAncestors(nodeAfterInsertionPos.get(), editingState); + if (editingState->isAborted()) + return false; + } m_startOfInsertedRange = start; m_endOfInsertedRange = end;
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.h b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.h index 4a36cb3..6467dd6 100644 --- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.h
@@ -93,20 +93,20 @@ void removeUnrenderedTextNodesAtEnds(InsertedNodes&); - void removeRedundantStylesAndKeepStyleSpanInline(InsertedNodes&); - void makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes&); - void moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<Element>, PassRefPtrWillBeRawPtr<Element> ancestor); - void handleStyleSpans(InsertedNodes&); + void removeRedundantStylesAndKeepStyleSpanInline(InsertedNodes&, EditingState*); + void makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes&, EditingState*); + void moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<Element>, PassRefPtrWillBeRawPtr<Element> ancestor, EditingState*); + void handleStyleSpans(InsertedNodes&, EditingState*); VisiblePosition positionAtStartOfInsertedContent() const; VisiblePosition positionAtEndOfInsertedContent() const; bool shouldPerformSmartReplace() const; void addSpacesForSmartReplace(); - void completeHTMLReplacement(const Position& lastPositionToSelect); - void mergeTextNodesAroundPosition(Position&, Position& positionOnlyToBeUpdated); + void completeHTMLReplacement(const Position& lastPositionToSelect, EditingState*); + void mergeTextNodesAroundPosition(Position&, Position& positionOnlyToBeUpdated, EditingState*); - bool performTrivialReplace(const ReplacementFragment&); + bool performTrivialReplace(const ReplacementFragment&, EditingState*); Position m_startOfInsertedContent; Position m_endOfInsertedContent;
diff --git a/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.h b/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.h index 990a89b..f0e6add3 100644 --- a/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.h
@@ -49,20 +49,22 @@ // LineOperation should define member function "opeartor (size_t lineOffset, size_t lineLength, bool isLastLine)". // lienLength doesn't include the newline character. So the value of lineLength could be 0. template <class LineOperation> -void forEachLineInString(const String& string, const LineOperation& operation) +void forEachLineInString(const String& string, const LineOperation& operation, EditingState* editingState) { unsigned offset = 0; size_t newline; while ((newline = string.find('\n', offset)) != kNotFound) { - operation(offset, newline - offset, false); + operation(offset, newline - offset, false, editingState); + if (editingState->isAborted()) + return; offset = newline + 1; } if (!offset) { - operation(0, string.length(), true); + operation(0, string.length(), true, editingState); } else { unsigned length = string.length(); if (length != offset) - operation(offset, length - offset, true); + operation(offset, length - offset, true, editingState); } }
diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp index d2dcf2565..58d157d3 100644 --- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
@@ -56,14 +56,20 @@ , m_text(text) { } - void operator()(size_t lineOffset, size_t lineLength, bool isLastLine) const + void operator()(size_t lineOffset, size_t lineLength, bool isLastLine, EditingState* editingState) const { if (isLastLine) { - if (!lineOffset || lineLength > 0) - m_typingCommand->insertTextRunWithoutNewlines(m_text.substring(lineOffset, lineLength), m_selectInsertedText); + if (!lineOffset || lineLength > 0) { + m_typingCommand->insertTextRunWithoutNewlines(m_text.substring(lineOffset, lineLength), m_selectInsertedText, editingState); + if (editingState->isAborted()) + return; + } } else { - if (lineLength > 0) - m_typingCommand->insertTextRunWithoutNewlines(m_text.substring(lineOffset, lineLength), false); + if (lineLength > 0) { + m_typingCommand->insertTextRunWithoutNewlines(m_text.substring(lineOffset, lineLength), false, editingState); + if (editingState->isAborted()) + return; + } m_typingCommand->insertParagraphSeparator(); } } @@ -190,7 +196,9 @@ lastTypingCommand->setCompositionType(compositionType); lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator); lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking); - lastTypingCommand->insertText(newText, options & SelectInsertedText); + EditingState editingState; + lastTypingCommand->insertText(newText, options & SelectInsertedText, &editingState); + // Nothing to do even if the command was aborted. return; } @@ -277,7 +285,7 @@ insertParagraphSeparatorInQuotedContent(); return; case InsertText: - insertText(m_textToInsert, m_selectInsertedText); + insertText(m_textToInsert, m_selectInsertedText, editingState); return; } @@ -334,7 +342,7 @@ frame->editor().appliedEditing(this); } -void TypingCommand::insertText(const String &text, bool selectInsertedText) +void TypingCommand::insertText(const String &text, bool selectInsertedText, EditingState* editingState) { // FIXME: Need to implement selectInsertedText for cases where more than one insert is involved. // This requires support from insertTextRunWithoutNewlines and insertParagraphSeparator for extending @@ -342,16 +350,17 @@ // select what's inserted, but there's no way to "extend selection" to include both an old selection // that ends just before where we want to insert text and the newly inserted text. TypingCommandLineOperation operation(this, selectInsertedText, text); - forEachLineInString(text, operation); + forEachLineInString(text, operation, editingState); } -void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText) +void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText, EditingState* editingState) { RefPtrWillBeRawPtr<InsertTextCommand> command = InsertTextCommand::create(document(), text, selectInsertedText, m_compositionType == TextCompositionNone ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces : InsertTextCommand::RebalanceAllWhitespaces); - applyCommandToComposite(command, endingSelection()); - + applyCommandToComposite(command, endingSelection(), editingState); + if (editingState->isAborted()) + return; typingAddedToOpenCommand(InsertText); } @@ -386,7 +395,7 @@ typingAddedToOpenCommand(InsertParagraphSeparatorInQuotedContent); } -bool TypingCommand::makeEditableRootEmpty() +bool TypingCommand::makeEditableRootEmpty(EditingState* editingState) { Element* root = endingSelection().rootEditableElement(); if (!root || !root->hasChildren()) @@ -400,8 +409,11 @@ } } - while (Node* child = root->firstChild()) - removeNode(child); + while (Node* child = root->firstChild()) { + removeNode(child, editingState); + if (editingState->isAborted()) + return false; + } addBlockPlaceholderIfNeeded(root); setEndingSelection(VisibleSelection(firstPositionInNode(root), TextAffinity::Downstream, endingSelection().isDirectional())); @@ -428,7 +440,10 @@ case CaretSelection: { // After breaking out of an empty mail blockquote, we still want continue with the deletion // so actual content will get deleted, and not just the quote style. - if (breakOutOfEmptyMailBlockquotedParagraph()) + bool breakOutResult = breakOutOfEmptyMailBlockquotedParagraph(editingState); + if (editingState->isAborted()) + return; + if (breakOutResult) typingAddedToOpenCommand(DeleteKey); m_smartDelete = false; @@ -442,15 +457,20 @@ VisiblePosition visibleStart(endingSelection().visibleStart()); if (previousPositionOf(visibleStart, CannotCrossEditingBoundary).isNull()) { // When the caret is at the start of the editable area in an empty list item, break out of the list item. - if (breakOutOfEmptyListItem()) { + bool breakOutOfEmptyListItemResult = breakOutOfEmptyListItem(editingState); + if (editingState->isAborted()) + return; + if (breakOutOfEmptyListItemResult) { typingAddedToOpenCommand(DeleteKey); return; } // When there are no visible positions in the editing root, delete its entire contents. - if (nextPositionOf(visibleStart, CannotCrossEditingBoundary).isNull() && makeEditableRootEmpty()) { + if (nextPositionOf(visibleStart, CannotCrossEditingBoundary).isNull() && makeEditableRootEmpty(editingState)) { typingAddedToOpenCommand(DeleteKey); return; } + if (editingState->isAborted()) + return; } // If we have a caret selection at the beginning of a cell, we have nothing to do.
diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommand.h b/third_party/WebKit/Source/core/editing/commands/TypingCommand.h index d015e60..780905c 100644 --- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.h
@@ -67,8 +67,8 @@ static void insertParagraphSeparatorInQuotedContent(Document&); static void closeTyping(LocalFrame*); - void insertText(const String &text, bool selectInsertedText); - void insertTextRunWithoutNewlines(const String &text, bool selectInsertedText); + void insertText(const String &text, bool selectInsertedText, EditingState*); + void insertTextRunWithoutNewlines(const String &text, bool selectInsertedText, EditingState*); void insertLineBreak(); void insertParagraphSeparatorInQuotedContent(); void insertParagraphSeparator(); @@ -109,7 +109,7 @@ void updatePreservesTypingStyle(ETypingCommand); void markMisspellingsAfterTyping(ETypingCommand); void typingAddedToOpenCommand(ETypingCommand); - bool makeEditableRootEmpty(); + bool makeEditableRootEmpty(EditingState*); void updateCommandTypeOfOpenCommand(ETypingCommand typingCommand) { m_commandType = typingCommand; } ETypingCommand commandTypeOfOpenCommand() const { return m_commandType; }
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp index b2fec3f..9e5e64b 100644 --- a/third_party/WebKit/Source/core/frame/Deprecation.cpp +++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -4,11 +4,13 @@ #include "core/frame/Deprecation.h" +#include "core/dom/Document.h" +#include "core/dom/ExecutionContext.h" #include "core/frame/FrameConsole.h" #include "core/frame/FrameHost.h" #include "core/frame/LocalFrame.h" -#include "core/frame/UseCounter.h" #include "core/inspector/ConsoleMessage.h" +#include "core/workers/WorkerGlobalScope.h" namespace blink { @@ -56,10 +58,298 @@ { switch (unresolvedProperty) { case CSSPropertyWebkitBackgroundComposite: - return UseCounter::willBeRemoved("'-webkit-background-composite'", 51, "6607299456008192"); + return willBeRemoved("'-webkit-background-composite'", 51, "6607299456008192"); default: return emptyString(); } } +void Deprecation::countDeprecation(const LocalFrame* frame, UseCounter::Feature feature) +{ + if (!frame) + return; + FrameHost* host = frame->host(); + if (!host) + return; + + if (!host->useCounter().hasRecordedMeasurement(feature)) { + host->useCounter().recordMeasurement(feature); + ASSERT(!deprecationMessage(feature).isEmpty()); + frame->console().addMessage(ConsoleMessage::create(DeprecationMessageSource, WarningMessageLevel, deprecationMessage(feature))); + } +} + +void Deprecation::countDeprecation(ExecutionContext* context, UseCounter::Feature feature) +{ + if (!context) + return; + if (context->isDocument()) { + Deprecation::countDeprecation(*toDocument(context), feature); + return; + } + if (context->isWorkerGlobalScope()) + toWorkerGlobalScope(context)->countDeprecation(feature); +} + +void Deprecation::countDeprecation(const Document& document, UseCounter::Feature feature) +{ + Deprecation::countDeprecation(document.frame(), feature); +} + +void Deprecation::countDeprecationIfNotPrivateScript(v8::Isolate* isolate, ExecutionContext* context, UseCounter::Feature feature) +{ + if (DOMWrapperWorld::current(isolate).isPrivateScriptIsolatedWorld()) + return; + Deprecation::countDeprecation(context, feature); +} + +static const char* milestoneString(int milestone) +{ + switch (milestone) { + case 50: + return "M50, around April 2016"; + case 51: + return "M51, around June 2016"; + case 52: + return "M52, around August 2016"; + case 53: + return "M53, around September 2016"; + } + + ASSERT_NOT_REACHED(); + return nullptr; +} + +static String replacedBy(const char* feature, const char* replacement) +{ + return String::format("%s is deprecated. Please use %s instead.", feature, replacement); +} + +String Deprecation::willBeRemoved(const char* feature, int milestone, const char* details) +{ + return String::format("%s is deprecated and will be removed in %s. See https://www.chromestatus.com/features/%s for more details.", feature, milestoneString(milestone), details); +} + +static String replacedWillBeRemoved(const char* feature, const char* replacement, int milestone, const char* details) +{ + return String::format("%s is deprecated and will be removed in %s. Please use %s instead. See https://www.chromestatus.com/features/%s for more details.", feature, milestoneString(milestone), replacement, details); +} + +String Deprecation::deprecationMessage(UseCounter::Feature feature) +{ + switch (feature) { + // Quota + case UseCounter::PrefixedStorageInfo: + return replacedBy("'window.webkitStorageInfo'", "'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage'"); + + // Keyboard Event (DOM Level 3) + case UseCounter::KeyboardEventKeyLocation: + return replacedWillBeRemoved("'KeyboardEvent.keyLocation'", "'KeyboardEvent.location'", 50, "4997403308457984"); + + case UseCounter::ConsoleMarkTimeline: + return replacedBy("'console.markTimeline'", "'console.timeStamp'"); + + case UseCounter::FileError: + return "FileError is deprecated. Please use the 'name' or 'message' attributes of DOMError rather than 'code'."; + + case UseCounter::CSSStyleSheetInsertRuleOptionalArg: + return "Calling CSSStyleSheet.insertRule() with one argument is deprecated. Please pass the index argument as well: insertRule(x, 0)."; + + case UseCounter::PrefixedVideoSupportsFullscreen: + return replacedBy("'HTMLVideoElement.webkitSupportsFullscreen'", "'Document.fullscreenEnabled'"); + + case UseCounter::PrefixedVideoDisplayingFullscreen: + return replacedBy("'HTMLVideoElement.webkitDisplayingFullscreen'", "'Document.fullscreenElement'"); + + case UseCounter::PrefixedVideoEnterFullscreen: + return replacedBy("'HTMLVideoElement.webkitEnterFullscreen()'", "'Element.requestFullscreen()'"); + + case UseCounter::PrefixedVideoExitFullscreen: + return replacedBy("'HTMLVideoElement.webkitExitFullscreen()'", "'Document.exitFullscreen()'"); + + case UseCounter::PrefixedVideoEnterFullScreen: + return replacedBy("'HTMLVideoElement.webkitEnterFullScreen()'", "'Element.requestFullscreen()'"); + + case UseCounter::PrefixedVideoExitFullScreen: + return replacedBy("'HTMLVideoElement.webkitExitFullScreen()'", "'Document.exitFullscreen()'"); + + case UseCounter::PrefixedIndexedDB: + return replacedBy("'webkitIndexedDB'", "'indexedDB'"); + + case UseCounter::PrefixedIDBCursorConstructor: + return replacedBy("'webkitIDBCursor'", "'IDBCursor'"); + + case UseCounter::PrefixedIDBDatabaseConstructor: + return replacedBy("'webkitIDBDatabase'", "'IDBDatabase'"); + + case UseCounter::PrefixedIDBFactoryConstructor: + return replacedBy("'webkitIDBFactory'", "'IDBFactory'"); + + case UseCounter::PrefixedIDBIndexConstructor: + return replacedBy("'webkitIDBIndex'", "'IDBIndex'"); + + case UseCounter::PrefixedIDBKeyRangeConstructor: + return replacedBy("'webkitIDBKeyRange'", "'IDBKeyRange'"); + + case UseCounter::PrefixedIDBObjectStoreConstructor: + return replacedBy("'webkitIDBObjectStore'", "'IDBObjectStore'"); + + case UseCounter::PrefixedIDBRequestConstructor: + return replacedBy("'webkitIDBRequest'", "'IDBRequest'"); + + case UseCounter::PrefixedIDBTransactionConstructor: + return replacedBy("'webkitIDBTransaction'", "'IDBTransaction'"); + + case UseCounter::PrefixedRequestAnimationFrame: + return "'webkitRequestAnimationFrame' is vendor-specific. Please use the standard 'requestAnimationFrame' instead."; + + case UseCounter::PrefixedCancelAnimationFrame: + return "'webkitCancelAnimationFrame' is vendor-specific. Please use the standard 'cancelAnimationFrame' instead."; + + case UseCounter::PrefixedCancelRequestAnimationFrame: + return "'webkitCancelRequestAnimationFrame' is vendor-specific. Please use the standard 'cancelAnimationFrame' instead."; + + case UseCounter::SyncXHRWithCredentials: + return "Setting 'XMLHttpRequest.withCredentials' for synchronous requests is deprecated."; + + case UseCounter::PictureSourceSrc: + return "<source src> with a <picture> parent is invalid and therefore ignored. Please use <source srcset> instead."; + + case UseCounter::ConsoleTimeline: + return replacedBy("'console.timeline'", "'console.time'"); + + case UseCounter::ConsoleTimelineEnd: + return replacedBy("'console.timelineEnd'", "'console.timeEnd'"); + + case UseCounter::XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload: + return "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/."; + + case UseCounter::GetMatchedCSSRules: + return "'getMatchedCSSRules()' is deprecated. For more help, check https://code.google.com/p/chromium/issues/detail?id=437569#c2"; + + case UseCounter::PrefixedImageSmoothingEnabled: + return replacedBy("'CanvasRenderingContext2D.webkitImageSmoothingEnabled'", "'CanvasRenderingContext2D.imageSmoothingEnabled'"); + + case UseCounter::AudioListenerDopplerFactor: + return "dopplerFactor is deprecated and will be removed in M45 when all doppler effects are removed"; + + case UseCounter::AudioListenerSpeedOfSound: + return "speedOfSound is deprecated and will be removed in M45 when all doppler effects are removed"; + + case UseCounter::AudioListenerSetVelocity: + return "setVelocity() is deprecated and will be removed in M45 when all doppler effects are removed"; + + case UseCounter::PrefixedWindowURL: + return replacedBy("'webkitURL'", "'URL'"); + + case UseCounter::PrefixedAudioContext: + return replacedBy("'webkitAudioContext'", "'AudioContext'"); + + case UseCounter::PrefixedOfflineAudioContext: + return replacedBy("'webkitOfflineAudioContext'", "'OfflineAudioContext'"); + + case UseCounter::RangeExpand: + return replacedBy("'Range.expand()'", "'Selection.modify()'"); + + case UseCounter::PrefixedMediaAddKey: + case UseCounter::PrefixedMediaGenerateKeyRequest: + case UseCounter::PrefixedMediaCancelKeyRequest: + return "The prefixed Encrypted Media Extensions APIs are deprecated. Please use 'navigator.requestMediaKeySystemAccess()' instead."; + + case UseCounter::CanPlayTypeKeySystem: + return replacedBy("canPlayType()'s 'keySystem' parameter", "'navigator.requestMediaKeySystemAccess()'"); + + // Powerful features on insecure origins (https://goo.gl/rStTGz) + case UseCounter::DeviceMotionInsecureOrigin: + return "The devicemotion event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; + + case UseCounter::DeviceOrientationInsecureOrigin: + return "The deviceorientation event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; + + case UseCounter::DeviceOrientationAbsoluteInsecureOrigin: + return "The deviceorientationabsolute event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; + + case UseCounter::GeolocationInsecureOrigin: + // TODO(jww): This message should be made less ambigous after WebView + // is fixed so geolocation can be removed there. After that, this + // should be updated to read similarly to GetUserMediaInsecureOrigin's + // message. + return "getCurrentPosition() and watchPosition() are deprecated on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; + + case UseCounter::GetUserMediaInsecureOrigin: + return "getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; + + case UseCounter::EncryptedMediaInsecureOrigin: + return "requestMediaKeySystemAccess() is deprecated on insecure origins in the specification. Support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; + + case UseCounter::ElementCreateShadowRootMultiple: + return "Calling Element.createShadowRoot() for an element which already hosts a shadow root is deprecated. See https://www.chromestatus.com/features/4668884095336448 for more details."; + + case UseCounter::ElementCreateShadowRootMultipleWithUserAgentShadowRoot: + return "Calling Element.createShadowRoot() for an element which already hosts a user-agent shadow root is deprecated. See https://www.chromestatus.com/features/4668884095336448 for more details."; + + case UseCounter::CSSDeepCombinator: + return "/deep/ combinator is deprecated. See https://www.chromestatus.com/features/6750456638341120 for more details."; + + case UseCounter::CSSSelectorPseudoShadow: + return "::shadow pseudo-element is deprecated. See https://www.chromestatus.com/features/6750456638341120 for more details."; + + case UseCounter::SVGSMILElementInDocument: + case UseCounter::SVGSMILAnimationInImageRegardlessOfCache: + return "SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead."; + + case UseCounter::PrefixedPerformanceClearResourceTimings: + return replacedBy("'Performance.webkitClearResourceTimings'", "'Performance.clearResourceTimings'"); + + case UseCounter::PrefixedPerformanceSetResourceTimingBufferSize: + return replacedBy("'Performance.webkitSetResourceTimingBufferSize'", "'Performance.setResourceTimingBufferSize'"); + + case UseCounter::PrefixedPerformanceResourceTimingBufferFull: + return replacedBy("'Performance.onwebkitresourcetimingbufferfull'", "'Performance.onresourcetimingbufferfull'"); + + case UseCounter::BluetoothDeviceInstanceId: + return replacedBy("'BluetoothDevice.instanceID'", "'BluetoothDevice.id'"); + + case UseCounter::BluetoothDeviceConnectGATT: + return replacedWillBeRemoved("'BluetoothDevice.connectGATT'", "'BluetoothDevice.gatt.connect'", 52, "5264933985976320"); + + case UseCounter::V8SVGElement_OffsetParent_AttributeGetter: + return willBeRemoved("'SVGElement.offsetParent'", 50, "5724912467574784"); + + case UseCounter::V8SVGElement_OffsetTop_AttributeGetter: + return willBeRemoved("'SVGElement.offsetTop'", 50, "5724912467574784"); + + case UseCounter::V8SVGElement_OffsetLeft_AttributeGetter: + return willBeRemoved("'SVGElement.offsetLeft'", 50, "5724912467574784"); + + case UseCounter::V8SVGElement_OffsetWidth_AttributeGetter: + return willBeRemoved("'SVGElement.offsetWidth'", 50, "5724912467574784"); + + case UseCounter::V8SVGElement_OffsetHeight_AttributeGetter: + return willBeRemoved("'SVGElement.offsetHeight'", 50, "5724912467574784"); + + case UseCounter::MediaStreamTrackGetSources: + return "MediaStreamTrack.getSources is deprecated. See https://www.chromestatus.com/feature/4765305641369600 for more details."; + + case UseCounter::DocumentDefaultCharset: + return willBeRemoved("'Document.defaultCharset'", 50, "6217124578066432"); + + case UseCounter::V8TouchEvent_InitTouchEvent_Method: + return replacedWillBeRemoved("'TouchEvent.initTouchEvent'", "the TouchEvent constructor", 53, "5730982598541312"); + + case UseCounter::RTCPeerConnectionCreateAnswerLegacyNoFailureCallback: + return "RTCPeerConnection.CreateAnswer without a failure callback is deprecated. The failure callback will be a required parameter in M50. See https://www.chromestatus.com/feature/5663288008376320 for more details"; + + case UseCounter::RTCPeerConnectionCreateOfferLegacyNoFailureCallback: + return "RTCPeerConnection.CreateOffer without a failure callback is deprecated. The failure callback will be a required parameter in M50. See https://www.chromestatus.com/feature/5663288008376320 for more details"; + + case UseCounter::ObjectObserve: + return willBeRemoved("'Object.observe'", 50, "6147094632988672"); + + // Features that aren't deprecated don't have a deprecation message. + default: + return String(); + } +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.h b/third_party/WebKit/Source/core/frame/Deprecation.h index beb24bb..42193fc 100644 --- a/third_party/WebKit/Source/core/frame/Deprecation.h +++ b/third_party/WebKit/Source/core/frame/Deprecation.h
@@ -6,6 +6,8 @@ #define Deprecation_h #include "core/CSSPropertyNames.h" +#include "core/CoreExport.h" +#include "core/frame/UseCounter.h" #include "wtf/BitVector.h" #include "wtf/Noncopyable.h" @@ -13,7 +15,7 @@ class LocalFrame; -class Deprecation { +class CORE_EXPORT Deprecation { DISALLOW_NEW(); WTF_MAKE_NONCOPYABLE(Deprecation); public: @@ -23,6 +25,26 @@ static void warnOnDeprecatedProperties(const LocalFrame*, CSSPropertyID unresolvedProperty); void clearSuppression(); + // "countDeprecation" sets the bit for this feature to 1, and sends a deprecation + // warning to the console. Repeated calls are ignored. + // + // Be considerate to developers' consoles: features should only send + // deprecation warnings when we're actively interested in removing them from + // the platform. + // + // For shared workers and service workers, the ExecutionContext* overload + // doesn't count the usage but only sends a console warning. + static void countDeprecation(const LocalFrame*, UseCounter::Feature); + static void countDeprecation(ExecutionContext*, UseCounter::Feature); + static void countDeprecation(const Document&, UseCounter::Feature); + // Use countDeprecationIfNotPrivateScript() instead of countDeprecation() + // if you don't want to count metrics in private scripts. You should use + // countDeprecationIfNotPrivateScript() in a binding layer. + static void countDeprecationIfNotPrivateScript(v8::Isolate*, ExecutionContext*, UseCounter::Feature); + static String deprecationMessage(UseCounter::Feature); + + static String willBeRemoved(const char* feature, int milestone, const char* details); + protected: void suppress(CSSPropertyID unresolvedProperty); bool isSuppressed(CSSPropertyID unresolvedProperty);
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index 86e31a8..ff3df3e 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -29,6 +29,7 @@ #include "core/css/StyleSheetContents.h" #include "core/dom/Document.h" #include "core/dom/ExecutionContext.h" +#include "core/frame/Deprecation.h" #include "core/frame/FrameConsole.h" #include "core/frame/FrameHost.h" #include "core/frame/LocalFrame.h" @@ -646,7 +647,7 @@ if (!host) return; - ASSERT(deprecationMessage(feature).isEmpty()); + ASSERT(Deprecation::deprecationMessage(feature).isEmpty()); host->useCounter().recordMeasurement(feature); } @@ -699,45 +700,6 @@ UseCounter::count(context, feature); } -void UseCounter::countDeprecation(const LocalFrame* frame, Feature feature) -{ - if (!frame) - return; - FrameHost* host = frame->host(); - if (!host) - return; - - if (!host->useCounter().hasRecordedMeasurement(feature)) { - host->useCounter().recordMeasurement(feature); - ASSERT(!deprecationMessage(feature).isEmpty()); - frame->console().addMessage(ConsoleMessage::create(DeprecationMessageSource, WarningMessageLevel, deprecationMessage(feature))); - } -} - -void UseCounter::countDeprecation(ExecutionContext* context, Feature feature) -{ - if (!context) - return; - if (context->isDocument()) { - UseCounter::countDeprecation(*toDocument(context), feature); - return; - } - if (context->isWorkerGlobalScope()) - toWorkerGlobalScope(context)->countDeprecation(feature); -} - -void UseCounter::countDeprecation(const Document& document, Feature feature) -{ - UseCounter::countDeprecation(document.frame(), feature); -} - -void UseCounter::countDeprecationIfNotPrivateScript(v8::Isolate* isolate, ExecutionContext* context, Feature feature) -{ - if (DOMWrapperWorld::current(isolate).isPrivateScriptIsolatedWorld()) - return; - UseCounter::countDeprecation(context, feature); -} - void UseCounter::countCrossOriginIframe(const Document& document, Feature feature) { Frame* frame = document.frame(); @@ -750,256 +712,6 @@ count(frame, feature); } -// TODO(nainar): Migrate all console message functions to Deprecation -static const char* milestoneString(int milestone) -{ - switch (milestone) { - case 50: - return "M50, around April 2016"; - case 51: - return "M51, around June 2016"; - case 52: - return "M52, around August 2016"; - case 53: - return "M53, around September 2016"; - } - - ASSERT_NOT_REACHED(); - return nullptr; -} - -static String replacedBy(const char* feature, const char* replacement) -{ - return String::format("%s is deprecated. Please use %s instead.", feature, replacement); -} - -String UseCounter::willBeRemoved(const char* feature, int milestone, const char* details) -{ - return String::format("%s is deprecated and will be removed in %s. See https://www.chromestatus.com/features/%s for more details.", feature, milestoneString(milestone), details); -} - -static String replacedWillBeRemoved(const char* feature, const char* replacement, int milestone, const char* details) -{ - return String::format("%s is deprecated and will be removed in %s. Please use %s instead. See https://www.chromestatus.com/features/%s for more details.", feature, milestoneString(milestone), replacement, details); -} - -String UseCounter::deprecationMessage(Feature feature) -{ - switch (feature) { - // Quota - case PrefixedStorageInfo: - return replacedBy("'window.webkitStorageInfo'", "'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage'"); - - // Keyboard Event (DOM Level 3) - case KeyboardEventKeyLocation: - return replacedWillBeRemoved("'KeyboardEvent.keyLocation'", "'KeyboardEvent.location'", 50, "4997403308457984"); - - case ConsoleMarkTimeline: - return replacedBy("'console.markTimeline'", "'console.timeStamp'"); - - case FileError: - return "FileError is deprecated. Please use the 'name' or 'message' attributes of DOMError rather than 'code'."; - - case CSSStyleSheetInsertRuleOptionalArg: - return "Calling CSSStyleSheet.insertRule() with one argument is deprecated. Please pass the index argument as well: insertRule(x, 0)."; - - case PrefixedVideoSupportsFullscreen: - return replacedBy("'HTMLVideoElement.webkitSupportsFullscreen'", "'Document.fullscreenEnabled'"); - - case PrefixedVideoDisplayingFullscreen: - return replacedBy("'HTMLVideoElement.webkitDisplayingFullscreen'", "'Document.fullscreenElement'"); - - case PrefixedVideoEnterFullscreen: - return replacedBy("'HTMLVideoElement.webkitEnterFullscreen()'", "'Element.requestFullscreen()'"); - - case PrefixedVideoExitFullscreen: - return replacedBy("'HTMLVideoElement.webkitExitFullscreen()'", "'Document.exitFullscreen()'"); - - case PrefixedVideoEnterFullScreen: - return replacedBy("'HTMLVideoElement.webkitEnterFullScreen()'", "'Element.requestFullscreen()'"); - - case PrefixedVideoExitFullScreen: - return replacedBy("'HTMLVideoElement.webkitExitFullScreen()'", "'Document.exitFullscreen()'"); - - case PrefixedIndexedDB: - return replacedBy("'webkitIndexedDB'", "'indexedDB'"); - - case PrefixedIDBCursorConstructor: - return replacedBy("'webkitIDBCursor'", "'IDBCursor'"); - - case PrefixedIDBDatabaseConstructor: - return replacedBy("'webkitIDBDatabase'", "'IDBDatabase'"); - - case PrefixedIDBFactoryConstructor: - return replacedBy("'webkitIDBFactory'", "'IDBFactory'"); - - case PrefixedIDBIndexConstructor: - return replacedBy("'webkitIDBIndex'", "'IDBIndex'"); - - case PrefixedIDBKeyRangeConstructor: - return replacedBy("'webkitIDBKeyRange'", "'IDBKeyRange'"); - - case PrefixedIDBObjectStoreConstructor: - return replacedBy("'webkitIDBObjectStore'", "'IDBObjectStore'"); - - case PrefixedIDBRequestConstructor: - return replacedBy("'webkitIDBRequest'", "'IDBRequest'"); - - case PrefixedIDBTransactionConstructor: - return replacedBy("'webkitIDBTransaction'", "'IDBTransaction'"); - - case PrefixedRequestAnimationFrame: - return "'webkitRequestAnimationFrame' is vendor-specific. Please use the standard 'requestAnimationFrame' instead."; - - case PrefixedCancelAnimationFrame: - return "'webkitCancelAnimationFrame' is vendor-specific. Please use the standard 'cancelAnimationFrame' instead."; - - case PrefixedCancelRequestAnimationFrame: - return "'webkitCancelRequestAnimationFrame' is vendor-specific. Please use the standard 'cancelAnimationFrame' instead."; - - case SyncXHRWithCredentials: - return "Setting 'XMLHttpRequest.withCredentials' for synchronous requests is deprecated."; - - case PictureSourceSrc: - return "<source src> with a <picture> parent is invalid and therefore ignored. Please use <source srcset> instead."; - - case ConsoleTimeline: - return replacedBy("'console.timeline'", "'console.time'"); - - case ConsoleTimelineEnd: - return replacedBy("'console.timelineEnd'", "'console.timeEnd'"); - - case XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload: - return "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/."; - - case GetMatchedCSSRules: - return "'getMatchedCSSRules()' is deprecated. For more help, check https://code.google.com/p/chromium/issues/detail?id=437569#c2"; - - case PrefixedImageSmoothingEnabled: - return replacedBy("'CanvasRenderingContext2D.webkitImageSmoothingEnabled'", "'CanvasRenderingContext2D.imageSmoothingEnabled'"); - - case AudioListenerDopplerFactor: - return "dopplerFactor is deprecated and will be removed in M45 when all doppler effects are removed"; - - case AudioListenerSpeedOfSound: - return "speedOfSound is deprecated and will be removed in M45 when all doppler effects are removed"; - - case AudioListenerSetVelocity: - return "setVelocity() is deprecated and will be removed in M45 when all doppler effects are removed"; - - case PrefixedWindowURL: - return replacedBy("'webkitURL'", "'URL'"); - - case PrefixedAudioContext: - return replacedBy("'webkitAudioContext'", "'AudioContext'"); - - case PrefixedOfflineAudioContext: - return replacedBy("'webkitOfflineAudioContext'", "'OfflineAudioContext'"); - - case RangeExpand: - return replacedBy("'Range.expand()'", "'Selection.modify()'"); - - case PrefixedMediaAddKey: - case PrefixedMediaGenerateKeyRequest: - case PrefixedMediaCancelKeyRequest: - return "The prefixed Encrypted Media Extensions APIs are deprecated. Please use 'navigator.requestMediaKeySystemAccess()' instead."; - - case CanPlayTypeKeySystem: - return replacedBy("canPlayType()'s 'keySystem' parameter", "'navigator.requestMediaKeySystemAccess()'"); - - // Powerful features on insecure origins (https://goo.gl/rStTGz) - case DeviceMotionInsecureOrigin: - return "The devicemotion event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; - - case DeviceOrientationInsecureOrigin: - return "The deviceorientation event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; - - case DeviceOrientationAbsoluteInsecureOrigin: - return "The deviceorientationabsolute event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; - - case GeolocationInsecureOrigin: - // TODO(jww): This message should be made less ambigous after WebView - // is fixed so geolocation can be removed there. After that, this - // should be updated to read similarly to GetUserMediaInsecureOrigin's - // message. - return "getCurrentPosition() and watchPosition() are deprecated on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; - - case GetUserMediaInsecureOrigin: - return "getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; - - case EncryptedMediaInsecureOrigin: - return "requestMediaKeySystemAccess() is deprecated on insecure origins in the specification. Support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details."; - - case ElementCreateShadowRootMultiple: - return "Calling Element.createShadowRoot() for an element which already hosts a shadow root is deprecated. See https://www.chromestatus.com/features/4668884095336448 for more details."; - - case ElementCreateShadowRootMultipleWithUserAgentShadowRoot: - return "Calling Element.createShadowRoot() for an element which already hosts a user-agent shadow root is deprecated. See https://www.chromestatus.com/features/4668884095336448 for more details."; - - case CSSDeepCombinator: - return "/deep/ combinator is deprecated. See https://www.chromestatus.com/features/6750456638341120 for more details."; - - case CSSSelectorPseudoShadow: - return "::shadow pseudo-element is deprecated. See https://www.chromestatus.com/features/6750456638341120 for more details."; - - case SVGSMILElementInDocument: - case SVGSMILAnimationInImageRegardlessOfCache: - return "SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead."; - - case PrefixedPerformanceClearResourceTimings: - return replacedBy("'Performance.webkitClearResourceTimings'", "'Performance.clearResourceTimings'"); - - case PrefixedPerformanceSetResourceTimingBufferSize: - return replacedBy("'Performance.webkitSetResourceTimingBufferSize'", "'Performance.setResourceTimingBufferSize'"); - - case PrefixedPerformanceResourceTimingBufferFull: - return replacedBy("'Performance.onwebkitresourcetimingbufferfull'", "'Performance.onresourcetimingbufferfull'"); - - case BluetoothDeviceInstanceId: - return replacedBy("'BluetoothDevice.instanceID'", "'BluetoothDevice.id'"); - - case BluetoothDeviceConnectGATT: - return replacedWillBeRemoved("'BluetoothDevice.connectGATT'", "'BluetoothDevice.gatt.connect'", 52, "5264933985976320"); - - case V8SVGElement_OffsetParent_AttributeGetter: - return willBeRemoved("'SVGElement.offsetParent'", 50, "5724912467574784"); - - case V8SVGElement_OffsetTop_AttributeGetter: - return willBeRemoved("'SVGElement.offsetTop'", 50, "5724912467574784"); - - case V8SVGElement_OffsetLeft_AttributeGetter: - return willBeRemoved("'SVGElement.offsetLeft'", 50, "5724912467574784"); - - case V8SVGElement_OffsetWidth_AttributeGetter: - return willBeRemoved("'SVGElement.offsetWidth'", 50, "5724912467574784"); - - case V8SVGElement_OffsetHeight_AttributeGetter: - return willBeRemoved("'SVGElement.offsetHeight'", 50, "5724912467574784"); - - case MediaStreamTrackGetSources: - return "MediaStreamTrack.getSources is deprecated. See https://www.chromestatus.com/feature/4765305641369600 for more details."; - - case DocumentDefaultCharset: - return willBeRemoved("'Document.defaultCharset'", 50, "6217124578066432"); - - case V8TouchEvent_InitTouchEvent_Method: - return replacedWillBeRemoved("'TouchEvent.initTouchEvent'", "the TouchEvent constructor", 53, "5730982598541312"); - - case RTCPeerConnectionCreateAnswerLegacyNoFailureCallback: - return "RTCPeerConnection.CreateAnswer without a failure callback is deprecated. The failure callback will be a required parameter in M50. See https://www.chromestatus.com/feature/5663288008376320 for more details"; - - case RTCPeerConnectionCreateOfferLegacyNoFailureCallback: - return "RTCPeerConnection.CreateOffer without a failure callback is deprecated. The failure callback will be a required parameter in M50. See https://www.chromestatus.com/feature/5663288008376320 for more details"; - - case ObjectObserve: - return willBeRemoved("'Object.observe'", 50, "6147094632988672"); - - // Features that aren't deprecated don't have a deprecation message. - default: - return String(); - } -} - void UseCounter::count(CSSParserMode cssParserMode, CSSPropertyID feature) { ASSERT(feature >= firstCSSProperty); @@ -1013,7 +725,7 @@ void UseCounter::count(Feature feature) { - ASSERT(deprecationMessage(feature).isEmpty()); + ASSERT(Deprecation::deprecationMessage(feature).isEmpty()); recordMeasurement(feature); }
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index 77bdc764..853b7e95 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1104,31 +1104,10 @@ void count(CSSParserMode, CSSPropertyID); void count(Feature); - // "countDeprecation" sets the bit for this feature to 1, and sends a deprecation - // warning to the console. Repeated calls are ignored. - // - // Be considerate to developers' consoles: features should only send - // deprecation warnings when we're actively interested in removing them from - // the platform. - // - // For shared workers and service workers, the ExecutionContext* overload - // doesn't count the usage but only sends a console warning. - static void countDeprecation(const LocalFrame*, Feature); - static void countDeprecation(ExecutionContext*, Feature); - static void countDeprecation(const Document&, Feature); - // Use countDeprecationIfNotPrivateScript() instead of countDeprecation() - // if you don't want to count metrics in private scripts. You should use - // countDeprecationIfNotPrivateScript() in a binding layer. - static void countDeprecationIfNotPrivateScript(v8::Isolate*, ExecutionContext*, Feature); - static String deprecationMessage(Feature); - // Count only features if they're being used in an iframe which does not // have script access into the top level document. static void countCrossOriginIframe(const Document&, Feature); - // TODO (nainar): Migrate all console message functions to Deprecation - static String willBeRemoved(const char* feature, int milestone, const char* details); - // Return whether the Feature was previously counted for this document. // NOTE: only for use in testing. static bool isCounted(Document&, Feature); @@ -1144,6 +1123,11 @@ static void muteForInspector(); static void unmuteForInspector(); + void recordMeasurement(Feature feature) { m_countBits.recordMeasurement(feature); } + void updateMeasurements(); + + bool hasRecordedMeasurement(Feature feature) const { return m_countBits.hasRecordedMeasurement(feature); } + class CountBits { DISALLOW_NEW(); public: @@ -1179,11 +1163,6 @@ friend class UseCounterTest; static int m_muteCount; - void recordMeasurement(Feature feature) { m_countBits.recordMeasurement(feature); } - void updateMeasurements(); - - bool hasRecordedMeasurement(Feature feature) const { return m_countBits.hasRecordedMeasurement(feature); } - CountBits m_countBits; BitVector m_CSSFeatureBits; };
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 40f436f5..407d7d15 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -52,6 +52,7 @@ #include "core/imagebitmap/ImageBitmapOptions.h" #include "core/layout/LayoutHTMLCanvas.h" #include "core/paint/PaintLayer.h" +#include "core/paint/PaintTiming.h" #include "platform/Histogram.h" #include "platform/MIMETypeRegistry.h" #include "platform/RuntimeEnabledFeatures.h" @@ -451,6 +452,9 @@ m_imageBuffer->setFilterQuality(filterQuality); } + if (hasImageBuffer() && !m_imageBufferIsClear) + PaintTiming::from(document()).markFirstContentfulPaint(); + if (!paintsIntoCanvasBuffer() && !document().printing()) return;
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp index b547215..ae623aa 100644 --- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -33,8 +33,8 @@ #include "core/dom/NodeTraversal.h" #include "core/dom/shadow/ShadowRoot.h" #include "core/fetch/ImageResource.h" +#include "core/frame/Deprecation.h" #include "core/frame/ImageBitmap.h" -#include "core/frame/UseCounter.h" #include "core/html/HTMLAnchorElement.h" #include "core/html/HTMLCanvasElement.h" #include "core/html/HTMLFormElement.h" @@ -331,7 +331,7 @@ HTMLSourceElement* source = toHTMLSourceElement(child); if (!source->fastGetAttribute(srcAttr).isNull()) - UseCounter::countDeprecation(document(), UseCounter::PictureSourceSrc); + Deprecation::countDeprecation(document(), UseCounter::PictureSourceSrc); String srcset = source->fastGetAttribute(srcsetAttr); if (srcset.isEmpty()) continue;
diff --git a/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp b/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp index e9d1fb2..2b36b211 100644 --- a/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp +++ b/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp
@@ -476,7 +476,7 @@ void DateTimeEditElement::addField(PassRefPtrWillBeRawPtr<DateTimeFieldElement> field) { - if (m_fields.size() == m_fields.capacity()) + if (m_fields.size() >= maximumNumberOfFields) return; m_fields.append(field.get()); fieldsWrapperElement()->appendChild(field);
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp index f6afbf0d..dfb5ce59 100644 --- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -181,27 +181,43 @@ page->chromeClient().didObserveNonGetFetchFromScript(); } - // If the fetch request will be handled by the ServiceWorker, the - // FetchRequestMode of the request must be FetchRequestModeCORS or - // FetchRequestModeCORSWithForcedPreflight. Otherwise the ServiceWorker can - // return a opaque response which is from the other origin site and the - // script in the page can read the content. - // // We assume that ServiceWorker is skipped for sync requests and unsupported // protocol requests by content/ code. if (m_async && !request.skipServiceWorker() && SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(request.url().protocol()) && document.fetcher()->isControlledByServiceWorker()) { ResourceRequest newRequest(request); - // FetchRequestMode should be set by the caller. But the expected value - // of FetchRequestMode is not speced yet except for XHR. So we set here. - // FIXME: When we support fetch API in document, this value should not - // be overridden here. - if (options.preflightPolicy == ForcePreflight) - newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORSWithForcedPreflight); - else - newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); - - m_fallbackRequestForServiceWorker = ResourceRequest(request); - m_fallbackRequestForServiceWorker.setSkipServiceWorker(true); + const WebURLRequest::RequestContext requestContext(request.requestContext()); + if (requestContext != WebURLRequest::RequestContextFetch) { + // When the request context is not "fetch", + // |crossOriginRequestPolicy| represents the fetch request mode, + // and |credentialsRequested| represents the fetch credentials mode. + // So we set those flags here so that we can see the correct request + // mode and credentials mode in the service worker's fetch event + // handler. + switch (m_options.crossOriginRequestPolicy) { + case DenyCrossOriginRequests: + newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeSameOrigin); + break; + case UseAccessControl: + if (options.preflightPolicy == ForcePreflight) + newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORSWithForcedPreflight); + else + newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); + break; + case AllowCrossOriginRequests: + // No-CORS requests are allowed only for those contexts. + RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(requestContext == WebURLRequest::RequestContextAudio || requestContext == WebURLRequest::RequestContextVideo || requestContext == WebURLRequest::RequestContextObject || requestContext == WebURLRequest::RequestContextFavicon || requestContext == WebURLRequest::RequestContextImage || requestContext == WebURLRequest::RequestContextScript); + newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeNoCORS); + break; + } + if (m_resourceLoaderOptions.allowCredentials == AllowStoredCredentials) + newRequest.setFetchCredentialsMode(WebURLRequest::FetchCredentialsModeInclude); + else + newRequest.setFetchCredentialsMode(WebURLRequest::FetchCredentialsModeSameOrigin); + } + if (newRequest.fetchRequestMode() == WebURLRequest::FetchRequestModeCORS || newRequest.fetchRequestMode() == WebURLRequest::FetchRequestModeCORSWithForcedPreflight) { + m_fallbackRequestForServiceWorker = ResourceRequest(request); + m_fallbackRequestForServiceWorker.setSkipServiceWorker(true); + } loadRequest(newRequest, m_resourceLoaderOptions); return; @@ -593,10 +609,6 @@ } if (response.wasFetchedViaServiceWorker()) { - // It's still possible to reach here with null m_fallbackRequestForServiceWorker - // if the request was for main resource loading (i.e. for SharedWorker), for which - // we create DocumentLoader before the controller ServiceWorker is set. - ASSERT(!m_fallbackRequestForServiceWorker.isNull() || m_requestContext == WebURLRequest::RequestContextSharedWorker); if (response.wasFallbackRequiredByServiceWorker()) { // At this point we must have m_fallbackRequestForServiceWorker. // (For SharedWorker the request won't be CORS or CORS-with-preflight,
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp index 7266759..f537aa7 100644 --- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp +++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -318,7 +318,6 @@ // Unlike raw <img>, we block mixed content inside of <picture> or <img srcset>. ResourceLoaderOptions resourceLoaderOptions = ResourceFetcher::defaultResourceOptions(); ResourceRequest resourceRequest(url); - resourceRequest.setFetchCredentialsMode(WebURLRequest::FetchCredentialsModeSameOrigin); if (updateBehavior == UpdateForcedReload) { resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadBypassingCache); resourceRequest.setLoFiState(WebURLRequest::LoFiOff);
diff --git a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp index ecfbc70..2cbc1dc 100644 --- a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp +++ b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
@@ -32,7 +32,7 @@ #include "core/events/Event.h" #include "core/events/EventListener.h" #include "core/events/EventSender.h" -#include "core/frame/UseCounter.h" +#include "core/frame/Deprecation.h" #include "core/svg/SVGDocumentExtensions.h" #include "core/svg/SVGSVGElement.h" #include "core/svg/SVGURIReference.h" @@ -326,7 +326,7 @@ if (!rootParent->inDocument()) return InsertionDone; - UseCounter::countDeprecation(document(), UseCounter::SVGSMILElementInDocument); + Deprecation::countDeprecation(document(), UseCounter::SVGSMILElementInDocument); setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr))); SVGSVGElement* owner = ownerSVGElement();
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp index 1059150..6e8d697 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -30,6 +30,7 @@ #include "core/animation/AnimationTimeline.h" #include "core/dom/NodeTraversal.h" #include "core/dom/shadow/FlatTreeTraversal.h" +#include "core/frame/Deprecation.h" #include "core/frame/FrameView.h" #include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" @@ -417,7 +418,7 @@ { if (SVGSVGElement* rootElement = svgRootElement(m_page.get())) { if (rootElement->timeContainer()->hasAnimations()) - UseCounter::countDeprecation(document, UseCounter::SVGSMILAnimationInImageRegardlessOfCache); + Deprecation::countDeprecation(document, UseCounter::SVGSMILAnimationInImageRegardlessOfCache); } }
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp index 7e662aba..3e3803e 100644 --- a/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp +++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp
@@ -32,6 +32,7 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/SerializedScriptValue.h" +#include "core/frame/Deprecation.h" #include "core/frame/LocalDOMWindow.h" #include "core/workers/DedicatedWorkerThread.h" #include "core/workers/WorkerClients.h" @@ -93,7 +94,7 @@ { ASSERT(context->isDocument()); if (m_isDeprecation) - UseCounter::countDeprecation(context, m_feature); + Deprecation::countDeprecation(context, m_feature); else UseCounter::count(context, m_feature); }
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp index fc59a51b..df55400 100644 --- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -46,12 +46,13 @@ #include "core/fetch/MemoryCache.h" #include "core/frame/DOMTimer.h" #include "core/frame/DOMTimerCoordinator.h" +#include "core/frame/Deprecation.h" +#include "core/frame/LocalDOMWindow.h" #include "core/inspector/ConsoleMessage.h" #include "core/inspector/ConsoleMessageStorage.h" #include "core/inspector/InspectorConsoleInstrumentation.h" #include "core/inspector/WorkerInspectorController.h" #include "core/loader/WorkerThreadableLoader.h" -#include "core/frame/LocalDOMWindow.h" #include "core/workers/WorkerNavigator.h" #include "core/workers/WorkerClients.h" #include "core/workers/WorkerConsole.h" @@ -354,9 +355,9 @@ // per worker lifecycle. if (!m_deprecationWarningBits.hasRecordedMeasurement(feature)) { m_deprecationWarningBits.recordMeasurement(feature); - ASSERT(!UseCounter::deprecationMessage(feature).isEmpty()); + ASSERT(!Deprecation::deprecationMessage(feature).isEmpty()); ASSERT(executionContext()); - executionContext()->addConsoleMessage(ConsoleMessage::create(DeprecationMessageSource, WarningMessageLevel, UseCounter::deprecationMessage(feature))); + executionContext()->addConsoleMessage(ConsoleMessage::create(DeprecationMessageSource, WarningMessageLevel, Deprecation::deprecationMessage(feature))); } }
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp index d52c89cb..7912da9 100644 --- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp +++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -47,8 +47,8 @@ #include "core/fileapi/File.h" #include "core/fileapi/FileReaderLoader.h" #include "core/fileapi/FileReaderLoaderClient.h" +#include "core/frame/Deprecation.h" #include "core/frame/Settings.h" -#include "core/frame/UseCounter.h" #include "core/frame/csp/ContentSecurityPolicy.h" #include "core/html/FormData.h" #include "core/html/HTMLDocument.h" @@ -535,7 +535,7 @@ // FIXME: According to XMLHttpRequest Level 2 we should throw InvalidAccessError exception here. // However for time being only print warning message to warn web developers. if (!m_async) - UseCounter::countDeprecation(executionContext(), UseCounter::SyncXHRWithCredentials); + Deprecation::countDeprecation(executionContext(), UseCounter::SyncXHRWithCredentials); m_includeCredentials = value; } @@ -608,7 +608,7 @@ // Refer : https://xhr.spec.whatwg.org/#sync-warning // Use count for XHR synchronous requests on main thread only. if (!document()->processingBeforeUnload()) - UseCounter::countDeprecation(executionContext(), UseCounter::XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload); + Deprecation::countDeprecation(executionContext(), UseCounter::XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload); } m_method = FetchUtils::normalizeMethod(method);
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp index abd7ee63..e4a79b63 100644 --- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp +++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp
@@ -5,9 +5,9 @@ #include "modules/device_orientation/DeviceMotionController.h" #include "core/dom/Document.h" +#include "core/frame/Deprecation.h" #include "core/frame/OriginsUsingFeatures.h" #include "core/frame/Settings.h" -#include "core/frame/UseCounter.h" #include "modules/EventModules.h" #include "modules/device_orientation/DeviceMotionData.h" #include "modules/device_orientation/DeviceMotionDispatcher.h" @@ -54,7 +54,7 @@ if (document().isSecureContext(errorMessage)) { UseCounter::count(document().frame(), UseCounter::DeviceMotionSecureOrigin); } else { - UseCounter::countDeprecation(document().frame(), UseCounter::DeviceMotionInsecureOrigin); + Deprecation::countDeprecation(document().frame(), UseCounter::DeviceMotionInsecureOrigin); OriginsUsingFeatures::countAnyWorld(document(), OriginsUsingFeatures::Feature::DeviceMotionInsecureOrigin); if (document().frame()->settings()->strictPowerfulFeatureRestrictions()) return;
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp index 9027b2f..cda7a481 100644 --- a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp +++ b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp
@@ -47,7 +47,7 @@ if (document().isSecureContext(errorMessage)) { UseCounter::count(document().frame(), UseCounter::DeviceOrientationAbsoluteSecureOrigin); } else { - UseCounter::countDeprecation(document().frame(), UseCounter::DeviceOrientationAbsoluteInsecureOrigin); + Deprecation::countDeprecation(document().frame(), UseCounter::DeviceOrientationAbsoluteInsecureOrigin); // TODO: add rappor logging of insecure origins as in DeviceOrientationController. if (document().frame()->settings()->strictPowerfulFeatureRestrictions()) return;
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp index 1b144e8..5a27c1f 100644 --- a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp +++ b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp
@@ -5,9 +5,9 @@ #include "modules/device_orientation/DeviceOrientationController.h" #include "core/dom/Document.h" +#include "core/frame/Deprecation.h" #include "core/frame/OriginsUsingFeatures.h" #include "core/frame/Settings.h" -#include "core/frame/UseCounter.h" #include "modules/EventModules.h" #include "modules/device_orientation/DeviceOrientationData.h" #include "modules/device_orientation/DeviceOrientationDispatcher.h" @@ -61,7 +61,7 @@ if (document().isSecureContext(errorMessage)) { UseCounter::count(document().frame(), UseCounter::DeviceOrientationSecureOrigin); } else { - UseCounter::countDeprecation(document().frame(), UseCounter::DeviceOrientationInsecureOrigin); + Deprecation::countDeprecation(document().frame(), UseCounter::DeviceOrientationInsecureOrigin); OriginsUsingFeatures::countAnyWorld(document(), OriginsUsingFeatures::Feature::DeviceOrientationInsecureOrigin); if (document().frame()->settings()->strictPowerfulFeatureRestrictions()) return;
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp index 82f0e18..a18e0255 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
@@ -9,8 +9,8 @@ #include "core/dom/DOMException.h" #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" +#include "core/frame/Deprecation.h" #include "core/frame/OriginsUsingFeatures.h" -#include "core/frame/UseCounter.h" #include "core/inspector/ConsoleMessage.h" #include "modules/encryptedmedia/EncryptedMediaUtils.h" #include "modules/encryptedmedia/MediaKeySession.h" @@ -235,7 +235,7 @@ if (executionContext->isSecureContext(errorMessage)) { UseCounter::count(executionContext, UseCounter::EncryptedMediaSecureOrigin); } else { - UseCounter::countDeprecation(executionContext, UseCounter::EncryptedMediaInsecureOrigin); + Deprecation::countDeprecation(executionContext, UseCounter::EncryptedMediaInsecureOrigin); // TODO(ddorwin): Implement the following: // Reject promise with a new DOMException whose name is NotSupportedError. }
diff --git a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp index 6d563050..6fe0bde 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp +++ b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
@@ -526,6 +526,8 @@ ResourceRequest request(m_request->url()); request.setRequestContext(m_request->context()); request.setHTTPMethod(m_request->method()); + request.setFetchRequestMode(m_request->mode()); + request.setFetchCredentialsMode(m_request->credentials()); const Vector<OwnPtr<FetchHeaderList::Header>>& list = m_request->headerList()->list(); for (size_t i = 0; i < list.size(); ++i) { request.addHTTPHeaderField(AtomicString(list[i]->first), AtomicString(list[i]->second));
diff --git a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp index 10cec9b..7b3f9e0 100644 --- a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp +++ b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
@@ -29,9 +29,9 @@ #include "core/dom/Document.h" #include "core/dom/Element.h" +#include "core/frame/Deprecation.h" #include "core/frame/OriginsUsingFeatures.h" #include "core/frame/Settings.h" -#include "core/frame/UseCounter.h" #include "core/html/HTMLFrameOwnerElement.h" #include "modules/geolocation/Coordinates.h" #include "modules/geolocation/GeolocationController.h" @@ -159,7 +159,7 @@ UseCounter::count(document, UseCounter::GeolocationSecureOrigin); UseCounter::countCrossOriginIframe(*document, UseCounter::GeolocationSecureOriginIframe); } else { - UseCounter::countDeprecation(document, UseCounter::GeolocationInsecureOrigin); + Deprecation::countDeprecation(document, UseCounter::GeolocationInsecureOrigin); UseCounter::countCrossOriginIframe(*document, UseCounter::GeolocationInsecureOriginIframe); OriginsUsingFeatures::countAnyWorld(*document, OriginsUsingFeatures::Feature::GeolocationInsecureOrigin); }
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp b/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp index 68bffa34..7a17bf6 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp +++ b/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp
@@ -30,7 +30,7 @@ #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" #include "core/events/Event.h" -#include "core/frame/UseCounter.h" +#include "core/frame/Deprecation.h" #include "modules/mediastream/MediaStream.h" #include "modules/mediastream/MediaStreamTrackSourcesCallback.h" #include "modules/mediastream/MediaStreamTrackSourcesRequestImpl.h" @@ -145,7 +145,7 @@ exceptionState.throwDOMException(NotSupportedError, "No sources controller available; is this a detached window?"); return; } - UseCounter::countDeprecation(context, UseCounter::MediaStreamTrackGetSources); + Deprecation::countDeprecation(context, UseCounter::MediaStreamTrackGetSources); MediaStreamTrackSourcesRequest* request = MediaStreamTrackSourcesRequestImpl::create(*context, callback); userMedia->requestSources(request); }
diff --git a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp index 854a5bab..d97557f 100644 --- a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp +++ b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp
@@ -39,8 +39,8 @@ #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" +#include "core/frame/Deprecation.h" #include "core/frame/LocalFrame.h" -#include "core/frame/UseCounter.h" #include "core/html/VoidCallback.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" @@ -395,7 +395,7 @@ if (errorCallback) UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyFailureCallback); else - UseCounter::countDeprecation(context, UseCounter::RTCPeerConnectionCreateOfferLegacyNoFailureCallback); + Deprecation::countDeprecation(context, UseCounter::RTCPeerConnectionCreateOfferLegacyNoFailureCallback); if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) return; @@ -437,7 +437,7 @@ if (errorCallback) UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyFailureCallback); else - UseCounter::countDeprecation(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyNoFailureCallback); + Deprecation::countDeprecation(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyNoFailureCallback); if (mediaConstraints.isObject()) UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyConstraints);
diff --git a/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp b/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp index 4312927..ca03444 100644 --- a/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp +++ b/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
@@ -37,7 +37,7 @@ #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" #include "core/dom/SpaceSplitString.h" -#include "core/frame/UseCounter.h" +#include "core/frame/Deprecation.h" #include "modules/mediastream/MediaConstraintsImpl.h" #include "modules/mediastream/MediaStream.h" #include "modules/mediastream/MediaStreamConstraints.h" @@ -132,7 +132,7 @@ // While getUserMedia is blocked on insecure origins, we still want to // count attempts to use it. - UseCounter::countDeprecation(document->frame(), UseCounter::GetUserMediaInsecureOrigin); + Deprecation::countDeprecation(document->frame(), UseCounter::GetUserMediaInsecureOrigin); UseCounter::countCrossOriginIframe(*document, UseCounter::GetUserMediaInsecureOriginIframe); OriginsUsingFeatures::countAnyWorld(*document, OriginsUsingFeatures::Feature::GetUserMediaInsecureOrigin); return false;
diff --git a/third_party/WebKit/Source/platform/CrossThreadCopier.h b/third_party/WebKit/Source/platform/CrossThreadCopier.h index 73f169c..fc5af66 100644 --- a/third_party/WebKit/Source/platform/CrossThreadCopier.h +++ b/third_party/WebKit/Source/platform/CrossThreadCopier.h
@@ -44,194 +44,194 @@ namespace blink { - class IntRect; - class IntSize; - class KURL; - class ResourceError; - class ResourceRequest; - class ResourceResponse; - struct CrossThreadResourceResponseData; - struct CrossThreadResourceRequestData; +class IntRect; +class IntSize; +class KURL; +class ResourceError; +class ResourceRequest; +class ResourceResponse; +struct CrossThreadResourceResponseData; +struct CrossThreadResourceRequestData; - template<typename T> struct CrossThreadCopierPassThrough { - STATIC_ONLY(CrossThreadCopierPassThrough); - typedef T Type; - static Type copy(const T& parameter) - { - return parameter; - } - }; - - template<bool isConvertibleToInteger, bool isThreadSafeRefCounted, bool isGarbageCollected, typename T> struct CrossThreadCopierBase; - - // Integers get passed through without any changes. - template<typename T> struct CrossThreadCopierBase<true, false, false, T> : public CrossThreadCopierPassThrough<T> { - STATIC_ONLY(CrossThreadCopierBase); - }; - - // nullptr_t can be passed through without any changes. - template<> struct CrossThreadCopierBase<false, false, false, std::nullptr_t> : public CrossThreadCopierPassThrough<std::nullptr_t> { - STATIC_ONLY(CrossThreadCopierBase); - }; - - // To allow a type to be passed across threads using its copy constructor, add a forward declaration of the type and - // a CopyThreadCopierBase<false, false, TypeName> : public CrossThreadCopierPassThrough<TypeName> { }; to this file. - template<> struct CrossThreadCopierBase<false, false, false, IntRect> : public CrossThreadCopierPassThrough<IntRect> { - STATIC_ONLY(CrossThreadCopierBase); - }; - - template<> struct CrossThreadCopierBase<false, false, false, IntSize> : public CrossThreadCopierPassThrough<IntSize> { - STATIC_ONLY(CrossThreadCopierBase); - }; - - // Custom copy methods. - template<typename T> struct CrossThreadCopierBase<false, true, false, T> { - STATIC_ONLY(CrossThreadCopierBase); - typedef typename WTF::RemoveTemplate<T, RefPtr>::Type TypeWithoutRefPtr; - typedef typename WTF::RemoveTemplate<TypeWithoutRefPtr, PassRefPtr>::Type TypeWithoutPassRefPtr; - typedef typename std::remove_pointer<TypeWithoutPassRefPtr>::type RefCountedType; - - // Verify that only one of the above did a change. - static_assert((std::is_same<RefPtr<RefCountedType>, T>::value - || std::is_same<PassRefPtr<RefCountedType>, T>::value - || std::is_same<RefCountedType*, T>::value), - "only one type modification should be allowed"); - - typedef PassRefPtr<RefCountedType> Type; - static Type copy(const T& refPtr) - { - return refPtr; - } - }; - - template<typename T> struct CrossThreadCopierBase<false, false, false, PassOwnPtr<T>> { - STATIC_ONLY(CrossThreadCopierBase); - typedef PassOwnPtr<T> Type; - static Type copy(Type ownPtr) - { - return ownPtr; - } - }; - - template<typename T> struct CrossThreadCopierBase<false, false, false, WeakMember<T>*> { - STATIC_ONLY(CrossThreadCopierBase); - typedef WeakMember<T>* Type; - static Type copy(Type ptr) - { - return ptr; - } - }; - - template<> struct CrossThreadCopierBase<false, false, false, KURL> { - STATIC_ONLY(CrossThreadCopierBase); - typedef KURL Type; - PLATFORM_EXPORT static Type copy(const KURL&); - }; - - template<> struct CrossThreadCopierBase<false, false, false, String> { - STATIC_ONLY(CrossThreadCopierBase); - typedef String Type; - PLATFORM_EXPORT static Type copy(const String&); - }; - - template<> struct CrossThreadCopierBase<false, false, false, ResourceError> { - STATIC_ONLY(CrossThreadCopierBase); - typedef ResourceError Type; - PLATFORM_EXPORT static Type copy(const ResourceError&); - }; - - template<> struct CrossThreadCopierBase<false, false, false, ResourceRequest> { - STATIC_ONLY(CrossThreadCopierBase); - typedef PassOwnPtr<CrossThreadResourceRequestData> Type; - PLATFORM_EXPORT static Type copy(const ResourceRequest&); - }; - - template<> struct CrossThreadCopierBase<false, false, false, ResourceResponse> { - STATIC_ONLY(CrossThreadCopierBase); - typedef PassOwnPtr<CrossThreadResourceResponseData> Type; - PLATFORM_EXPORT static Type copy(const ResourceResponse&); - }; - - template<typename T> struct CrossThreadCopierBase<false, false, true, T> { - STATIC_ONLY(CrossThreadCopierBase); - typedef typename std::remove_pointer<T>::type TypeWithoutPointer; - typedef RawPtr<TypeWithoutPointer> Type; - static Type copy(const T& ptr) - { - return ptr; - } - }; - - template<typename T> struct CrossThreadCopierBase<false, false, true, RawPtr<T>> { - STATIC_ONLY(CrossThreadCopierBase); - typedef RawPtr<T> Type; - static Type copy(const Type& ptr) - { - return ptr; - } - }; - - template<typename T> struct CrossThreadCopierBase<false, false, true, Member<T>> { - STATIC_ONLY(CrossThreadCopierBase); - typedef RawPtr<T> Type; - static Type copy(const Member<T>& ptr) - { - return ptr; - } - }; - - template<typename T> struct CrossThreadCopierBase<false, false, true, WeakMember<T>> { - STATIC_ONLY(CrossThreadCopierBase); - typedef RawPtr<T> Type; - static Type copy(const WeakMember<T>& ptr) - { - return ptr; - } - }; - - template<typename T> struct CrossThreadCopier : public CrossThreadCopierBase<std::is_convertible<T, int>::value, - WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, RefPtr>::Type, ThreadSafeRefCounted>::value - || WTF::IsSubclassOfTemplate<typename std::remove_pointer<T>::type, ThreadSafeRefCounted>::value - || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, PassRefPtr>::Type, ThreadSafeRefCounted>::value, - WTF::IsSubclassOfTemplate<typename std::remove_pointer<T>::type, GarbageCollected>::value - || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, RawPtr>::Type, GarbageCollected>::value - || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, Member>::Type, GarbageCollected>::value - || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, WeakMember>::Type, GarbageCollected>::value, - T> { - STATIC_ONLY(CrossThreadCopier); - }; - - // |T| is |C*| or |const WeakPtr<C>&|. - template<typename T> struct AllowCrossThreadAccessWrapper { - STACK_ALLOCATED(); - public: - explicit AllowCrossThreadAccessWrapper(T value) : m_value(value) { } - T value() const { return m_value; } - private: - // This raw pointer is safe since AllowCrossThreadAccessWrapper is - // always stack-allocated. Ideally this should be Member<T> if T is - // garbage-collected and T* otherwise, but we don't want to introduce - // another template magic just for distinguishing Member<T> from T*. - // From the perspective of GC, T* always works correctly. - GC_PLUGIN_IGNORE("") - T m_value; - }; - - template<typename T> struct CrossThreadCopierBase<false, false, false, AllowCrossThreadAccessWrapper<T>> { - STATIC_ONLY(CrossThreadCopierBase); - typedef T Type; - static Type copy(const AllowCrossThreadAccessWrapper<T>& wrapper) { return wrapper.value(); } - }; - - template<typename T> AllowCrossThreadAccessWrapper<T*> AllowCrossThreadAccess(T* value) +template<typename T> struct CrossThreadCopierPassThrough { + STATIC_ONLY(CrossThreadCopierPassThrough); + typedef T Type; + static Type copy(const T& parameter) { - return AllowCrossThreadAccessWrapper<T*>(value); + return parameter; } +}; - template<typename T> AllowCrossThreadAccessWrapper<const WeakPtr<T>&> AllowCrossThreadAccess(const WeakPtr<T>& value) +template<bool isConvertibleToInteger, bool isThreadSafeRefCounted, bool isGarbageCollected, typename T> struct CrossThreadCopierBase; + +// Integers get passed through without any changes. +template<typename T> struct CrossThreadCopierBase<true, false, false, T> : public CrossThreadCopierPassThrough<T> { + STATIC_ONLY(CrossThreadCopierBase); +}; + +// nullptr_t can be passed through without any changes. +template<> struct CrossThreadCopierBase<false, false, false, std::nullptr_t> : public CrossThreadCopierPassThrough<std::nullptr_t> { + STATIC_ONLY(CrossThreadCopierBase); +}; + +// To allow a type to be passed across threads using its copy constructor, add a forward declaration of the type and +// a CopyThreadCopierBase<false, false, TypeName> : public CrossThreadCopierPassThrough<TypeName> { }; to this file. +template<> struct CrossThreadCopierBase<false, false, false, IntRect> : public CrossThreadCopierPassThrough<IntRect> { + STATIC_ONLY(CrossThreadCopierBase); +}; + +template<> struct CrossThreadCopierBase<false, false, false, IntSize> : public CrossThreadCopierPassThrough<IntSize> { + STATIC_ONLY(CrossThreadCopierBase); +}; + +// Custom copy methods. +template<typename T> struct CrossThreadCopierBase<false, true, false, T> { + STATIC_ONLY(CrossThreadCopierBase); + typedef typename WTF::RemoveTemplate<T, RefPtr>::Type TypeWithoutRefPtr; + typedef typename WTF::RemoveTemplate<TypeWithoutRefPtr, PassRefPtr>::Type TypeWithoutPassRefPtr; + typedef typename std::remove_pointer<TypeWithoutPassRefPtr>::type RefCountedType; + + // Verify that only one of the above did a change. + static_assert((std::is_same<RefPtr<RefCountedType>, T>::value + || std::is_same<PassRefPtr<RefCountedType>, T>::value + || std::is_same<RefCountedType*, T>::value), + "only one type modification should be allowed"); + + typedef PassRefPtr<RefCountedType> Type; + static Type copy(const T& refPtr) { - return AllowCrossThreadAccessWrapper<const WeakPtr<T>&>(value); + return refPtr; } +}; + +template<typename T> struct CrossThreadCopierBase<false, false, false, PassOwnPtr<T>> { + STATIC_ONLY(CrossThreadCopierBase); + typedef PassOwnPtr<T> Type; + static Type copy(Type ownPtr) + { + return ownPtr; + } +}; + +template<typename T> struct CrossThreadCopierBase<false, false, false, WeakMember<T>*> { + STATIC_ONLY(CrossThreadCopierBase); + typedef WeakMember<T>* Type; + static Type copy(Type ptr) + { + return ptr; + } +}; + +template<> struct CrossThreadCopierBase<false, false, false, KURL> { + STATIC_ONLY(CrossThreadCopierBase); + typedef KURL Type; + PLATFORM_EXPORT static Type copy(const KURL&); +}; + +template<> struct CrossThreadCopierBase<false, false, false, String> { + STATIC_ONLY(CrossThreadCopierBase); + typedef String Type; + PLATFORM_EXPORT static Type copy(const String&); +}; + +template<> struct CrossThreadCopierBase<false, false, false, ResourceError> { + STATIC_ONLY(CrossThreadCopierBase); + typedef ResourceError Type; + PLATFORM_EXPORT static Type copy(const ResourceError&); +}; + +template<> struct CrossThreadCopierBase<false, false, false, ResourceRequest> { + STATIC_ONLY(CrossThreadCopierBase); + typedef PassOwnPtr<CrossThreadResourceRequestData> Type; + PLATFORM_EXPORT static Type copy(const ResourceRequest&); +}; + +template<> struct CrossThreadCopierBase<false, false, false, ResourceResponse> { + STATIC_ONLY(CrossThreadCopierBase); + typedef PassOwnPtr<CrossThreadResourceResponseData> Type; + PLATFORM_EXPORT static Type copy(const ResourceResponse&); +}; + +template<typename T> struct CrossThreadCopierBase<false, false, true, T> { + STATIC_ONLY(CrossThreadCopierBase); + typedef typename std::remove_pointer<T>::type TypeWithoutPointer; + typedef RawPtr<TypeWithoutPointer> Type; + static Type copy(const T& ptr) + { + return ptr; + } +}; + +template<typename T> struct CrossThreadCopierBase<false, false, true, RawPtr<T>> { + STATIC_ONLY(CrossThreadCopierBase); + typedef RawPtr<T> Type; + static Type copy(const Type& ptr) + { + return ptr; + } +}; + +template<typename T> struct CrossThreadCopierBase<false, false, true, Member<T>> { + STATIC_ONLY(CrossThreadCopierBase); + typedef RawPtr<T> Type; + static Type copy(const Member<T>& ptr) + { + return ptr; + } +}; + +template<typename T> struct CrossThreadCopierBase<false, false, true, WeakMember<T>> { + STATIC_ONLY(CrossThreadCopierBase); + typedef RawPtr<T> Type; + static Type copy(const WeakMember<T>& ptr) + { + return ptr; + } +}; + +template<typename T> struct CrossThreadCopier : public CrossThreadCopierBase<std::is_convertible<T, int>::value, + WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, RefPtr>::Type, ThreadSafeRefCounted>::value + || WTF::IsSubclassOfTemplate<typename std::remove_pointer<T>::type, ThreadSafeRefCounted>::value + || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, PassRefPtr>::Type, ThreadSafeRefCounted>::value, + WTF::IsSubclassOfTemplate<typename std::remove_pointer<T>::type, GarbageCollected>::value + || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, RawPtr>::Type, GarbageCollected>::value + || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, Member>::Type, GarbageCollected>::value + || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, WeakMember>::Type, GarbageCollected>::value, + T> { + STATIC_ONLY(CrossThreadCopier); +}; + +// |T| is |C*| or |const WeakPtr<C>&|. +template<typename T> struct AllowCrossThreadAccessWrapper { + STACK_ALLOCATED(); +public: + explicit AllowCrossThreadAccessWrapper(T value) : m_value(value) { } + T value() const { return m_value; } +private: + // This raw pointer is safe since AllowCrossThreadAccessWrapper is + // always stack-allocated. Ideally this should be Member<T> if T is + // garbage-collected and T* otherwise, but we don't want to introduce + // another template magic just for distinguishing Member<T> from T*. + // From the perspective of GC, T* always works correctly. + GC_PLUGIN_IGNORE("") + T m_value; +}; + +template<typename T> struct CrossThreadCopierBase<false, false, false, AllowCrossThreadAccessWrapper<T>> { + STATIC_ONLY(CrossThreadCopierBase); + typedef T Type; + static Type copy(const AllowCrossThreadAccessWrapper<T>& wrapper) { return wrapper.value(); } +}; + +template<typename T> AllowCrossThreadAccessWrapper<T*> AllowCrossThreadAccess(T* value) +{ + return AllowCrossThreadAccessWrapper<T*>(value); +} + +template<typename T> AllowCrossThreadAccessWrapper<const WeakPtr<T>&> AllowCrossThreadAccess(const WeakPtr<T>& value) +{ + return AllowCrossThreadAccessWrapper<const WeakPtr<T>&>(value); +} } // namespace blink
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi index d080b17..8feb02bb 100644 --- a/third_party/WebKit/Source/platform/blink_platform.gypi +++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -388,6 +388,8 @@ 'exported/WrappedResourceResponse.h', 'exported/linux/WebFontInfo.cpp', 'exported/linux/WebFontRenderStyle.cpp', + 'fonts/AcceptLanguagesResolver.cpp', + 'fonts/AcceptLanguagesResolver.h', 'fonts/AlternateFontFamily.h', 'fonts/Character.cpp', 'fonts/Character.h', @@ -1106,6 +1108,7 @@ 'animation/CompositorFloatAnimationCurveTest.cpp', 'blob/BlobDataTest.cpp', 'clipboard/ClipboardUtilitiesTest.cpp', + 'fonts/AcceptLanguagesResolverTest.cpp', 'fonts/CharacterTest.cpp', 'fonts/FontCacheTest.cpp', 'fonts/FontDescriptionTest.cpp',
diff --git a/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolver.cpp b/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolver.cpp new file mode 100644 index 0000000..dd675167 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolver.cpp
@@ -0,0 +1,78 @@ +// 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 "platform/fonts/AcceptLanguagesResolver.h" + +#include "platform/Language.h" +#include "platform/text/LocaleToScriptMapping.h" +#include <unicode/locid.h> + +namespace blink { + +UScriptCode AcceptLanguagesResolver::m_preferredHanScript = USCRIPT_COMMON; +const char* AcceptLanguagesResolver::m_preferredHanSkFontMgrLocale = nullptr; + +// SkFontMgr requires script-based locale names, like "zh-Hant" and "zh-Hans", +// instead of "zh-CN" and "zh-TW". +static const char* toSkFontMgrLocaleForHan(UScriptCode script) +{ + switch (script) { + case USCRIPT_KATAKANA_OR_HIRAGANA: + return "ja-jp"; + case USCRIPT_HANGUL: + return "ko-kr"; + case USCRIPT_SIMPLIFIED_HAN: + return "zh-Hans"; + case USCRIPT_TRADITIONAL_HAN: + return "zh-Hant"; + default: + ASSERT_NOT_REACHED(); + return nullptr; + } +} + +void AcceptLanguagesResolver::acceptLanguagesChanged( + const String& acceptLanguages) +{ + // Use the UI locale if it can disambiguate the Unified Han. + // Historically we use ICU on Windows. crbug.com/586520 +#if OS(WIN) + // Since Chrome synchronizes the ICU default locale with its UI locale, + // this ICU locale tells the current UI locale of Chrome. + m_preferredHanScript = scriptCodeForHanFromLocale( + icu::Locale::getDefault().getName(), '_'); +#else + m_preferredHanScript = scriptCodeForHanFromLocale(defaultLanguage()); +#endif + if (m_preferredHanScript != USCRIPT_COMMON) { + // We don't need additional locale if defaultLanguage() can disambiguate + // since it's always passed to matchFamilyStyleCharacter() separately. + m_preferredHanSkFontMgrLocale = nullptr; + return; + } + + updateFromAcceptLanguages(acceptLanguages); +} + +void AcceptLanguagesResolver::updateFromAcceptLanguages( + const String& acceptLanguages) +{ + // Use the first acceptLanguages that can disambiguate. + Vector<String> languages; + acceptLanguages.split(',', languages); + for (String token : languages) { + token = token.stripWhiteSpace(); + m_preferredHanScript = scriptCodeForHanFromLocale(token); + if (m_preferredHanScript != USCRIPT_COMMON) { + m_preferredHanSkFontMgrLocale = toSkFontMgrLocaleForHan( + m_preferredHanScript); + return; + } + } + + m_preferredHanScript = USCRIPT_COMMON; + m_preferredHanSkFontMgrLocale = nullptr; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolver.h b/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolver.h new file mode 100644 index 0000000..c643d5e --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolver.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 AcceptLanguagesResolver_h +#define AcceptLanguagesResolver_h + +#include "platform/PlatformExport.h" +#include "wtf/text/WTFString.h" + +#include <unicode/uscript.h> + +namespace blink { + +class PLATFORM_EXPORT AcceptLanguagesResolver { +public: + static UScriptCode preferredHanScript() { return m_preferredHanScript; } + static const char* preferredHanSkFontMgrLocale() + { + return m_preferredHanSkFontMgrLocale; + } + + static void acceptLanguagesChanged(const String&); + + static void updateFromAcceptLanguages(const String&); + +private: + static UScriptCode m_preferredHanScript; + static const char* m_preferredHanSkFontMgrLocale; +}; + +} // namespace blink + +#endif // AcceptLanguagesResolver_h
diff --git a/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolverTest.cpp b/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolverTest.cpp new file mode 100644 index 0000000..94f636e --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/AcceptLanguagesResolverTest.cpp
@@ -0,0 +1,53 @@ +// 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 "platform/fonts/AcceptLanguagesResolver.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(AcceptLanguagesResolverTest, AcceptLanguagesChanged) +{ + struct { + const char* acceptLanguages; + UScriptCode script; + const char* locale; + } tests[] = { + // Non-Han script cases. + { "", USCRIPT_COMMON, nullptr }, + { "en-US", USCRIPT_COMMON, nullptr }, + { ",en-US", USCRIPT_COMMON, nullptr }, + + // Single value cases. + { "ja-JP", USCRIPT_KATAKANA_OR_HIRAGANA, "ja-jp" }, + { "ko-KR", USCRIPT_HANGUL, "ko-kr" }, + { "zh-CN", USCRIPT_SIMPLIFIED_HAN, "zh-Hans" }, + { "zh-HK", USCRIPT_TRADITIONAL_HAN, "zh-Hant" }, + { "zh-TW", USCRIPT_TRADITIONAL_HAN, "zh-Hant" }, + + // Unusual combinations. + { "en-JP", USCRIPT_KATAKANA_OR_HIRAGANA, "ja-jp" }, + + // Han scripts not in the first item. + { "en-US,ja-JP", USCRIPT_KATAKANA_OR_HIRAGANA, "ja-jp" }, + { "en-US,en-JP", USCRIPT_KATAKANA_OR_HIRAGANA, "ja-jp" }, + + // Multiple Han scripts. The first one wins. + { "ja-JP,zh-CN", USCRIPT_KATAKANA_OR_HIRAGANA, "ja-jp" }, + { "zh-TW,ja-JP", USCRIPT_TRADITIONAL_HAN, "zh-Hant" }, + }; + + for (auto& test : tests) { + AcceptLanguagesResolver::updateFromAcceptLanguages(test.acceptLanguages); + + EXPECT_EQ(test.script, AcceptLanguagesResolver::preferredHanScript()) + << test.acceptLanguages; + EXPECT_STREQ(test.locale, + AcceptLanguagesResolver::preferredHanSkFontMgrLocale()) + << test.acceptLanguages; + } +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/FontCache.cpp b/third_party/WebKit/Source/platform/fonts/FontCache.cpp index 649e475b..d2b7c7c 100644 --- a/third_party/WebKit/Source/platform/fonts/FontCache.cpp +++ b/third_party/WebKit/Source/platform/fonts/FontCache.cpp
@@ -33,6 +33,7 @@ #include "platform/Histogram.h" #include "platform/RuntimeEnabledFeatures.h" +#include "platform/fonts/AcceptLanguagesResolver.h" #include "platform/fonts/AlternateFontFamily.h" #include "platform/fonts/FontCacheClient.h" #include "platform/fonts/FontCacheKey.h" @@ -161,6 +162,11 @@ return verticalData; } +void FontCache::acceptLanguagesChanged(const String& acceptLanguages) +{ + AcceptLanguagesResolver::acceptLanguagesChanged(acceptLanguages); +} + static FontDataCache* gFontDataCache = 0; PassRefPtr<SimpleFontData> FontCache::getFontData(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName, ShouldRetain shouldRetain)
diff --git a/third_party/WebKit/Source/platform/fonts/android/FontCacheAndroid.cpp b/third_party/WebKit/Source/platform/fonts/android/FontCacheAndroid.cpp index 335b243f..4a552100 100644 --- a/third_party/WebKit/Source/platform/fonts/android/FontCacheAndroid.cpp +++ b/third_party/WebKit/Source/platform/fonts/android/FontCacheAndroid.cpp
@@ -31,6 +31,7 @@ #include "platform/fonts/FontCache.h" #include "platform/Language.h" +#include "platform/fonts/AcceptLanguagesResolver.h" #include "platform/fonts/SimpleFontData.h" #include "platform/fonts/FontDescription.h" #include "platform/fonts/FontFaceCreationParams.h" @@ -57,16 +58,13 @@ } } -void FontCache::acceptLanguagesChanged(const String&) -{ - // TODO(kojii): Take acceptLanguages into account for ambiguos scripts. -} - static AtomicString getFamilyNameForCharacter(UChar32 c, const FontDescription& fontDescription) { RefPtr<SkFontMgr> fm = adoptRef(SkFontMgr::RefDefault()); - const char* bcp47Locales[2]; + const char* bcp47Locales[3]; int localeCount = 0; + if (const char* hanLocale = AcceptLanguagesResolver::preferredHanSkFontMgrLocale()) + bcp47Locales[localeCount++] = hanLocale; CString defaultLocale = toSkFontMgrLocale(defaultLanguage()); bcp47Locales[localeCount++] = defaultLocale.data(); CString fontLocale;
diff --git a/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp b/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp index fe9ae67f..70493006 100644 --- a/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp +++ b/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp
@@ -32,8 +32,6 @@ namespace blink { -void FontCache::acceptLanguagesChanged(const String&) {} - void FontCache::getFontForCharacter(UChar32 c, const char* preferredLocale, FontCache::PlatformFallbackFont* fallbackFont) { WebFallbackFont webFallbackFont;
diff --git a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm index 159b06d1..629b7eb 100644 --- a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm +++ b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
@@ -96,8 +96,6 @@ return appKitFontWeight >= 7; } -void FontCache::acceptLanguagesChanged(const String&) {} - PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 character, const SimpleFontData* fontDataToSubstitute) { // FIXME: We should fix getFallbackFamily to take a UChar32
diff --git a/third_party/WebKit/Source/platform/fonts/win/FontCacheSkiaWin.cpp b/third_party/WebKit/Source/platform/fonts/win/FontCacheSkiaWin.cpp index 9e2f761..3945eda 100644 --- a/third_party/WebKit/Source/platform/fonts/win/FontCacheSkiaWin.cpp +++ b/third_party/WebKit/Source/platform/fonts/win/FontCacheSkiaWin.cpp
@@ -112,11 +112,6 @@ m_fontManager = adoptPtr(fontManager); } -void FontCache::acceptLanguagesChanged(const String&) -{ - // TODO(kojii): Take acceptLanguages into account for ambiguos scripts. -} - // Given the desired base font, this will create a SimpleFontData for a specific // font that can be used to render the given range of characters. PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(
diff --git a/third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp b/third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp index 0ff4e29e..ed479845 100644 --- a/third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp +++ b/third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp
@@ -30,6 +30,7 @@ #include "platform/fonts/win/FontFallbackWin.h" +#include "platform/fonts/AcceptLanguagesResolver.h" #include "platform/fonts/FontCache.h" #include "SkFontMgr.h" #include "SkTypeface.h" @@ -230,6 +231,19 @@ scriptFontMap[USCRIPT_HAN] = localeFamily; } +static UScriptCode scriptForHan(UScriptCode contentScript, + const AtomicString& contentLocale) +{ + UScriptCode script = scriptCodeForHanFromLocale(contentScript, contentLocale); + if (script != USCRIPT_COMMON) + return script; + script = AcceptLanguagesResolver::preferredHanScript(); + if (script != USCRIPT_COMMON) + return script; + // Use UI locale. See initializeScriptFontMap(). + return USCRIPT_HAN; +} + // There are a lot of characters in USCRIPT_COMMON that can be covered // by fonts for scripts closely related to them. See // http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:Script=Common:] @@ -408,13 +422,10 @@ if (script == USCRIPT_COMMON) script = getScriptBasedOnUnicodeBlock(character); - // For unified-Han scripts, try the lang attribute. - if (script == USCRIPT_HAN) { - script = scriptCodeForHanFromLocale(contentScript, contentLocale); - // Use the UI locale if it is still ambiguous. - if (script == USCRIPT_COMMON) - script = USCRIPT_SIMPLIFIED_HAN; - } + // For unified-Han scripts, try the lang attribute, system, or + // accept-languages. + if (script == USCRIPT_HAN) + script = scriptForHan(contentScript, contentLocale); family = getFontFamilyForScript(script, generic, fontManager); // Another lame work-around to cover non-BMP characters.
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp index 8a414e3e..7f7e19e 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.cpp +++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -52,6 +52,9 @@ namespace blink { +HeapAllocHooks::AllocationHook* HeapAllocHooks::m_allocationHook = nullptr; +HeapAllocHooks::FreeHook* HeapAllocHooks::m_freeHook = nullptr; + class GCForbiddenScope final { DISALLOW_NEW(); public:
diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h index 34f76741..ece92ca 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.h +++ b/third_party/WebKit/Source/platform/heap/Heap.h
@@ -45,6 +45,45 @@ namespace blink { +class PLATFORM_EXPORT HeapAllocHooks { +public: + // TODO(hajimehoshi): Pass a type name of the allocated object. + typedef void AllocationHook(Address, size_t); + typedef void FreeHook(Address); + + static void setAllocationHook(AllocationHook* hook) { m_allocationHook = hook; } + static void setFreeHook(FreeHook* hook) { m_freeHook = hook; } + + static void allocationHookIfEnabled(Address address, size_t size) + { + AllocationHook* allocationHook = m_allocationHook; + if (UNLIKELY(!!allocationHook)) + allocationHook(address, size); + } + + static void freeHookIfEnabled(Address address) + { + FreeHook* freeHook = m_freeHook; + if (UNLIKELY(!!freeHook)) + freeHook(address); + } + + static void reallocHookIfEnabled(Address oldAddress, Address newAddress, size_t size) + { + // Report a reallocation as a free followed by an allocation. + AllocationHook* allocationHook = m_allocationHook; + FreeHook* freeHook = m_freeHook; + if (UNLIKELY(allocationHook && freeHook)) { + freeHook(oldAddress); + allocationHook(newAddress, size); + } + } + +private: + static AllocationHook* m_allocationHook; + static FreeHook* m_freeHook; +}; + class CrossThreadPersistentRegion; template<typename T> class Member; template<typename T> class WeakMember; @@ -456,7 +495,9 @@ Address Heap::allocate(size_t size, bool eagerlySweep) { ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); - return Heap::allocateOnHeapIndex(state, size, eagerlySweep ? BlinkGC::EagerSweepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::index()); + Address address = Heap::allocateOnHeapIndex(state, size, eagerlySweep ? BlinkGC::EagerSweepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::index()); + HeapAllocHooks::allocationHookIfEnabled(address, size); + return address; } template<typename T> @@ -489,6 +530,7 @@ if (copySize > size) copySize = size; memcpy(address, previous, copySize); + HeapAllocHooks::reallocHookIfEnabled(static_cast<Address>(previous), address, size); return address; }
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp index e9dcbe1..5fb397c1 100644 --- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp +++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -98,6 +98,7 @@ void HeapObjectHeader::finalize(Address object, size_t objectSize) { + HeapAllocHooks::freeHookIfEnabled(object); const GCInfo* gcInfo = Heap::gcInfo(gcInfoIndex()); if (gcInfo->hasFinalizer()) gcInfo->m_finalize(object);
diff --git a/third_party/WebKit/Source/platform/network/ResourceRequest.cpp b/third_party/WebKit/Source/platform/network/ResourceRequest.cpp index 24fa32ae5..3601422 100644 --- a/third_party/WebKit/Source/platform/network/ResourceRequest.cpp +++ b/third_party/WebKit/Source/platform/network/ResourceRequest.cpp
@@ -429,10 +429,7 @@ m_requestContext = WebURLRequest::RequestContextUnspecified; m_frameType = WebURLRequest::FrameTypeNone; m_fetchRequestMode = WebURLRequest::FetchRequestModeNoCORS; - // Contrary to the Fetch spec, we default to same-origin mode here, and deal - // with CORS modes in updateRequestForAccessControl if we're called in a - // context which requires it. - m_fetchCredentialsMode = WebURLRequest::FetchCredentialsModeSameOrigin; + m_fetchCredentialsMode = WebURLRequest::FetchCredentialsModeInclude; m_fetchRedirectMode = WebURLRequest::FetchRedirectModeFollow; m_referrerPolicy = ReferrerPolicyDefault; m_loFiState = WebURLRequest::LoFiUnspecified;
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 5d4f1d8..93a1057 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -18738,6 +18738,18 @@ </summary> </histogram> +<histogram name="Media.Audio.AudioUnitRenderHasWorkedMac" + enum="BooleanEverWorked"> + <owner>henrika@chromium.org</owner> + <summary> + Stored in combination with Media.Audio.RenderFailsWhenBufferSizeChangesMac. + It is set to true if calls to AudioUnitRender has ever worked, i.e., we did + not start to see kAudioUnitErr_CannotDoInCurrentContext error messages + directly from start but there has been at least on successful call to + AudioUnitRender. + </summary> +</histogram> + <histogram name="Media.Audio.AutomaticGainControlMac" enum="BooleanEnabled"> <owner>henrika@chromium.org</owner> <summary> @@ -18837,6 +18849,17 @@ </summary> </histogram> +<histogram name="Media.Audio.RenderFailsWhenBufferSizeChangesMac" + enum="BooleanChanged"> + <owner>henrika@chromium.org</owner> + <summary> + True if a call to AudioUnitRender failed with an error code of + kAudioUnitErr_CannotDoInCurrentContext (-10863) and the call was preceded + with a change in the native I/O buffer size. This value is logged while + input audio is active but it should be a very rare event. + </summary> +</histogram> + <histogram name="Media.Audio.RequestedInputBufferFrameSizeMac"> <owner>henrika@chromium.org</owner> <summary> @@ -26930,6 +26953,15 @@ </summary> </histogram> +<histogram name="Net.ResourceLoader.InliningStatus" + enum="ResourceLoaderInliningStatus"> + <owner>tzik@chromium.org</owner> + <summary> + Counts whether the chunk inlining is applicable or not to a resource + loading. Counts the reason if inapplicable. + </summary> +</histogram> + <histogram name="Net.ResourceLoader.ReadDeferral" units="ms"> <owner>clamy@chromium.org</owner> <summary> @@ -58638,6 +58670,11 @@ <int value="1" label="Can check"/> </enum> +<enum name="BooleanChanged" type="int"> + <int value="0" label="Not changed"/> + <int value="1" label="Changed"/> +</enum> + <enum name="BooleanCloseTimeout" type="int"> <int value="0" label="Closed normally"/> <int value="1" label="Timed out"/> @@ -58738,6 +58775,11 @@ <int value="1" label="Error"/> </enum> +<enum name="BooleanEverWorked" type="int"> + <int value="0" label="Has never worked"/> + <int value="1" label="Has worked at least once"/> +</enum> + <enum name="BooleanExpired" type="int"> <int value="0" label="Unexpired"/> <int value="1" label="Expired"/> @@ -77054,6 +77096,15 @@ <int value="1" label="Has client"/> </enum> +<enum name="ResourceLoaderInliningStatus" type="int"> + <int value="0" label="Applicable"/> + <int value="1" label="EarlyAllocation"/> + <int value="2" label="UnknownContentLength"/> + <int value="3" label="LargeContent"/> + <int value="4" label="HasTransferEncoding"/> + <int value="5" label="HasContentEncoding"/> +</enum> + <enum name="ResourcePrefetchPredictorMainFrameRequestStats" type="int"> <int value="0" label="MAIN_FRAME_REQUEST_STATS_TOTAL_REQUESTS"/> <int value="1" label="MAIN_FRAME_REQUEST_STATS_PROCESSED_REQUESTS"/> @@ -86880,6 +86931,8 @@ <suffix name="LT_512kB" label="Sliced for resources smaller than 512kB and larger than 32kB."/> <suffix name="Over_512kB" label="Sliced for resources larger than 512kB."/> + <suffix name="InliningApplicable" + label="Resources that the chunk inlining is applicable."/> <affected-histogram name="Net.ResourceLoader.ResponseStartToEnd"/> </histogram_suffixes>
diff --git a/tools/perf/profile_creators/extension_profile_extender_unittest.py b/tools/perf/profile_creators/extension_profile_extender_unittest.py index 08beec9..6049872 100644 --- a/tools/perf/profile_creators/extension_profile_extender_unittest.py +++ b/tools/perf/profile_creators/extension_profile_extender_unittest.py
@@ -17,7 +17,8 @@ Creates an extension profile and verifies that it has non-empty contents. """ - @decorators.Enabled('mac') # Extension generation only works on Mac for now. + # Should be enabled on mac, disabled because flaky: https://crbug.com/586362. + @decorators.Disabled('all') # Extension generation only works on Mac for now. def testExtensionProfileCreation(self): tmp_dir = tempfile.mkdtemp() files_in_crx_dir = 0
diff --git a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js index 2bf0ca4..1aa179f8 100644 --- a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js +++ b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js
@@ -111,6 +111,8 @@ 'click', this.processOKAction_.bind(this)); dialogFooter.cancelButton.addEventListener( 'click', this.onCancelBound_); + dialogFooter.newFolderButton.addEventListener( + 'click', this.processNewFolderAction_.bind(this)); dialogFooter.fileTypeSelector.addEventListener( 'change', this.onFileTypeFilterChanged_.bind(this)); dialogFooter.filenameInput.addEventListener( @@ -122,6 +124,10 @@ dialogFooter.initFileTypeFilter( this.fileTypes_, launchParam.includeAllFiles); this.onFileTypeFilterChanged_(); + + this.newFolderCommand_ = document.getElementById('new-folder'); + this.newFolderCommand_.addEventListener( + 'disabledChange', this.updateNewFolderButton_.bind(this)); } /** @@ -246,6 +252,23 @@ }; /** + * Creates a new folder using new-folder command. + * @private + */ +DialogActionController.prototype.processNewFolderAction_ = function() { + this.newFolderCommand_.canExecuteChange(this.dialogFooter_.newFolderButton); + this.newFolderCommand_.execute(this.dialogFooter_.newFolderButton); +}; + +/** + * Handles disabledChange event to update the new-folder button's avaliability. + * @private + */ +DialogActionController.prototype.updateNewFolderButton_ = function() { + this.dialogFooter_.newFolderButton.disabled = this.newFolderCommand_.disabled; +}; + +/** * Tries to close this modal dialog with some files selected. * Performs preprocessing if needed (e.g. for Drive). * @param {Object} selection Contains urls, filterIndex and multiple fields.
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index 0440716..d241144 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -275,20 +275,39 @@ }; /** - * If entry is fake or root entry, we don't show menu item for it. + * Returns true if the given entry is the root entry of the volume. + * @param {VolumeManagerWrapper} volumeManager + * @param {(!Entry|!FakeEntry)} entry Entry or a fake entry. + * @return {boolean} True if the entry is a root entry. + */ +CommandUtil.isRootEntry = function(volumeManager, entry) { + if (!volumeManager || !entry) + return false; + + var volumeInfo = volumeManager.getVolumeInfo(entry); + return !!volumeInfo && volumeInfo.displayRoot === entry; +}; + +/** + * If entry is fake/invalid/root, we don't show menu item for it. * @param {VolumeManagerWrapper} volumeManager * @param {(!Entry|!FakeEntry)} entry Entry or a fake entry. * @return {boolean} True if we should show menu item for the entry. */ CommandUtil.shouldShowMenuItemForEntry = function(volumeManager, entry) { - if (!volumeManager || util.isFakeEntry(entry)) + // If the entry is fake entry, hide context menu entries. + if (util.isFakeEntry(entry)) return false; - var volumeInfo = volumeManager.getVolumeInfo(entry); - if (!volumeInfo) + // If the entry is not a valid entry, hide context menu entries. + if (!volumeManager || !volumeManager.getVolumeInfo(entry)) return false; - return volumeInfo.displayRoot !== entry; + // If the entry is root entry of its volume, hide context menu entries. + if (CommandUtil.isRootEntry(volumeManager, entry)) + return false; + + return true; }; /** @@ -600,8 +619,7 @@ if (event.target instanceof DirectoryItem || event.target instanceof DirectoryTree) { var entry = CommandUtil.getCommandEntry(event.target); - if (!entry || !CommandUtil.shouldShowMenuItemForEntry( - fileManager.volumeManager, entry)) { + if (!entry || util.isFakeEntry(entry)) { event.canExecute = false; event.command.setHidden(true); return; @@ -609,7 +627,8 @@ var locationInfo = fileManager.volumeManager.getLocationInfo(entry); event.canExecute = locationInfo && !locationInfo.isReadOnly; - event.command.setHidden(false); + event.command.setHidden( + CommandUtil.isRootEntry(fileManager.volumeManager, entry)); } else { var directoryModel = fileManager.directoryModel; event.canExecute = !fileManager.isOnReadonlyDirectory() &&
diff --git a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js index f2c2dad..3e21c27b 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js +++ b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js
@@ -50,6 +50,14 @@ (container.querySelector('.cancel')); /** + * New folder button in the footer. + * @const + * @type {!HTMLButtonElement} + */ + this.newFolderButton = /** @type {!HTMLButtonElement} */ + (container.querySelector('#new-folder-button')); + + /** * File type selector in the footer. * @const * @type {!HTMLSelectElement}
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index d13b5ea9..766e64cc 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -405,8 +405,7 @@ <div class="left"> <!-- TODO(fukino): Turn this button into paper-button when the CommandButton supports paper-button. --> <button id="new-folder-button" class="primary" - visibleif="saveas-file folder" command="#new-folder" - tabindex="3" disabled> + visibleif="saveas-file folder" tabindex="3" disabled> <paper-ripple fit></paper-ripple> <span i18n-content="NEW_FOLDER_BUTTON_LABEL"></span> </button>