diff --git a/DEPS b/DEPS index 899460c..a1b7a73 100644 --- a/DEPS +++ b/DEPS
@@ -39,7 +39,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'bda86098ab2784968d0a1222dd1f4c18d18fe050', + 'skia_revision': '31d59e71cf5a571ff903d64ba2a6f17b715bfcfb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -271,7 +271,7 @@ 'src/third_party/catapult': Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' + - 'e9247fc201c518dbb7a0f8bf6a4b920a21bf3d63', + '2db923269e2f3f82819928c6e9cb09e8bb4157c7', 'src/third_party/openh264/src': Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
diff --git a/WATCHLISTS b/WATCHLISTS index a25b1e7..7731949 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -503,12 +503,13 @@ 'metrics': { 'filepath': 'base/metrics/'\ '|chrome/browser/metrics/'\ - '|chrome/common/metrics/'\ '|chrome/browser/chromeos/external_metrics'\ '|chrome/browser/extensions/api/metrics_private/'\ '|chrome/browser/ui/webui/metrics_handler'\ + '|chromecast/browser/metrics/'\ '|content/browser/user_metrics.cc'\ '|components/metrics/'\ + '|components/metrics_services_manager/'\ '|components/rappor/'\ '|components/variations/'\ '|content/public/browser/user_metrics.h'\
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java index 34515e3..3fec3c8 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java
@@ -12,13 +12,13 @@ import android.webkit.WebChromeClient; import android.widget.FrameLayout; -import org.chromium.content.browser.ContentVideoViewClient; +import org.chromium.content.browser.ContentVideoViewEmbedder; import org.chromium.content.browser.ContentViewClient; /** * ContentViewClient implementation for WebView */ -public class AwContentViewClient extends ContentViewClient implements ContentVideoViewClient { +public class AwContentViewClient extends ContentViewClient implements ContentVideoViewEmbedder { private final AwContentsClient mAwContentsClient; private final AwSettings mAwSettings; private final AwContents mAwContents; @@ -63,7 +63,7 @@ } @Override - public final ContentVideoViewClient getContentVideoViewClient() { + public final ContentVideoViewEmbedder getContentVideoViewEmbedder() { return this; }
diff --git a/base/logging.h b/base/logging.h index 300c9b5..643b710a 100644 --- a/base/logging.h +++ b/base/logging.h
@@ -373,9 +373,6 @@ #define LOG_IF(severity, condition) \ LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition)) -#define SYSLOG(severity) LOG(severity) -#define SYSLOG_IF(severity, condition) LOG_IF(severity, condition) - // The VLOG macros log with negative verbosities. #define VLOG_STREAM(verbose_level) \ logging::LogMessage(__FILE__, __LINE__, -verbose_level).stream() @@ -408,8 +405,6 @@ #define LOG_ASSERT(condition) \ LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " -#define SYSLOG_ASSERT(condition) \ - SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " #if defined(OS_WIN) #define PLOG_STREAM(severity) \
diff --git a/blimp/net/BUILD.gn b/blimp/net/BUILD.gn index 30075bc0..627b09b8c 100644 --- a/blimp/net/BUILD.gn +++ b/blimp/net/BUILD.gn
@@ -66,7 +66,6 @@ testonly = true sources = [ - "blimp_net_test_export.h", "test_common.cc", "test_common.h", ]
diff --git a/build/android/gyp/apkbuilder.py b/build/android/gyp/apkbuilder.py index 8c7a449..8278b2c 100755 --- a/build/android/gyp/apkbuilder.py +++ b/build/android/gyp/apkbuilder.py
@@ -193,11 +193,7 @@ _AddAssets(out_apk, _assets, disable_compression=False) _AddAssets(out_apk, _uncompressed_assets, disable_compression=True) - # 3. Resources - for info in resource_infos[1:]: - copy_resource(info) - - # 4. Dex files + # 3. Dex files if options.dex_file and options.dex_file.endswith('.zip'): with zipfile.ZipFile(options.dex_file, 'r') as dex_zip: for dex in (d for d in dex_zip.namelist() if d.endswith('.dex')): @@ -206,7 +202,7 @@ build_utils.AddToZipHermetic(out_apk, 'classes.dex', src_path=options.dex_file) - # 5. Native libraries. + # 4. Native libraries. for path in native_libs: basename = os.path.basename(path) apk_path = 'lib/%s/%s' % (options.android_abi, basename) @@ -218,6 +214,10 @@ apk_path = 'lib/%s/%s' % (options.android_abi, name) build_utils.AddToZipHermetic(out_apk, apk_path, data='') + # 5. Resources + for info in resource_infos[1:]: + copy_resource(info) + # 6. Java resources. Used only when coverage is enabled, so order # doesn't matter). if options.emma_device_jar:
diff --git a/build/common.gypi b/build/common.gypi index 3377177..ab51e18 100644 --- a/build/common.gypi +++ b/build/common.gypi
@@ -5520,7 +5520,9 @@ 'DEPLOYMENT_POSTPROCESSING': 'YES', 'STRIP_INSTALLED_PRODUCT': 'YES', 'conditions': [ - ['buildtype!="Official"', { + ['buildtype=="Official"', { + 'DEBUG_INFORMATION_FORMAT': 'dwarf-with-dsym', + }, { # Remove dSYM to reduce build time. 'DEBUG_INFORMATION_FORMAT': 'dwarf', }],
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index ab0d6c5..57b614c 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -307,6 +307,14 @@ cflags += [ "-fcolor-diagnostics" ] } + # Makes builds independent of absolute file path. + # Currently disabled for nacl since its toolchain lacks this flag (too old). + # TODO(zforman): Once nacl's toolchain is updated, remove check. + if (is_clang && !is_nacl) { + absolute_path = rebase_path("//.") + cflags += [ "-fdebug-prefix-map=$absolute_path=." ] + } + # C++11 compiler flags setup. # --------------------------- if (is_linux || is_android || (is_nacl && is_clang)) {
diff --git a/build/config/linux/pkg_config.gni b/build/config/linux/pkg_config.gni index 58769e2..9ab1de9 100644 --- a/build/config/linux/pkg_config.gni +++ b/build/config/linux/pkg_config.gni
@@ -52,7 +52,7 @@ # Pass the sysroot if we're using one (it requires the CPU arch also). pkg_config_args = [ "-s", - sysroot, + rebase_path(sysroot), "-a", current_cpu, "--system_libdir",
diff --git a/build/config/posix/BUILD.gn b/build/config/posix/BUILD.gn index 6f65443..1abbceb 100644 --- a/build/config/posix/BUILD.gn +++ b/build/config/posix/BUILD.gn
@@ -13,7 +13,7 @@ config("runtime_library") { if (!is_mac && sysroot != "") { # Pass the sysroot to all C compiler variants, the assembler, and linker. - cflags = [ "--sysroot=" + sysroot ] + cflags = [ "--sysroot=" + rebase_path(sysroot, root_build_dir) ] asmflags = cflags ldflags = cflags
diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni index 29a2b61..dcd215a 100644 --- a/build/config/sysroot.gni +++ b/build/config/sysroot.gni
@@ -19,17 +19,17 @@ } else if (is_android) { import("//build/config/android/config.gni") if (current_cpu == "x86") { - sysroot = rebase_path("$android_ndk_root/$x86_android_sysroot_subdir") + sysroot = "$android_ndk_root/$x86_android_sysroot_subdir" } else if (current_cpu == "arm") { - sysroot = rebase_path("$android_ndk_root/$arm_android_sysroot_subdir") + sysroot = "$android_ndk_root/$arm_android_sysroot_subdir" } else if (current_cpu == "mipsel") { - sysroot = rebase_path("$android_ndk_root/$mips_android_sysroot_subdir") + sysroot = "$android_ndk_root/$mips_android_sysroot_subdir" } else if (current_cpu == "x64") { - sysroot = rebase_path("$android_ndk_root/$x86_64_android_sysroot_subdir") + sysroot = "$android_ndk_root/$x86_64_android_sysroot_subdir" } else if (current_cpu == "arm64") { - sysroot = rebase_path("$android_ndk_root/$arm64_android_sysroot_subdir") + sysroot = "$android_ndk_root/$arm64_android_sysroot_subdir" } else if (current_cpu == "mips64") { - sysroot = rebase_path("$android_ndk_root/$mips64_android_sysroot_subdir") + sysroot = "$android_ndk_root/$mips64_android_sysroot_subdir" } else { sysroot = "" } @@ -37,13 +37,13 @@ # By default build against a sysroot image downloaded from Cloud Storage # during gclient runhooks. if (current_cpu == "x64") { - sysroot = rebase_path("//build/linux/debian_wheezy_amd64-sysroot") + sysroot = "//build/linux/debian_wheezy_amd64-sysroot" } else if (current_cpu == "x86") { - sysroot = rebase_path("//build/linux/debian_wheezy_i386-sysroot") + sysroot = "//build/linux/debian_wheezy_i386-sysroot" } else if (current_cpu == "mipsel") { - sysroot = rebase_path("//build/linux/debian_wheezy_mips-sysroot") + sysroot = "//build/linux/debian_wheezy_mips-sysroot" } else if (current_cpu == "arm") { - sysroot = rebase_path("//build/linux/debian_wheezy_arm-sysroot") + sysroot = "//build/linux/debian_wheezy_arm-sysroot" } else { # Any other builds don't use a sysroot. sysroot = "" @@ -63,7 +63,9 @@ _script_arch = "amd64" } assert( - exec_script("//build/dir_exists.py", [ sysroot ], "string") == "True", + exec_script("//build/dir_exists.py", + [ rebase_path(sysroot) ], + "string") == "True", "Missing sysroot ($sysroot). To fix, run: build/linux/sysroot_scripts/install-sysroot.py --arch=$_script_arch") } } else if (is_mac) {
diff --git a/build/experimental/install-build-deps.py b/build/experimental/install-build-deps.py index 7cc3760df..25da84e 100755 --- a/build/experimental/install-build-deps.py +++ b/build/experimental/install-build-deps.py
@@ -17,6 +17,7 @@ {'number': '14.04', 'codename': 'trusty'}, {'number': '14.10', 'codename': 'utopic'}, {'number': '15.04', 'codename': 'vivid'}, + {'number': '15.10', 'codename': 'wily'}, ) @@ -30,7 +31,6 @@ # Packages needed for development. _packages_dev = ( - 'apache2.2-bin', 'bison', 'cdbs', 'curl', @@ -103,7 +103,6 @@ 'ttf-kochi-gothic', 'ttf-kochi-mincho', 'wdiff', - 'xfonts-mathml', 'zip', ) @@ -360,6 +359,16 @@ else: _packages_dev += ('libbrlapi0.5',) + if package_exists('apache2-bin'): + _packages_dev += ('apache2-bin',) + else: + _packages_dev += ('apache2.2-bin',) + + if package_exists('fonts-stix'): + _packages_dev += ('fonts-stix',) + else: + _packages_dev += ('xfonts-mathml',) + # Some packages are only needed if the distribution actually supports # installing them. if package_exists('appmenu-gtk'):
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh index cb5ec20..d882f25 100755 --- a/build/install-build-deps.sh +++ b/build/install-build-deps.sh
@@ -73,11 +73,12 @@ fi lsb_release=$(lsb_release --codename --short) -ubuntu_codenames="(precise|trusty|utopic|vivid)" +ubuntu_codenames="(precise|trusty|utopic|vivid|wily)" if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then if [[ ! $lsb_release =~ $ubuntu_codenames ]]; then echo "ERROR: Only Ubuntu 12.04 (precise), 14.04 (trusty), " \ - "14.10 (utopic) and 15.04 (vivid) are currently supported" >&2 + "14.10 (utopic), 15.04 (vivid) and 15.10 (wily) " + "are currently supported" >&2 exit 1 fi @@ -97,7 +98,7 @@ chromeos_dev_list="libbluetooth-dev libxkbcommon-dev realpath" # Packages needed for development -dev_list="apache2.2-bin bison cdbs curl dpkg-dev elfutils devscripts fakeroot +dev_list="bison cdbs curl dpkg-dev elfutils devscripts fakeroot flex fonts-thai-tlwg g++ git-core git-svn gperf language-pack-da language-pack-fr language-pack-he language-pack-zh-hant libapache2-mod-php5 libasound2-dev libbrlapi-dev libav-tools @@ -110,7 +111,7 @@ openbox patch perl php5-cgi pkg-config python python-cherrypy3 python-crypto python-dev python-numpy python-opencv python-openssl python-psutil python-yaml rpm ruby subversion ttf-dejavu-core - ttf-indic-fonts ttf-kochi-gothic ttf-kochi-mincho wdiff xfonts-mathml + ttf-indic-fonts ttf-kochi-gothic ttf-kochi-mincho wdiff zip $chromeos_dev_list" # 64-bit systems need a minimum set of 32-bit compat packages for the pre-built @@ -228,7 +229,16 @@ else dev_list="${dev_list} libbrlapi0.5" fi - +if package_exists apache2-bin; then + dev_list="${dev_list} apache2-bin" +else + dev_list="${dev_list} apache2.2-bin" +fi +if package_exists fonts-stix; then + dev_list="${dev_list} fonts-stix" +else + dev_list="${dev_list} xfonts-mathml" +fi # Some packages are only needed if the distribution actually supports # installing them.
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index d329041..76c91a0 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc
@@ -1345,8 +1345,7 @@ static bool CdpPerfTracingEnabled() { bool tracing_enabled; - TRACE_EVENT_CATEGORY_GROUP_ENABLED( - TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), &tracing_enabled); + TRACE_EVENT_CATEGORY_GROUP_ENABLED("cdp.perf", &tracing_enabled); return tracing_enabled; } @@ -2813,10 +2812,16 @@ active_tree_root->layer_tree_impl()->LastScrolledLayerId()); jitter = CalculateFrameJitter(last_scrolled_layer); } - TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), "jitter", - jitter); + TRACE_EVENT_ASYNC_BEGIN1( + "cdp.perf", "jitter", + inputs->root_layer->layer_tree_impl()->source_frame_number(), "value", + jitter); inputs->root_layer->layer_tree_impl()->set_is_first_frame_after_commit( false); + TRACE_EVENT_ASYNC_END1( + "cdp.perf", "jitter", + inputs->root_layer->layer_tree_impl()->source_frame_number(), "value", + jitter); } } }
diff --git a/chrome/VERSION b/chrome/VERSION index e08d3eae..ebe78155 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=50 MINOR=0 -BUILD=2626 +BUILD=2627 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index f2f5fe22..8dc2aa3f 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -178,7 +178,8 @@ ":custom_tabs_service_aidl", "//chrome:page_info_connection_type_javagen", "//components/enhanced_bookmarks:enhanced_bookmarks_java_enums_srcjar", - "//components/offline_pages:offline_pages_enums_java", + "//components/offline_pages:offline_page_feature_enums_java", + "//components/offline_pages:offline_page_model_enums_java", "//components/omnibox/browser:autocomplete_match_type_javagen", "//components/security_state:security_state_enums_java", ]
diff --git a/chrome/android/chrome_apk.gyp b/chrome/android/chrome_apk.gyp index 9fc4083..d6d3312 100644 --- a/chrome/android/chrome_apk.gyp +++ b/chrome/android/chrome_apk.gyp
@@ -291,7 +291,8 @@ '../../chrome/chrome.gyp:chrome_java_test_support', '../../components/components.gyp:invalidation_javatests', '../../components/components.gyp:gcm_driver_java', - '../../components/components.gyp:offline_pages_enums_java', + '../../components/components.gyp:offline_page_feature_enums_java', + '../../components/components.gyp:offline_page_model_enums_java', '../../components/components.gyp:precache_javatests', '../../components/components.gyp:security_state_enums_java', '../../components/components.gyp:web_contents_delegate_android_java',
diff --git a/chrome/android/java/res/layout/new_tab_page.xml b/chrome/android/java/res/layout/new_tab_page.xml index 8af21286..ae218471 100644 --- a/chrome/android/java/res/layout/new_tab_page.xml +++ b/chrome/android/java/res/layout/new_tab_page.xml
@@ -174,7 +174,7 @@ android:layout_height="match_parent" android:layout_weight="1" android:background="?attr/listChoiceBackgroundIndicator" - android:contentDescription="@string/accessibility_ntp_toolbar_btn_bookmarks" + android:contentDescription="@null" android:paddingTop="12dp" android:paddingBottom="12dp" > <TextView @@ -183,7 +183,7 @@ android:layout_gravity="center_horizontal" android:drawablePadding="8dp" android:gravity="center_vertical" - android:text="@string/ntp_bookmarks" + android:text="@null" android:textSize="12sp" android:textColor="#5a5a5a" /> </FrameLayout>
diff --git a/chrome/android/java/res/layout/new_tab_page_incognito.xml b/chrome/android/java/res/layout/new_tab_page_incognito.xml index 9bbd65e6..00777bf 100644 --- a/chrome/android/java/res/layout/new_tab_page_incognito.xml +++ b/chrome/android/java/res/layout/new_tab_page_incognito.xml
@@ -57,7 +57,7 @@ android:layout_marginBottom="10dp" android:maxWidth="660dp" android:singleLine="false" - android:text="@string/new_tab_incognito_message" + android:text="@null" android:textColor="#bdbdbd" android:textSize="14sp" android:lineSpacingMultiplier="1.2" />
diff --git a/chrome/android/java/res/menu/eb_action_bar_menu.xml b/chrome/android/java/res/menu/eb_action_bar_menu.xml index 8df9339..9952be7 100644 --- a/chrome/android/java/res/menu/eb_action_bar_menu.xml +++ b/chrome/android/java/res/menu/eb_action_bar_menu.xml
@@ -16,7 +16,7 @@ <item android:id="@+id/search_menu_id" android:icon="@drawable/ic_search" - android:title="@string/enhanced_bookmark_action_bar_search" + android:title="@null" android:visible="false" chrome:showAsAction="ifRoom"/> <item @@ -31,17 +31,17 @@ <item android:id="@+id/selection_mode_edit_menu_id" android:icon="@drawable/eb_edit_active" - android:title="@string/edit_bookmark" + android:title="@null" chrome:showAsAction="ifRoom"/> <item android:id="@+id/selection_mode_move_menu_id" android:icon="@drawable/eb_move_active" - android:title="@string/enhanced_bookmark_action_bar_move" + android:title="@null" chrome:showAsAction="ifRoom"/> <item android:id="@+id/selection_mode_delete_menu_id" android:icon="@drawable/eb_delete_white" - android:title="@string/enhanced_bookmark_action_bar_delete" + android:title="@null" chrome:showAsAction="ifRoom"/> </group>
diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml index fd02acd..74afcd1 100644 --- a/chrome/android/java/res/menu/main_menu.xml +++ b/chrome/android/java/res/menu/main_menu.xml
@@ -32,7 +32,7 @@ <item android:id="@+id/new_incognito_tab_menu_id" android:title="@string/menu_new_incognito_tab" /> <item android:id="@+id/all_bookmarks_menu_id" - android:title="@string/menu_bookmarks" /> + android:title="@null" /> <item android:id="@+id/recent_tabs_menu_id" android:title="@string/menu_recent_tabs" /> <item android:id="@+id/open_history_menu_id"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java index 636c14a7..691d0ebb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java
@@ -176,11 +176,32 @@ public static final String NTP_SWITCH_TO_EXISTING_TAB = "ntp-switch-to-existing-tab"; /** - * Enable offline pages. + * Enables offline pages. + * Native switch - switches::kEnableOfflinePages */ public static final String ENABLE_OFFLINE_PAGES = "enable-offline-pages"; /** + * Enables offline pages, showing 'bookmarks' name in UI strings. + * Native switch - switches::kEnableOfflinePagesAsBookmarks + */ + public static final String ENABLE_OFFLINE_PAGES_AS_BOOKMARKS = + "enable-offline-pages-as-bookmarks"; + + /** + * Enables offline pages, showing 'saved pages' name in UI strings. + * Native switch - switches::kEnableOfflinePagesAsSavedPages + */ + public static final String ENABLE_OFFLINE_PAGES_AS_SAVED_PAGES = + "enable-offline-pages-as-saved-pages"; + + /** + * Disables offline pages. + * Native switch - switches::kDisableOfflinePages + */ + public static final String DISABLE_OFFLINE_PAGES = "disable-offline-pages"; + + /** * Enable keyboard accessory view that shows autofill suggestions on top of the keyboard. * Native switch - autofill::switches::kEnableAccessorySuggestionView */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java index 1fb2909f..26120fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java
@@ -14,7 +14,7 @@ import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.bookmark.BookmarksBridge; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils; import org.chromium.chrome.browser.preferences.PrefServiceBridge; @@ -119,11 +119,9 @@ recentTabsMenuItem.setVisible(!isIncognito && FeatureUtilities.canAllowSync(mActivity)); recentTabsMenuItem.setTitle(R.string.menu_recent_tabs); - if (OfflinePageBridge.isEnabled()) { - MenuItem allBookmarksMenuItem = menu.findItem(R.id.all_bookmarks_menu_id); - allBookmarksMenuItem.setTitle(mActivity.getString( - R.string.menu_bookmarks_offline_pages)); - } + MenuItem allBookmarksMenuItem = menu.findItem(R.id.all_bookmarks_menu_id); + allBookmarksMenuItem.setTitle( + mActivity.getString(OfflinePageUtils.getStringId(R.string.menu_bookmarks))); // Don't allow "chrome://" pages to be shared. menu.findItem(R.id.share_row_menu_id).setVisible(!isChromeScheme);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java index 3d0f4d8..6a22e52 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java
@@ -147,7 +147,6 @@ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - mRenderHost.onOverdrawBottomHeightChanged(getOverdrawBottomHeight()); } @Override @@ -164,21 +163,6 @@ } /** - * @return The amount the surface view is overdrawing the window bounds. - */ - public int getOverdrawBottomHeight() { - if (mRootActivityView == null) { - mRootActivityView = mRootView.findViewById(android.R.id.content); - } - if (mRootActivityView != null) { - int compositorHeight = getHeight(); - int rootViewHeight = mRootActivityView.getHeight(); - return Math.max(0, compositorHeight - rootViewHeight); - } - return 0; - } - - /** * Should be called for cleanup when the CompositorView instance is no longer used. */ public void shutDown() { @@ -412,11 +396,7 @@ provider.getViewportPixel(mCacheViewport); nativeSetLayoutViewport(mNativeCompositorView, mCacheViewport.left, mCacheViewport.top, mCacheViewport.width(), mCacheViewport.height(), mCacheVisibleViewport.left, - mCacheVisibleViewport.top, mRenderHost.getCurrentOverdrawBottomHeight(), 1.0f); - - mCacheVisibleViewport.right = mCacheVisibleViewport.left + mSurfaceWidth; - mCacheVisibleViewport.bottom = mCacheVisibleViewport.top - + Math.max(mSurfaceHeight - mRenderHost.getCurrentOverdrawBottomHeight(), 0); + mCacheVisibleViewport.top, 1.0f); // TODO(changwan): move to treeprovider. updateToolbarLayer(provider, forRotation, progressBarDrawingInfo); @@ -464,7 +444,7 @@ private native void nativeSetNeedsComposite(long nativeCompositorView); private native void nativeSetLayoutViewport(long nativeCompositorView, float x, float y, float width, float height, float visibleXOffset, float visibleYOffset, - float overdrawBottomHeight, float dpToPixel); + float dpToPixel); private native void nativeUpdateToolbarLayer(long nativeCompositorView, int resourceId, int toolbarBackgroundColor, int urlBarResourceId, float urlBarAlpha, float topOffset, float brightness, boolean visible, boolean showShadow);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index 56acc0e..a9be5fd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -91,8 +91,6 @@ new ArrayList<Invalidator.Client>(); private boolean mSkipInvalidation = false; - private boolean mSkipNextToolbarTextureUpdate = false; - /** * A task to be performed after a resize event. */ @@ -422,23 +420,6 @@ sCachedCVCList.clear(); } - @Override - public void onOverdrawBottomHeightChanged(int overdrawHeight) { - mSkipNextToolbarTextureUpdate = true; - requestRender(); - } - - @Override - public int getCurrentOverdrawBottomHeight() { - if (mTabVisible != null) { - float overdrawBottomHeight = mTabVisible.getFullscreenOverdrawBottomHeightPix(); - if (!Float.isNaN(overdrawBottomHeight)) { - return (int) overdrawBottomHeight; - } - } - return mCompositorView.getOverdrawBottomHeight(); - } - /** * Called whenever the host activity is started. */ @@ -533,19 +514,11 @@ assert mProgressBarDrawingInfo == null; } - mCompositorView.finalizeLayers(mLayoutManager, mSkipNextToolbarTextureUpdate, + mCompositorView.finalizeLayers(mLayoutManager, false, mProgressBarDrawingInfo); - - // TODO(changwan): Check if this hack can be removed. - // This is a hack to draw one more frame if the screen just rotated for Nexus 10 + L. - // See http://crbug/440469 for more. - if (mSkipNextToolbarTextureUpdate) { - requestRender(); - } } TraceEvent.end("CompositorViewHolder:layout"); - mSkipNextToolbarTextureUpdate = false; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java index 2ed3e45..641f88d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java
@@ -40,21 +40,6 @@ void onPhysicalBackingSizeChanged(int width, int height); /** - * Indicates that the amount the surface is overdrawing on the bottom has changed. - * - * This occurs when the surface is larger than the window viewport. - * - * @param overdrawHeight The overdraw amount. - */ - void onOverdrawBottomHeightChanged(int overdrawHeight); - - /** - * @see #onOverdrawBottomHeightChanged(int) - * @return The overdraw bottom height of the last frame rendered by the current tab. - */ - int getCurrentOverdrawBottomHeight(); - - /** * @return The number of actually drawn {@link LayoutTab}. */ int getLayoutTabsDrawnCount();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java index 62b21be..d8d4049 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java
@@ -42,10 +42,6 @@ public void onDismissNoAction(Object actionData) { } - @Override - public void onDismissForEachType(boolean isTimeout) { - } - /** * Called to display the download succeeded snackbar. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkActionBar.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkActionBar.java index 9111640b..bb76d1a9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkActionBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkActionBar.java
@@ -19,7 +19,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.bookmark.BookmarksBridge.BookmarkItem; import org.chromium.chrome.browser.bookmark.BookmarksBridge.BookmarkModelObserver; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.widget.NumberRollView; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkType; @@ -58,16 +58,20 @@ if (DeviceFormFactor.isTablet(context)) getMenu().removeItem(R.id.close_menu_id); setOnMenuItemClickListener(this); - if (OfflinePageBridge.isEnabled()) { - getMenu().findItem(R.id.search_menu_id).setTitle( - R.string.offline_pages_action_bar_search); - getMenu().findItem(R.id.selection_mode_edit_menu_id).setTitle( - R.string.offline_pages_edit_item); - getMenu().findItem(R.id.selection_mode_move_menu_id).setTitle( - R.string.offline_pages_action_bar_move); - getMenu().findItem(R.id.selection_mode_delete_menu_id).setTitle( - R.string.offline_pages_action_bar_delete); - } + getMenu() + .findItem(R.id.search_menu_id) + .setTitle(OfflinePageUtils.getStringId( + R.string.enhanced_bookmark_action_bar_search)); + getMenu() + .findItem(R.id.selection_mode_edit_menu_id) + .setTitle(OfflinePageUtils.getStringId(R.string.edit_bookmark)); + getMenu() + .findItem(R.id.selection_mode_move_menu_id) + .setTitle(OfflinePageUtils.getStringId(R.string.enhanced_bookmark_action_bar_move)); + getMenu() + .findItem(R.id.selection_mode_delete_menu_id) + .setTitle(OfflinePageUtils.getStringId( + R.string.enhanced_bookmark_action_bar_delete)); } @Override @@ -295,8 +299,6 @@ } private int getTitleForAllItems() { - return OfflinePageBridge.isEnabled() - ? R.string.offline_pages_all_items - : R.string.enhanced_bookmark_title_bar_all_items; + return OfflinePageUtils.getStringId(R.string.enhanced_bookmark_title_bar_all_items); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkActivity.java index 485f05d..fb0c1b6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkActivity.java
@@ -11,7 +11,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.UrlConstants; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarManageable; import org.chromium.components.bookmarks.BookmarkId; @@ -42,9 +42,8 @@ mBookmarkManager.updateForUrl(url); setContentView(mBookmarkManager.getView()); - EnhancedBookmarkUtils.setTaskDescriptionInDocumentMode(this, getString( - OfflinePageBridge.isEnabled() ? R.string.offline_pages_saved_pages - : R.string.bookmarks)); + EnhancedBookmarkUtils.setTaskDescriptionInDocumentMode( + this, getString(OfflinePageUtils.getStringId(R.string.bookmarks))); // Hack to work around inferred theme false lint error: http://crbug.com/445633 assert (R.layout.eb_main_content != 0);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkContentView.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkContentView.java index f59752e..9f00503 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkContentView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkContentView.java
@@ -12,7 +12,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.widget.FadingShadow; import org.chromium.chrome.browser.widget.FadingShadowView; import org.chromium.chrome.browser.widget.LoadingView; @@ -45,8 +45,7 @@ super.onFinishInflate(); mItemsContainer = (EnhancedBookmarkRecyclerView) findViewById(R.id.eb_items_container); TextView emptyView = (TextView) findViewById(R.id.eb_empty_view); - emptyView.setText(OfflinePageBridge.isEnabled() - ? R.string.offline_pages_folder_empty : R.string.bookmarks_folder_empty); + emptyView.setText(OfflinePageUtils.getStringId(R.string.bookmarks_folder_empty)); mItemsContainer.setEmptyView(emptyView); mActionBar = (EnhancedBookmarkActionBar) findViewById(R.id.eb_action_bar); mLoadingView = (LoadingView) findViewById(R.id.eb_initial_loading_view);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkDrawerListViewAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkDrawerListViewAdapter.java index 2fd4c83..e7a3035 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkDrawerListViewAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkDrawerListViewAdapter.java
@@ -12,6 +12,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.components.bookmarks.BookmarkId; import java.util.ArrayList; @@ -326,10 +327,8 @@ switch (item.mType) { case TYPE_ALL_ITEMS: - title = listItemView.getContext().getResources() - .getString(OfflinePageBridge.isEnabled() - ? R.string.offline_pages_all_items - : R.string.enhanced_bookmark_drawer_all_items); + title = listItemView.getContext().getResources().getString( + OfflinePageUtils.getStringId(R.string.enhanced_bookmark_drawer_all_items)); iconDrawableId = R.drawable.btn_star; break; case TYPE_FOLDER:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkEditActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkEditActivity.java index d5f5c5c5..a925f57 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkEditActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkEditActivity.java
@@ -26,6 +26,7 @@ import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.OfflinePageModelObserver; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.SavePageCallback; import org.chromium.chrome.browser.offlinepages.OfflinePageItem; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.util.UrlUtilities; import org.chromium.chrome.browser.widget.EmptyAlertEditText; import org.chromium.chrome.browser.widget.TintedDrawable; @@ -106,9 +107,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - int title = OfflinePageBridge.isEnabled() - ? R.string.offline_pages_edit_item - : R.string.edit_bookmark; + int title = OfflinePageUtils.getStringId(R.string.edit_bookmark); setTitle(title); EnhancedBookmarkUtils.setTaskDescriptionInDocumentMode(this, getString(title)); mEnhancedBookmarksModel = new EnhancedBookmarksModel(); @@ -257,17 +256,21 @@ .getPageByBookmarkId(mBookmarkId); if (offlinePage != null) { // Offline page exists. Show information and button to remove. - offlinePageInfoTextView.setText(getString(R.string.bookmark_offline_page_size, - Formatter.formatFileSize(this, offlinePage.getFileSize()))); + offlinePageInfoTextView.setText( + getString(OfflinePageUtils.getStringId( + R.string.offline_pages_as_bookmarks_offline_page_size), + Formatter.formatFileSize(this, offlinePage.getFileSize()))); updateButtonToDeleteOfflinePage(saveRemoveVisitButton); } else if (mWebContents != null) { // Offline page is not saved, but a bookmarked page is opened. Show save button. - offlinePageInfoTextView.setText(getString(R.string.bookmark_offline_page_none)); + offlinePageInfoTextView.setText( + getString(OfflinePageUtils.getStringId(R.string.bookmark_offline_page_none))); updateButtonToSaveOfflinePage(saveRemoveVisitButton); } else { // Offline page is not saved, and edit page was opened from the bookmarks UI, which // means there is no action the user can take any action - hide button. - offlinePageInfoTextView.setText(getString(R.string.bookmark_offline_page_visit)); + offlinePageInfoTextView.setText(getString(OfflinePageUtils.getStringId( + R.string.offline_pages_as_bookmarks_offline_page_visit))); updateButtonToVisitOfflinePage(saveRemoveVisitButton); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPage.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPage.java index 889be8c9..68b3223b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPage.java
@@ -14,7 +14,7 @@ import org.chromium.chrome.browser.NativePage; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.enhancedbookmarks.EnhancedBookmarkDelegate.EnhancedBookmarkStateChangeListener; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.tab.Tab; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.base.DeviceFormFactor; @@ -46,8 +46,7 @@ private EnhancedBookmarkPage(Activity activity, Tab tab) { mActivity = activity; mTab = tab; - mTitle = activity.getString(OfflinePageBridge.isEnabled() - ? R.string.offline_pages_saved_pages : R.string.bookmarks); + mTitle = activity.getString(OfflinePageUtils.getStringId(R.string.bookmarks)); mBackgroundColor = ApiCompatibilityUtils.getColor(activity.getResources(), R.color.default_primary_color); mThemeColor = ApiCompatibilityUtils.getColor(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUndoController.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUndoController.java index 89392084..65bb0b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUndoController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUndoController.java
@@ -59,10 +59,6 @@ public void onDismissNoAction(Object actionData) { } - @Override - public void onDismissForEachType(boolean isTimeout) { - } - // Overriding BookmarkModelObserver @Override public void bookmarkModelChanged() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java index 2069677..8a3b995 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java
@@ -133,26 +133,30 @@ int buttonId = R.string.enhanced_bookmark_item_edit; if (saveResult == AddBookmarkCallback.SKIPPED) { - messageId = R.string.offline_pages_page_skipped; + messageId = OfflinePageUtils.getStringId( + R.string.offline_pages_as_bookmarks_page_skipped); } else if (isStorageAlmostFull) { - messageId = saveResult == AddBookmarkCallback.SAVED - ? R.string.offline_pages_page_saved_storage_near_full - : R.string.offline_pages_page_failed_to_save_storage_near_full; + messageId = OfflinePageUtils.getStringId(saveResult == AddBookmarkCallback.SAVED + ? R.string.offline_pages_as_bookmarks_page_saved_storage_near_full + : R.string.offline_pages_as_bookmarks_page_failed_to_save_storage_near_full); // Show "Free up space" button. - buttonId = R.string.offline_pages_free_up_space_title; + buttonId = OfflinePageUtils.getStringId(R.string.offline_pages_free_up_space_title); snackbarController = createSnackbarControllerForFreeUpSpaceButton( bookmarkModel, snackbarManager, activity); } else { if (saveResult == AddBookmarkCallback.SAVED) { if (getLastUsedParent(activity) == null) { - messageId = R.string.offline_pages_page_saved; + messageId = OfflinePageUtils.getStringId( + R.string.offline_pages_as_bookmarks_page_saved); } else { - messageId = R.string.offline_pages_page_saved_folder; + messageId = OfflinePageUtils.getStringId( + R.string.offline_pages_as_bookmarks_page_saved_folder); suffix = bookmarkModel.getBookmarkTitle( bookmarkModel.getBookmarkById(bookmarkId).getParentId()); } } else { - messageId = R.string.offline_pages_page_failed_to_save; + messageId = OfflinePageUtils.getStringId( + R.string.offline_pages_as_bookmarks_page_failed_to_save); } } if (snackbarController == null) { @@ -206,8 +210,6 @@ final EnhancedBookmarksModel bookmarkModel, final Activity activity, final BookmarkId bookmarkId) { return new SnackbarController() { - @Override - public void onDismissForEachType(boolean isTimeout) {} @Override public void onDismissNoAction(Object actionData) { @@ -234,9 +236,6 @@ final Activity activity) { return new SnackbarController() { @Override - public void onDismissForEachType(boolean isTimeout) {} - - @Override public void onDismissNoAction(Object actionData) { // This method will be called only if the snackbar is dismissed by timeout. RecordUserAction.record(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java index 1cc0128..b1db008 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java
@@ -18,7 +18,7 @@ import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider; import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.ntp.IncognitoNewTabPageView.IncognitoNewTabPageManager; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.profiles.Profile; /** @@ -67,12 +67,10 @@ (IncognitoNewTabPageView) inflater.inflate(R.layout.new_tab_page_incognito, null); mIncognitoNewTabPageView.initialize(mIncognitoNewTabPageManager); - if (OfflinePageBridge.isEnabled()) { - TextView newTabIncognitoMessage = (TextView) mIncognitoNewTabPageView.findViewById( - R.id.new_tab_incognito_message); - newTabIncognitoMessage.setText(activity.getResources().getString( - R.string.offline_pages_new_tab_incognito_message)); - } + TextView newTabIncognitoMessage = (TextView) mIncognitoNewTabPageView.findViewById( + R.id.new_tab_incognito_message); + newTabIncognitoMessage.setText(activity.getResources().getString( + OfflinePageUtils.getStringId(R.string.new_tab_incognito_message))); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageToolbar.java index cfdb9a2..97eda057 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageToolbar.java
@@ -13,7 +13,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.widget.TintedDrawable; /** @@ -47,14 +47,11 @@ protected void onFinishInflate() { mBookmarksButton = initButton(R.id.bookmarks_button, R.drawable.btn_star); mRecentTabsButton = initButton(R.id.recent_tabs_button, R.drawable.btn_recents); - if (OfflinePageBridge.isEnabled()) { - ((TextView) mBookmarksButton.getChildAt(0)).setText( - R.string.offline_pages_ntp_button_name); - ((TextView) mBookmarksButton.getChildAt(0)).setContentDescription( - getResources().getString(R.string.offline_pages_ntp_button_accessibility)); - } - ((TextView) mBookmarksButton.getChildAt(0)).setText(OfflinePageBridge.isEnabled() - ? R.string.offline_pages_ntp_button_name : R.string.ntp_bookmarks); + ((TextView) mBookmarksButton.getChildAt(0)) + .setText(OfflinePageUtils.getStringId(R.string.ntp_bookmarks)); + ((TextView) mBookmarksButton.getChildAt(0)) + .setContentDescription(getResources().getString(OfflinePageUtils.getStringId( + R.string.accessibility_ntp_toolbar_btn_bookmarks))); mInterestsButton = initButton(R.id.interests_button, R.drawable.btn_star_filled); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java index 9aea635..92b63d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -16,6 +16,7 @@ import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkType; import org.chromium.components.offlinepages.DeletePageResult; +import org.chromium.components.offlinepages.FeatureMode; import org.chromium.components.offlinepages.SavePageResult; import org.chromium.content_public.browser.WebContents; @@ -33,8 +34,8 @@ private final ObserverList<OfflinePageModelObserver> mObservers = new ObserverList<OfflinePageModelObserver>(); - /** Whether the offline pages feature is enabled. */ - private static Boolean sIsEnabled; + /** Mode of the offline pages feature */ + private static Integer sFeatureMode; /** * Callback used to saving an offline page. @@ -158,12 +159,22 @@ } /** - * Returns true if the offline pages feature is enabled. + * @return The mode of the offline pages feature. Uses + * {@see org.chromium.components.offlinepages.FeatureMode} enum. + */ + public static int getFeatureMode() { + ThreadUtils.assertOnUiThread(); + if (sFeatureMode == null) sFeatureMode = nativeGetFeatureMode(); + return sFeatureMode; + } + + /** + * @return True if the offline pages feature is enabled, regardless whether bookmark or saved + * page shown in UI strings. */ public static boolean isEnabled() { ThreadUtils.assertOnUiThread(); - if (sIsEnabled == null) sIsEnabled = nativeIsOfflinePagesEnabled(); - return sIsEnabled; + return getFeatureMode() != FeatureMode.DISABLED; } /** @@ -413,7 +424,7 @@ url, bookmarkId, offlineUrl, fileSize, creationTime, accessCount, lastAccessTimeMs); } - private static native boolean nativeIsOfflinePagesEnabled(); + private static native int nativeGetFeatureMode(); private static native boolean nativeCanSavePage(String url); private native long nativeInit(Profile profile);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageFreeUpSpaceDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageFreeUpSpaceDialog.java index 16a4cd43..69234be2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageFreeUpSpaceDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageFreeUpSpaceDialog.java
@@ -52,11 +52,10 @@ * Creates a snackbar informing user that the storage has been cleared. */ public static Snackbar createStorageClearedSnackbar(Context context) { - return Snackbar.make(context.getString(R.string.offline_pages_storage_cleared), + return Snackbar.make(context.getString(OfflinePageUtils.getStringId( + R.string.offline_pages_storage_cleared)), new SnackbarController() { @Override - public void onDismissForEachType(boolean isTimeout) {} - @Override public void onDismissNoAction(Object actionData) {} @Override public void onAction(Object actionData) {} @@ -70,10 +69,12 @@ mOfflinePagesToDelete = mOfflinePageBridge.getPagesToCleanUp(); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) - .setTitle(R.string.offline_pages_free_up_space_title) + .setTitle(OfflinePageUtils.getStringId( + R.string.offline_pages_free_up_space_title)) .setPositiveButton(R.string.delete, this) .setNegativeButton(R.string.cancel, this) - .setMessage(getString(R.string.offline_pages_free_up_space_message, + .setMessage(getString(OfflinePageUtils.getStringId( + R.string.offline_pages_free_up_space_message), mOfflinePagesToDelete.size(), Formatter.formatFileSize(getActivity(), getTotalSize()))); return builder.create();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOpenStorageSettingsDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOpenStorageSettingsDialog.java index 921beaf..b5b7172b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOpenStorageSettingsDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOpenStorageSettingsDialog.java
@@ -33,10 +33,12 @@ AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AlertDialogTheme) - .setTitle(R.string.offline_pages_free_up_space_title) + .setTitle(OfflinePageUtils.getStringId( + R.string.offline_pages_free_up_space_title)) .setPositiveButton(R.string.offline_pages_view_button, listener) .setNegativeButton(R.string.cancel, listener) - .setMessage(R.string.offline_pages_open_storage_settings_dialog_text); + .setMessage(OfflinePageUtils.getStringId( + R.string.offline_pages_open_storage_settings_dialog_text)); builder.create().show(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageStorageSpaceHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageStorageSpaceHeader.java index 3bd62b21..fb5e727 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageStorageSpaceHeader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageStorageSpaceHeader.java
@@ -55,7 +55,8 @@ R.layout.eb_offline_pages_storage_space_header, parent, false); ((TextView) header.findViewById(R.id.storage_header_message)) - .setText(mContext.getString(R.string.offline_pages_storage_space_message, + .setText(mContext.getString( + OfflinePageUtils.getStringId(R.string.offline_pages_storage_space_message), Formatter.formatFileSize( mContext, mOfflinePageStorageSpacePolicy.getSizeOfAllPages())));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java index bec2a474..a750c05 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkType; +import org.chromium.components.offlinepages.FeatureMode; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.base.PageTransition; @@ -71,6 +72,66 @@ } /** + * Finds out the appropriate resource ID of UI string shown to the user. + * @param stringResId The resource ID of UI string used when 'bookmarks' name is used in UI + * strings. + * return The resource ID of UI string shown to the user, depending on the experiment. + */ + public static int getStringId(int stringResId) { + if (!OfflinePageBridge.isEnabled()) { + return stringResId; + } + if (OfflinePageBridge.getFeatureMode() != FeatureMode.ENABLED_AS_SAVED_PAGES) { + return stringResId; + } + if (stringResId == R.string.enhanced_bookmark_action_bar_delete) { + return R.string.offline_pages_action_bar_delete; + } else if (stringResId == R.string.enhanced_bookmark_action_bar_move) { + return R.string.offline_pages_action_bar_move; + } else if (stringResId == R.string.enhanced_bookmark_action_bar_search) { + return R.string.offline_pages_action_bar_search; + } else if (stringResId == R.string.edit_bookmark) { + return R.string.offline_pages_edit_item; + } else if (stringResId == R.string.enhanced_bookmark_drawer_all_items) { + return R.string.offline_pages_all_items; + } else if (stringResId == R.string.enhanced_bookmark_title_bar_all_items) { + return R.string.offline_pages_all_items; + } else if (stringResId == R.string.bookmarks) { + return R.string.offline_pages_saved_pages; + } else if (stringResId == R.string.menu_bookmarks) { + return R.string.menu_bookmarks_offline_pages; + } else if (stringResId == R.string.ntp_bookmarks) { + return R.string.offline_pages_ntp_button_name; + } else if (stringResId == R.string.accessibility_ntp_toolbar_btn_bookmarks) { + return R.string.offline_pages_ntp_button_accessibility; + } else if (stringResId == R.string.bookmarks_folder_empty) { + return R.string.offline_pages_folder_empty; + } else if (stringResId == R.string.new_tab_incognito_message) { + return R.string.offline_pages_new_tab_incognito_message; + } else if (stringResId == R.string.offline_pages_as_bookmarks_page_saved) { + return R.string.offline_pages_page_saved; + } else if (stringResId == R.string.offline_pages_as_bookmarks_page_skipped) { + return R.string.offline_pages_page_skipped; + } else if (stringResId + == R.string.offline_pages_as_bookmarks_page_saved_storage_near_full) { + return R.string.offline_pages_page_saved_storage_near_full; + } else if (stringResId == R.string.offline_pages_as_bookmarks_page_failed_to_save) { + return R.string.offline_pages_page_failed_to_save; + } else if (stringResId + == R.string.offline_pages_as_bookmarks_page_failed_to_save_storage_near_full) { + return R.string.offline_pages_page_failed_to_save_storage_near_full; + } else if (stringResId == R.string.offline_pages_as_bookmarks_storage_space_message) { + return R.string.offline_pages_storage_space_message; + } else if (stringResId == R.string.offline_pages_as_bookmarks_viewing_offline_page) { + return R.string.offline_pages_viewing_offline_page; + } else if (stringResId == R.string.offline_pages_as_bookmarks_offline_page_size) { + return R.string.bookmark_offline_page_size; + } else { + return stringResId; + } + } + + /** * Retrieves the url to launch a bookmark or saved page. If latter, also marks it as * accessed and reports the UMAs. * @@ -190,7 +251,7 @@ final long bookmarkId, final int buttonType, final int actionTextId) { Context context = activity.getBaseContext(); - final int snackbarTextId = R.string.offline_pages_viewing_offline_page; + final int snackbarTextId = getStringId(R.string.offline_pages_viewing_offline_page); SnackbarController snackbarController = new SnackbarController() { @Override @@ -232,9 +293,6 @@ break; } } - - @Override - public void onDismissForEachType(boolean isTimeout) {} }; Snackbar snackbar = Snackbar.make(context.getString(snackbarTextId), snackbarController) .setAction(context.getString(actionTextId), buttonType);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationSnackbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationSnackbarController.java index 3fe6818..fa0a08b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationSnackbarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationSnackbarController.java
@@ -126,9 +126,6 @@ public void onDismissNoAction(Object actionData) {} @Override - public void onDismissForEachType(boolean isTimeout) {} - - @Override public void onAction(Object actionData) { View view = (View) actionData; UiUtils.hideKeyboard(view);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/DataUseSnackbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/DataUseSnackbarController.java index 3da6729..479f873 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/DataUseSnackbarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/DataUseSnackbarController.java
@@ -90,7 +90,4 @@ @Override public void onDismissNoAction(Object actionData) {} - - @Override - public void onDismissForEachType(boolean isTimeout) {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/LoFiBarPopupController.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/LoFiBarPopupController.java index 2bf2863..ab85ceb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/LoFiBarPopupController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/LoFiBarPopupController.java
@@ -125,7 +125,4 @@ @Override public void onDismissNoAction(Object actionData) {} - - @Override - public void onDismissForEachType(boolean isTimeout) {} } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java index e2da38d6..688d122 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java
@@ -20,7 +20,6 @@ import org.chromium.ui.UiUtils; import org.chromium.ui.base.DeviceFormFactor; -import java.util.HashSet; import java.util.Stack; /** @@ -56,30 +55,16 @@ */ public static interface SnackbarController { /** - * Callback triggered when user clicks on button at end of snackbar. This method is only - * called for controller having posted the entry the user clicked on; other controllers are - * not notified. Also once this {@link #onAction(Object)} is called, - * {@link #onDismissNoAction(Object)} and {@link #onDismissForEachType(boolean)} will not be - * called. + * Called when the user clicks the action button on the snackbar. * @param actionData Data object passed when showing this specific snackbar. */ void onAction(Object actionData); /** - * Callback triggered when the snackbar is dismissed by either timeout or UI environment - * change. This callback will be called for each entry a controller has posted, _except_ for - * entries which the user has done action with, by clicking the action button. + * Called when the snackbar is dismissed by tiemout or UI enviroment change. * @param actionData Data object associated with the dismissed snackbar entry. */ void onDismissNoAction(Object actionData); - - /** - * Notify each SnackbarControllers instance only once immediately before the snackbar is - * dismissed. This function is likely to be used for controllers to do user metrics for - * dismissal. - * @param isTimeout Whether this dismissal is triggered by timeout. - */ - void onDismissForEachType(boolean isTimeout); } private static final int DEFAULT_SNACKBAR_DURATION_MS = 3000; @@ -186,14 +171,8 @@ mPopup = null; } - HashSet<SnackbarController> controllers = new HashSet<SnackbarController>(); - while (!mStack.isEmpty()) { Snackbar snackbar = mStack.pop(); - if (!controllers.contains(snackbar.getController())) { - snackbar.getController().onDismissForEachType(isTimeout); - controllers.add(snackbar.getController()); - } snackbar.getController().onDismissNoAction(snackbar.getActionData()); if (isTimeout && !mStack.isEmpty() && mStack.peek().getForceDisplay()) { @@ -221,7 +200,7 @@ } if (!isFound) return; - finishSnackbarRemoval(controller); + finishSnackbarRemoval(); } /** @@ -242,12 +221,10 @@ } if (!isFound) return; - finishSnackbarRemoval(controller); + finishSnackbarRemoval(); } - private void finishSnackbarRemoval(SnackbarController controller) { - controller.onDismissForEachType(false); - + private void finishSnackbarRemoval() { if (mStack.isEmpty()) { dismissAllSnackbars(false); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java index 6ff38eb..87a80b21 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java
@@ -87,10 +87,7 @@ public void onAction(Object actionData) {} @Override - public void onDismissNoAction(Object actionData) {} - - @Override - public void onDismissForEachType(boolean isTimeout) { + public void onDismissNoAction(Object actionData) { mTab.removeObserver(mTabObserver); } }
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 a50683d..2ab3a8b1 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
@@ -41,8 +41,6 @@ private static final int TAB_CLOSE_UNDO_TOAST_SHOWN_COLD = 0; private static final int TAB_CLOSE_UNDO_TOAST_SHOWN_WARM = 1; private static final int TAB_CLOSE_UNDO_TOAST_PRESSED = 2; - private static final int TAB_CLOSE_UNDO_TOAST_DISMISSED_TIMEOUT = 3; - private static final int TAB_CLOSE_UNDO_TOAST_DISMISSED_ACTION = 4; private static final int TAB_CLOSE_UNDO_TOAST_COUNT = 5; private final TabModelSelector mTabModelSelector; @@ -193,12 +191,4 @@ TabModel model = mTabModelSelector.getModelForTabId(tabId); if (model != null) model.commitTabClosure(tabId); } - - @Override - public void onDismissForEachType(boolean isTimeout) { - RecordHistogram.recordEnumeratedHistogram("AndroidTabCloseUndo.Toast", - isTimeout ? TAB_CLOSE_UNDO_TOAST_DISMISSED_TIMEOUT - : TAB_CLOSE_UNDO_TOAST_DISMISSED_ACTION, - TAB_CLOSE_UNDO_TOAST_COUNT); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 364e697..7a4be239 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -75,8 +75,8 @@ import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.components.navigation_interception.InterceptNavigationDelegate; import org.chromium.components.security_state.ConnectionSecurityLevel; -import org.chromium.content.browser.ActivityContentVideoViewClient; -import org.chromium.content.browser.ContentVideoViewClient; +import org.chromium.content.browser.ActivityContentVideoViewEmbedder; +import org.chromium.content.browser.ContentVideoViewEmbedder; import org.chromium.content.browser.ContentView; import org.chromium.content.browser.ContentViewClient; import org.chromium.content.browser.ContentViewCore; @@ -340,7 +340,6 @@ private FullscreenManager mFullscreenManager; private float mPreviousFullscreenTopControlsOffsetY = Float.NaN; private float mPreviousFullscreenContentOffsetY = Float.NaN; - private float mPreviousFullscreenOverdrawBottomHeight = Float.NaN; private int mFullscreenHungRendererToken = FullscreenManager.INVALID_TOKEN; private boolean mIsFullscreenWaitingForLoad = false; @@ -371,9 +370,8 @@ @Override public void onOffsetsForFullscreenChanged( - float topControlsOffsetY, float contentOffsetY, float overdrawBottomHeight) { - onOffsetsChanged(topControlsOffsetY, contentOffsetY, overdrawBottomHeight, - isShowingSadTab()); + float topControlsOffsetY, float contentOffsetY) { + onOffsetsChanged(topControlsOffsetY, contentOffsetY, isShowingSadTab()); } @Override @@ -429,8 +427,8 @@ } @Override - public ContentVideoViewClient getContentVideoViewClient() { - return new ActivityContentVideoViewClient(mActivity) { + public ContentVideoViewEmbedder getContentVideoViewEmbedder() { + return new ActivityContentVideoViewEmbedder(mActivity) { @Override public void enterFullscreenVideo(View view) { super.enterFullscreenVideo(view); @@ -1186,7 +1184,6 @@ mFullscreenManager.setPersistentFullscreenMode(false); mFullscreenManager.hideControlsPersistent(mFullscreenHungRendererToken); mFullscreenHungRendererToken = FullscreenManager.INVALID_TOKEN; - mPreviousFullscreenOverdrawBottomHeight = Float.NaN; } if (mTabUma != null) mTabUma.onHide(); @@ -2361,14 +2358,12 @@ * compositor. * @param topControlsOffsetY The Y offset of the top controls in physical pixels. * @param contentOffsetY The Y offset of the content in physical pixels. - * @param overdrawBottomHeight The overdraw height. * @param isNonFullscreenPage Whether a current page is non-fullscreen page or not. */ private void onOffsetsChanged(float topControlsOffsetY, float contentOffsetY, - float overdrawBottomHeight, boolean isNonFullscreenPage) { + boolean isNonFullscreenPage) { mPreviousFullscreenTopControlsOffsetY = topControlsOffsetY; mPreviousFullscreenContentOffsetY = contentOffsetY; - mPreviousFullscreenOverdrawBottomHeight = overdrawBottomHeight; if (mFullscreenManager == null) return; if (isNonFullscreenPage || isNativePage()) { @@ -2511,13 +2506,6 @@ } /** - * @return The most recent frame's overdraw bottom height in pixels. - */ - public float getFullscreenOverdrawBottomHeightPix() { - return mPreviousFullscreenOverdrawBottomHeight; - } - - /** * Add a new navigation entry for the current URL and page title. */ void pushNativePageStateToNavigationEntry() {
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index e50d72f..f61856a 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2000,6 +2000,39 @@ View </message> + <!-- Offline pages (Use 'bookmarks' name in UI strings) --> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_OFFLINE_PAGE_SIZE" desc="Label specifying that given saved page has an offline copy of a specific size (Use 'bookmarks' name in UI strings)."> + <ph name="PAGE_SIZE_STRING">%1$s<ex>1.32 MB</ex></ph> bookmark saved offline + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_OFFLINE_PAGE_VISIT" desc="Label specifying that given saved page does not have an offline copy, and user does not have that page open (Use 'bookmarks' name in UI strings)."> + Visit bookmark to save offline + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_PAGE_SAVED" desc="Message shown after user adds a new offline page (Use 'bookmarks' name in UI strings)."> + Bookmark saved offline + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_PAGE_SAVED_FOLDER" desc="Message shown after user saves a new offline page. Also specifies in which folder the bookmark was added (Use 'bookmarks' name in UI strings)."> + Bookmark saved offline to <ph name="FOLDER_NAME">%1$s<ex>Mobile bookmarks</ex></ph> + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_PAGE_SKIPPED" desc="Message shown after a page was saved as a bookmark, but an offline copy was not created due to that the page is not HTTP or HTTPS page (Use 'bookmarks' name in UI strings)."> + Bookmarked + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_PAGE_SAVED_STORAGE_NEAR_FULL" desc="Message shown after user adds a new offline page and the storage is almost full (Use 'bookmarks' name in UI strings)."> + Bookmark saved offline. Storage almost full. + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_PAGE_FAILED_TO_SAVE" desc="Message shown after a page was saved as a bookmark, but an offline copy was not created due to problems other than storage (Use 'bookmarks' name in UI strings)."> + Bookmark not available offline + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_PAGE_FAILED_TO_SAVE_STORAGE_NEAR_FULL" desc="Message shown after a page was saved as a bookmark, but an offline copy was not created due to storage problem (Use 'bookmarks' name in UI strings)."> + Bookmark not available offline. Storage almost full. + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_STORAGE_SPACE_MESSAGE" desc="Text explaining how much storage is currently used for offline copies of saved pages (Use 'bookmarks' name in UI strings)."> + Bookmarks are currently taking up <ph name="TOTAL_OFFLINE_STORAGE_SIZE">%1$s<ex>780 MB</ex></ph>. + </message> + <message name="IDS_OFFLINE_PAGES_AS_BOOKMARKS_VIEWING_OFFLINE_PAGE" desc="Text explaining that the user is viewing an offline copy of a web page (Use 'bookmarks' name in UI strings)."> + Viewing an offline copy of this bookmark + </message> + + <!-- Find in page --> <message name="IDS_HINT_FIND_IN_PAGE" desc="Hint text to show for the find in page search field when the search field is empty."> Find in page
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java index 9ffb8da..6833f0d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java
@@ -6,6 +6,7 @@ import android.content.Context; import android.content.Intent; +import android.test.FlakyTest; import android.test.suitebuilder.annotation.MediumTest; import org.chromium.base.test.util.Feature; @@ -114,6 +115,7 @@ /** * Check that the runnable gets posted and canceled when Main is sent to the background. */ + @FlakyTest // https://crbug.com/579363 @MediumTest @Feature({"Omaha", "Sync"}) public void testRunnableGetsCanceled() throws Exception {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java index 15031c93..8d425e08 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java
@@ -64,14 +64,6 @@ public void onPhysicalBackingSizeChanged(int width, int height) { } @Override - public void onOverdrawBottomHeightChanged(int overdrawHeight) {} - - @Override - public int getCurrentOverdrawBottomHeight() { - return 0; - } - - @Override public Context getContext() { return mContext; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastTestBase.java index f0b6bbf..5fe83fd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastTestBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastTestBase.java
@@ -616,12 +616,11 @@ ContentViewCore core = tab.getContentViewCore(); int clickX = (int) core.getRenderCoordinates().fromLocalCssToPix( - ((float) (rect.left + rect.right)) / 2) - + core.getViewportSizeOffsetWidthPix(); + ((float) (rect.left + rect.right)) / 2); int clickY = (int) core.getRenderCoordinates().fromLocalCssToPix( ((float) (rect.top + rect.bottom)) / 2) - + core.getViewportSizeOffsetHeightPix(); + + core.getTopControlsHeightPix(); // Click using a virtual mouse, since a touch may result in a disambiguation pop-up. mouseSingleClickView(getInstrumentation(), tab.getView(), clickX, clickY); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageFeatureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageFeatureTest.java new file mode 100644 index 0000000..b63e5a6 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageFeatureTest.java
@@ -0,0 +1,80 @@ +// 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. + +package org.chromium.chrome.browser.offlinepages; + +import android.test.UiThreadTest; +import android.test.suitebuilder.annotation.SmallTest; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.components.offlinepages.FeatureMode; +import org.chromium.content.browser.test.NativeLibraryTestBase; + +/** Unit tests for offline pages feature. */ +public class OfflinePageFeatureTest extends NativeLibraryTestBase { + @Override + protected void setUp() throws Exception { + super.setUp(); + loadNativeLibraryAndInitBrowserProcess(); + } + + @CommandLineFlags.Add({ChromeSwitches.ENABLE_OFFLINE_PAGES_AS_BOOKMARKS}) + @SmallTest + @UiThreadTest + public void testEnableOfflinePagesAsBookmarks() throws Exception { + assertEquals(FeatureMode.ENABLED_AS_BOOKMARKS, OfflinePageBridge.getFeatureMode()); + + /** String is not updated since the experiment switch asks for the "bookmarks" version. */ + assertEquals( + R.string.menu_bookmarks, OfflinePageUtils.getStringId(R.string.menu_bookmarks)); + /** String is not updated when no mapping exists. */ + assertEquals(R.string.bookmark_offline_page_none, + OfflinePageUtils.getStringId(R.string.bookmark_offline_page_none)); + } + + @CommandLineFlags.Add({ChromeSwitches.ENABLE_OFFLINE_PAGES_AS_SAVED_PAGES}) + @SmallTest + @UiThreadTest + public void testEnableOfflinePagesAsSavedPages() throws Exception { + assertEquals(FeatureMode.ENABLED_AS_SAVED_PAGES, OfflinePageBridge.getFeatureMode()); + + /** String is updated when a mapping is found. */ + assertEquals(R.string.menu_bookmarks_offline_pages, + OfflinePageUtils.getStringId(R.string.menu_bookmarks)); + /** String is not updated when no mapping exists. */ + assertEquals(R.string.bookmark_offline_page_none, + OfflinePageUtils.getStringId(R.string.bookmark_offline_page_none)); + } + + @CommandLineFlags.Add({ChromeSwitches.ENABLE_OFFLINE_PAGES}) + @SmallTest + @UiThreadTest + public void testEnableOfflinePages() throws Exception { + assertEquals(FeatureMode.ENABLED_AS_SAVED_PAGES, OfflinePageBridge.getFeatureMode()); + + /** String is not updated since the experiment switch asks for the "bookmarks" version. */ + assertEquals(R.string.menu_bookmarks_offline_pages, + OfflinePageUtils.getStringId(R.string.menu_bookmarks)); + /** String is not updated when no mapping exists. */ + assertEquals(R.string.bookmark_offline_page_none, + OfflinePageUtils.getStringId(R.string.bookmark_offline_page_none)); + } + + @CommandLineFlags.Add({ChromeSwitches.DISABLE_OFFLINE_PAGES}) + @SmallTest + @UiThreadTest + public void testDisableOfflinePages() throws Exception { + assertEquals(FeatureMode.DISABLED, OfflinePageBridge.getFeatureMode()); + + /** Strings are not updated regardless whether the mappings exist when the feature is + * disabled. + */ + assertEquals( + R.string.menu_bookmarks, OfflinePageUtils.getStringId(R.string.menu_bookmarks)); + assertEquals(R.string.bookmark_offline_page_none, + OfflinePageUtils.getStringId(R.string.bookmark_offline_page_none)); + } +}
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 0ccee99..2d8bfd4 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -14431,6 +14431,12 @@ <message name="IDS_FLAGS_OFFLINE_PAGES_DESCRIPTION" desc="Description for the flag to enable offline pages."> Enable storing pages locally for offline use. </message> + <message name="IDS_FLAGS_ENABLE_OFFLINE_PAGES_AS_BOOKMARKS" desc="Option to enable offline pages feature using name 'bookmarks' shown in user-visible strings"> + Enabled as bookmarks + </message> + <message name="IDS_FLAGS_ENABLE_OFFLINE_PAGES_AS_SAVED_PAGES" desc="Option to enable offline pages feature using name 'saved pages' shown in user-visible strings"> + Enabled as saved pages + </message> <message name="IDS_FLAGS_NTP_POPULAR_SITES_NAME" desc="Name for the flag to enable showing non-personalized popular suggestions on the New Tab Page, when no personal suggestions are available yet."> Show popular sites on the New Tab page </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7a40fc86..0cb7d73 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -507,6 +507,18 @@ }; #endif // defined(OS_ANDROID) +#if defined(OS_ANDROID) +const FeatureEntry::Choice kEnableOfflinePagesChoices[] = { + {IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", ""}, + {IDS_FLAGS_ENABLE_OFFLINE_PAGES_AS_BOOKMARKS, + switches::kEnableOfflinePagesAsBookmarks, ""}, + {IDS_FLAGS_ENABLE_OFFLINE_PAGES_AS_SAVED_PAGES, + switches::kEnableOfflinePagesAsSavedPages, ""}, + {IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, switches::kDisableOfflinePages, + ""}, +}; +#endif // defined(OS_ANDROID) + // RECORDING USER METRICS FOR FLAGS: // ----------------------------------------------------------------------------- // The first line of the entry is the internal name. If you'd like to gather @@ -1939,12 +1951,9 @@ MULTI_VALUE_TYPE(kProgressBarAnimationChoices)}, #endif // defined(OS_ANDROID) #if defined(OS_ANDROID) - {"offline-pages", - IDS_FLAGS_OFFLINE_PAGES_NAME, - IDS_FLAGS_OFFLINE_PAGES_DESCRIPTION, - kOsAndroid, - ENABLE_DISABLE_VALUE_TYPE(switches::kEnableOfflinePages, - switches::kDisableOfflinePages)}, + {"offline-pages-mode", IDS_FLAGS_OFFLINE_PAGES_NAME, + IDS_FLAGS_OFFLINE_PAGES_DESCRIPTION, kOsAndroid, + MULTI_VALUE_TYPE(kEnableOfflinePagesChoices)}, #endif // defined(OS_ANDROID) {"low-priority-iframes", IDS_FLAGS_LOW_PRIORITY_IFRAMES_UI_NAME,
diff --git a/chrome/browser/accessibility/accessibility_extension_api.cc b/chrome/browser/accessibility/accessibility_extension_api.cc index 851097e..70906a0 100644 --- a/chrome/browser/accessibility/accessibility_extension_api.cc +++ b/chrome/browser/accessibility/accessibility_extension_api.cc
@@ -10,9 +10,7 @@ #include "base/strings/string_number_conversions.h" #include "base/values.h" #include "build/build_config.h" -#include "chrome/browser/accessibility/accessibility_extension_api.h" #include "chrome/browser/extensions/api/tabs/tabs_constants.h" -#include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/infobars/infobar_service.h" @@ -29,7 +27,6 @@ #include "extensions/common/manifest_handlers/background_info.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h" #endif @@ -85,36 +82,3 @@ error_ = kErrorNotSupported; return false; } - -ExtensionFunction::ResponseAction -AccessibilityPrivateSetKeyboardListenerFunction::Run() { - ChromeExtensionFunctionDetails details(this); - CHECK(extension()); - -#if defined(OS_CHROMEOS) - bool enabled; - bool capture; - EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled)); - EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &capture)); - - chromeos::AccessibilityManager* manager = - chromeos::AccessibilityManager::Get(); - - const std::string current_id = manager->keyboard_listener_extension_id(); - if (!current_id.empty() && extension()->id() != current_id) - return RespondNow(Error("Existing keyboard listener registered.")); - - if (enabled) { - manager->SetKeyboardListenerExtensionId(extension()->id(), - details.GetProfile()); - manager->set_keyboard_listener_capture(capture); - } else { - manager->SetKeyboardListenerExtensionId(std::string(), - details.GetProfile()); - manager->set_keyboard_listener_capture(false); - } - return RespondNow(NoArguments()); -#endif // defined OS_CHROMEOS - - return RespondNow(Error(kErrorNotSupported)); -}
diff --git a/chrome/browser/accessibility/accessibility_extension_api.h b/chrome/browser/accessibility/accessibility_extension_api.h index 4f68eeb..43b60d7 100644 --- a/chrome/browser/accessibility/accessibility_extension_api.h +++ b/chrome/browser/accessibility/accessibility_extension_api.h
@@ -32,13 +32,4 @@ ACCESSIBILITY_PRIVATE_SETFOCUSRING) }; -// API function that sets keyboard capture mode. -class AccessibilityPrivateSetKeyboardListenerFunction - : public UIThreadExtensionFunction { - ~AccessibilityPrivateSetKeyboardListenerFunction() override {} - ResponseAction Run() override; - DECLARE_EXTENSION_FUNCTION("accessibilityPrivate.setKeyboardListener", - ACCESSIBILITY_PRIVATE_SETKEYBOARDLISTENER) -}; - #endif // CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EXTENSION_API_H_
diff --git a/chrome/browser/android/compositor/compositor_view.cc b/chrome/browser/android/compositor/compositor_view.cc index 2f94e838..6958080 100644 --- a/chrome/browser/android/compositor/compositor_view.cc +++ b/chrome/browser/android/compositor/compositor_view.cc
@@ -88,7 +88,6 @@ current_surface_format_(0), content_width_(0), content_height_(0), - overdraw_bottom_height_(0), overlay_video_mode_(false), empty_background_color_(empty_background_color), weak_factory_(this) { @@ -187,9 +186,7 @@ jfloat height, jfloat visible_x_offset, jfloat visible_y_offset, - jfloat overdraw_bottom_height, jfloat dp_to_pixel) { - overdraw_bottom_height_ = overdraw_bottom_height; compositor_->setDeviceScaleFactor(dp_to_pixel); root_layer_->SetBounds(gfx::Size(content_width_, content_height_)); } @@ -245,10 +242,6 @@ } } -int CompositorView::GetUsableContentHeight() { - return std::max(content_height_ - overdraw_bottom_height_, 0); -} - void CompositorView::UpdateToolbarLayer(JNIEnv* env, const JavaParamRef<jobject>& object, jint toolbar_resource_id,
diff --git a/chrome/browser/android/compositor/compositor_view.h b/chrome/browser/android/compositor/compositor_view.h index 1b3fbdb..1d7f4bb 100644 --- a/chrome/browser/android/compositor/compositor_view.h +++ b/chrome/browser/android/compositor/compositor_view.h
@@ -81,7 +81,6 @@ jfloat height, jfloat visible_x_offset, jfloat visible_y_offset, - jfloat overdraw_bottom_height, jfloat dp_to_pixel); void UpdateToolbarLayer(JNIEnv* env, const base::android::JavaParamRef<jobject>& object, @@ -140,8 +139,6 @@ void SetBackground(bool visible, SkColor color); - int GetUsableContentHeight(); - base::android::ScopedJavaGlobalRef<jobject> obj_; scoped_ptr<content::Compositor> compositor_; LayerTitleCache* layer_title_cache_; @@ -155,7 +152,6 @@ int current_surface_format_; int content_width_; int content_height_; - int overdraw_bottom_height_; bool overlay_video_mode_; SkColor empty_background_color_;
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.cc b/chrome/browser/android/offline_pages/offline_page_bridge.cc index 6101adc..716403c09 100644 --- a/chrome/browser/android/offline_pages/offline_page_bridge.cc +++ b/chrome/browser/android/offline_pages/offline_page_bridge.cc
@@ -67,9 +67,8 @@ } // namespace -static jboolean IsOfflinePagesEnabled(JNIEnv* env, - const JavaParamRef<jclass>& clazz) { - return offline_pages::IsOfflinePagesEnabled(); +static jint GetFeatureMode(JNIEnv* env, const JavaParamRef<jclass>& clazz) { + return static_cast<jint>(offline_pages::GetOfflinePageFeatureMode()); } static jboolean CanSavePage(JNIEnv* env,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index cd50af3..b3cdde7 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -192,6 +192,7 @@ #include "chrome/common/descriptors_android.h" #include "components/crash/content/browser/crash_dump_manager_android.h" #include "components/navigation_interception/intercept_navigation_delegate.h" +#include "components/offline_pages/offline_page_switches.h" #include "ui/base/resource/resource_bundle_android.h" #elif defined(OS_POSIX) #include "chrome/browser/chrome_browser_main_posix.h" @@ -1604,6 +1605,9 @@ #endif switches::kEnableNetBenchmarking, switches::kEnableNewBookmarkApps, +#if defined(OS_ANDROID) + switches::kEnableOfflinePagesAsBookmarks, +#endif switches::kJavaScriptHarmony, switches::kMessageLoopHistogrammer, switches::kPpapiFlashArgs,
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 00442a2..e18961c 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -411,7 +411,6 @@ scoped_braille_observer_(this), braille_ime_current_(false), chromevox_panel_(nullptr), - extension_registry_observer_(this), weak_ptr_factory_(this) { notification_registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, @@ -1162,18 +1161,6 @@ } } -void AccessibilityManager::OnExtensionUnloaded( - content::BrowserContext* browser_context, - const extensions::Extension* extension, - extensions::UnloadedExtensionInfo::Reason reason) { - if (extension->id() == keyboard_listener_extension_id_) { - keyboard_listener_extension_id_ = std::string(); - keyboard_listener_capture_ = false; - extension_registry_observer_.Remove( - extensions::ExtensionRegistry::Get(browser_context)); - } -} - void AccessibilityManager::PostLoadChromeVox(Profile* profile) { // Do any setup work needed immediately after ChromeVox actually loads. ash::PlaySystemSoundAlways(SOUND_SPOKEN_FEEDBACK_ENABLED); @@ -1224,15 +1211,4 @@ chromevox_panel_ = nullptr; } -void AccessibilityManager::SetKeyboardListenerExtensionId( - const std::string& id, - content::BrowserContext* context) { - keyboard_listener_extension_id_ = id; - - extensions::ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(context); - if (!extension_registry_observer_.IsObserving(registry) && !id.empty()) - extension_registry_observer_.Add(registry); -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h index 9b735095..ea9ebdc 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -79,7 +79,6 @@ class AccessibilityManager : public content::NotificationObserver, public extensions::api::braille_display_private::BrailleObserver, - public extensions::ExtensionRegistryObserver, public ash::SessionStateObserver, public ash::ShellObserver, public input_method::InputMethodManager::Observer { @@ -213,19 +212,6 @@ // Profile having the a11y context. Profile* profile() { return profile_; } - // Extension id of extension receiving keyboard events. - void SetKeyboardListenerExtensionId(const std::string& id, - content::BrowserContext* context); - const std::string& keyboard_listener_extension_id() { - return keyboard_listener_extension_id_; - } - - // Whether keyboard listener extension gets to capture keys. - void set_keyboard_listener_capture(bool val) { - keyboard_listener_capture_ = val; - } - bool keyboard_listener_capture() { return keyboard_listener_capture_; } - protected: AccessibilityManager(); ~AccessibilityManager() override; @@ -269,12 +255,6 @@ void OnBrailleKeyEvent( const extensions::api::braille_display_private::KeyEvent& event) override; - // ExtensionRegistryObserver implementation. - void OnExtensionUnloaded( - content::BrowserContext* browser_context, - const extensions::Extension* extension, - extensions::UnloadedExtensionInfo::Reason reason) override; - // InputMethodManager::Observer void InputMethodChanged(input_method::InputMethodManager* manager, Profile* profile, @@ -325,14 +305,6 @@ ChromeVoxPanel* chromevox_panel_; scoped_ptr<ChromeVoxPanelWidgetObserver> chromevox_panel_widget_observer_; - std::string keyboard_listener_extension_id_; - bool keyboard_listener_capture_; - - // Listen to extension unloaded notifications. - ScopedObserver<extensions::ExtensionRegistry, - extensions::ExtensionRegistryObserver> - extension_registry_observer_; - base::WeakPtrFactory<AccessibilityManager> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(AccessibilityManager);
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.cc index 6b1c91f..f4a6105 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.cc
@@ -30,8 +30,7 @@ } bool SpokenFeedbackEventRewriterDelegate::DispatchKeyEventToChromeVox( - const ui::KeyEvent& key_event, - bool capture) { + const ui::KeyEvent& key_event) { if (!chromeos::AccessibilityManager::Get()) return false; @@ -53,12 +52,8 @@ content::RenderViewHost* rvh = host->render_view_host(); - // Listen for any unhandled keyboard events from ChromeVox's background page - // when capturing keys to reinject. - if (capture) - host->host_contents()->SetDelegate(this); - else - host->host_contents()->SetDelegate(nullptr); + // Listen for any unhandled keyboard events from ChromeVox's background page. + host->host_contents()->SetDelegate(this); // Forward all key events to ChromeVox's background page. const content::NativeWebKeyboardEvent web_event(key_event); @@ -68,7 +63,7 @@ (key_event.key_code() <= ui::VKEY_F12)) return false; - return capture; + return true; } void SpokenFeedbackEventRewriterDelegate::HandleKeyboardEvent( @@ -126,15 +121,8 @@ event.type() != ui::ET_KEY_RELEASED)) return ui::EVENT_REWRITE_CONTINUE; - std::string extension_id = - chromeos::AccessibilityManager::Get()->keyboard_listener_extension_id(); - if (extension_id.empty()) - return ui::EVENT_REWRITE_CONTINUE; - - bool capture = - chromeos::AccessibilityManager::Get()->keyboard_listener_capture(); const ui::KeyEvent key_event = static_cast<const ui::KeyEvent&>(event); - if (delegate_->DispatchKeyEventToChromeVox(key_event, capture)) + if (delegate_->DispatchKeyEventToChromeVox(key_event)) return ui::EVENT_REWRITE_DISCARD; return ui::EVENT_REWRITE_CONTINUE; }
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h index 126b19c7..5afc35c 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h
@@ -26,8 +26,7 @@ virtual bool IsSpokenFeedbackEnabled() const; // Returns true when |key_event| is dispatched to ChromeVox. - virtual bool DispatchKeyEventToChromeVox(const ui::KeyEvent& key_event, - bool capture); + virtual bool DispatchKeyEventToChromeVox(const ui::KeyEvent& key_event); // WebContentsDelegate: void HandleKeyboardEvent(
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc index 7516d8ef0..4f0eb54 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc
@@ -54,8 +54,7 @@ return is_spoken_feedback_enabled_; } - bool DispatchKeyEventToChromeVox(const ui::KeyEvent& key_event, - bool capture) override { + bool DispatchKeyEventToChromeVox(const ui::KeyEvent& key_event) override { return dispatch_result_; }
diff --git a/chrome/browser/memory/tab_manager.cc b/chrome/browser/memory/tab_manager.cc index 405ea68..371d9837 100644 --- a/chrome/browser/memory/tab_manager.cc +++ b/chrome/browser/memory/tab_manager.cc
@@ -141,6 +141,22 @@ discard_once_ = true; else discard_once_ = false; + + // Check the variation parameter to see if a tab is to be protected for an + // amount of time after being backgrounded. The value is in seconds. + std::string minimum_protection_time_string = + variations::GetVariationParamValue(features::kAutomaticTabDiscarding.name, + "MinimumProtectionTime"); + if (!minimum_protection_time_string.empty()) { + unsigned int minimum_protection_time_seconds = 0; + if (base::StringToUint(minimum_protection_time_string, + &minimum_protection_time_seconds)) { + if (minimum_protection_time_seconds > 0) + minimum_protection_time_ = + base::TimeDelta::FromSeconds(minimum_protection_time_seconds); + } + } + #elif defined(OS_CHROMEOS) // On Chrome OS, tab manager is always started and tabs can be discarded more // than once. @@ -506,6 +522,14 @@ if (discard_once_ && GetWebContentsData(web_contents)->DiscardCount() > 0) return false; + // Do not discard a recently used tab. + if (minimum_protection_time_.InSeconds() > 0) { + auto delta = + NowTicks() - GetWebContentsData(web_contents)->LastInactiveTime(); + if (delta < minimum_protection_time_) + return false; + } + return true; } @@ -580,7 +604,9 @@ TabManager::WebContentsData* TabManager::GetWebContentsData( content::WebContents* contents) const { WebContentsData::CreateForWebContents(contents); - return WebContentsData::FromWebContents(contents); + auto web_contents_data = WebContentsData::FromWebContents(contents); + web_contents_data->set_test_tick_clock(test_tick_clock_); + return web_contents_data; } // static
diff --git a/chrome/browser/memory/tab_manager.h b/chrome/browser/memory/tab_manager.h index 2e93f3bb..cc838c9e 100644 --- a/chrome/browser/memory/tab_manager.h +++ b/chrome/browser/memory/tab_manager.h
@@ -108,6 +108,7 @@ FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardedTabKeepsLastActiveTime); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardWebContentsAt); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, IsInternalPage); + FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectRecentlyUsedTabs); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ReloadDiscardedTabContextMenu); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, TabManagerBasics); @@ -212,6 +213,10 @@ // Whether a tab can only ever discarded once. bool discard_once_; + // This allows protecting tabs for a certain amount of time after being + // backgrounded. + base::TimeDelta minimum_protection_time_; + #if defined(OS_CHROMEOS) scoped_ptr<TabManagerDelegate> delegate_; #endif
diff --git a/chrome/browser/memory/tab_manager_browsertest.cc b/chrome/browser/memory/tab_manager_browsertest.cc index 98f68162..a76e4e0 100644 --- a/chrome/browser/memory/tab_manager_browsertest.cc +++ b/chrome/browser/memory/tab_manager_browsertest.cc
@@ -5,6 +5,7 @@ #include "base/base_switches.h" #include "base/command_line.h" #include "base/memory/memory_pressure_listener.h" +#include "base/test/simple_test_tick_clock.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/memory/tab_manager.h" @@ -278,6 +279,45 @@ EXPECT_FALSE(tab_manager->DiscardTab()); } +// Makes sure that recently used tabs are protected, depending on the value of +// of |minimum_protection_time_|. +// TODO(georgesak): Move this to a unit test instead (requires change to API). +IN_PROC_BROWSER_TEST_F(TabManagerTest, ProtectRecentlyUsedTabs) { + const int protection_time = 5; + TabManager* tab_manager = g_browser_process->GetTabManager(); + ASSERT_TRUE(tab_manager); + + base::SimpleTestTickClock test_clock_; + tab_manager->set_test_tick_clock(&test_clock_); + + // Set the minimum time of protection. + tab_manager->minimum_protection_time_ = + base::TimeDelta::FromMinutes(protection_time); + + // Open 2 tabs, the second one being in the background. + ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL)); + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL(chrome::kChromeUIAboutURL), NEW_BACKGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + // Set the last inactive time of the background tab. + auto tab = browser()->tab_strip_model()->GetWebContentsAt(1); + tab_manager->GetWebContentsData(tab) + ->SetLastInactiveTime(test_clock_.NowTicks()); + + // Advance the clock for less than the protection time. + test_clock_.Advance(base::TimeDelta::FromMinutes(protection_time / 2)); + + // Should not be able to discard a tab. + ASSERT_FALSE(tab_manager->DiscardTab()); + + // Advance the clock for more than the protection time. + test_clock_.Advance(base::TimeDelta::FromMinutes(protection_time / 2 + 2)); + + // Should be able to discard the background tab now. + EXPECT_TRUE(tab_manager->DiscardTab()); +} + } // namespace memory #endif // OS_WIN || OS_CHROMEOS
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 05518590..4dde865 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -170,6 +170,9 @@ { key::kDefaultPopupsSetting, prefs::kManagedDefaultPopupsSetting, base::Value::TYPE_INTEGER }, + { key::kDefaultKeygenSetting, + prefs::kManagedDefaultKeygenSetting, + base::Value::TYPE_INTEGER }, { key::kAutoSelectCertificateForUrls, prefs::kManagedAutoSelectCertificateForUrls, base::Value::TYPE_LIST }, @@ -206,6 +209,12 @@ { key::kPopupsBlockedForUrls, prefs::kManagedPopupsBlockedForUrls, base::Value::TYPE_LIST }, + { key::kKeygenAllowedForUrls, + prefs::kManagedKeygenAllowedForUrls, + base::Value::TYPE_LIST }, + { key::kKeygenBlockedForUrls, + prefs::kManagedKeygenBlockedForUrls, + base::Value::TYPE_LIST }, { key::kNotificationsAllowedForUrls, prefs::kManagedNotificationsAllowedForUrls, base::Value::TYPE_LIST },
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/externs.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/externs.js index 8d6d6bc4..9b04b6d 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/externs.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/externs.js
@@ -23,13 +23,6 @@ }; /** - * @param {boolean} enabled - * @param {boolean} capture - */ -chrome.accessibilityPrivate.setKeyboardListener = function(enabled, capture) { -}; - -/** * @param {number} tabId * @param {function(Array<!Object>)} callback */
diff --git a/chrome/browser/resources/chromeos/chromevox/common/string_util.js b/chrome/browser/resources/chromeos/chromevox/common/string_util.js index 5b771c5a..6a6a7525 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/string_util.js +++ b/chrome/browser/resources/chromeos/chromevox/common/string_util.js
@@ -30,3 +30,46 @@ } return i; }; + +/** + * The last code point of the Unicode basic multilingual plane. + * Code points larger than this value are represented in UTF-16 by a surrogate + * pair, that is two code units. + * @const {number} + */ +StringUtil.MAX_BMP_CODEPOINT = 65535; + +/** + * Returns the offset after the code point denoted by |offset|. + * If |offset| points at a character that is not the first code unit of + * a valid code point, then |offset + 1| is returned. If there are no + * characters after the code point denoted by |offset|, then the length of + * |str| is returned. + * @param {string} str String of characters. + * @param {number} offset A valid character index in |str|. + * @return {number} A valid index of |str| or |str.length|. + */ +StringUtil.nextCodePointOffset = function(str, offset) { + if (offset >= str.length) + return str.length; + if (str.codePointAt(offset) > StringUtil.MAX_BMP_CODEPOINT) + return offset + 2; + return offset + 1; +}; + +/** + * Returns the offset of the first code unit of the last code point before + * |offset| in a string. If there is no valid code point right before + * |offset| (including if offset is zero), |offset -1| is returned. + * @param {string} str String of characters. + * @param {number} offset A valid character offset into |str|. + * @return {number} A valid character index into |str| (or -1 in the case + * where |offset| is 0). + */ +StringUtil.previousCodePointOffset = function(str, offset) { + if (offset <= 0) + return -1; + if (offset > 1 && str.codePointAt(offset - 2) > StringUtil.MAX_BMP_CODEPOINT) + return offset - 2; + return offset - 1; +};
diff --git a/chrome/browser/resources/chromeos/chromevox/common/string_util_test.unitjs b/chrome/browser/resources/chromeos/chromevox/common/string_util_test.unitjs index efd31a5a..4739f0c 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/string_util_test.unitjs +++ b/chrome/browser/resources/chromeos/chromevox/common/string_util_test.unitjs
@@ -30,3 +30,32 @@ assertEquals(0, lcpl('hello', '')); assertEquals(1, lcpl('hi', 'hello')); }); + +var EMOJI = String.fromCodePoint(0X1F30C); // Milky way +var INVALID_SURROGATE_PAIR = 'a' + EMOJI[0]; + +TEST_F('StringUtilUnitTest', 'previousCodePointOffset', function() { + var prev = StringUtil.previousCodePointOffset; + assertEquals(-1, prev('', 0)); + assertEquals(-1, prev('', -1)); + assertEquals(-1, prev('test', 0)); + assertEquals(0, prev('test', 1)); + assertEquals('test'.length - 1, prev('test', 'test'.length)); + assertEquals(0, prev('a' + EMOJI, 1)); + assertEquals(1, prev('a' + EMOJI + 'b', 3)); + assertEquals(1, prev(INVALID_SURROGATE_PAIR, INVALID_SURROGATE_PAIR.length)); + assertEquals(0, prev('a' + INVALID_SURROGATE_PAIR, 1)); +}); + +TEST_F('StringUtilUnitTest', 'nextCodePointOffset', function() { + var next = StringUtil.nextCodePointOffset; + assertEquals(0, next('', 0)); + assertEquals(0, next('', 1)); + assertEquals(1, next('test', 0)); + assertEquals('test'.length, next('test', 'test'.length - 1)); + assertEquals(1, next('a' + EMOJI, 0)); + assertEquals(EMOJI.length, next(EMOJI, 0)); + assertEquals(3, next('a' + EMOJI + 'b', 1)); + assertEquals(1, next(INVALID_SURROGATE_PAIR, 0)); + assertEquals(1, next('a' + INVALID_SURROGATE_PAIR, 0)); +});
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js index 7edc764e..281f5b9 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -123,9 +123,6 @@ // Live region handler. this.liveRegions_ = new LiveRegions(this); - - if (!chrome.accessibilityPrivate.setKeyboardListener) - chrome.accessibilityPrivate.setKeyboardListener = function() {}; }; Background.prototype = { @@ -156,13 +153,10 @@ if (chrome.commands && chrome.commands.onCommand.hasListener(this.onGotCommand)) chrome.commands.onCommand.removeListener(this.onGotCommand); - chrome.accessibilityPrivate.setKeyboardListener(false, false); } else { if (chrome.commands && !chrome.commands.onCommand.hasListener(this.onGotCommand)) chrome.commands.onCommand.addListener(this.onGotCommand); - chrome.accessibilityPrivate.setKeyboardListener( - true, cvox.ChromeVox.isStickyPrefOn); } chrome.tabs.query({active: true}, function(tabs) { @@ -470,11 +464,6 @@ cvox.ChromeVoxBackground.setPref('sticky', !cvox.ChromeVox.isStickyPrefOn, true); - - if (cvox.ChromeVox.isStickyPrefOn) - chrome.accessibilityPrivate.setKeyboardListener(true, true); - else - chrome.accessibilityPrivate.setKeyboardListener(true, false); break; default: return true;
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js index a351f811..2cac7aa 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
@@ -141,14 +141,19 @@ switch (unit) { case Unit.CHARACTER: // BOUND and DIRECTIONAL are the same for characters. - newIndex = dir == Dir.FORWARD ? newIndex + 1 : newIndex - 1; - if (newIndex < 0 || newIndex >= this.getText().length) { + var text = this.getText(); + newIndex = dir == Dir.FORWARD ? + StringUtil.nextCodePointOffset(text, newIndex) : + StringUtil.previousCodePointOffset(text, newIndex); + if (newIndex < 0 || newIndex >= text.length) { newNode = AutomationUtil.findNextNode( newNode, dir, AutomationPredicate.leafWithText); if (newNode) { + var newText = this.getText(newNode); newIndex = - dir == Dir.FORWARD ? 0 : this.getText(newNode).length - 1; - newIndex = newIndex == -1 ? 0 : newIndex; + dir == Dir.FORWARD ? 0 : + StringUtil.previousCodePointOffset(newText, newText.length); + newIndex = Math.max(newIndex, 0); } else { newIndex = this.index_; } @@ -243,7 +248,7 @@ } break; default: - throw 'Unrecognized unit: ' + unit; + throw Error('Unrecognized unit: ' + unit); } newNode = newNode || this.node_; newIndex = goog.isDef(newIndex) ? newIndex : this.index_;
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js index 79b8d77..64f95c5 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -331,7 +331,7 @@ ready: function() { this.elementReadyTimeMs_ = performance.now(); this.showSinkList_(); - this.updateMaxSinkListHeight(this.dialogHeight_); + this.updateElementPositioning_(); }, attached: function() { @@ -765,7 +765,7 @@ this.currentView_ = media_router.MediaRouterView.ISSUE; } else { this.async(function() { - this.updateMaxSinkListHeight(this.dialogHeight_); + this.updateElementPositioning_(); }); } }, @@ -1132,27 +1132,32 @@ }, /** - * Compute the new maximum height of the sink list and update the style. + * Update the position-related styling of some elements. * - * @param {number} dialogHeight The height of the Media Router dialog. + * @private */ - updateMaxSinkListHeight: function(dialogHeight) { - this.dialogHeight_ = dialogHeight; + updateElementPositioning_: function() { var headerHeight = this.$$('#container-header').offsetHeight; - var firstRunFlowHeight = - this.computeShowFirstRunFlow_(this.showFirstRunFlow, - this.currentView_) ? + var firstRunFlowHeight = this.$$('#first-run-flow') ? this.$$('#first-run-flow').offsetHeight : 0; - this.$['container-header'].style.marginTop = firstRunFlowHeight + 'px'; - this.$['sink-list-view'].style.marginTop = - firstRunFlowHeight + headerHeight + 'px'; - - // A non-blocking issue banner may appear below the sink list. var issueHeight = this.$$('#issue-banner') ? this.$$('#issue-banner').offsetHeight : 0; + this.$['container-header'].style.marginTop = firstRunFlowHeight + 'px'; + this.$['sink-list-view'].style.marginTop = + firstRunFlowHeight + headerHeight + 'px'; this.$['sink-list'].style.maxHeight = this.dialogHeight_ - headerHeight - firstRunFlowHeight - - issueHeight + 'px'; + issueHeight + 'px'; + }, + + /** + * Update the max dialog height and update the positioning of the elements. + * + * @param {number} height The max height of the Media Router dialog. + */ + updateMaxDialogHeight: function(height) { + this.dialogHeight_ = height; + this.updateElementPositioning_(); }, });
diff --git a/chrome/browser/resources/media_router/media_router_ui_interface.js b/chrome/browser/resources/media_router/media_router_ui_interface.js index fb53eff..44d9479 100644 --- a/chrome/browser/resources/media_router/media_router_ui_interface.js +++ b/chrome/browser/resources/media_router/media_router_ui_interface.js
@@ -107,7 +107,7 @@ * @param {number} height */ function updateMaxHeight(height) { - container.updateMaxSinkListHeight(height); + container.updateMaxDialogHeight(height); } return {
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 717381df..45656f3 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1059,7 +1059,8 @@ // Discarded tabs always get reloaded. // TODO(georgesak): Validate the usefulness of this. And if needed then move // to TabManager. - if (g_browser_process->GetTabManager()->IsTabDiscarded(new_contents)) + if (g_browser_process->GetTabManager() && + g_browser_process->GetTabManager()->IsTabDiscarded(new_contents)) chrome::Reload(this, CURRENT_TAB); // If we have any update pending, do it now.
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 7981349..446a75f 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -126,6 +126,7 @@ #include "ui/accessibility/ax_view_state.h" #include "ui/base/accelerators/accelerator.h" #include "ui/base/hit_test.h" +#include "ui/base/ime/input_method.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h" @@ -1706,6 +1707,8 @@ FROM_HERE, base::Bind(&BrowserView::ActivateAppModalDialog, activate_modal_dialog_factory_.GetWeakPtr())); #endif + GetNativeWindow()->GetHost()->GetInputMethod()->GetLogCollector()->AddString( + "BrowserView cannot be activated."); return false; }
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index e4fc38e0..dc2af782 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -2484,8 +2484,13 @@ tabs_.set_ideal_bounds(i, tabs_bounds[i]); } - const int new_tab_x = tabs_.ideal_bounds(tabs_.view_size() - 1).right() - - GetLayoutConstant(TABSTRIP_NEW_TAB_BUTTON_OVERLAP); + const int max_new_tab_x = width() - newtab_button_bounds_.width(); + // For non-stacked tabs the ideal bounds may go outside the bounds of the + // tabstrip. Constrain the x-coordinate of the new tab button so that it is + // always visible. + const int new_tab_x = std::min( + max_new_tab_x, tabs_.ideal_bounds(tabs_.view_size() - 1).right() - + GetLayoutConstant(TABSTRIP_NEW_TAB_BUTTON_OVERLAP)); const int old_max_x = newtab_button_bounds_.right(); newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, 0)); if (newtab_button_bounds_.right() != old_max_x)
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout.h b/chrome/browser/ui/views/tabs/tab_strip_layout.h index 508de75..147b7bc 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout.h +++ b/chrome/browser/ui/views/tabs/tab_strip_layout.h
@@ -44,7 +44,9 @@ std::vector<gfx::Rect>* tabs_bounds); // Calculates and returns the bounds of the tabs. |width| is the available -// width to use for tab layout. +// width to use for tab layout. This never sizes the tabs smaller then the +// minimum widths in TabSizeInfo, and as a result the calculated bounds may go +// beyond |width|. std::vector<gfx::Rect> CalculateBounds(const TabSizeInfo& tab_size_info, int num_pinned_tabs, int num_tabs,
diff --git a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc index 9c5d4d6f..d5354bc 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
@@ -160,6 +160,8 @@ return tab->HitTestPoint(point_in_tab_coords); } + void DoLayout() { tab_strip_->DoLayout(); } + // Owned by TabStrip. FakeBaseTabStripController* controller_; // Owns |tab_strip_|. @@ -347,7 +349,6 @@ tab_strip_->SetStackedLayout(true); tab_strip_->DoLayout(); - // Tests involving |left_tab|, which has part of its bounds occluded by // |active_tab|. @@ -614,3 +615,15 @@ // don't hit it. EXPECT_FALSE(tab_strip_->GetTooltipHandlerForPoint(gfx::Point(-1, 2))); } + +TEST_F(TabStripTest, NewTabButtonStaysVisible) { + const int kTabStripWidth = 500; + tab_strip_->SetBounds(0, 0, kTabStripWidth, 20); + + for (int i = 0; i < 100; ++i) + controller_->AddTab(i, (i == 0)); + + DoLayout(); + + EXPECT_LE(tab_strip_->GetNewTabButtonBounds().right(), kTabStripWidth); +}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index a424f37..1ad742e 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp
@@ -559,7 +559,8 @@ '../components/components.gyp:gcm_driver_java', '../components/components.gyp:invalidation_java', '../components/components.gyp:navigation_interception_java', - '../components/components.gyp:offline_pages_enums_java', + '../components/components.gyp:offline_page_feature_enums_java', + '../components/components.gyp:offline_page_model_enums_java', '../components/components.gyp:precache_java', '../components/components.gyp:safe_json_java', '../components/components.gyp:security_state_enums_java',
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 8417794..fb57a95 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -85,6 +85,7 @@ "//components/metrics:net", "//components/nacl/common:process_type", "//components/nacl/common:switches", + "//components/offline_pages:switches", "//components/omnibox/common", "//components/policy:policy_component_common", "//components/strings",
diff --git a/chrome/common/DEPS b/chrome/common/DEPS index 84bf958..ead1d81 100644 --- a/chrome/common/DEPS +++ b/chrome/common/DEPS
@@ -16,6 +16,7 @@ "+components/metrics/client_info.h", "+components/metrics/metrics_pref_names.h", "+components/nacl/common", + "+components/offline_pages/offline_page_feature.h", "+components/password_manager/core/common", "+components/printing/common", "+components/policy/core/common",
diff --git a/chrome/common/extensions/api/accessibility_private.json b/chrome/common/extensions/api/accessibility_private.json index a43cf9a..773a7f9 100644 --- a/chrome/common/extensions/api/accessibility_private.json +++ b/chrome/common/extensions/api/accessibility_private.json
@@ -58,23 +58,6 @@ "description": "Array of rectangles to draw the accessibility focus ring around." } ] - }, - { - "name": "setKeyboardListener", - "type": "function", - "description": "Sets the calling extension as a listener of all keyboard events optionally allowing the calling extension to capture/swallow the key event via DOM apis. Returns false via callback when unable to set the listener.", - "parameters": [ - { - "type": "boolean", - "name": "enabled", - "description": "True if the caller wants to listen to key events; false to stop listening to events. Note that there is only ever one extension listening to key events." - }, - { - "type": "boolean", - "name": "capture", - "description": "True if key events should be swallowed natively and not propagated if preventDefault() gets called by the extension's background page." - } - ] } ], "events": [
diff --git a/chrome/common/extensions/api/automation.idl b/chrome/common/extensions/api/automation.idl index cc5dde03..65e3adc 100644 --- a/chrome/common/extensions/api/automation.idl +++ b/chrome/common/extensions/api/automation.idl
@@ -53,6 +53,7 @@ // Describes the purpose of an $(ref:automation.AutomationNode). enum RoleType { + abbr, alertDialog, alert, annotation,
diff --git a/chrome/common/localized_error.cc b/chrome/common/localized_error.cc index 8ff1643..8867eca 100644 --- a/chrome/common/localized_error.cc +++ b/chrome/common/localized_error.cc
@@ -33,6 +33,10 @@ #include "base/win/windows_version.h" #endif +#if defined(OS_ANDROID) +#include "components/offline_pages/offline_page_feature.h" +#endif + using error_page::OfflinePageStatus; // Some error pages have no details. @@ -775,8 +779,11 @@ OfflinePageStatus::HAS_OTHER_OFFLINE_PAGES) { base::DictionaryValue* show_offline_pages_button = new base::DictionaryValue; - base::string16 button_text = - l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_SHOW_OFFLINE_PAGES); + base::string16 button_text = l10n_util::GetStringUTF16( + offline_pages::GetOfflinePageFeatureMode() == + offline_pages::FeatureMode::ENABLED_AS_BOOKMARKS + ? IDS_ERRORPAGES_BUTTON_SHOW_OFFLINE_PAGES_AS_BOOKMARKS + : IDS_ERRORPAGES_BUTTON_SHOW_OFFLINE_PAGES); show_offline_pages_button->SetString("msg", button_text); error_strings->Set("showOfflinePagesButton", show_offline_pages_button); }
diff --git a/chrome/test/data/chromeos/enterprise/policies b/chrome/test/data/chromeos/enterprise/policies index 35bb3d1..fad3993 100644 --- a/chrome/test/data/chromeos/enterprise/policies +++ b/chrome/test/data/chromeos/enterprise/policies
@@ -22,6 +22,7 @@ u'DefaultGeolocationSetting': 2, u'DefaultImagesSetting': 2, u'DefaultJavaScriptSetting': 2, + u'DefaultKeygenSetting': 2, u'DefaultNotificationsSetting': 2, u'DefaultPluginsSetting': 2, u'DefaultPopupsSetting': 2, @@ -83,6 +84,7 @@ u'DefaultGeolocationSetting': 3, u'DefaultImagesSetting': 1, u'DefaultJavaScriptSetting': 1, + u'DefaultKeygenSetting': 2, u'DefaultNotificationsSetting': 1, u'DefaultPluginsSetting': 1, u'DefaultPopupsSetting': 1, @@ -136,6 +138,7 @@ u'PolicyRefreshRate': 5400000, u'ProxyPacUrl': u'http://proxyconfig.corp.google.com/wpad.dat', u'DefaultJavaScriptSetting': 1, + u'DefaultKeygenSetting': 2, u'RestoreOnStartup': 4, u'DefaultSearchProviderSuggestURL': u'http://search.my.company/suggest?q={searchTerms}', @@ -197,6 +200,7 @@ u'DefaultCookiesSetting': 1, u'DefaultGeolocationSetting': 1, u'DefaultJavaScriptSetting': 1, + u'DefaultKeygenSetting': 2, u'DefaultNotificationsSetting': 1, u'DefaultPopupsSetting': 2, u'DefaultSearchProviderEnabled': True, @@ -273,6 +277,7 @@ u'DefaultGeolocationSetting': 2, u'DefaultImagesSetting': 2, u'DefaultJavaScriptSetting': 2, + u'DefaultKeygenSetting': 2, u'DefaultNotificationsSetting': 2, u'DefaultPluginsSetting': 2, u'DefaultPopupsSetting': 2, @@ -334,6 +339,7 @@ u'DefaultGeolocationSetting': 3, u'DefaultImagesSetting': 1, u'DefaultJavaScriptSetting': 1, + u'DefaultKeygenSetting': 2, u'DefaultNotificationsSetting': 1, u'DefaultPluginsSetting': 1, u'DefaultPopupsSetting': 1, @@ -387,6 +393,7 @@ u'PolicyRefreshRate': 5400000, u'ProxyPacUrl': u'http://proxyconfig.corp.google.com/wpad.dat', u'DefaultJavaScriptSetting': 1, + u'DefaultKeygenSetting': 2, u'RestoreOnStartup': 4, u'DefaultSearchProviderSuggestURL': u'http://search.my.company/suggest?q={searchTerms}', @@ -448,6 +455,7 @@ u'DefaultCookiesSetting': 1, u'DefaultGeolocationSetting': 1, u'DefaultJavaScriptSetting': 1, + u'DefaultKeygenSetting': 2, u'DefaultNotificationsSetting': 1, u'DefaultPopupsSetting': 2, u'DefaultSearchProviderEnabled': True,
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 68a08372..8bca4430 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -992,6 +992,24 @@ "note": "TODO(bartfab): Flag this with can_be_recommended when http://crbug.com/106682 is fixed." }, + "DefaultKeygenSetting": { + "os": ["win", "linux", "mac", "chromeos", "android"], + "test_policy": { "DefaultKeygenSetting": 2 }, + "pref_mappings": [ + { "pref": "profile.managed_default_content_settings.keygen", + "indicator_selector": "[content-setting=keygen]", + "indicator_tests": [ + { "policy": { "DefaultKeygenSetting": 1 }, + "value": "allow"}, + { "policy": { "DefaultKeygenSetting": 2 }, + "value": "block"} + ] + } + ], + + "note": "TODO(bartfab): Flag this with can_be_recommended when http://crbug.com/106682 is fixed." + }, + "DefaultPluginsSetting": { "os": ["win", "linux", "mac", "chromeos"], "test_policy": { "DefaultPluginsSetting": 2 }, @@ -1316,6 +1334,38 @@ "note": "TODO(bartfab): Flag this with can_be_recommended when http://crbug.com/106682 is fixed." }, + "KeygenAllowedForUrls": { + "os": ["win", "linux", "mac", "chromeos", "android"], + "test_policy": { "KeygenAllowedForUrls": ["[*.]google.com"] }, + "pref_mappings": [ + { "pref": "profile.managed_keygen_allowed_for_urls", + "indicator_test_setup_js": "document.querySelector('button.exceptions-list-button[contentType=keygen]').click();", + "indicator_selector": "[content-exception=keygen]", + "indicator_tests": [ + { "policy": { "KeygenAllowedForUrls": ["[*.]google.com"] } } + ] + } + ], + + "note": "TODO(bartfab): Flag this with can_be_recommended when http://crbug.com/106682 is fixed." + }, + + "KeygenBlockedForUrls": { + "os": ["win", "linux", "mac", "chromeos", "android"], + "test_policy": { "KeygenBlockedForUrls": ["[*.]google.com"] }, + "pref_mappings": [ + { "pref": "profile.managed_keygen_blocked_for_urls", + "indicator_test_setup_js": "document.querySelector('button.exceptions-list-button[contentType=keygen]').click();", + "indicator_selector": "[content-exception=keygen]", + "indicator_tests": [ + { "policy": { "KeygenBlockedForUrls": ["[*.]google.com"] } } + ] + } + ], + + "note": "TODO(bartfab): Flag this with can_be_recommended when http://crbug.com/106682 is fixed." + }, + "PluginsAllowedForUrls": { "os": ["win", "linux", "mac", "chromeos"], "test_policy": { "PluginsAllowedForUrls": ["[*.]google.com"] },
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastShellActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastShellActivity.java index f79b3345..ec3b3933 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastShellActivity.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastShellActivity.java
@@ -21,8 +21,8 @@ import org.chromium.base.CommandLine; import org.chromium.base.Log; -import org.chromium.content.browser.ActivityContentVideoViewClient; -import org.chromium.content.browser.ContentVideoViewClient; +import org.chromium.content.browser.ActivityContentVideoViewEmbedder; +import org.chromium.content.browser.ContentVideoViewEmbedder; import org.chromium.content.browser.ContentViewClient; import org.chromium.content.browser.ContentViewCore; import org.chromium.content.common.ContentSwitches; @@ -123,8 +123,8 @@ getActiveContentViewCore().setContentViewClient(new ContentViewClient() { @Override - public ContentVideoViewClient getContentVideoViewClient() { - return new ActivityContentVideoViewClient(CastShellActivity.this); + public ContentVideoViewEmbedder getContentVideoViewEmbedder() { + return new ActivityContentVideoViewEmbedder(CastShellActivity.this); } }); }
diff --git a/chromeos/binder/transaction_data_reader.cc b/chromeos/binder/transaction_data_reader.cc index 99eb0b8..b1006ab 100644 --- a/chromeos/binder/transaction_data_reader.cc +++ b/chromeos/binder/transaction_data_reader.cc
@@ -9,6 +9,7 @@ #include <linux/android/binder.h> +#include "base/logging.h" #include "chromeos/binder/local_object.h" #include "chromeos/binder/object.h" #include "chromeos/binder/remote_object.h"
diff --git a/components/error_page_strings.grdp b/components/error_page_strings.grdp index f18c2ce..8a66053 100644 --- a/components/error_page_strings.grdp +++ b/components/error_page_strings.grdp
@@ -30,6 +30,9 @@ </message> </if> <if expr="is_android"> + <message name="IDS_ERRORPAGES_BUTTON_SHOW_OFFLINE_PAGES_AS_BOOKMARKS" desc="Label for the button on an error page to show bookmarks that have been saved offline"> + Show all bookmarks + </message> <message name="IDS_ERRORPAGES_BUTTON_SHOW_OFFLINE_PAGES" desc="Label for the button on an error page to show pages that have been saved offline"> Show all saved pages </message>
diff --git a/components/offline_pages.gypi b/components/offline_pages.gypi index 33e34ae4..6ba8033 100644 --- a/components/offline_pages.gypi +++ b/components/offline_pages.gypi
@@ -70,8 +70,17 @@ ['OS == "android"', { 'targets': [ { - # GN: //components/offline_pages:offline_pages_enums_java - 'target_name': 'offline_pages_enums_java', + # GN: //components/offline_pages:offline_page_feature_enums_java + 'target_name': 'offline_page_feature_enums_java', + 'type': 'none', + 'variables': { + 'source_file': 'offline_pages/offline_page_feature.h', + }, + 'includes': [ '../build/android/java_cpp_enum.gypi' ], + }, + { + # GN: //components/offline_pages:offline_page_model_enums_java + 'target_name': 'offline_page_model_enums_java', 'type': 'none', 'variables': { 'source_file': 'offline_pages/offline_page_model.h',
diff --git a/components/offline_pages/BUILD.gn b/components/offline_pages/BUILD.gn index 26f2852..88dbd1e 100644 --- a/components/offline_pages/BUILD.gn +++ b/components/offline_pages/BUILD.gn
@@ -10,8 +10,6 @@ static_library("offline_pages") { sources = [ "offline_page_archiver.h", - "offline_page_feature.cc", - "offline_page_feature.h", "offline_page_item.cc", "offline_page_item.h", "offline_page_metadata_store.cc", @@ -20,11 +18,10 @@ "offline_page_metadata_store_impl.h", "offline_page_model.cc", "offline_page_model.h", - "offline_page_switches.cc", - "offline_page_switches.h", ] deps = [ + ":switches", "//base", "//components/bookmarks/browser", "//components/keyed_service/core", @@ -47,12 +44,26 @@ deps = [ ":offline_pages", + ":switches", "//base", "//testing/gtest", "//url", ] } +source_set("switches") { + sources = [ + "offline_page_feature.cc", + "offline_page_feature.h", + "offline_page_switches.cc", + "offline_page_switches.h", + ] + + deps = [ + "//base", + ] +} + source_set("unit_tests") { testonly = true sources = [ @@ -75,7 +86,13 @@ } if (is_android) { - java_cpp_enum("offline_pages_enums_java") { + java_cpp_enum("offline_page_feature_enums_java") { + sources = [ + "offline_page_feature.h", + ] + } + + java_cpp_enum("offline_page_model_enums_java") { sources = [ "offline_page_model.h", ]
diff --git a/components/offline_pages/offline_page_feature.cc b/components/offline_pages/offline_page_feature.cc index 586ed208..60f239b8 100644 --- a/components/offline_pages/offline_page_feature.cc +++ b/components/offline_pages/offline_page_feature.cc
@@ -17,22 +17,50 @@ namespace { const char kOfflinePagesFieldTrialName[] = "OfflinePages"; -const char kOfflinePagesFieldTrialEnabledGroupName[] = "Enabled"; +// The old experiment has only one mode to enable offline pages. +const char kEnabledGroupName[] = "Enabled"; +// The new experiment supports two modes for offline pages. +const char kEnabledAsBookmarksGroupName[] = "EnabledAsBookmarks"; +const char kEnabledAsSavedPagesGroupName[] = "EnabledAsSavedPages"; } // namespace -bool IsOfflinePagesEnabled() { +FeatureMode GetOfflinePageFeatureMode() { + // The old experiment 'Enabled' defaults to showing saved page. if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableOfflinePages)) { - return true; + return FeatureMode::ENABLED_AS_SAVED_PAGES; + } + // The new experiment can control showing either bookmark or saved page. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableOfflinePagesAsBookmarks)) { + return FeatureMode::ENABLED_AS_BOOKMARKS; + } + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableOfflinePagesAsSavedPages)) { + return FeatureMode::ENABLED_AS_SAVED_PAGES; } if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableOfflinePages)) { - return false; + return FeatureMode::DISABLED; } std::string group_name = base::FieldTrialList::FindFullName(kOfflinePagesFieldTrialName); - return group_name == kOfflinePagesFieldTrialEnabledGroupName; + // The old experiment 'Enabled' defaults to showing saved page. + if (group_name == kEnabledGroupName) + return FeatureMode::ENABLED_AS_SAVED_PAGES; + // The new experiment can control showing either bookmark or saved page. + if (group_name == kEnabledAsBookmarksGroupName) + return FeatureMode::ENABLED_AS_BOOKMARKS; + if (group_name == kEnabledAsSavedPagesGroupName) + return FeatureMode::ENABLED_AS_SAVED_PAGES; + return FeatureMode::DISABLED; +} + +bool IsOfflinePagesEnabled() { + FeatureMode mode = GetOfflinePageFeatureMode(); + return mode == FeatureMode::ENABLED_AS_BOOKMARKS || + mode == FeatureMode::ENABLED_AS_SAVED_PAGES; } } // namespace offline_pages
diff --git a/components/offline_pages/offline_page_feature.h b/components/offline_pages/offline_page_feature.h index 0bf6ad2..600140ff 100644 --- a/components/offline_pages/offline_page_feature.h +++ b/components/offline_pages/offline_page_feature.h
@@ -11,6 +11,19 @@ namespace offline_pages { +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.offlinepages +enum class FeatureMode { + // Offline pages feature is disabled. + DISABLED, + // Offline pages feature is enabled, showing bookmarks in UI strings. + ENABLED_AS_BOOKMARKS, + // Offline pages feature is enabled, showing saved pages in UI strings. + ENABLED_AS_SAVED_PAGES +}; + +// Returns the mode where Offline Pages feature is running. +FeatureMode GetOfflinePageFeatureMode(); + // Returns true if offline pages is enabled. bool IsOfflinePagesEnabled();
diff --git a/components/offline_pages/offline_page_switches.cc b/components/offline_pages/offline_page_switches.cc index 2a24c35c..e326a17 100644 --- a/components/offline_pages/offline_page_switches.cc +++ b/components/offline_pages/offline_page_switches.cc
@@ -12,4 +12,12 @@ // Disable Offline Pages. const char kDisableOfflinePages[] = "disable-offline-pages"; +// Enable Offline Pages showing "bookmarks" in UI strings. +const char kEnableOfflinePagesAsBookmarks[] = + "enable-offline-pages-as-bookmarks"; + +// Enable Offline Pages showing "saved pages" in UI strings. +const char kEnableOfflinePagesAsSavedPages[] = + "enable-offline-pages-as-saved-pages"; + } // namespace switches
diff --git a/components/offline_pages/offline_page_switches.h b/components/offline_pages/offline_page_switches.h index 4df0618..46e75c0 100644 --- a/components/offline_pages/offline_page_switches.h +++ b/components/offline_pages/offline_page_switches.h
@@ -9,6 +9,8 @@ extern const char kEnableOfflinePages[]; extern const char kDisableOfflinePages[]; +extern const char kEnableOfflinePagesAsBookmarks[]; +extern const char kEnableOfflinePagesAsSavedPages[]; } // namespace switches
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 5e23030..d32fe4f 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -137,7 +137,7 @@ # persistent IDs for all fields (but not for groups!) are needed. These are # specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs, # because doing so would break the deployed wire format! -# For your editing convenience: highest ID currently used: 312 +# For your editing convenience: highest ID currently used: 315 # # Placeholders: # The following placeholder strings are automatically substituted: @@ -3053,6 +3053,38 @@ If this policy is left not set, 'PromptOnAccess' will be used and the user will be able to change it.''', }, { + 'name': 'DefaultKeygenSetting', + 'type': 'int-enum', + 'schema': { + 'type': 'integer', + 'enum': [ 1, 2 ], + }, + 'items': [ + { + 'name': 'AllowKeygen', + 'value': 1, + 'caption': '''Allow all sites to use key generation''', + }, + { + 'name': 'BlockKeygen', + 'value': 2, + 'caption': '''Do not allow any site to use key generation''', + }, + ], + 'supported_on': ['chrome.*:49-', 'chrome_os:49-', 'android:49-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': 2, + 'id': 313, + 'caption': '''Default key generation setting''', + 'tags': ['system-security', 'website-sharing', 'local-data-access'], + 'desc': '''Allows you to set whether websites are allowed to use key generation. Using key generation can be either allowed for all websites or denied for all websites. + + If this policy is left not set, 'BlockKeygen' will be used and the user will be able to change it.''', + }, + { 'name': 'AutoSelectCertificateForUrls', 'type': 'list', 'schema': { @@ -3234,6 +3266,46 @@ If this policy is left not set the global default value will be used for all sites either from the 'DefaultJavaScriptSetting' policy if it is set, or the user's personal configuration otherwise.''', }, { + 'name': 'KeygenAllowedForUrls', + 'type': 'list', + 'schema': { + 'type': 'array', + 'items': { 'type': 'string' }, + }, + 'supported_on': ['chrome.*:49-', 'chrome_os:49-', 'android:49-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': ['https://www.example.com', '[*.]example.edu'], + 'id': 314, + 'caption': '''Allow key generation on these sites''', + 'tags': ['system-security', 'website-sharing', 'local-data-access'], + 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to use key generation. If a url pattern is in 'KeygenBlockedForUrls', that overrides these exceptions. + + If this policy is left not set the global default value will be used for all sites either from the 'DefaultKeygenSetting' policy if it is set, or the user's personal configuration otherwise.''', + }, + { + 'name': 'KeygenBlockedForUrls', + 'type': 'list', + 'schema': { + 'type': 'array', + 'items': { 'type': 'string' }, + }, + 'supported_on': ['chrome.*:49-', 'chrome_os:49-', 'android:49-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': ['https://www.example.com', '[*.]example.edu'], + 'id': 315, + 'caption': '''Block key generation on these sites''', + 'tags': ['system-security', 'website-sharing', 'local-data-access'], + 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to use key generation. If a url pattern is in 'KeygenAllowedForUrls', this policy overrides these exceptions. + + If this policy is left not set the global default value will be used for all sites either from the 'DefaultKeygenSetting' policy if it is set, or the user's personal configuration otherwise.''', + }, + { 'name': 'PluginsAllowedForUrls', 'type': 'list', 'schema': {
diff --git a/components/test_runner/web_ax_object_proxy.cc b/components/test_runner/web_ax_object_proxy.cc index 8c71884..347da31 100644 --- a/components/test_runner/web_ax_object_proxy.cc +++ b/components/test_runner/web_ax_object_proxy.cc
@@ -25,6 +25,8 @@ { std::string result = "AXRole: AX"; switch (role) { + case blink::WebAXRoleAbbr: + return result.append("Abbr"); case blink::WebAXRoleAlertDialog: return result.append("AlertDialog"); case blink::WebAXRoleAlert:
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 20beb7f..f28f11b 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -699,11 +699,7 @@ if (!parent) return false; - BrowserAccessibility* grandparent = parent->GetParent(); - if (!grandparent) - return false; - - return grandparent->GetRole() == ui::AX_ROLE_IFRAME_PRESENTATIONAL; + return parent->GetRole() == ui::AX_ROLE_IFRAME_PRESENTATIONAL; } bool BrowserAccessibility::IsControl() const {
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index 1505d34..45b0aa4 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -4612,6 +4612,7 @@ ia2_state |= IA2_STATE_SINGLE_LINE; ia2_state |= IA2_STATE_SELECTABLE_TEXT; break; + case ui::AX_ROLE_ABBR: case ui::AX_ROLE_TIME: role_name = html_tag; ia_role = ROLE_SYSTEM_TEXT;
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 1e4fe79..ba24d26 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -656,6 +656,9 @@ switches::kUseGL); if (gpu_driver_bugs_.find(gpu::DISABLE_D3D11) != gpu_driver_bugs_.end()) command_line->AppendSwitch(switches::kDisableD3D11); + if (gpu_driver_bugs_.find(gpu::DISABLE_DIRECT_COMPOSITION) != + gpu_driver_bugs_.end()) + command_line->AppendSwitch(switches::kDisableDirectComposition); if (use_swiftshader_) { command_line->AppendSwitchASCII(switches::kUseGL, "swiftshader"); } else if ((IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL) ||
diff --git a/content/browser/media/midi_host.cc b/content/browser/media/midi_host.cc index 30261ef7..d335364 100644 --- a/content/browser/media/midi_host.cc +++ b/content/browser/media/midi_host.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/metrics/histogram_macros.h" #include "base/process/process.h" #include "base/trace_event/trace_event.h" #include "content/browser/bad_message.h" @@ -234,6 +235,7 @@ // static bool MidiHost::IsValidWebMIDIData(const std::vector<uint8_t>& data) { bool in_sysex = false; + size_t sysex_start_offset = 0; size_t waiting_data_length = 0; for (size_t i = 0; i < data.size(); ++i) { const uint8_t current = data[i]; @@ -246,14 +248,18 @@ continue; // Found data byte as expected. } if (in_sysex) { - if (data[i] == kEndOfSysExByte) + if (data[i] == kEndOfSysExByte) { in_sysex = false; - else if (!IsDataByte(current)) + UMA_HISTOGRAM_COUNTS("Media.Midi.SysExMessageSizeUpTo1MB", + sysex_start_offset - i + 1); + } else if (!IsDataByte(current)) { return false; // Error: |current| should have been data byte. + } continue; // Found data byte as expected. } if (current == kSysExByte) { in_sysex = true; + sysex_start_offset = i; continue; // Found SysEX } waiting_data_length = media::midi::GetMidiMessageLength(current);
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index c0f6449..7a74672 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi
@@ -215,6 +215,7 @@ 'renderer/gpu/queue_message_swap_promise.h', 'renderer/gpu/render_widget_compositor.cc', 'renderer/gpu/render_widget_compositor.h', + 'renderer/gpu/render_widget_compositor_delegate.h', 'renderer/gpu/stream_texture_host_android.cc', 'renderer/gpu/stream_texture_host_android.h', 'renderer/history_controller.cc',
diff --git a/content/public/android/java/src/org/chromium/content/browser/ActivityContentVideoViewClient.java b/content/public/android/java/src/org/chromium/content/browser/ActivityContentVideoViewEmbedder.java similarity index 94% rename from content/public/android/java/src/org/chromium/content/browser/ActivityContentVideoViewClient.java rename to content/public/android/java/src/org/chromium/content/browser/ActivityContentVideoViewEmbedder.java index e2a914f..fece9d1 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ActivityContentVideoViewClient.java +++ b/content/public/android/java/src/org/chromium/content/browser/ActivityContentVideoViewEmbedder.java
@@ -16,11 +16,11 @@ /** * Uses an existing Activity to handle displaying video in full screen. */ -public class ActivityContentVideoViewClient implements ContentVideoViewClient { +public class ActivityContentVideoViewEmbedder implements ContentVideoViewEmbedder { private final Activity mActivity; private View mView; - public ActivityContentVideoViewClient(Activity activity) { + public ActivityContentVideoViewEmbedder(Activity activity) { this.mActivity = activity; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java b/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java index cdd6bf6..205d927 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java
@@ -69,7 +69,7 @@ // Progress view when the video is loading. private View mProgressView; - private final ContentVideoViewClient mClient; + private final ContentVideoViewEmbedder mEmbedder; private boolean mInitialOrientation; private boolean mPossibleAccidentalChange; @@ -146,10 +146,10 @@ }; private ContentVideoView(Context context, long nativeContentVideoView, - ContentVideoViewClient client) { + ContentVideoViewEmbedder embedder) { super(context); mNativeContentVideoView = nativeContentVideoView; - mClient = client; + mEmbedder = embedder; mUmaRecorded = false; mPossibleAccidentalChange = false; initResources(context); @@ -158,8 +158,8 @@ setVisibility(View.VISIBLE); } - private ContentVideoViewClient getContentVideoViewClient() { - return mClient; + private ContentVideoViewEmbedder getContentVideoViewEmbedder() { + return mEmbedder; } private void initResources(Context context) { @@ -183,7 +183,7 @@ ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER)); - mProgressView = mClient.getVideoLoadingProgressView(); + mProgressView = mEmbedder.getVideoLoadingProgressView(); if (mProgressView == null) { mProgressView = new ProgressView(getContext(), mVideoLoadingText); } @@ -305,9 +305,10 @@ ContentViewCore contentViewCore, long nativeContentVideoView) { ThreadUtils.assertOnUiThread(); Context context = contentViewCore.getContext(); - ContentVideoViewClient client = contentViewCore.getContentVideoViewClient(); - ContentVideoView videoView = new ContentVideoView(context, nativeContentVideoView, client); - client.enterFullscreenVideo(videoView); + ContentVideoViewEmbedder embedder = contentViewCore.getContentVideoViewEmbedder(); + ContentVideoView videoView = + new ContentVideoView(context, nativeContentVideoView, embedder); + embedder.enterFullscreenVideo(videoView); return videoView; } @@ -342,7 +343,7 @@ * Called when the fullscreen window gets focused. */ public void onFullscreenWindowFocused() { - mClient.setSystemUiVisibility(true); + mEmbedder.setSystemUiVisibility(true); } /** @@ -356,7 +357,7 @@ setVisibility(View.GONE); // To prevent re-entrance, call this after removeSurfaceView. - mClient.exitFullscreenVideo(); + mEmbedder.exitFullscreenVideo(); } if (nativeViewDestroyed) { mNativeContentVideoView = 0;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentVideoViewClient.java b/content/public/android/java/src/org/chromium/content/browser/ContentVideoViewEmbedder.java similarity index 97% rename from content/public/android/java/src/org/chromium/content/browser/ContentVideoViewClient.java rename to content/public/android/java/src/org/chromium/content/browser/ContentVideoViewEmbedder.java index a8424b0..198a5a2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentVideoViewClient.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentVideoViewEmbedder.java
@@ -18,7 +18,7 @@ * The implementer is responsible for displaying the Android view when * {@link #enterFullscreenVideo(View)} is called. */ -public interface ContentVideoViewClient { +public interface ContentVideoViewEmbedder { /** * Called when the {@link ContentVideoView}, which contains the fullscreen video, * is ready to be shown. Must be implemented.
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java index 6ebab15..ccf76b05 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java
@@ -46,11 +46,9 @@ * Notifies the client that the position of the top controls has changed. * @param topControlsOffsetYPix The Y offset of the top controls in physical pixels. * @param contentOffsetYPix The Y offset of the content in physical pixels. - * @param overdrawBottomHeightPix The overdraw height. */ public void onOffsetsForFullscreenChanged( - float topControlsOffsetYPix, float contentOffsetYPix, float overdrawBottomHeightPix) { - } + float topControlsOffsetYPix, float contentOffsetYPix) { } public boolean shouldOverrideKeyEvent(KeyEvent event) { int keyCode = event.getKeyCode(); @@ -153,7 +151,7 @@ } } - public ContentVideoViewClient getContentVideoViewClient() { + public ContentVideoViewEmbedder getContentVideoViewEmbedder() { return null; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 67c1dfa..86db2eb 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -1038,17 +1038,6 @@ return mPhysicalBackingHeightPix; } - /* TODO(aelias): Remove these when downstream callers disappear. */ - @VisibleForTesting - public int getViewportSizeOffsetWidthPix() { - return 0; - } - - @VisibleForTesting - public int getViewportSizeOffsetHeightPix() { - return mTopControlsShrinkBlinkSize ? mTopControlsHeightPix : 0; - } - /** * @return The amount that the viewport size given to Blink is shrunk by the URL-bar.. */ @@ -2363,7 +2352,7 @@ final float controlsOffsetPix = controlsOffsetYCss * deviceScale; // TODO(aelias): Remove last argument after downstream removes it. getContentViewClient().onOffsetsForFullscreenChanged( - controlsOffsetPix, contentOffsetYPix, 0); + controlsOffsetPix, contentOffsetYPix); if (mBrowserAccessibilityManager != null) { mBrowserAccessibilityManager.notifyFrameInfoInitialized(); @@ -3143,8 +3132,8 @@ return mWheelScrollFactorInPixels; } - ContentVideoViewClient getContentVideoViewClient() { - return getContentViewClient().getContentVideoViewClient(); + ContentVideoViewEmbedder getContentVideoViewEmbedder() { + return getContentViewClient().getContentVideoViewEmbedder(); } @CalledByNative
diff --git a/content/renderer/accessibility/blink_ax_enum_conversion.cc b/content/renderer/accessibility/blink_ax_enum_conversion.cc index 1c56d5a..88f0fff 100644 --- a/content/renderer/accessibility/blink_ax_enum_conversion.cc +++ b/content/renderer/accessibility/blink_ax_enum_conversion.cc
@@ -92,6 +92,8 @@ ui::AXRole AXRoleFromBlink(blink::WebAXRole role) { switch (role) { + case blink::WebAXRoleAbbr: + return ui::AX_ROLE_ABBR; case blink::WebAXRoleAlert: return ui::AX_ROLE_ALERT; case blink::WebAXRoleAlertDialog:
diff --git a/content/renderer/accessibility/renderer_accessibility_browsertest.cc b/content/renderer/accessibility/renderer_accessibility_browsertest.cc index 0c6958e..f085593 100644 --- a/content/renderer/accessibility/renderer_accessibility_browsertest.cc +++ b/content/renderer/accessibility/renderer_accessibility_browsertest.cc
@@ -403,38 +403,4 @@ // so we don't have a test expectation for it. } -TEST_F(RendererAccessibilityTest, EventOnObjectNotInTree) { - // Test RendererAccessibility and make sure it doesn't send anything - // if we get a notification from Blink for an object that isn't in the - // tree, like the scroll area that's the parent of the main document, - // which we don't expose. - std::string html = "<body><input></body>"; - LoadHTML(html.c_str()); - - scoped_ptr<TestRendererAccessibility> accessibility( - new TestRendererAccessibility(frame())); - accessibility->SendPendingAccessibilityEvents(); - EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser()); - - WebDocument document = view()->GetWebView()->mainFrame()->document(); - WebAXObject root_obj = document.accessibilityObject(); - WebAXObject scroll_area = root_obj.parentObject(); - EXPECT_EQ(blink::WebAXRoleScrollArea, scroll_area.role()); - - // Try to fire a message on the scroll area, and assert that we just - // ignore it. - sink_->ClearMessages(); - accessibility->HandleAXEvent(scroll_area, - ui::AX_EVENT_VALUE_CHANGED); - - accessibility->SendPendingAccessibilityEvents(); - - const IPC::Message* message = - sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID); - ASSERT_TRUE(message); - base::Tuple<std::vector<AccessibilityHostMsg_EventParams>, int> param; - AccessibilityHostMsg_Events::Read(message, ¶m); - ASSERT_EQ(0U, base::get<0>(param).size()); -} - } // namespace content
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index 4048e3b..beaae753 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -45,6 +45,7 @@ #include "content/common/content_switches_internal.h" #include "content/common/gpu/client/context_provider_command_buffer.h" #include "content/public/common/content_switches.h" +#include "content/renderer/gpu/render_widget_compositor_delegate.h" #include "content/renderer/input/input_handler_manager.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/service/gpu_switches.h" @@ -54,7 +55,6 @@ #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" #include "third_party/WebKit/public/web/WebSelection.h" -#include "third_party/WebKit/public/web/WebWidget.h" #include "ui/gl/gl_switches.h" #include "ui/native_theme/native_theme_switches.h" @@ -135,7 +135,7 @@ return cc_selection; } -gfx::Size CalculateDefaultTileSize(RenderWidget* widget) { +gfx::Size CalculateDefaultTileSize(float initial_device_scale_factor) { int default_tile_size = 256; #if defined(OS_ANDROID) // TODO(epenner): unify this for all platforms if it @@ -180,7 +180,7 @@ } #elif defined(OS_CHROMEOS) // Use 512 for high DPI (dsf=2.0f) devices. - if (widget->screen_info().deviceScaleFactor >= 2.0f) + if (initial_device_scale_factor >= 2.0f) default_tile_size = 512; #endif @@ -205,27 +205,27 @@ // static scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create( - RenderWidget* widget, + RenderWidgetCompositorDelegate* delegate, + float device_scale_factor, CompositorDependencies* compositor_deps) { scoped_ptr<RenderWidgetCompositor> compositor( - new RenderWidgetCompositor(widget, compositor_deps)); - compositor->Initialize(); + new RenderWidgetCompositor(delegate, compositor_deps)); + compositor->Initialize(device_scale_factor); return compositor; } RenderWidgetCompositor::RenderWidgetCompositor( - RenderWidget* widget, + RenderWidgetCompositorDelegate* delegate, CompositorDependencies* compositor_deps) : num_failed_recreate_attempts_(0), - widget_(widget), + delegate_(delegate), compositor_deps_(compositor_deps), never_visible_(false), layout_and_paint_async_callback_(nullptr), remote_proto_channel_receiver_(nullptr), - weak_factory_(this) { -} + weak_factory_(this) {} -void RenderWidgetCompositor::Initialize() { +void RenderWidgetCompositor::Initialize(float device_scale_factor) { base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); cc::LayerTreeSettings settings; @@ -257,7 +257,7 @@ blink::WebRuntimeFeatures::enableCompositorAnimationTimelines( settings.use_compositor_animation_timelines); - settings.default_tile_size = CalculateDefaultTileSize(widget_); + settings.default_tile_size = CalculateDefaultTileSize(device_scale_factor); if (cmd->HasSwitch(switches::kDefaultTileWidth)) { int tile_width = 0; GetSwitchValueAsInt(*cmd, @@ -456,7 +456,7 @@ settings.renderer_settings.use_rgba_4444_textures &= !cmd->HasSwitch(switches::kDisableRGBA4444Textures); - if (widget_->for_oopif()) { + if (delegate_->ForOOPIF()) { // TODO(simonhong): Apply BeginFrame scheduling for OOPIF. // See crbug.com/471411. settings.use_external_begin_frame_source = false; @@ -489,8 +489,7 @@ scoped_ptr<cc::BeginFrameSource> external_begin_frame_source; if (settings.use_external_begin_frame_source) { - external_begin_frame_source = - compositor_deps_->CreateExternalBeginFrameSource(widget_->routing_id()); + external_begin_frame_source = delegate_->CreateExternalBeginFrameSource(); } cc::LayerTreeHost::InitParams params; @@ -865,7 +864,7 @@ } void RenderWidgetCompositor::WillBeginMainFrame() { - widget_->WillBeginCompositorFrame(); + delegate_->WillBeginCompositorFrame(); } void RenderWidgetCompositor::DidBeginMainFrame() { @@ -874,7 +873,7 @@ void RenderWidgetCompositor::BeginMainFrame(const cc::BeginFrameArgs& args) { compositor_deps_->GetRendererScheduler()->WillBeginFrame(args); double frame_time_sec = (args.frame_time - base::TimeTicks()).InSecondsF(); - widget_->webwidget()->beginFrame(frame_time_sec); + delegate_->BeginMainFrame(frame_time_sec); } void RenderWidgetCompositor::BeginMainFrameNotExpectedSoon() { @@ -882,8 +881,7 @@ } void RenderWidgetCompositor::UpdateLayerTreeHost() { - widget_->webwidget()->updateAllLifecyclePhases(); - + delegate_->UpdateVisualState(); if (temporary_copy_output_request_) { // For WebViewImpl, this will always have a root layer. For other widgets, // the widget may be closed before servicing this request, so ignore it. @@ -903,24 +901,22 @@ const gfx::Vector2dF& elastic_overscroll_delta, float page_scale, float top_controls_delta) { - widget_->webwidget()->applyViewportDeltas( - inner_delta, - outer_delta, - elastic_overscroll_delta, - page_scale, - top_controls_delta); + delegate_->ApplyViewportDeltas(inner_delta, outer_delta, + elastic_overscroll_delta, page_scale, + top_controls_delta); } void RenderWidgetCompositor::RequestNewOutputSurface() { // If the host is closing, then no more compositing is possible. This // prevents shutdown races between handling the close message and // the CreateOutputSurface task. - if (widget_->host_closing()) + if (delegate_->IsClosing()) return; bool fallback = num_failed_recreate_attempts_ >= OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK; - scoped_ptr<cc::OutputSurface> surface(widget_->CreateOutputSurface(fallback)); + scoped_ptr<cc::OutputSurface> surface( + delegate_->CreateOutputSurface(fallback)); if (!surface) { DidFailToInitializeOutputSurface(); @@ -954,35 +950,35 @@ void RenderWidgetCompositor::DidCommit() { DCHECK(!temporary_copy_output_request_); - widget_->DidCommitCompositorFrame(); + delegate_->DidCommitCompositorFrame(); compositor_deps_->GetRendererScheduler()->DidCommitFrameToCompositor(); } void RenderWidgetCompositor::DidCommitAndDrawFrame() { - widget_->DidCommitAndDrawCompositorFrame(); + delegate_->DidCommitAndDrawCompositorFrame(); } void RenderWidgetCompositor::DidCompleteSwapBuffers() { - widget_->DidCompleteSwapBuffers(); + delegate_->DidCompleteSwapBuffers(); bool threaded = !!compositor_deps_->GetCompositorImplThreadTaskRunner().get(); if (!threaded) - widget_->OnSwapBuffersComplete(); + delegate_->OnSwapBuffersComplete(); } void RenderWidgetCompositor::DidCompletePageScaleAnimation() { - widget_->DidCompletePageScaleAnimation(); + delegate_->DidCompletePageScaleAnimation(); } void RenderWidgetCompositor::ScheduleAnimation() { - widget_->scheduleAnimation(); + delegate_->ScheduleAnimation(); } void RenderWidgetCompositor::DidPostSwapBuffers() { - widget_->OnSwapBuffersPosted(); + delegate_->OnSwapBuffersPosted(); } void RenderWidgetCompositor::DidAbortSwapBuffers() { - widget_->OnSwapBuffersAborted(); + delegate_->OnSwapBuffersAborted(); } void RenderWidgetCompositor::SetProtoReceiver(ProtoReceiver* receiver) { @@ -995,39 +991,14 @@ size_t unsigned_size = base::checked_cast<size_t>(signed_size); std::vector<uint8_t> serialized(unsigned_size); proto.SerializeToArray(serialized.data(), signed_size); - widget_->ForwardCompositorProto(serialized); + delegate_->ForwardCompositorProto(serialized); } void RenderWidgetCompositor::RecordFrameTimingEvents( scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events, scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> main_frame_events) { - for (const auto& composite_event : *composite_events ) { - int64_t frameId = composite_event.first; - const std::vector<cc::FrameTimingTracker::CompositeTimingEvent>& events = - composite_event.second; - std::vector<blink::WebFrameTimingEvent> webEvents; - for (size_t i = 0; i < events.size(); ++i) { - webEvents.push_back(blink::WebFrameTimingEvent( - events[i].frame_id, - (events[i].timestamp - base::TimeTicks()).InSecondsF())); - } - widget_->webwidget()->recordFrameTimingEvent( - blink::WebWidget::CompositeEvent, frameId, webEvents); - } - for (const auto& main_frame_event : *main_frame_events ) { - int64_t frameId = main_frame_event.first; - const std::vector<cc::FrameTimingTracker::MainFrameTimingEvent>& events = - main_frame_event.second; - std::vector<blink::WebFrameTimingEvent> webEvents; - for (size_t i = 0; i < events.size(); ++i) { - webEvents.push_back(blink::WebFrameTimingEvent( - events[i].frame_id, - (events[i].timestamp - base::TimeTicks()).InSecondsF(), - (events[i].end_time - base::TimeTicks()).InSecondsF())); - } - widget_->webwidget()->recordFrameTimingEvent( - blink::WebWidget::RenderEvent, frameId, webEvents); - } + delegate_->RecordFrameTimingEvents(std::move(composite_events), + std::move(main_frame_events)); } void RenderWidgetCompositor::SetSurfaceIdNamespace(
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h index 0eac7cd..9600506a 100644 --- a/content/renderer/gpu/render_widget_compositor.h +++ b/content/renderer/gpu/render_widget_compositor.h
@@ -42,7 +42,8 @@ } namespace content { -class RenderWidget; + +class RenderWidgetCompositorDelegate; class CONTENT_EXPORT RenderWidgetCompositor : NON_EXPORTED_BASE(public blink::WebLayerTreeView), @@ -53,7 +54,8 @@ // Attempt to construct and initialize a compositor instance for the widget // with the given settings. Returns NULL if initialization fails. static scoped_ptr<RenderWidgetCompositor> Create( - RenderWidget* widget, + RenderWidgetCompositorDelegate* delegate, + float device_scale_factor, CompositorDependencies* compositor_deps); ~RenderWidgetCompositor() override; @@ -184,10 +186,10 @@ }; protected: - RenderWidgetCompositor(RenderWidget* widget, + RenderWidgetCompositor(RenderWidgetCompositorDelegate* delegate, CompositorDependencies* compositor_deps); - void Initialize(); + void Initialize(float device_scale_factor); cc::LayerTreeHost* layer_tree_host() { return layer_tree_host_.get(); } private: @@ -197,8 +199,8 @@ void SynchronouslyComposite(); int num_failed_recreate_attempts_; - RenderWidget* widget_; - CompositorDependencies* compositor_deps_; + RenderWidgetCompositorDelegate* const delegate_; + CompositorDependencies* const compositor_deps_; scoped_ptr<cc::LayerTreeHost> layer_tree_host_; bool never_visible_;
diff --git a/content/renderer/gpu/render_widget_compositor_delegate.h b/content/renderer/gpu/render_widget_compositor_delegate.h new file mode 100644 index 0000000..94ed1e6 --- /dev/null +++ b/content/renderer/gpu/render_widget_compositor_delegate.h
@@ -0,0 +1,103 @@ +// 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. + +#ifndef CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_DELEGATE_H_ +#define CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_DELEGATE_H_ + +#include "cc/debug/frame_timing_tracker.h" + +namespace blink { +class WebWidget; +struct WebScreenInfo; +} + +namespace cc { +class BeginFrameSource; +class OutputSurface; +} + +namespace content { + +// Consumers of RenderWidgetCompositor implement this delegate in order to +// transport compositing information across processes. +class CONTENT_EXPORT RenderWidgetCompositorDelegate { + public: + // Report viewport related properties during a commit from the compositor + // thread. + virtual void ApplyViewportDeltas( + const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, + const gfx::Vector2dF& elastic_overscroll_delta, + float page_scale, + float top_controls_delta) = 0; + + // Notifies that the compositor has issed a BeginMainFrame. + virtual void BeginMainFrame(double frame_time_sec) = 0; + + // Requests an OutputSurface to render into. + virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback) = 0; + + // Requests an external BeginFrameSource from the delegate. + virtual scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource() = 0; + + // Notifies that the draw commands for a committed frame have been issued. + virtual void DidCommitAndDrawCompositorFrame() = 0; + + // Notifies about a compositor frame commit operation having finished. + virtual void DidCommitCompositorFrame() = 0; + + // Called by the compositor when page scale animation completed. + virtual void DidCompletePageScaleAnimation() = 0; + + // Notifies that the compositor has posted a swapbuffers operation to the GPU + // process. + virtual void DidCompleteSwapBuffers() = 0; + + // TODO(simonhong, fsamuel): Remove this once crbug.com/471411 is resolved. + // Indicates whether this RenderWidgetCompositor is for an out-of-process + // iframe or not. + virtual bool ForOOPIF() const = 0; + + // Called by the compositor to forward a proto that represents serialized + // compositor state. + virtual void ForwardCompositorProto(const std::vector<uint8_t>& proto) = 0; + + // Indicates whether the RenderWidgetCompositor is about to close. + virtual bool IsClosing() const = 0; + + // Called by the compositor in single-threaded mode when a swap is aborted. + virtual void OnSwapBuffersAborted() = 0; + + // Called by the compositor in single-threaded mode when a swap completes. + virtual void OnSwapBuffersComplete() = 0; + + // Called by the compositor in single-threaded mode when a swap is posted. + virtual void OnSwapBuffersPosted() = 0; + + // Called by the compositor to request the delegate to record frame timing. + virtual void RecordFrameTimingEvents( + scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events, + scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> + main_frame_events) = 0; + + // Requests that the client schedule a composite now, and calculate + // appropriate delay for potential future frame. + virtual void ScheduleAnimation() = 0; + + // Requests a visual frame-based update to the state of the delegate if there + // an update available. + virtual void UpdateVisualState() = 0; + + // Indicates that the compositor is about to begin a frame. This is primarily + // to signal to flow control mechanisms that a frame is beginning, not to + // perform actual painting work. + virtual void WillBeginCompositorFrame() = 0; + + protected: + virtual ~RenderWidgetCompositorDelegate() {} +}; + +} // namespace content + +#endif // CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_DELEGATE_H_
diff --git a/content/renderer/gpu/render_widget_compositor_unittest.cc b/content/renderer/gpu/render_widget_compositor_unittest.cc index 228fc47b..b217639 100644 --- a/content/renderer/gpu/render_widget_compositor_unittest.cc +++ b/content/renderer/gpu/render_widget_compositor_unittest.cc
@@ -62,9 +62,10 @@ RenderWidgetCompositorTest() : compositor_deps_(new FakeCompositorDependencies), render_widget_(new TestRenderWidget(compositor_deps_.get())), - render_widget_compositor_( - RenderWidgetCompositor::Create(render_widget_.get(), - compositor_deps_.get())) {} + render_widget_compositor_(RenderWidgetCompositor::Create( + render_widget_.get(), + 1.f /* initial_device_scale_factor */, + compositor_deps_.get())) {} ~RenderWidgetCompositorTest() override {} protected: @@ -243,7 +244,8 @@ render_widget_(new RenderWidgetOutputSurface(compositor_deps_.get())) { render_widget_compositor_.reset(new RenderWidgetCompositorOutputSurface( render_widget_.get(), compositor_deps_.get())); - render_widget_compositor_->Initialize(); + render_widget_compositor_->Initialize( + 1.f /* initial_device_scale_factor */); render_widget_->SetCompositor(render_widget_compositor_.get()); }
diff --git a/content/renderer/media/media_stream_audio_processor.cc b/content/renderer/media/media_stream_audio_processor.cc index 1deb1e4..3ec7fa4 100644 --- a/content/renderer/media/media_stream_audio_processor.cc +++ b/content/renderer/media/media_stream_audio_processor.cc
@@ -439,8 +439,13 @@ int sample_rate, int audio_delay_milliseconds) { DCHECK(render_thread_checker_.CalledOnValidThread()); - DCHECK(audio_processing_->echo_control_mobile()->is_enabled() ^ - audio_processing_->echo_cancellation()->is_enabled()); +#if defined(OS_ANDROID) || defined(OS_IOS) + DCHECK(audio_processing_->echo_control_mobile()->is_enabled()); + DCHECK(!audio_processing_->echo_cancellation()->is_enabled()); +#else + DCHECK(!audio_processing_->echo_control_mobile()->is_enabled()); + DCHECK(audio_processing_->echo_cancellation()->is_enabled()); +#endif TRACE_EVENT0("audio", "MediaStreamAudioProcessor::OnPlayoutData"); DCHECK_LT(audio_delay_milliseconds,
diff --git a/content/renderer/media/media_stream_audio_processor_options.cc b/content/renderer/media/media_stream_audio_processor_options.cc index 52ed1d7..c8889ba 100644 --- a/content/renderer/media/media_stream_audio_processor_options.cc +++ b/content/renderer/media/media_stream_audio_processor_options.cc
@@ -11,7 +11,6 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/macros.h" -#include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -282,17 +281,11 @@ void EnableEchoCancellation(AudioProcessing* audio_processing) { #if defined(OS_ANDROID) || defined(OS_IOS) - const std::string group_name = - base::FieldTrialList::FindFullName("ReplaceAECMWithAEC"); - if (group_name.empty() || - !(group_name == "Enabled" || group_name == "DefaultEnabled")) { - // Mobile devices are using AECM. - int err = audio_processing->echo_control_mobile()->set_routing_mode( - webrtc::EchoControlMobile::kSpeakerphone); - err |= audio_processing->echo_control_mobile()->Enable(true); - CHECK_EQ(err, 0); - return; - } + // Mobile devices are using AECM. + CHECK_EQ(0, audio_processing->echo_control_mobile()->set_routing_mode( + webrtc::EchoControlMobile::kSpeakerphone)); + CHECK_EQ(0, audio_processing->echo_control_mobile()->Enable(true)); + return; #endif int err = audio_processing->echo_cancellation()->set_suppression_level( webrtc::EchoCancellation::kHighSuppression);
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 0ddaf21e..244d5ceb 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -24,6 +24,7 @@ #include "cc/base/switches.h" #include "cc/debug/benchmark_instrumentation.h" #include "cc/output/output_surface.h" +#include "cc/scheduler/begin_frame_source.h" #include "cc/trees/layer_tree_host.h" #include "components/scheduler/renderer/render_widget_scheduling_state.h" #include "components/scheduler/renderer/renderer_scheduler.h" @@ -963,6 +964,46 @@ return GURL(); } +void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event, + const ui::LatencyInfo& latency_info) { + if (!input_event) + return; + input_handler_->HandleInputEvent(*input_event, latency_info); +} + +void RenderWidget::OnCursorVisibilityChange(bool is_visible) { + if (webwidget_) + webwidget_->setCursorVisibilityState(is_visible); +} + +void RenderWidget::OnMouseCaptureLost() { + if (webwidget_) + webwidget_->mouseCaptureLost(); +} + +void RenderWidget::OnSetFocus(bool enable) { + if (webwidget_) + webwidget_->setFocus(enable); +} + +/////////////////////////////////////////////////////////////////////////////// +// RenderWidgetCompositorDelegate + +void RenderWidget::ApplyViewportDeltas( + const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, + const gfx::Vector2dF& elastic_overscroll_delta, + float page_scale, + float top_controls_delta) { + webwidget_->applyViewportDeltas(inner_delta, outer_delta, + elastic_overscroll_delta, page_scale, + top_controls_delta); +} + +void RenderWidget::BeginMainFrame(double frame_time_sec) { + webwidget_->beginFrame(frame_time_sec); +} + scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { DCHECK(webwidget_); // For widgets that are never visible, we don't start the compositor, so we @@ -1055,16 +1096,74 @@ worker_context_provider, frame_swap_message_queue_, cc::RGBA_8888)); } +scoped_ptr<cc::BeginFrameSource> +RenderWidget::CreateExternalBeginFrameSource() { + return compositor_deps_->CreateExternalBeginFrameSource(routing_id_); +} + +void RenderWidget::DidCommitAndDrawCompositorFrame() { + // NOTE: Tests may break if this event is renamed or moved. See + // tab_capture_performancetest.cc. + TRACE_EVENT0("gpu", "RenderWidget::DidCommitAndDrawCompositorFrame"); + // Notify subclasses that we initiated the paint operation. + DidInitiatePaint(); +} + +void RenderWidget::DidCommitCompositorFrame() { + FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_, + DidCommitCompositorFrame()); + FOR_EACH_OBSERVER(RenderFrameProxy, render_frame_proxies_, + DidCommitCompositorFrame()); +#if defined(VIDEO_HOLE) + FOR_EACH_OBSERVER(RenderFrameImpl, video_hole_frames_, + DidCommitCompositorFrame()); +#endif // defined(VIDEO_HOLE) + input_handler_->FlushPendingInputEventAck(); +} + +void RenderWidget::DidCompletePageScaleAnimation() {} + +void RenderWidget::DidCompleteSwapBuffers() { + TRACE_EVENT0("renderer", "RenderWidget::DidCompleteSwapBuffers"); + + // Notify subclasses threaded composited rendering was flushed to the screen. + DidFlushPaint(); + + if (!next_paint_flags_ && !need_update_rect_for_auto_resize_ && + !plugin_window_moves_.size()) { + return; + } + + ViewHostMsg_UpdateRect_Params params; + params.view_size = size_; + params.plugin_window_moves.swap(plugin_window_moves_); + params.flags = next_paint_flags_; + + Send(new ViewHostMsg_UpdateRect(routing_id_, params)); + next_paint_flags_ = 0; + need_update_rect_for_auto_resize_ = false; +} + +bool RenderWidget::ForOOPIF() const { + // TODO(simonhong): Remove this when we enable BeginFrame scheduling for + // OOPIF(crbug.com/471411). + return for_oopif_; +} + +void RenderWidget::ForwardCompositorProto(const std::vector<uint8_t>& proto) { + Send(new ViewHostMsg_ForwardCompositorProto(routing_id_, proto)); +} + +bool RenderWidget::IsClosing() const { + return host_closing_; +} + void RenderWidget::OnSwapBuffersAborted() { TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); // Schedule another frame so the compositor learns about it. ScheduleComposite(); } -void RenderWidget::OnSwapBuffersPosted() { - TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted"); -} - void RenderWidget::OnSwapBuffersComplete() { TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete"); @@ -1072,26 +1171,58 @@ DidFlushPaint(); } -void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event, - const ui::LatencyInfo& latency_info) { - if (!input_event) - return; - input_handler_->HandleInputEvent(*input_event, latency_info); +void RenderWidget::OnSwapBuffersPosted() { + TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted"); } -void RenderWidget::OnCursorVisibilityChange(bool is_visible) { - if (webwidget_) - webwidget_->setCursorVisibilityState(is_visible); +void RenderWidget::RecordFrameTimingEvents( + scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events, + scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> main_frame_events) { + for (const auto& composite_event : *composite_events) { + int64_t frameId = composite_event.first; + const std::vector<cc::FrameTimingTracker::CompositeTimingEvent>& events = + composite_event.second; + std::vector<blink::WebFrameTimingEvent> webEvents; + for (size_t i = 0; i < events.size(); ++i) { + webEvents.push_back(blink::WebFrameTimingEvent( + events[i].frame_id, + (events[i].timestamp - base::TimeTicks()).InSecondsF())); + } + webwidget_->recordFrameTimingEvent(blink::WebWidget::CompositeEvent, + frameId, webEvents); + } + for (const auto& main_frame_event : *main_frame_events) { + int64_t frameId = main_frame_event.first; + const std::vector<cc::FrameTimingTracker::MainFrameTimingEvent>& events = + main_frame_event.second; + std::vector<blink::WebFrameTimingEvent> webEvents; + for (size_t i = 0; i < events.size(); ++i) { + webEvents.push_back(blink::WebFrameTimingEvent( + events[i].frame_id, + (events[i].timestamp - base::TimeTicks()).InSecondsF(), + (events[i].end_time - base::TimeTicks()).InSecondsF())); + } + webwidget_->recordFrameTimingEvent(blink::WebWidget::RenderEvent, frameId, + webEvents); + } } -void RenderWidget::OnMouseCaptureLost() { - if (webwidget_) - webwidget_->mouseCaptureLost(); +void RenderWidget::ScheduleAnimation() { + scheduleAnimation(); } -void RenderWidget::OnSetFocus(bool enable) { - if (webwidget_) - webwidget_->setFocus(enable); +void RenderWidget::UpdateVisualState() { + webwidget_->updateAllLifecyclePhases(); +} + +void RenderWidget::WillBeginCompositorFrame() { + TRACE_EVENT0("gpu", "RenderWidget::willBeginCompositorFrame"); + + // The UpdateTextInputState can result in further layout and possibly + // enable GPU acceleration so they need to be called before any painting + // is done. + UpdateTextInputState(ShowIme::HIDE_IME, ChangeSource::FROM_NON_IME); + UpdateSelectionBounds(); } /////////////////////////////////////////////////////////////////////////////// @@ -1248,7 +1379,8 @@ void RenderWidget::initializeLayerTreeView() { DCHECK(!host_closing_); - compositor_ = RenderWidgetCompositor::Create(this, compositor_deps_); + compositor_ = RenderWidgetCompositor::Create(this, device_scale_factor_, + compositor_deps_); compositor_->setViewportSize(physical_backing_size_); OnDeviceScaleFactorChanged(); // For background pages and certain tests, we don't want to trigger @@ -1286,58 +1418,6 @@ DidMeaningfulLayout(layout_type)); } -void RenderWidget::WillBeginCompositorFrame() { - TRACE_EVENT0("gpu", "RenderWidget::willBeginCompositorFrame"); - - // The UpdateTextInputState can result in further layout and possibly - // enable GPU acceleration so they need to be called before any painting - // is done. - UpdateTextInputState(ShowIme::HIDE_IME, ChangeSource::FROM_NON_IME); - UpdateSelectionBounds(); -} - -void RenderWidget::DidCommitCompositorFrame() { - FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_, - DidCommitCompositorFrame()); - FOR_EACH_OBSERVER(RenderFrameProxy, render_frame_proxies_, - DidCommitCompositorFrame()); -#if defined(VIDEO_HOLE) - FOR_EACH_OBSERVER(RenderFrameImpl, video_hole_frames_, - DidCommitCompositorFrame()); -#endif // defined(VIDEO_HOLE) - input_handler_->FlushPendingInputEventAck(); -} - -void RenderWidget::DidCommitAndDrawCompositorFrame() { - // NOTE: Tests may break if this event is renamed or moved. See - // tab_capture_performancetest.cc. - TRACE_EVENT0("gpu", "RenderWidget::DidCommitAndDrawCompositorFrame"); - // Notify subclasses that we initiated the paint operation. - DidInitiatePaint(); -} - -void RenderWidget::DidCompleteSwapBuffers() { - TRACE_EVENT0("renderer", "RenderWidget::DidCompleteSwapBuffers"); - - // Notify subclasses threaded composited rendering was flushed to the screen. - DidFlushPaint(); - - if (!next_paint_flags_ && - !need_update_rect_for_auto_resize_ && - !plugin_window_moves_.size()) { - return; - } - - ViewHostMsg_UpdateRect_Params params; - params.view_size = size_; - params.plugin_window_moves.swap(plugin_window_moves_); - params.flags = next_paint_flags_; - - Send(new ViewHostMsg_UpdateRect(routing_id_, params)); - next_paint_flags_ = 0; - need_update_rect_for_auto_resize_ = false; -} - void RenderWidget::ScheduleComposite() { if (compositor_ && compositor_deps_->GetCompositorImplThreadTaskRunner().get()) { @@ -1890,10 +1970,6 @@ UpdateCompositionInfo(false); } -void RenderWidget::ForwardCompositorProto(const std::vector<uint8_t>& proto) { - Send(new ViewHostMsg_ForwardCompositorProto(routing_id_, proto)); -} - // Check blink::WebTextInputType and ui::TextInputType is kept in sync. #define STATIC_ASSERT_WTIT_ENUM_MATCH(a, b) \ static_assert(int(blink::WebTextInputType##a) \
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 20d98e8..4e5dd83 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -23,6 +23,7 @@ #include "content/common/cursors/webcursor.h" #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" #include "content/common/input/synthetic_gesture_params.h" +#include "content/renderer/gpu/render_widget_compositor_delegate.h" #include "content/renderer/input/render_widget_input_handler.h" #include "content/renderer/input/render_widget_input_handler_delegate.h" #include "content/renderer/message_delivery_policy.h" @@ -103,6 +104,7 @@ : public IPC::Listener, public IPC::Sender, NON_EXPORTED_BASE(virtual public blink::WebWidgetClient), + public RenderWidgetCompositorDelegate, public RenderWidgetInputHandlerDelegate, public base::RefCounted<RenderWidget> { public: @@ -137,7 +139,6 @@ // Temporary for debugging purposes... bool closing() const { return closing_; } bool is_swapped_out() { return is_swapped_out_; } - bool for_oopif() { return for_oopif_; } bool has_host_context_menu_location() { return has_host_context_menu_location_; } @@ -168,6 +169,33 @@ // IPC::Sender bool Send(IPC::Message* msg) override; + // RenderWidgetCompositorDelegate + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, + const gfx::Vector2dF& elastic_overscroll_delta, + float page_scale, + float top_controls_delta) override; + void BeginMainFrame(double frame_time_sec) override; + scoped_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback) override; + scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource() override; + void DidCommitAndDrawCompositorFrame() override; + void DidCommitCompositorFrame() override; + void DidCompletePageScaleAnimation() override; + void DidCompleteSwapBuffers() override; + bool ForOOPIF() const override; + void ForwardCompositorProto(const std::vector<uint8_t>& proto) override; + bool IsClosing() const override; + void OnSwapBuffersAborted() override; + void OnSwapBuffersComplete() override; + void OnSwapBuffersPosted() override; + void RecordFrameTimingEvents( + scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events, + scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> main_frame_events) + override; + void ScheduleAnimation() override; + void UpdateVisualState() override; + void WillBeginCompositorFrame() override; + // RenderWidgetInputHandlerDelegate void FocusChangeComplete() override; bool HasTouchEventHandlersAt(const gfx::Point& point) const override; @@ -256,8 +284,6 @@ // we should not send an extra ack (see SendAckForMouseMoveFromDebugger). void IgnoreAckForMouseMoveFromDebugger(); - virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback); - // Callback for use with synthetic gestures (e.g. BeginSmoothScroll). typedef base::Callback<void()> SyntheticGestureCompletionCallback; @@ -286,9 +312,6 @@ // Returns whether we currently should handle an IME event. bool ShouldHandleImeEvent(); - // Called by the compositor when page scale animation completed. - virtual void DidCompletePageScaleAnimation() {} - // ScreenMetricsEmulator class manages screen emulation inside a render // widget. This includes resizing, placing view on the screen at desired // position, changing device scale factor, and scaling down the whole @@ -298,37 +321,16 @@ void SetPopupOriginAdjustmentsForEmulation(ScreenMetricsEmulator* emulator); gfx::Rect AdjustValidationMessageAnchor(const gfx::Rect& anchor); - // Indicates that the compositor is about to begin a frame. This is primarily - // to signal to flow control mechanisms that a frame is beginning, not to - // perform actual painting work. - void WillBeginCompositorFrame(); - - // Notifies about a compositor frame commit operation having finished. - virtual void DidCommitCompositorFrame(); - - // Notifies that the draw commands for a committed frame have been issued. - void DidCommitAndDrawCompositorFrame(); - - // Notifies that the compositor has posted a swapbuffers operation to the GPU - // process. - void DidCompleteSwapBuffers(); void ScheduleComposite(); void ScheduleCompositeWithForcedRedraw(); - // Called by the compositor in single-threaded mode when a swap is posted, - // completes or is aborted. - void OnSwapBuffersPosted(); - void OnSwapBuffersComplete(); - void OnSwapBuffersAborted(); - // Checks if the selection bounds have been changed. If they are changed, // the new value will be sent to the browser process. void UpdateSelectionBounds(); // Called by the compositor to forward a proto that represents serialized // compositor state. - void ForwardCompositorProto(const std::vector<uint8_t>& proto); virtual void GetSelectionBounds(gfx::Rect* start, gfx::Rect* end); @@ -340,8 +342,6 @@ // handle composition range and composition character bounds. void UpdateCompositionInfo(bool should_update_range); - bool host_closing() const { return host_closing_; } - protected: // Friend RefCounted so that the dtor can be non-public. Using this class // without ref-counting is an error.
diff --git a/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java b/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java index 278291c..a0119d3 100644 --- a/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java +++ b/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java
@@ -15,8 +15,8 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import org.chromium.content.browser.ActivityContentVideoViewClient; -import org.chromium.content.browser.ContentVideoViewClient; +import org.chromium.content.browser.ActivityContentVideoViewEmbedder; +import org.chromium.content.browser.ContentVideoViewEmbedder; import org.chromium.content.browser.ContentViewClient; import org.chromium.content.browser.ContentViewCore; import org.chromium.content.browser.ContentViewRenderView; @@ -47,8 +47,8 @@ nativeInit(this); mContentViewClient = new ContentViewClient() { @Override - public ContentVideoViewClient getContentVideoViewClient() { - return new ActivityContentVideoViewClient((Activity) context) { + public ContentVideoViewEmbedder getContentVideoViewEmbedder() { + return new ActivityContentVideoViewEmbedder((Activity) context) { @Override public void enterFullscreenVideo(View view) { super.enterFullscreenVideo(view);
diff --git a/content/test/data/accessibility/html/abbr-expected-mac.txt b/content/test/data/accessibility/html/abbr-expected-mac.txt index 422d2c4..a9d0506 100644 --- a/content/test/data/accessibility/html/abbr-expected-mac.txt +++ b/content/test/data/accessibility/html/abbr-expected-mac.txt
@@ -1,6 +1,6 @@ AXWebArea AXRoleDescription='HTML content' ++AXGroup AXRoleDescription='group' ++++AXStaticText AXRoleDescription='text' AXValue='The ' -++++AXUnknown AXRoleDescription='unknown' AXDescription='World Health Organization' +++++AXGroup AXRoleDescription='group' AXDescription='World Health Organization' ++++++AXStaticText AXRoleDescription='text' AXValue='WHO' -++++AXStaticText AXRoleDescription='text' AXValue=' was founded in 1948.' +++++AXStaticText AXRoleDescription='text' AXValue=' was founded in 1948.' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/abbr-expected-win.txt b/content/test/data/accessibility/html/abbr-expected-win.txt index 11821cd6..d519189 100644 --- a/content/test/data/accessibility/html/abbr-expected-win.txt +++ b/content/test/data/accessibility/html/abbr-expected-win.txt
@@ -1,6 +1,6 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++IA2_ROLE_PARAGRAPH ++++ROLE_SYSTEM_STATICTEXT name='The ' -++++ROLE_SYSTEM_CLIENT name='World Health Organization' +++++IA2_ROLE_TEXT_FRAME name='World Health Organization' ++++++ROLE_SYSTEM_STATICTEXT name='WHO' -++++ROLE_SYSTEM_STATICTEXT name=' was founded in 1948.' +++++ROLE_SYSTEM_STATICTEXT name=' was founded in 1948.' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/frameset-expected-mac.txt b/content/test/data/accessibility/html/frameset-expected-mac.txt index a20c175..0296493 100644 --- a/content/test/data/accessibility/html/frameset-expected-mac.txt +++ b/content/test/data/accessibility/html/frameset-expected-mac.txt
@@ -1,17 +1,15 @@ #<skip -- Flaky failure crbug.com/414157> AXWebArea ++AXUnknown -++++AXUnknown -++++++AXWebArea -++++++++AXGroup -++++++++++AXStaticText AXValue='My favorite browser is' -++++++++++AXStaticText AXValue='ABC' -++++++++++AXStaticText AXValue='Chrome' -++++++++++AXStaticText AXValue='!' +++++AXWebArea +++++++AXGroup +++++++++AXStaticText AXValue='My favorite browser is' +++++++++AXStaticText AXValue='ABC' +++++++++AXStaticText AXValue='Chrome' +++++++++AXStaticText AXValue='!' ++AXUnknown -++++AXUnknown -++++++AXWebArea -++++++++AXGroup -++++++++++AXStaticText AXValue='This test is to check ' -++++++++++AXStaticText AXValue='mark tag' -++++++++++AXStaticText AXValue='.' +++++AXWebArea +++++++AXGroup +++++++++AXStaticText AXValue='This test is to check ' +++++++++AXStaticText AXValue='mark tag' +++++++++AXStaticText AXValue='.'
diff --git a/content/test/data/accessibility/html/iframe-coordinates-expected-android.txt b/content/test/data/accessibility/html/iframe-coordinates-expected-android.txt index 968f102..74aa86b 100644 --- a/content/test/data/accessibility/html/iframe-coordinates-expected-android.txt +++ b/content/test/data/accessibility/html/iframe-coordinates-expected-android.txt
@@ -5,13 +5,11 @@ ++++android.widget.Button clickable focusable name='Button' ++android.view.View ++++android.view.View -++++++android.view.View -++++++++android.view.View scrollable -++++++++++android.view.View -++++++++++++android.widget.Button clickable focusable name='Ordinary Button' +++++++android.view.View scrollable +++++++++android.view.View +++++++++++android.widget.Button clickable focusable name='Ordinary Button' ++android.view.View ++++android.view.View -++++++android.view.View -++++++++android.view.View scrollable -++++++++++android.view.View -++++++++++++android.widget.Button clickable focusable name='Scrolled Button' +++++++android.view.View scrollable +++++++++android.view.View +++++++++++android.widget.Button clickable focusable name='Scrolled Button'
diff --git a/content/test/data/accessibility/html/iframe-coordinates-expected-blink.txt b/content/test/data/accessibility/html/iframe-coordinates-expected-blink.txt index 85944f9..4ef1683 100644 --- a/content/test/data/accessibility/html/iframe-coordinates-expected-blink.txt +++ b/content/test/data/accessibility/html/iframe-coordinates-expected-blink.txt
@@ -5,14 +5,12 @@ ++++button location=(25, 175) size=(250, 50) name='Button' ++div location=(0, 300) size=(300, 150) ++++iframe location=(0, 300) size=(300, 100) -++++++scrollArea location=(0, 300) size=(300, 100) -++++++++webArea location=(0, 0) size=(300, 100) scrollX=0 scrollXMin=0 scrollXMax=0 scrollY=0 scrollYMin=0 scrollYMax=0 -++++++++++div location=(0, 0) size=(300, 100) -++++++++++++button location=(25, 25) size=(250, 50) name='Ordinary Button' +++++++webArea location=(0, 0) size=(300, 100) scrollX=0 scrollXMin=0 scrollXMax=0 scrollY=0 scrollYMin=0 scrollYMax=0 +++++++++div location=(0, 0) size=(300, 100) +++++++++++button location=(25, 25) size=(250, 50) name='Ordinary Button' ++div location=(0, 450) size=(300, 150) ++++iframe location=(0, 450) size=(150, 50) -++++++scrollArea location=(0, 450) size=(150, 50) -++++++++webArea location=(0, 0) size=(300, 100) scrollX=150 scrollXMin=0 scrollXMax=150 scrollY=50 scrollYMin=0 scrollYMax=50 -++++++++++div location=(0, 0) size=(300, 100) -++++++++++++button location=(25, 25) size=(250, 50) name='Scrolled Button' +++++++webArea location=(0, 0) size=(300, 100) scrollX=150 scrollXMin=0 scrollXMax=150 scrollY=50 scrollYMin=0 scrollYMax=50 +++++++++div location=(0, 0) size=(300, 100) +++++++++++button location=(25, 25) size=(250, 50) name='Scrolled Button' <-- End-of-file --> \ No newline at end of file
diff --git a/content/test/data/accessibility/html/iframe-coordinates-expected-mac.txt b/content/test/data/accessibility/html/iframe-coordinates-expected-mac.txt index 504db30..0fd1a7b 100644 --- a/content/test/data/accessibility/html/iframe-coordinates-expected-mac.txt +++ b/content/test/data/accessibility/html/iframe-coordinates-expected-mac.txt
@@ -5,13 +5,11 @@ ++++AXButton position=(25, 175) size=(250, 50) ++AXGroup position=(0, 300) size=(300, 150) ++++AXGroup position=(0, 300) size=(300, 100) -++++++AXUnknown position=(0, 300) size=(300, 100) -++++++++AXWebArea position=(0, 300) size=(300, 100) -++++++++++AXGroup position=(0, 300) size=(300, 100) -++++++++++++AXButton position=(25, 325) size=(250, 50) +++++++AXWebArea position=(0, 300) size=(300, 100) +++++++++AXGroup position=(0, 300) size=(300, 100) +++++++++++AXButton position=(25, 325) size=(250, 50) ++AXGroup position=(0, 450) size=(300, 150) ++++AXGroup position=(0, 450) size=(150, 50) -++++++AXUnknown position=(0, 450) size=(150, 50) -++++++++AXWebArea position=(0, 450) size=(300, 100) -++++++++++AXGroup position=(-150, 400) size=(300, 100) -++++++++++++AXButton position=(-125, 425) size=(250, 50) +++++++AXWebArea position=(0, 450) size=(300, 100) +++++++++AXGroup position=(-150, 400) size=(300, 100) +++++++++++AXButton position=(-125, 425) size=(250, 50)
diff --git a/content/test/data/accessibility/html/iframe-coordinates-expected-win.txt b/content/test/data/accessibility/html/iframe-coordinates-expected-win.txt index 97ee953c..41e07cf 100644 --- a/content/test/data/accessibility/html/iframe-coordinates-expected-win.txt +++ b/content/test/data/accessibility/html/iframe-coordinates-expected-win.txt
@@ -5,13 +5,12 @@ ++++ROLE_SYSTEM_PUSHBUTTON name='Button' FOCUSABLE location=(25, 175) size=(250, 50) ++IA2_ROLE_SECTION location=(0, 300) size=(300, 150) ++++IA2_ROLE_INTERNAL_FRAME READONLY location=(0, 300) size=(300, 100) -++++++IA2_ROLE_SCROLL_PANE location=(0, 300) size=(300, 100) -++++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE location=(0, 300) size=(300, 100) -++++++++++IA2_ROLE_SECTION location=(0, 300) size=(300, 100) -++++++++++++ROLE_SYSTEM_PUSHBUTTON name='Ordinary Button' FOCUSABLE location=(25, 325) size=(250, 50) + +++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE location=(0, 300) size=(300, 100) +++++++++IA2_ROLE_SECTION location=(0, 300) size=(300, 100) +++++++++++ROLE_SYSTEM_PUSHBUTTON name='Ordinary Button' FOCUSABLE location=(25, 325) size=(250, 50) ++IA2_ROLE_SECTION location=(0, 450) size=(300, 150) ++++IA2_ROLE_INTERNAL_FRAME READONLY location=(0, 450) size=(150, 50) -++++++IA2_ROLE_SCROLL_PANE location=(0, 450) size=(150, 50) -++++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE location=(0, 450) size=(300, 100) -++++++++++IA2_ROLE_SECTION location=(-150, 400) size=(300, 100) -++++++++++++ROLE_SYSTEM_PUSHBUTTON name='Scrolled Button' FOCUSABLE location=(-125, 425) size=(250, 50) +++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE location=(0, 450) size=(300, 100) +++++++++IA2_ROLE_SECTION location=(-150, 400) size=(300, 100) +++++++++++ROLE_SYSTEM_PUSHBUTTON name='Scrolled Button' FOCUSABLE location=(-125, 425) size=(250, 50)
diff --git a/content/test/data/accessibility/html/iframe-expected-android.txt b/content/test/data/accessibility/html/iframe-expected-android.txt index 47bcb38..a24ab80 100644 --- a/content/test/data/accessibility/html/iframe-expected-android.txt +++ b/content/test/data/accessibility/html/iframe-expected-android.txt
@@ -1,5 +1,4 @@ android.webkit.WebView focusable focused scrollable ++android.view.View ++++android.view.View -++++++android.view.View -++++++++android.view.View scrollable +++++++android.view.View scrollable
diff --git a/content/test/data/accessibility/html/iframe-expected-blink.txt b/content/test/data/accessibility/html/iframe-expected-blink.txt index 2f02520..2840d6fbc 100644 --- a/content/test/data/accessibility/html/iframe-expected-blink.txt +++ b/content/test/data/accessibility/html/iframe-expected-blink.txt
@@ -1,6 +1,5 @@ rootWebArea ++group ++++iframe -++++++scrollArea -++++++++webArea +++++++webArea <-- End-of-file --> \ No newline at end of file
diff --git a/content/test/data/accessibility/html/iframe-expected-mac.txt b/content/test/data/accessibility/html/iframe-expected-mac.txt index 193f4893..92dd839 100644 --- a/content/test/data/accessibility/html/iframe-expected-mac.txt +++ b/content/test/data/accessibility/html/iframe-expected-mac.txt
@@ -1,5 +1,4 @@ AXWebArea AXRoleDescription='HTML content' ++AXGroup AXRoleDescription='group' ++++AXGroup AXRoleDescription='group' -++++++AXUnknown AXRoleDescription='unknown' -++++++++AXWebArea AXRoleDescription='HTML content' +++++++AXWebArea AXRoleDescription='HTML content'
diff --git a/content/test/data/accessibility/html/iframe-expected-win.txt b/content/test/data/accessibility/html/iframe-expected-win.txt index b077df4..16acc1b 100644 --- a/content/test/data/accessibility/html/iframe-expected-win.txt +++ b/content/test/data/accessibility/html/iframe-expected-win.txt
@@ -1,5 +1,4 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++IA2_ROLE_SECTION ++++IA2_ROLE_INTERNAL_FRAME READONLY -++++++IA2_ROLE_SCROLL_PANE -++++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE +++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
diff --git a/content/test/data/accessibility/html/iframe-presentational-expected-android.txt b/content/test/data/accessibility/html/iframe-presentational-expected-android.txt index 47bcb38..a24ab80 100644 --- a/content/test/data/accessibility/html/iframe-presentational-expected-android.txt +++ b/content/test/data/accessibility/html/iframe-presentational-expected-android.txt
@@ -1,5 +1,4 @@ android.webkit.WebView focusable focused scrollable ++android.view.View ++++android.view.View -++++++android.view.View -++++++++android.view.View scrollable +++++++android.view.View scrollable
diff --git a/content/test/data/accessibility/html/iframe-presentational-expected-mac.txt b/content/test/data/accessibility/html/iframe-presentational-expected-mac.txt index f64cd9a..228de27 100644 --- a/content/test/data/accessibility/html/iframe-presentational-expected-mac.txt +++ b/content/test/data/accessibility/html/iframe-presentational-expected-mac.txt
@@ -1,5 +1,4 @@ AXWebArea AXRoleDescription='HTML content' ++AXGroup AXRoleDescription='group' ++++AXGroup AXRoleDescription='presentation' -++++++AXUnknown AXRoleDescription='unknown' -++++++++AXGroup AXRoleDescription='group' +++++++AXGroup AXRoleDescription='group'
diff --git a/content/test/data/accessibility/html/iframe-presentational-expected-win.txt b/content/test/data/accessibility/html/iframe-presentational-expected-win.txt index 4b0d7be9..6a9bfff 100644 --- a/content/test/data/accessibility/html/iframe-presentational-expected-win.txt +++ b/content/test/data/accessibility/html/iframe-presentational-expected-win.txt
@@ -1,5 +1,4 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++IA2_ROLE_SECTION ++++ROLE_SYSTEM_GROUPING FOCUSABLE -++++++IA2_ROLE_SCROLL_PANE -++++++++ROLE_SYSTEM_GROUPING READONLY FOCUSABLE +++++++ROLE_SYSTEM_GROUPING READONLY FOCUSABLE
diff --git a/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-android.txt b/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-android.txt index edecaf4..f9a191d 100644 --- a/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-android.txt +++ b/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-android.txt
@@ -2,7 +2,6 @@ ++android.view.View ++++android.view.View clickable name='Test for modal dialog closed in an iframe. ' ++++android.view.View -++++++android.view.View -++++++++android.view.View scrollable -++++++++++android.view.View -++++++++++++android.widget.Button clickable focusable name='I am a non-inert button!' +++++++android.view.View scrollable +++++++++android.view.View +++++++++++android.widget.Button clickable focusable name='I am a non-inert button!'
diff --git a/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-mac.txt b/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-mac.txt index e6db6e6..a9159f8 100644 --- a/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-mac.txt +++ b/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-mac.txt
@@ -2,7 +2,6 @@ ++AXGroup ++++AXStaticText AXValue='Test for modal dialog closed in an iframe. ' ++++AXGroup -++++++AXUnknown -++++++++AXWebArea -++++++++++AXGroup -++++++++++++AXButton AXTitle='I am a non-inert button!' +++++++AXWebArea +++++++++AXGroup +++++++++++AXButton AXTitle='I am a non-inert button!'
diff --git a/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-win.txt b/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-win.txt index 00836d6..61470fe 100644 --- a/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-win.txt
@@ -2,7 +2,6 @@ ++IA2_ROLE_SECTION ++++ROLE_SYSTEM_STATICTEXT name='Test for modal dialog closed in an iframe. ' ++++IA2_ROLE_INTERNAL_FRAME READONLY -++++++IA2_ROLE_SCROLL_PANE -++++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE -++++++++++IA2_ROLE_SECTION -++++++++++++ROLE_SYSTEM_PUSHBUTTON name='I am a non-inert button!' FOCUSABLE +++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE +++++++++IA2_ROLE_SECTION +++++++++++ROLE_SYSTEM_PUSHBUTTON name='I am a non-inert button!' FOCUSABLE
diff --git a/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-android.txt b/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-android.txt index f306406..df99556 100644 --- a/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-android.txt +++ b/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-android.txt
@@ -2,8 +2,7 @@ ++android.view.View ++++android.view.View clickable name='Test for modal dialog opened in an iframe.' ++++android.view.View -++++++android.view.View -++++++++android.view.View scrollable -++++++++++android.view.View -++++++++++android.view.View clickable name='Text in the dialog.' -++++++++android.view.View editable_text +++++++android.view.View scrollable +++++++++android.view.View +++++++++android.view.View clickable name='Text in the dialog.' +++++++android.view.View editable_text
diff --git a/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-mac.txt b/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-mac.txt index b617f8c0..cf0d36d 100644 --- a/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-mac.txt +++ b/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-mac.txt
@@ -2,7 +2,6 @@ ++AXGroup ++++AXStaticText AXValue='Test for modal dialog opened in an iframe. ' ++++AXGroup -++++++AXUnknown -++++++++AXWebArea -++++++++++AXGroup AXSubrole=AXApplicationDialog -++++++++++++AXStaticText AXValue='Text in the dialog.' +++++++AXWebArea +++++++++AXGroup AXSubrole=AXApplicationDialog +++++++++++AXStaticText AXValue='Text in the dialog.'
diff --git a/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-win.txt b/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-win.txt index e3c97f56..d0b886a 100644 --- a/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-in-iframe-opened-expected-win.txt
@@ -2,7 +2,6 @@ ++IA2_ROLE_SECTION ++++ROLE_SYSTEM_STATICTEXT name='Test for modal dialog opened in an iframe. ' ++++IA2_ROLE_INTERNAL_FRAME READONLY -++++++IA2_ROLE_SCROLL_PANE -++++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE -++++++++++ROLE_SYSTEM_DIALOG -++++++++++++ROLE_SYSTEM_STATICTEXT name='Text in the dialog.' +++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE +++++++++ROLE_SYSTEM_DIALOG +++++++++++ROLE_SYSTEM_STATICTEXT name='Text in the dialog.'
diff --git a/device/bluetooth/bluetooth_device.cc b/device/bluetooth/bluetooth_device.cc index 05532cc..c85af11 100644 --- a/device/bluetooth/bluetooth_device.cc +++ b/device/bluetooth/bluetooth_device.cc
@@ -303,6 +303,10 @@ } void BluetoothDevice::DidFailToConnectGatt(ConnectErrorCode error) { + // Connection request should only be made if there are no active + // connections. + DCHECK(gatt_connections_.empty()); + for (const auto& error_callback : create_gatt_connection_error_callbacks_) error_callback.Run(error); create_gatt_connection_success_callbacks_.clear(); @@ -311,13 +315,8 @@ void BluetoothDevice::DidDisconnectGatt() { // Pending calls to connect GATT are not expected, if they were then - // DidFailToConnectGatt should be called. But in case callbacks exist - // flush them to ensure a consistent state. - if (create_gatt_connection_error_callbacks_.size() > 0) { - VLOG(1) << "Unexpected / unexplained DidDisconnectGatt call while " - "create_gatt_connection_error_callbacks_ are pending."; - } - DidFailToConnectGatt(ERROR_FAILED); + // DidFailToConnectGatt should have been called. + DCHECK(create_gatt_connection_error_callbacks_.empty()); // Invalidate all BluetoothGattConnection objects. for (BluetoothGattConnection* connection : gatt_connections_) {
diff --git a/device/bluetooth/bluetooth_device_android.cc b/device/bluetooth/bluetooth_device_android.cc index 71ceb666..253680bb 100644 --- a/device/bluetooth/bluetooth_device_android.cc +++ b/device/bluetooth/bluetooth_device_android.cc
@@ -8,6 +8,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" +#include "base/metrics/sparse_histogram.h" #include "base/strings/stringprintf.h" #include "device/bluetooth/bluetooth_adapter_android.h" #include "device/bluetooth/bluetooth_remote_gatt_service_android.h" @@ -17,6 +18,20 @@ using base::android::AppendJavaStringArrayToStringVector; namespace device { +namespace { +void RecordConnectionSuccessResult(int32_t status) { + UMA_HISTOGRAM_SPARSE_SLOWLY("Bluetooth.Android.GATTConnection.Success.Result", + status); +} +void RecordConnectionFailureResult(int32_t status) { + UMA_HISTOGRAM_SPARSE_SLOWLY("Bluetooth.Android.GATTConnection.Failure.Result", + status); +} +void RecordConnectionTerminatedResult(int32_t status) { + UMA_HISTOGRAM_SPARSE_SLOWLY( + "Bluetooth.Android.GATTConnection.Disconnected.Result", status); +} +} // namespace BluetoothDeviceAndroid* BluetoothDeviceAndroid::Create( BluetoothAdapterAndroid* adapter, @@ -208,36 +223,21 @@ bool connected) { gatt_connected_ = connected; if (gatt_connected_) { + RecordConnectionSuccessResult(status); DidConnectGatt(); + } else if (!create_gatt_connection_error_callbacks_.empty()) { + // We assume that if there are any pending connection callbacks there + // was a failed connection attempt. + RecordConnectionFailureResult(status); + // TODO(ortuno): Return an error code based on |status| + // http://crbug.com/578191 + DidFailToConnectGatt(ERROR_FAILED); } else { + // Otherwise an existing connection was terminated. + RecordConnectionTerminatedResult(status); gatt_services_.clear(); SetGattServicesDiscoveryComplete(false); - - switch (status) { // Constants are from android.bluetooth.BluetoothGatt. - case 0x0000008f: // GATT_CONNECTION_CONGESTED - return DidFailToConnectGatt(ERROR_CONNECTION_CONGESTED); - case 0x00000101: // GATT_FAILURE - return DidFailToConnectGatt(ERROR_FAILED); - case 0x00000005: // GATT_INSUFFICIENT_AUTHENTICATION - return DidFailToConnectGatt(ERROR_AUTH_FAILED); - case 0x0000000f: // GATT_INSUFFICIENT_ENCRYPTION - return DidFailToConnectGatt(ERROR_INSUFFICIENT_ENCRYPTION); - case 0x0000000d: // GATT_INVALID_ATTRIBUTE_LENGTH - return DidFailToConnectGatt(ERROR_ATTRIBUTE_LENGTH_INVALID); - case 0x00000007: // GATT_INVALID_OFFSET - return DidFailToConnectGatt(ERROR_OFFSET_INVALID); - case 0x00000002: // GATT_READ_NOT_PERMITTED - return DidFailToConnectGatt(ERROR_READ_NOT_PERMITTED); - case 0x00000006: // GATT_REQUEST_NOT_SUPPORTED - return DidFailToConnectGatt(ERROR_REQUEST_NOT_SUPPORTED); - case 0x00000000: // GATT_SUCCESS - return DidDisconnectGatt(); - case 0x00000003: // GATT_WRITE_NOT_PERMITTED - return DidFailToConnectGatt(ERROR_WRITE_NOT_PERMITTED); - default: - VLOG(1) << "Unhandled status: " << status; - return DidFailToConnectGatt(ERROR_UNKNOWN); - } + DidDisconnectGatt(); } }
diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc index 69410b5..4fc30e4 100644 --- a/device/bluetooth/bluetooth_device_unittest.cc +++ b/device/bluetooth/bluetooth_device_unittest.cc
@@ -457,7 +457,11 @@ EXPECT_EQ(1, gatt_connection_attempts_); SimulateGattConnectionError(device, BluetoothDevice::ERROR_AUTH_FAILED); SimulateGattConnectionError(device, BluetoothDevice::ERROR_FAILED); - EXPECT_EQ(BluetoothDevice::ERROR_AUTH_FAILED, last_connect_error_code_); + // TODO: Change to ERROR_AUTH_FAILED. We should be getting a callback + // only with the first error, but our android framework doesn't yet + // support sending different errors. + // http://crbug.com/578191 + EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_); for (BluetoothGattConnection* connection : gatt_connections_) EXPECT_FALSE(connection->IsConnected()); }
diff --git a/device/bluetooth/test/bluetooth_test_android.cc b/device/bluetooth/test/bluetooth_test_android.cc index 353822db..e23a8354 100644 --- a/device/bluetooth/test/bluetooth_test_android.cc +++ b/device/bluetooth/test/bluetooth_test_android.cc
@@ -84,52 +84,16 @@ void BluetoothTestAndroid::SimulateGattConnectionError( BluetoothDevice* device, - BluetoothDevice::ConnectErrorCode error) { - int android_error_value = 0; - switch (error) { // Constants are from android.bluetooth.BluetoothGatt. - case BluetoothDevice::ERROR_ATTRIBUTE_LENGTH_INVALID: - android_error_value = 0x0000000d; // GATT_INVALID_ATTRIBUTE_LENGTH - break; - case BluetoothDevice::ERROR_AUTH_FAILED: - android_error_value = 0x00000005; // GATT_INSUFFICIENT_AUTHENTICATION - break; - case BluetoothDevice::ERROR_CONNECTION_CONGESTED: - android_error_value = 0x0000008f; // GATT_CONNECTION_CONGESTED - break; - case BluetoothDevice::ERROR_FAILED: - android_error_value = 0x00000101; // GATT_FAILURE - break; - case BluetoothDevice::ERROR_INSUFFICIENT_ENCRYPTION: - android_error_value = 0x0000000f; // GATT_INSUFFICIENT_ENCRYPTION - break; - case BluetoothDevice::ERROR_OFFSET_INVALID: - android_error_value = 0x00000007; // GATT_INVALID_OFFSET - break; - case BluetoothDevice::ERROR_READ_NOT_PERMITTED: - android_error_value = 0x00000002; // GATT_READ_NOT_PERMITTED - break; - case BluetoothDevice::ERROR_REQUEST_NOT_SUPPORTED: - android_error_value = 0x00000006; // GATT_REQUEST_NOT_SUPPORTED - break; - case BluetoothDevice::ERROR_WRITE_NOT_PERMITTED: - android_error_value = 0x00000003; // GATT_WRITE_NOT_PERMITTED - break; - case BluetoothDevice::ERROR_AUTH_CANCELED: - case BluetoothDevice::ERROR_AUTH_REJECTED: - case BluetoothDevice::ERROR_AUTH_TIMEOUT: - case BluetoothDevice::ERROR_INPROGRESS: - case BluetoothDevice::ERROR_UNKNOWN: - case BluetoothDevice::ERROR_UNSUPPORTED_DEVICE: - case BluetoothDevice::NUM_CONNECT_ERROR_CODES: - NOTREACHED() << "No translation for error code: " << error; - } - + BluetoothDevice::ConnectErrorCode) { BluetoothDeviceAndroid* device_android = static_cast<BluetoothDeviceAndroid*>(device); Java_FakeBluetoothDevice_connectionStateChange( AttachCurrentThread(), device_android->GetJavaObject().obj(), - android_error_value, + // TODO(ortuno): Add all types of errors Android can produce. For now we + // just return a timeout error. + // http://crbug.com/578191 + 0x08, // Connection Timeout from Bluetooth Spec. false); // connected } @@ -139,7 +103,7 @@ Java_FakeBluetoothDevice_connectionStateChange( AttachCurrentThread(), device_android->GetJavaObject().obj(), - 0, // android.bluetooth.BluetoothGatt.GATT_SUCCESS + 0x13, // Connection terminate by peer user from Bluetooth Spec. false); // disconnected }
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 001309fc..2ea86c99 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1162,7 +1162,6 @@ WEBRTCLOGGINGPRIVATE_STOPAUDIODEBUGRECORDINGS, TERMINALPRIVATE_ACKOUTPUT, INPUT_IME_CREATEWINDOW, - ACCESSIBILITY_PRIVATE_SETKEYBOARDLISTENER, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 06b16c88..c7f7d9c 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -208,7 +208,6 @@ "command_buffer/common/gles2_cmd_format_test_autogen.h", "command_buffer/common/gles2_cmd_utils_unittest.cc", "command_buffer/common/id_allocator_test.cc", - "command_buffer/common/trace_event.h", "command_buffer/common/unittest_main.cc", "command_buffer/service/buffer_manager_unittest.cc", "command_buffer/service/cmd_parser_test.cc",
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc index 6f5bc2e..ab1a47ac 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -16,10 +16,10 @@ #include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/buffer.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/trace_event.h" namespace gpu {
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 0f23569..e308647c 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -24,6 +24,7 @@ #include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/client/buffer_tracker.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gpu_control.h" @@ -34,7 +35,6 @@ #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/id_allocator.h" #include "gpu/command_buffer/common/sync_token.h" -#include "gpu/command_buffer/common/trace_event.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h"
diff --git a/gpu/command_buffer/client/gles2_trace_implementation.cc b/gpu/command_buffer/client/gles2_trace_implementation.cc index 234f243..782a7cd 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation.cc +++ b/gpu/command_buffer/client/gles2_trace_implementation.cc
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/trace_event/trace_event.h" #include "gpu/command_buffer/client/gles2_trace_implementation.h" -#include "gpu/command_buffer/common/trace_event.h" namespace gpu { namespace gles2 {
diff --git a/gpu/command_buffer/common/trace_event.h b/gpu/command_buffer/common/trace_event.h deleted file mode 100644 index 4bc18d7..0000000 --- a/gpu/command_buffer/common/trace_event.h +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright (c) 2011 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_COMMAND_BUFFER_COMMON_TRACE_EVENT_H_ -#define GPU_COMMAND_BUFFER_COMMON_TRACE_EVENT_H_ - -#include "base/trace_event/trace_event.h" - -#endif // GPU_COMMAND_BUFFER_COMMON_TRACE_EVENT_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 08eb70d..fff3466 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -11409,12 +11409,16 @@ Clip(x, width, size.width(), ©X, ©Width); Clip(y, height, size.height(), ©Y, ©Height); - if (xoffset != 0 || yoffset != 0 || width != size.width() || - height != size.height()) { + GLint dx = copyX - x; + GLint dy = copyY - y; + GLint destX = xoffset + dx; + GLint destY = yoffset + dy; + if (destX != 0 || destY != 0 || copyWidth != size.width() || + copyHeight != size.height()) { gfx::Rect cleared_rect; if (TextureManager::CombineAdjacentRects( texture->GetLevelClearedRect(target, level), - gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) { + gfx::Rect(destX, destY, copyWidth, copyHeight), &cleared_rect)) { DCHECK_GE(cleared_rect.size().GetArea(), texture->GetLevelClearedRect(target, level).size().GetArea()); texture_manager()->SetLevelClearedRect(texture_ref, target, level, @@ -11433,31 +11437,7 @@ texture_manager()->SetLevelCleared(texture_ref, target, level, true); } - if (copyX != x || - copyY != y || - copyWidth != width || - copyHeight != height) { - // some part was clipped so clear the sub rect. - uint32_t pixels_size = 0; - if (!GLES2Util::ComputeImageDataSizes( - width, height, 1, format, type, state_.unpack_alignment, &pixels_size, - NULL, NULL)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); - return; - } - scoped_ptr<char[]> zero(new char[pixels_size]); - memset(zero.get(), 0, pixels_size); - glTexSubImage2D( - target, level, xoffset, yoffset, width, height, - format, type, zero.get()); - } - if (copyHeight > 0 && copyWidth > 0) { - GLint dx = copyX - x; - GLint dy = copyY - y; - GLint destX = xoffset + dx; - GLint destY = yoffset + dy; glCopyTexSubImage2D(target, level, destX, destY, copyX, copyY, copyWidth, copyHeight);
diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h index 46cbb03..bccf63b6 100644 --- a/gpu/config/gpu_driver_bug_workaround_type.h +++ b/gpu/config/gpu_driver_bug_workaround_type.h
@@ -150,6 +150,8 @@ unbind_egl_context_to_flush_driver_caches) \ GPU_OP(SET_ZERO_LEVEL_BEFORE_GENERATING_MIPMAP, \ set_zero_level_before_generating_mipmap) \ + GPU_OP(DISABLE_DIRECT_COMPOSITION, \ + disable_direct_composition) \ namespace gpu {
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 58130ca9..18c35939 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp
@@ -199,7 +199,6 @@ 'command_buffer/common/gles2_cmd_format_test_autogen.h', 'command_buffer/common/gles2_cmd_utils_unittest.cc', 'command_buffer/common/id_allocator_test.cc', - 'command_buffer/common/trace_event.h', 'command_buffer/common/unittest_main.cc', 'command_buffer/service/buffer_manager_unittest.cc', 'command_buffer/service/cmd_parser_test.cc',
diff --git a/ios/web/public/web_state/crw_web_view_scroll_view_proxy.h b/ios/web/public/web_state/crw_web_view_scroll_view_proxy.h index 7b49f89c3..54af234 100644 --- a/ios/web/public/web_state/crw_web_view_scroll_view_proxy.h +++ b/ios/web/public/web_state/crw_web_view_scroll_view_proxy.h
@@ -35,6 +35,12 @@ // Returns the scrollview's gesture recognizers. @property(nonatomic, readonly) NSArray* gestureRecognizers; +// Returns YES if the UIScrollView is currently being updated through the proxy. +// This can be used by CRWWebViewScrollViewObserver to differentiate renderer- +// initiated updates from those caused by the proxy API. +@property(nonatomic, readonly, getter=isUpdatingThroughProxy) + BOOL updatingThroughProxy; + // Calls UIScrollView's implementation of setContentInset: directly. This // bypasses a very slow update path in UIWebView. - (void)setContentInsetFast:(UIEdgeInsets)contentInset;
diff --git a/ios/web/web_state/crw_web_view_scroll_view_proxy.mm b/ios/web/web_state/crw_web_view_scroll_view_proxy.mm index 306a9ca..3f263a03 100644 --- a/ios/web/web_state/crw_web_view_scroll_view_proxy.mm +++ b/ios/web/web_state/crw_web_view_scroll_view_proxy.mm
@@ -18,6 +18,8 @@ // update and reset the contentOffset to force a fast update. These updates // should be a no-op for the contentOffset, so the callbacks can be ignored. BOOL _ignoreScroll; + // The number of calls through the proxy API in the current stack. + NSUInteger _proxyCallCount; } // Returns the key paths that need to be observed for UIScrollView. @@ -84,6 +86,7 @@ } - (void)setScrollEnabled:(BOOL)scrollEnabled { + base::AutoReset<NSUInteger> autoReset(&_proxyCallCount, _proxyCallCount + 1); [_scrollView setScrollEnabled:scrollEnabled]; } @@ -92,6 +95,7 @@ } - (void)setBounces:(BOOL)bounces { + base::AutoReset<NSUInteger> autoReset(&_proxyCallCount, _proxyCallCount + 1); [_scrollView setBounces:bounces]; } @@ -104,6 +108,7 @@ } - (void)setContentOffset:(CGPoint)contentOffset { + base::AutoReset<NSUInteger> autoReset(&_proxyCallCount, _proxyCallCount + 1); [_scrollView setContentOffset:contentOffset]; } @@ -112,6 +117,7 @@ } - (void)setContentInsetFast:(UIEdgeInsets)contentInset { + base::AutoReset<NSUInteger> autoReset(&_proxyCallCount, _proxyCallCount + 1); if (!_scrollView) return; @@ -139,7 +145,7 @@ // contentOffset will cause the -scrollViewDidScroll callback to fire. // Because we are eventually setting the contentOffset back to it's original // position, we can ignore these calls. - base::AutoReset<BOOL> autoReset(&_ignoreScroll, YES); + base::AutoReset<BOOL> ignoreScrollAutoReset(&_ignoreScroll, YES); CGPoint contentOffset = [_scrollView contentOffset]; _scrollView.get().contentOffset = CGPointMake(contentOffset.x, contentOffset.y + 1); @@ -147,6 +153,7 @@ } - (void)setContentInset:(UIEdgeInsets)contentInset { + base::AutoReset<NSUInteger> autoReset(&_proxyCallCount, _proxyCallCount + 1); [_scrollView setContentInset:contentInset]; } @@ -155,6 +162,7 @@ } - (void)setScrollIndicatorInsets:(UIEdgeInsets)scrollIndicatorInsets { + base::AutoReset<NSUInteger> autoReset(&_proxyCallCount, _proxyCallCount + 1); [_scrollView setScrollIndicatorInsets:scrollIndicatorInsets]; } @@ -163,6 +171,7 @@ } - (void)setContentSize:(CGSize)contentSize { + base::AutoReset<NSUInteger> autoReset(&_proxyCallCount, _proxyCallCount + 1); [_scrollView setContentSize:contentSize]; } @@ -171,6 +180,7 @@ } - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated { + base::AutoReset<NSUInteger> autoReset(&_proxyCallCount, _proxyCallCount + 1); [_scrollView setContentOffset:contentOffset animated:animated]; } @@ -182,6 +192,10 @@ return [_scrollView gestureRecognizers]; } +- (BOOL)isUpdatingThroughProxy { + return _proxyCallCount > 0; +} + #pragma mark - #pragma mark UIScrollViewDelegate callbacks
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 7f298c8..f89ae845 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -282,6 +282,9 @@ // The receiver of JavaScripts. base::scoped_nsobject<CRWJSInjectionReceiver> _jsInjectionReceiver; + + // The last recorded content offset of |webScrollView|. + CGPoint _lastContentOffset; } // The container view. The container view should be accessed through this @@ -2661,6 +2664,7 @@ self.userInteractionRegistered = NO; _pageHasZoomed = NO; + _lastContentOffset = CGPointZero; [[self sessionController] commitPendingEntry]; _webStateImpl->GetRequestTracker()->StartPageLoad( @@ -3334,6 +3338,19 @@ #pragma mark - #pragma mark CRWWebViewScrollViewProxyObserver +- (void)webViewScrollViewDidScroll: + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { + BOOL isRendererInitiated = + !webViewScrollViewProxy.updatingThroughProxy && !_applyingPageState; + if (isRendererInitiated && !self.userInteractionRegistered) { + // Ignore renderer-initiated scrolling that does not correspond with a user + // interaction. + webViewScrollViewProxy.contentOffset = _lastContentOffset; + } else { + _lastContentOffset = webViewScrollViewProxy.contentOffset; + } +} + - (void)webViewScrollViewDidZoom: (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { _pageHasZoomed = YES; @@ -3348,13 +3365,13 @@ if (contentSize.width < CGRectGetWidth(webViewScrollViewProxy.frame)) { // The renderer incorrectly resized the content area. Resetting the scroll // view's zoom scale will force a re-rendering. rdar://23963992 - _applyingPageState = YES; - web::PageZoomState zoomState = - currentItem->GetPageDisplayState().zoom_state(); + web::PageDisplayState displayState = currentItem->GetPageDisplayState(); + displayState.set_scroll_state( + web::PageScrollState(_lastContentOffset.x, _lastContentOffset.y)); + const web::PageZoomState& zoomState = displayState.zoom_state(); if (!zoomState.IsValid() || zoomState.IsLegacyFormat()) - zoomState = web::PageZoomState(1.0, 1.0, 1.0); - [self applyWebViewScrollZoomScaleFromZoomState:zoomState]; - _applyingPageState = NO; + displayState.set_zoom_state(web::PageZoomState(1.0, 1.0, 1.0)); + [self applyPageDisplayState:displayState]; } } #pragma mark -
diff --git a/media/audio/mac/audio_auhal_mac.cc b/media/audio/mac/audio_auhal_mac.cc index 4cc44b0..6657286 100644 --- a/media/audio/mac/audio_auhal_mac.cc +++ b/media/audio/mac/audio_auhal_mac.cc
@@ -61,15 +61,16 @@ // We must have a manager. DCHECK(manager_); - DVLOG(1) << "AUHALStream::AUHALStream()"; - DVLOG(1) << "Device: " << device; - DVLOG(1) << "Output channels: " << output_channels_; - DVLOG(1) << "Sample rate: " << params_.sample_rate(); - DVLOG(1) << "Buffer size: " << number_of_frames_; + DVLOG(1) << "ctor"; + DVLOG(1) << "device ID: 0x" << std::hex << device; + DVLOG(1) << "buffer size: " << number_of_frames_; + DVLOG(1) << "output channels: " << output_channels_; + DVLOG(1) << "sample rate: " << params_.sample_rate(); } AUHALStream::~AUHALStream() { DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(1) << "~dtor"; CHECK(!audio_unit_); ReportAndResetStats(); @@ -79,6 +80,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!output_bus_.get()); DCHECK(!audio_unit_); + DVLOG(1) << "Open"; // Get the total number of output channels that the // hardware supports. @@ -118,6 +120,7 @@ void AUHALStream::Close() { DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(1) << "Close"; CloseAudioUnit(); // Inform the audio manager that we have been closed. This will cause our // destruction. @@ -126,6 +129,7 @@ void AUHALStream::Start(AudioSourceCallback* callback) { DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(1) << "Start"; DCHECK(callback); if (!audio_unit_) { DLOG(ERROR) << "Open() has not been called successfully"; @@ -170,15 +174,13 @@ deferred_start_cb_.Cancel(); if (stopped_) return; - + DVLOG(1) << "Stop"; OSStatus result = AudioOutputUnitStop(audio_unit_); OSSTATUS_DLOG_IF(ERROR, result != noErr, result) << "AudioOutputUnitStop() failed."; if (result != noErr) source_->OnError(this); - ReportAndResetStats(); - base::AutoLock auto_lock(source_lock_); source_ = NULL; stopped_ = true;
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc index cfa32773b..eb328af6 100644 --- a/media/audio/mac/audio_low_latency_input_mac.cc +++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -86,11 +86,14 @@ format_.mBytesPerFrame = format_.mBytesPerPacket; format_.mReserved = 0; - DVLOG(1) << "Desired output format: " << format_; + DVLOG(1) << "ctor"; + DVLOG(1) << "device ID: 0x" << std::hex << audio_device_id; + DVLOG(1) << "buffer size : " << number_of_frames_; + DVLOG(1) << "desired output format: " << format_; // Derive size (in bytes) of the buffers that we will render to. UInt32 data_byte_size = number_of_frames_ * format_.mBytesPerFrame; - DVLOG(1) << "Size of data buffer in bytes : " << data_byte_size; + DVLOG(1) << "size of data buffer in bytes : " << data_byte_size; // Allocate AudioBuffers to be used as storage for the received audio. // The AudioBufferList structure works as a placeholder for the @@ -104,11 +107,14 @@ audio_buffer->mData = audio_data_buffer_.get(); } -AUAudioInputStream::~AUAudioInputStream() {} +AUAudioInputStream::~AUAudioInputStream() { + DVLOG(1) << "~dtor"; +} // Obtain and open the AUHAL AudioOutputUnit for recording. bool AUAudioInputStream::Open() { DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(1) << "Open"; // Verify that we are not already opened. if (audio_unit_) return false; @@ -306,6 +312,7 @@ DLOG_IF(ERROR, !audio_unit_) << "Open() has not been called successfully"; if (started_ || !audio_unit_) return; + DVLOG(1) << "Start"; // Check if we should defer Start() for http://crbug.com/160920. if (manager_->ShouldDeferStreamStart()) { @@ -347,6 +354,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!started_) return; + DVLOG(1) << "Stop"; StopAgc(); input_callback_timer_.reset(); OSStatus result = AudioOutputUnitStop(audio_unit_); @@ -361,6 +369,7 @@ void AUAudioInputStream::Close() { DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(1) << "Close"; // It is valid to call Close() before calling open or Start(). // It is also valid to call Close() after Start() has been called. if (started_) { @@ -552,6 +561,7 @@ UInt32 new_size = number_of_frames * audio_input->format_.mBytesPerFrame; AudioBuffer* audio_buffer = audio_input->audio_buffer_list()->mBuffers; if (new_size != audio_buffer->mDataByteSize) { + DVLOG(1) << "New size of number_of_frames detected: " << number_of_frames; if (new_size > audio_buffer->mDataByteSize) { // This can happen if the device is unpluged during recording. We // allocate enough memory here to avoid depending on how CoreAudio
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc index bd443f1..4541074 100644 --- a/media/audio/mac/audio_manager_mac.cc +++ b/media/audio/mac/audio_manager_mac.cc
@@ -89,6 +89,22 @@ output_device_id != kAudioObjectUnknown; } +static std::string GetAudioDeviceNameFromDeviceId(AudioDeviceID device_id, + bool is_input) { + CFStringRef device_name = nullptr; + UInt32 data_size = sizeof(device_name); + AudioObjectPropertyAddress property_address = GetAudioObjectPropertyAddress( + kAudioDevicePropertyDeviceNameCFString, is_input); + OSStatus result = AudioObjectGetPropertyData( + device_id, &property_address, 0, nullptr, &data_size, &device_name); + std::string device; + if (result == noErr) { + device = base::SysCFStringRefToUTF8(device_name); + CFRelease(device_name); + } + return device; +} + // Retrieves information on audio devices, and prepends the default // device to the list if the list is non-empty. static void GetAudioDeviceInfo(bool is_input, @@ -263,7 +279,7 @@ AudioPowerObserver() : is_suspending_(false), is_monitoring_(base::PowerMonitor::Get()) { - // The PowerMonitor requires signifcant setup (a CFRunLoop and preallocated + // The PowerMonitor requires significant setup (a CFRunLoop and preallocated // IO ports) so it's not available under unit tests. See the OSX impl of // base::PowerMonitorDeviceSource for more details. if (!is_monitoring_) @@ -353,7 +369,7 @@ bool AudioManagerMac::GetDefaultDevice(AudioDeviceID* device, bool input) { CHECK(device); - // Obtain the current output device selected by the user. + // Obtain the AudioDeviceID of the default input or output AudioDevice. AudioObjectPropertyAddress pa; pa.mSelector = input ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice; @@ -367,12 +383,10 @@ 0, &size, device); - if ((result != kAudioHardwareNoError) || (*device == kAudioDeviceUnknown)) { DLOG(ERROR) << "Error getting default AudioDevice."; return false; } - return true; } @@ -387,8 +401,13 @@ AudioObjectPropertyScope scope, int* channels) { CHECK(channels); + const bool is_input = (scope == kAudioDevicePropertyScopeInput); + DVLOG(1) << "GetDeviceChannels(id=0x" << std::hex << device + << ", is_input=" << is_input << ")"; - // Get stream configuration. + // Get the stream configuration of the device in an AudioBufferList (with the + // buffer pointers set to NULL) which describes the list of streams and the + // number of channels in each stream. AudioObjectPropertyAddress pa; pa.mSelector = kAudioDevicePropertyStreamConfiguration; pa.mScope = scope; @@ -399,7 +418,6 @@ if (result != noErr || !size) return false; - // Allocate storage. scoped_ptr<uint8_t[]> list_storage(new uint8_t[size]); AudioBufferList& buffer_list = *reinterpret_cast<AudioBufferList*>(list_storage.get()); @@ -408,17 +426,16 @@ if (result != noErr) return false; - // Determine number of input channels. - int channels_per_frame = buffer_list.mNumberBuffers > 0 ? - buffer_list.mBuffers[0].mNumberChannels : 0; - if (channels_per_frame == 1 && buffer_list.mNumberBuffers > 1) { - // Non-interleaved. - *channels = buffer_list.mNumberBuffers; - } else { - // Interleaved. - *channels = channels_per_frame; + // Determine number of channels based on the AudioBufferList. + // |mNumberBuffers] is the number of interleaved channels in the buffer. + // If the number is 1, the buffer is noninterleaved. + // TODO(henrika): add UMA stats to track utilized hardware configurations. + int num_channels = 0; + for (UInt32 i = 0; i < buffer_list.mNumberBuffers; ++i) { + num_channels += buffer_list.mBuffers[i].mNumberChannels; } - + *channels = num_channels; + DVLOG(1) << "#channels: " << *channels; return true; } @@ -577,7 +594,7 @@ return *iter; } - // Failed to figure out which is the matching device, return an emtpy string. + // Failed to figure out which is the matching device, return an empty string. return std::string(); } @@ -746,8 +763,9 @@ GetDefaultOutputDevice(&new_output_device); if (current_sample_rate_ == new_sample_rate && - current_output_device_ == new_output_device) + current_output_device_ == new_output_device) { return; + } current_sample_rate_ = new_sample_rate; current_output_device_ = new_output_device; @@ -792,11 +810,16 @@ bool* size_was_changed) { const bool is_input = (element == 1); DVLOG(1) << "MaybeChangeBufferSize(id=0x" << std::hex << device_id - << ", is_input=" << is_input << ", buffer_size=" << std::dec + << ", is_input=" << is_input << ", desired_buffer_size=" << std::dec << desired_buffer_size << ")"; *size_was_changed = false; + // Log the device name (and id) for debugging purposes. + std::string device_name = GetAudioDeviceNameFromDeviceId(device_id, is_input); + DVLOG(1) << "name: " << device_name << " (ID: 0x" << std::hex << device_id + << ")"; + // Get the current size of the I/O buffer for the specified device. The // property is read on a global scope, hence using element 0. The default IO // buffer size on Mac OSX for OS X 10.9 and later is 512 audio frames. @@ -858,7 +881,7 @@ // 4410 will on most devices be limited to 4096 without any further notice. UInt32 minimum, maximum; GetIOBufferFrameSizeRange(device_id, is_input, &minimum, &maximum); - DVLOG(1) << "valid IO buffe size range: [" << minimum << ", " << maximum + DVLOG(1) << "valid IO buffer size range: [" << minimum << ", " << maximum << "]"; buffer_size = desired_buffer_size; if (buffer_size < minimum)
diff --git a/media/test/data/eme_player_js/eme_app.js b/media/test/data/eme_player_js/eme_app.js index fed3919..dff5ce8 100644 --- a/media/test/data/eme_player_js/eme_app.js +++ b/media/test/data/eme_player_js/eme_app.js
@@ -40,7 +40,13 @@ if (this.testConfig_.runFPS) FPSObserver.observe(this.video_); - return videoPlayer.init().then(function(result) { return videoPlayer; }); + return videoPlayer.init().then(function(result) { + if (result != videoPlayer) { + Utils.timeLog('Media player mismatch.'); + } + Utils.timeLog('Media player created.'); + return videoPlayer; + }); }; EMEApp.prototype.updateDocument = function(testConfig) {
diff --git a/media/test/data/eme_player_js/player_utils.js b/media/test/data/eme_player_js/player_utils.js index a532e1a..b9f1732c 100644 --- a/media/test/data/eme_player_js/player_utils.js +++ b/media/test/data/eme_player_js/player_utils.js
@@ -177,6 +177,7 @@ Utils.timeLog('Loading media using src.'); player.video.src = player.testConfig.mediaFile; } + Utils.timeLog('video.src has been set to ' + player.video.src); }; // Initialize the player to play encrypted content. Returns a promise that @@ -184,6 +185,7 @@ PlayerUtils.initEMEPlayer = function(player) { return player.registerEventListeners().then(function(result) { PlayerUtils.setVideoSource(player); + Utils.timeLog('initEMEPlayer() done'); return player; }); };
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn index df7e878b..673fcb53 100644 --- a/mojo/BUILD.gn +++ b/mojo/BUILD.gn
@@ -73,11 +73,11 @@ "//ipc/mojo:ipc_mojo_unittests", "//mojo/common:mojo_common_unittests", "//mojo/converters/surfaces/tests:mojo_surfaces_lib_unittests", + "//mojo/edk/js/test:js_integration_tests", "//mojo/edk/js/test:js_unittests", "//mojo/shell/public/cpp/tests:mojo_public_application_unittests", # TODO(use_chrome_edk): - #"//mojo/edk/js/test:js_integration_tests2", #"//mojo/edk/system:mojo_message_pipe_perftests", #"//mojo/edk/system:mojo_system_unittests", #"//mojo/edk/test:mojo_public_bindings_unittests",
diff --git a/net/BUILD.gn b/net/BUILD.gn index 129003a..6203ce4 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -319,6 +319,11 @@ net_shared_sources += [ "third_party/nss/ssl/cmpcert.c" ] } + if (is_chromecast && use_nss_certs) { + net_shared_sources += [ "ssl/ssl_platform_key_chromecast.cc" ] + net_shared_sources -= [ "ssl/ssl_platform_key_nss.cc" ] + } + if (!enable_mdns) { net_shared_sources -= [ "dns/mdns_cache.cc",
diff --git a/net/net_common.gypi b/net/net_common.gypi index a6da6a89..b08beb8 100644 --- a/net/net_common.gypi +++ b/net/net_common.gypi
@@ -140,6 +140,16 @@ 'dependencies': [ '../third_party/boringssl/boringssl.gyp:boringssl', ], + 'conditions': [ + ['chromecast==1 and use_nss_certs==1', { + 'sources': [ + 'ssl/ssl_platform_key_chromecast.cc', + ], + 'sources!': [ + 'ssl/ssl_platform_key_nss.cc', + ], + }], + ], }, { # else !use_openssl: remove the unneeded files and depend on NSS. 'sources!': [
diff --git a/net/ssl/ssl_platform_key_chromecast.cc b/net/ssl/ssl_platform_key_chromecast.cc new file mode 100644 index 0000000..ef1fef5 --- /dev/null +++ b/net/ssl/ssl_platform_key_chromecast.cc
@@ -0,0 +1,136 @@ +// 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 "net/ssl/ssl_platform_key.h" + +#include <keyhi.h> +#include <pk11pub.h> +#include <prerror.h> + +#include <openssl/rsa.h> + +#include "base/logging.h" +#include "base/macros.h" +#include "base/sequenced_task_runner.h" +#include "crypto/scoped_nss_types.h" +#include "crypto/scoped_openssl_types.h" +#include "net/cert/x509_certificate.h" +#include "net/ssl/client_key_store.h" +#include "net/ssl/ssl_platform_key_task_runner.h" +#include "net/ssl/ssl_private_key.h" +#include "net/ssl/threaded_ssl_private_key.h" + +namespace net { + +namespace { + +void LogPRError() { + PRErrorCode err = PR_GetError(); + const char* err_name = PR_ErrorToName(err); + if (err_name == nullptr) + err_name = ""; + LOG(ERROR) << "Could not sign digest: " << err << " (" << err_name << ")"; +} + +class SSLPlatformKeyChromecast : public ThreadedSSLPrivateKey::Delegate { + public: + SSLPlatformKeyChromecast(crypto::ScopedSECKEYPrivateKey key) + : key_(std::move(key)) {} + ~SSLPlatformKeyChromecast() override {} + + SSLPrivateKey::Type GetType() override { return SSLPrivateKey::Type::RSA; } + + std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override { + static const SSLPrivateKey::Hash kHashes[] = { + SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1, + SSLPrivateKey::Hash::MD5_SHA1}; + return std::vector<SSLPrivateKey::Hash>(kHashes, + kHashes + arraysize(kHashes)); + } + + size_t GetMaxSignatureLengthInBytes() override { + int len = PK11_SignatureLen(key_.get()); + if (len <= 0) + return 0; + return static_cast<size_t>(len); + } + + Error SignDigest(SSLPrivateKey::Hash hash, + const base::StringPiece& input, + std::vector<uint8_t>* signature) override { + SECItem digest_item; + digest_item.data = + const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(input.data())); + digest_item.len = input.size(); + + crypto::ScopedOpenSSLBytes free_digest_info; + // PK11_Sign expects the caller to prepend the DigestInfo. + int hash_nid = NID_undef; + switch (hash) { + case SSLPrivateKey::Hash::MD5_SHA1: + hash_nid = NID_md5_sha1; + break; + case SSLPrivateKey::Hash::SHA1: + hash_nid = NID_sha1; + break; + case SSLPrivateKey::Hash::SHA256: + hash_nid = NID_sha256; + break; + default: + return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + } + DCHECK_NE(NID_undef, hash_nid); + int is_alloced; + size_t prefix_len; + if (!RSA_add_pkcs1_prefix(&digest_item.data, &prefix_len, &is_alloced, + hash_nid, digest_item.data, digest_item.len)) { + return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + } + digest_item.len = prefix_len; + if (is_alloced) + free_digest_info.reset(digest_item.data); + + int len = PK11_SignatureLen(key_.get()); + if (len <= 0) { + LogPRError(); + return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + } + signature->resize(len); + SECItem signature_item; + signature_item.data = signature->data(); + signature_item.len = signature->size(); + + SECStatus rv = PK11_Sign(key_.get(), &signature_item, &digest_item); + if (rv != SECSuccess) { + LogPRError(); + return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + } + signature->resize(signature_item.len); + + return OK; + } + + private: + crypto::ScopedSECKEYPrivateKey key_; + + DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyChromecast); +}; + +} // namespace + +scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( + X509Certificate* certificate) { + crypto::ScopedSECKEYPrivateKey key( + PK11_FindKeyByAnyCert(certificate->os_cert_handle(), nullptr)); + if (!key) { + return ClientKeyStore::GetInstance()->FetchClientCertPrivateKey( + *certificate); + } + + return make_scoped_refptr(new ThreadedSSLPrivateKey( + make_scoped_ptr(new SSLPlatformKeyChromecast(std::move(key))), + GetSSLPlatformKeyTaskRunner())); +} + +} // namespace net
diff --git a/printing/BUILD.gn b/printing/BUILD.gn index 45dfcc8..3b05be4 100644 --- a/printing/BUILD.gn +++ b/printing/BUILD.gn
@@ -131,7 +131,7 @@ cups_version = exec_script("cups_config_helper.py", [ "--api-version", - sysroot, + rebase_path(sysroot), ], "trim string") @@ -254,7 +254,7 @@ libs = exec_script("cups_config_helper.py", [ "--libs-for-gn", - sysroot, + rebase_path(sysroot), ], "value") }
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index aa74281..75ad5c3 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1476,4 +1476,6 @@ crbug.com/516751 svg/custom/pointer-events-image.svg [ NeedsRebaseline ] crbug.com/516751 svg/hixie/perf/004.xml [ NeedsRebaseline ] -crbug.com/579365 [ Mac ] fast/replaced/border-radius-clip.html [ NeedsRebaseline ] \ No newline at end of file +crbug.com/579365 [ Mac ] fast/replaced/border-radius-clip.html [ NeedsRebaseline ] + +crbug.com/579385 [ Win Linux Debug ] fast/forms/select-popup/popup-menu-resize-after-open.html [ Failure ] \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache-expected.txt b/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache-expected.txt index e8e7639..9f05038 100644 --- a/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache-expected.txt +++ b/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache-expected.txt
@@ -20,10 +20,9 @@ AXRole: AXInlineTextBox "Before" AXRole: AXGroup AXRole: AXUnknown - AXRole: AXScrollArea - AXRole: AXWebArea - AXRole: AXGroup - AXRole: AXButton "Click me" + AXRole: AXWebArea + AXRole: AXGroup + AXRole: AXButton "Click me" AXRole: AXParagraph AXRole: AXStaticText "After" AXRole: AXInlineTextBox "After"
diff --git a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt index 22929f9..8584a35 100644 --- a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt +++ b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
@@ -170,11 +170,9 @@ AXRole: AXInlineTextBox "This is an open dialog window" AXRole: AXGroup AXRole: AXUnknown - AXRole: AXScrollArea - AXRole: AXWebArea + AXRole: AXWebArea AXRole: AXUnknown - AXRole: AXScrollArea - AXRole: AXWebArea + AXRole: AXWebArea AXRole: AXTable "Caption" AXRole: AXCaption AXRole: AXStaticText "Caption"
diff --git a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification.html b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification.html index 2a3262b..203b03c 100644 --- a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification.html +++ b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification.html
@@ -32,11 +32,11 @@ shouldBeUndefined("accessibilityController.accessibleElementById('innerbutton')"); window.accessibilityController.addNotificationListener(function (target, notification) { - if (!target.parentElement() || !target.parentElement().parentElement()) + if (!target.parentElement()) return; // Ignore this notification if it's not within the subtree of the iframe. - var frameTarget = target.parentElement().parentElement(); + var frameTarget = target.parentElement(); if (frameTarget.name.indexOf("InnerFrame") == -1) return;
diff --git a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt index 79db71a..c9170f3 100644 --- a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt +++ b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt
@@ -14,7 +14,6 @@ TEST COMPLETE PASS iframe.isEqual(newIframe) is true -PASS scrollarea.isEqual(newScrollarea) is false PASS subwebarea.isEqual(newSubwebarea) is false PASS newSubwebarea.childrenCount > 0 is true
diff --git a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree.html b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree.html index 141d67e..dbb726c0 100644 --- a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree.html +++ b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree.html
@@ -12,19 +12,16 @@ if (window.accessibilityController) { window.iframe = accessibilityController.accessibleElementById('iframe'); - window.scrollarea = iframe.childAtIndex(0); - window.subwebarea = scrollarea.childAtIndex(0); + window.subwebarea = iframe.childAtIndex(0); } window.iframeElement = document.getElementById("iframe"); iframeElement.addEventListener("load", function() { if (window.accessibilityController) { window.newIframe = accessibilityController.accessibleElementById('iframe'); - window.newScrollarea = newIframe.childAtIndex(0); - window.newSubwebarea = newScrollarea.childAtIndex(0); + window.newSubwebarea = newIframe.childAtIndex(0); shouldBeTrue("iframe.isEqual(newIframe)"); - shouldBeFalse("scrollarea.isEqual(newScrollarea)"); shouldBeFalse("subwebarea.isEqual(newSubwebarea)"); shouldBeTrue("newSubwebarea.childrenCount > 0"); }
diff --git a/third_party/WebKit/LayoutTests/accessibility/role-attribute-expected.txt b/third_party/WebKit/LayoutTests/accessibility/role-attribute-expected.txt index 5948ec0af..6771d64 100644 --- a/third_party/WebKit/LayoutTests/accessibility/role-attribute-expected.txt +++ b/third_party/WebKit/LayoutTests/accessibility/role-attribute-expected.txt
@@ -4,7 +4,7 @@ Implicit Item 1 Implicit Item 2 Implicit Item 3 - + End of test This tests that the role attribute is not missed. @@ -37,6 +37,14 @@ AXRole: AXListBox AXRole: AXListBoxOption "Implicit Option 1" AXRole: AXListBoxOption "Implicit Option 2" + AXRole: AXGroup + AXRole: AXMenuListPopup + AXRole: AXTextField "Explicit dropdown 1" + AXRole: AXTextField "Explicit dropdown 2" + AXRole: AXPopUpButton + AXRole: AXMenuListPopup + AXRole: AXMenuListOption "Implicit dropdown 1" + AXRole: AXMenuListOption "Implicit dropdown 2" AXRole: AXStatus AXRole: AXProgressIndicator AXRole: AXStatus
diff --git a/third_party/WebKit/LayoutTests/accessibility/role-attribute.html b/third_party/WebKit/LayoutTests/accessibility/role-attribute.html index d8c51f75..7f35c95 100644 --- a/third_party/WebKit/LayoutTests/accessibility/role-attribute.html +++ b/third_party/WebKit/LayoutTests/accessibility/role-attribute.html
@@ -18,6 +18,14 @@ <option>Implicit Option 1</option> <option>Implicit Option 2</option> </select> +<select role="group"> + <option role="textbox">Explicit dropdown 1</option> + <option role="textbox">Explicit dropdown 2</option> +</select> +<select> + <option>Implicit dropdown 1</option> + <option>Implicit dropdown 2</option> +</select> <progress value="22" max="100" role="status"></progress> <progress value="22" max="100"></progress> <input type="range" name="points" min="0" max="10" role="status">
diff --git a/third_party/WebKit/LayoutTests/fast/css/content-image-set-disallowed-url-crash.html b/third_party/WebKit/LayoutTests/fast/css/content-image-set-disallowed-url-crash.html new file mode 100644 index 0000000..f57b6ff --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/content-image-set-disallowed-url-crash.html
@@ -0,0 +1,16 @@ +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> + +<style> +#target { + content: -webkit-image-set(url("chrome://disallowed-url/") 1x); +} +</style> + +<img id="target"></img> + +<script> +test(() => { + console.log(getComputedStyle(target).content); +}, 'This test passes if it does not crash.'); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-css-text.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-css-text.html new file mode 100644 index 0000000..d0a0147 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/slotted-pseudo-element-css-text.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<script src='../../../resources/testharness.js'></script> +<script src='../../../resources/testharnessreport.js'></script> +<style id="style1"> +::slotted { display: block; } /* invalid - no parameter */ +::slotted() { display: block; } /* invalid - empty parameter */ +::slotted(*) { display: block; } +*::slotted(*) { display: block; } +::slotted(div) { display: block; } /* expects universal selector (*) on the left in cssText */ +::slotted( div) { display: block; } /* allow a space on left */ +::slotted(div ) { display: block; } /* allow a space on right */ +::slotted(div::before) { display: block; } /* having a pseudo element in () is invalid */ + +.foo::slotted(div) { color: blue; } +#id::slotted(*) { color: blue; } +[attr=foo]::slotted(*) { color: blue; } +.foo .bar::slotted(div) { color: blue; } +.foo::before .bar::slotted(div) { color: blue; } /* invalid, only one pseudo element is allowed at the rightmost compound */ +.foo::slotted(div) .bar { color: blue; } /* invalid, same as above */ +::slotted(div, div) { color: blue; } /* invalid - selector list */ +::slotted(div div) { color: blue; } /* invalid - complex selector (combinator is used) */ + +slot::slotted(.green) { color: green; } +slot::slotted(#green) { color: green; } +slot::slotted([green=green]) { color: green; } +slot::slotted(div.green) { color: green; } + +div ::slotted(div) { color: red; } +div + slot::slotted(div) { color: red; } + +span::slotted(*) { color: red; } /* never matches, but valid as a selector */ +::slotted(span)::slotted(span) { color: red; } /* invalid */ +::slotted(::slotted(div)) { color: red; } /* invalid */ +</style> +<script> +'use strict'; +test(() => { + var style1 = document.getElementById('style1'); + var cssRules = style1.sheet.cssRules; + + var expectedCSSTexts = [ + "::slotted(*) { display: block; }", + "*::slotted(*) { display: block; }", + "::slotted(div) { display: block; }", + "::slotted(div) { display: block; }", + "::slotted(div) { display: block; }", + ".foo::slotted(div) { color: blue; }", + "#id::slotted(*) { color: blue; }", + "[attr=\"foo\"]::slotted(*) { color: blue; }", + ".foo .bar::slotted(div) { color: blue; }", + "slot::slotted(.green) { color: green; }", + "slot::slotted(#green) { color: green; }", + "slot::slotted([green=\"green\"]) { color: green; }", + "slot::slotted(div.green) { color: green; }", + "div ::slotted(div) { color: red; }", + "div + slot::slotted(div) { color: red; }", + "span::slotted(*) { color: red; }" + ]; + + for (var i = 0; i < expectedCSSTexts.length; ++i) + assert_equals(cssRules.item(i).cssText, expectedCSSTexts[i]); + assert_equals(cssRules.length, expectedCSSTexts.length); + +}, "Test for cssText of '::slotted' rule."); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-default-slots.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-default-slots.html index db41b3e5..a973bbc0 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-default-slots.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-default-slots.html
@@ -37,8 +37,8 @@ }, "getAssignedNodes"); test(() => { - assert_array_equals(slot1.getDistributedNodes(), [child2, child4]); - assert_array_equals(slot2.getDistributedNodes(), []); - assert_array_equals(slot3.getDistributedNodes(), [child3]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [child2, child4]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), []); + assert_array_equals(slot3.getAssignedNodes({flatten: true}), [child3]); }, "getDistributedNodes"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-1.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-1.html index cac4ea7d..17f927e 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-1.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-1.html
@@ -38,8 +38,8 @@ }, "getAssignedNodes"); test(() => { - assert_array_equals(slot1.getDistributedNodes(), [child1, child2]); - assert_array_equals(slot2.getDistributedNodes(), [child3]); - assert_array_equals(slot3.getDistributedNodes(), []); -}, "getDistributedNodes"); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [child1, child2]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [child3]); + assert_array_equals(slot3.getAssignedNodes({flatten: true}), []); +}, "getAssignedNodes({flatten: true})"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-2.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-2.html index 55d78ff6..cf44ac3 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-2.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-2.html
@@ -71,11 +71,17 @@ }, "getAssignedNodes"); test(() => { - assert_array_equals(d1_s0.getDistributedNodes(), [d5]); - assert_array_equals(d1_s1.getDistributedNodes(), [d2]); - assert_array_equals(d1_s2.getDistributedNodes(), [d3]); + assert_array_equals(d1_1_s1.getAssignedNodes({flatten: false}), [d1_s1, d1_4], + "{flatten: false} should not have any effect"); +}, "getAssignedNodes({flatten: false})"); - assert_array_equals(d1_1_s1.getDistributedNodes(), [d2, d1_4]); - assert_array_equals(d1_1_s2.getDistributedNodes(), []); -}, "getDistributedNodes"); +test(() => { + assert_array_equals(d1_s0.getAssignedNodes({flatten: true}), [d5]); + assert_array_equals(d1_s1.getAssignedNodes({flatten: true}), [d2]); + assert_array_equals(d1_s2.getAssignedNodes({flatten: true}), [d3]); + + assert_array_equals(d1_1_s1.getAssignedNodes({flatten: true}), [d2, d1_4]); + assert_array_equals(d1_1_s1.getAssignedNodes({flatten: true}), [d2, d1_4]); + assert_array_equals(d1_1_s2.getAssignedNodes({flatten: true}), []); +}, "getAssignedNodes({flatten: true})"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-with-closed-shadow-tree.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-with-closed-shadow-tree.html index dd5e1f9..bb1b3dd 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-with-closed-shadow-tree.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-api-with-closed-shadow-tree.html
@@ -49,8 +49,8 @@ }, "A closed shadow tree has nothing to do with the behavior of getAssignedNodes"); test(() => { - assert_array_equals(d1_s1.getDistributedNodes(), [d2]); - assert_array_equals(d1_s2.getDistributedNodes(), [d3]); - assert_array_equals(d1_1_s1.getDistributedNodes(), [d1_2, d2]); -}, "A closed shadow tree has nothing to do with the behavior of getDistributedNodes"); + assert_array_equals(d1_s1.getAssignedNodes({flatten: true}), [d2]); + assert_array_equals(d1_s2.getAssignedNodes({flatten: true}), [d3]); + assert_array_equals(d1_1_s1.getAssignedNodes({flatten: true}), [d1_2, d2]); +}, "A closed shadow tree has nothing to do with the behavior of getAssignedNodes({flatten: true}}"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-dom-mutation.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-dom-mutation.html index 5757aa011..bc5c47a 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-dom-mutation.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-dom-mutation.html
@@ -25,8 +25,8 @@ const fallback2 = host.shadowRoot.querySelector('#fallback2'); test(() => { - assert_array_equals(slot1.getDistributedNodes(), [child1]); - assert_array_equals(slot2.getDistributedNodes(), [fallback2]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [child1]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [fallback2]); }, "Slot's distributed nodes"); test(() => { @@ -35,24 +35,24 @@ slot0.setAttribute('name', 'slot1'); host.shadowRoot.insertBefore(slot0, slot1); - assert_array_equals(slot0.getDistributedNodes(), [child1]); - assert_array_equals(slot1.getDistributedNodes(), [fallback1]); - assert_array_equals(slot2.getDistributedNodes(), [fallback2]); + assert_array_equals(slot0.getAssignedNodes({flatten: true}), [child1]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [fallback1]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [fallback2]); // Remove host.shadowRoot.removeChild(slot0); - assert_array_equals(slot1.getDistributedNodes(), [child1]); - assert_array_equals(slot2.getDistributedNodes(), [fallback2]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [child1]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [fallback2]); }, "Slot's distributed nodes after inserting/removeing a slot."); test(() => { // Attribute change slot1.setAttribute('name', 'slot-foo'); - assert_array_equals(slot1.getDistributedNodes(), [fallback1]); - assert_array_equals(slot2.getDistributedNodes(), [fallback2]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [fallback1]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [fallback2]); child1.setAttribute('slot', 'slot-foo'); - assert_array_equals(slot1.getDistributedNodes(), [child1]); - assert_array_equals(slot2.getDistributedNodes(), [fallback2]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [child1]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [fallback2]); }, "Slot's distributed nodes after the attribute is changed."); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-1.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-1.html index 15dbd5f..e1ab2df 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-1.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-1.html
@@ -33,7 +33,7 @@ }, "getAssignedNodes"); test(() => { - assert_array_equals(slot1.getDistributedNodes(), [child1]); - assert_array_equals(slot2.getDistributedNodes(), [fallback2]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [child1]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [fallback2]); }, "getDistributedNodes"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-2.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-2.html index 32e26f8..7d5a3f1 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-2.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-2.html
@@ -47,9 +47,9 @@ }, "getAssignedNodes"); test(() => { - assert_array_equals(slot1.getDistributedNodes(), [fallback1, child1]); - assert_array_equals(slot2.getDistributedNodes(), [child1]); - assert_array_equals(slot3.getDistributedNodes(), [fallback3]); - assert_array_equals(slot4.getDistributedNodes(), [fallback3]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [fallback1, child1]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [child1]); + assert_array_equals(slot3.getAssignedNodes({flatten: true}), [fallback3]); + assert_array_equals(slot4.getAssignedNodes({flatten: true}), [fallback3]); }, "getDistributedNodes"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-3.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-3.html index b548272d..3976b9e1 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-3.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-fallback-api-3.html
@@ -74,12 +74,12 @@ }, "getAssignedNodes"); test(() => { - assert_array_equals(slot1.getDistributedNodes(), [fallback1, child1]); - assert_array_equals(slot2.getDistributedNodes(), [child1]); - assert_array_equals(slot3.getDistributedNodes(), [fallback3]); - assert_array_equals(slot4.getDistributedNodes(), [fallback3]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [fallback1, child1]); + assert_array_equals(slot2.getAssignedNodes({flatten: true}), [child1]); + assert_array_equals(slot3.getAssignedNodes({flatten: true}), [fallback3]); + assert_array_equals(slot4.getAssignedNodes({flatten: true}), [fallback3]); - assert_array_equals(slot_a.getDistributedNodes(), [fallback1, child1, fallback_a]); - assert_array_equals(slot_b.getDistributedNodes(), [fallback1, child1]); + assert_array_equals(slot_a.getAssignedNodes({flatten: true}), [fallback1, child1, fallback_a]); + assert_array_equals(slot_b.getAssignedNodes({flatten: true}), [fallback1, child1]); }, "getDistributedNodes"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-text-nodes.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-text-nodes.html index 7ef4a8bc..979c61c 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-text-nodes.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/v1-slots-text-nodes.html
@@ -40,8 +40,8 @@ }, "assignedSlot"); test(() => { - assert_array_equals(defaultSlot.getDistributedNodes(), [textHello, child2, textWorld]); - assert_array_equals(slot1.getDistributedNodes(), [child1]); + assert_array_equals(defaultSlot.getAssignedNodes({flatten: true}), [textHello, child2, textWorld]); + assert_array_equals(slot1.getAssignedNodes({flatten: true}), [child1]); }, "getDistributedNodes"); add_completion_callback(() => {
diff --git a/third_party/WebKit/LayoutTests/fast/forms/select/select-ask-for-reset.html b/third_party/WebKit/LayoutTests/fast/forms/select/select-ask-for-reset.html index fbee983..f2d7432 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/select/select-ask-for-reset.html +++ b/third_party/WebKit/LayoutTests/fast/forms/select/select-ask-for-reset.html
@@ -29,5 +29,16 @@ // option list. assert_equals(select.selectedIndex, -1); }, 'Removing a SELECT tree from another tree should not reset selection.'); + +test(function() { + var form = document.createElement('form'); + document.body.appendChild(form); + var select = document.createElement('select'); + form.appendChild(select); + select.innerHTML = '<option disabled>Apple</option><option>Banana</option><option>Cherry</option>'; + assert_equals(select.selectedIndex, 1); + form.reset(); + assert_equals(select.selectedIndex, 1); +}, 'Reset should select the first option element in the list of options that is not disabled to true'); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-empty-block-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-empty-block-expected.html new file mode 100644 index 0000000..7c4b0daf --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-empty-block-expected.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<p>There should be three vertical lines below.</p> +<div style="height:50px;"> + <div style="float:left; height:100%; width:50px; padding-right:3px; border-right:3px solid;"></div> + <div style="float:left; height:100%; width:50px; padding:0 3px; border-right:3px solid;"></div> + <div style="float:left; height:100%; width:50px; padding:0 3px; border-right:3px solid;"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-empty-block.html b/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-empty-block.html new file mode 100644 index 0000000..25ec481 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-empty-block.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<p>There should be three vertical lines below.</p> +<div style="-webkit-columns:2; -webkit-column-rule:3px solid; -webkit-column-gap:9px; width:227px;"> + <div style="-webkit-columns:2; -webkit-column-rule:3px solid; -webkit-column-gap:9px;"> + <div style="height:200px;"></div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-tall-line-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-tall-line-expected.html new file mode 100644 index 0000000..7c4b0daf --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-tall-line-expected.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<p>There should be three vertical lines below.</p> +<div style="height:50px;"> + <div style="float:left; height:100%; width:50px; padding-right:3px; border-right:3px solid;"></div> + <div style="float:left; height:100%; width:50px; padding:0 3px; border-right:3px solid;"></div> + <div style="float:left; height:100%; width:50px; padding:0 3px; border-right:3px solid;"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-tall-line.html b/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-tall-line.html new file mode 100644 index 0000000..6a493b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/nested-with-single-tall-line.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<p>There should be three vertical lines below.</p> +<div style="-webkit-columns:2; -webkit-column-rule:3px solid; -webkit-column-gap:9px; column-fill:auto; width:227px; height:50px; line-height:200px;"> + <div style="-webkit-columns:2; -webkit-column-rule:3px solid; -webkit-column-gap:9px; column-fill:auto; height:100px;"> + <br> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/short-columns-insane-unbreakable-content-height-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/short-columns-insane-unbreakable-content-height-crash-expected.txt new file mode 100644 index 0000000..2cbf68c --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/short-columns-insane-unbreakable-content-height-crash-expected.txt
@@ -0,0 +1,5 @@ +PASS if no crash or assertion failure. + + + +
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/short-columns-insane-unbreakable-content-height-crash.html b/third_party/WebKit/LayoutTests/fast/multicol/short-columns-insane-unbreakable-content-height-crash.html new file mode 100644 index 0000000..8c034d5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/short-columns-insane-unbreakable-content-height-crash.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<script> + if (window.testRunner) + testRunner.dumpAsText(); +</script> +<p>PASS if no crash or assertion failure.</p> +<div style="-webkit-columns:2; column-fill:auto; height:145px; line-height:5551234567px;"> + <br> + <div> + <br> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/autocomplete-general.html b/third_party/WebKit/LayoutTests/inspector/sources/autocomplete-general.html index 5113ef2..1f88e31 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/autocomplete-general.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/autocomplete-general.html
@@ -32,7 +32,7 @@ InspectorTest.typeIn(textEditor, "m"); function onAutocompletionSuggestBox() { - document.activeElement.dispatchEvent(InspectorTest.createKeyEvent("Enter")); + document.activeElement.dispatchEvent(InspectorTest.createKeyEvent("U+0009")); dumpDictionary(next); } },
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-usertiming-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-usertiming-expected.txt new file mode 100644 index 0000000..a3e8a60 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-usertiming-expected.txt
@@ -0,0 +1,21 @@ +Test performance.mark/measure records on Timeline + + +Running: testSimplePerformanceMeasure +a + +Running: testNestedPerformanceMeasure +a +b +c +d + +Running: testUnbalancedPerformanceMeasure +a +b + +Running: testParentMeasureIsOnTop +durationTimeTotal +durationTime1 +durationTime2 +
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-usertiming.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-usertiming.html new file mode 100644 index 0000000..24672e0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-usertiming.html
@@ -0,0 +1,114 @@ +<html> +<head> +<script src="../../http/tests/inspector/inspector-test.js"></script> +<script src="../../http/tests/inspector/timeline-test.js"></script> +<script src="../tracing-test.js"></script> +<script> + +function simplePerformanceMeasure() +{ + performance.mark("a-start"); + performance.mark("a-end"); + performance.measure("a", "a-start", "a-end"); +} + +function nestedPerformanceMeasure() +{ + performance.mark("a-start"); + { + performance.mark("b-start"); + performance.mark("b-end"); + { + performance.mark("c-start"); + { + performance.mark("d-start"); + performance.mark("d-end"); + } + performance.mark("c-end"); + } + } + performance.mark("a-end"); + performance.measure("a", "a-start", "a-end"); + performance.measure("b", "b-start", "b-end"); + performance.measure("c", "c-start", "c-end"); + performance.measure("d", "d-start", "d-end"); +} + + +function unbalancedPerformanceMeasure() +{ + performance.mark("a-start"); + performance.mark("b-start"); + performance.mark("a-end"); + performance.mark("b-end"); + performance.measure("a", "a-start", "a-end"); + performance.measure("b", "b-start", "b-end"); +} + + +function parentMeasureIsOnTop() +{ + performance.mark("startTime1"); + performance.mark("endTime1"); + + performance.mark("startTime2"); + performance.mark("endTime2"); + + performance.measure("durationTime1", "startTime1", "endTime1"); + performance.measure("durationTime2", "startTime2", "endTime2"); + performance.measure("durationTimeTotal", "startTime1", "endTime2"); +} + + +function test() +{ + InspectorTest.runTestSuite([ + function testSimplePerformanceMeasure(next) + { + performActions("simplePerformanceMeasure()", next); + }, + + function testNestedPerformanceMeasure(next) + { + performActions("nestedPerformanceMeasure()", next); + }, + + function testUnbalancedPerformanceMeasure(next) + { + performActions("unbalancedPerformanceMeasure()", next); + }, + + function testParentMeasureIsOnTop(next) + { + performActions("parentMeasureIsOnTop()", next); + } + ]); + + function dumpUserTimings() + { + var model = InspectorTest.timelineModel(); + var asyncEvents = model.mainThreadAsyncEvents() + + asyncEvents.forEach(function(eventGroup) { + eventGroup.forEach(function(event) { + if (event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) + InspectorTest.addResult(event.name); + }); + }) + } + + function performActions(actions, next) + { + InspectorTest.evaluateWithTimeline(actions, _ => { dumpUserTimings(); next(); }); + + } +} + +</script> +</head> + +<body onload="runTest()"> +<p>Test performance.mark/measure records on Timeline</p> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/transitions/retargetted-transition-with-box-sizing.html b/third_party/WebKit/LayoutTests/transitions/retargetted-transition-with-box-sizing.html new file mode 100644 index 0000000..62b76b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/transitions/retargetted-transition-with-box-sizing.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<style> +#target { + width: 100px; + height: 200px; + transition-properties: transform; + transition-duration: 1s; + transition-delay: -0.5s; + transition-timing-function: linear; +} +</style> +<div id="target"></div> +<script> +test(() => { + target.style.transform = 'translate(50%, 50%)'; + assert_equals(getComputedStyle(target).transform, 'matrix(1, 0, 0, 1, 50, 100)'); + target.style.transform = 'translate3D(50%, 50%, 100px)'; + assert_equals(getComputedStyle(target).transform, 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 50, 100, 50, 1)'); +}, 'Retargeting transitions on box size relative transitions should work.'); +</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/calclength.html b/third_party/WebKit/LayoutTests/typedcssom/calclength.html index 7180dc1..e8ee3f48 100644 --- a/third_party/WebKit/LayoutTests/typedcssom/calclength.html +++ b/third_party/WebKit/LayoutTests/typedcssom/calclength.html
@@ -36,23 +36,40 @@ }, 'Test that subtracting two CalcLengths produces a new CalcLength with the correct values.'); test(function() { - var calcLength = new CalcLength({px: 1, percent: 5.2}); - var result = calcLength.multiply(3); + var calcLength = new CalcLength({px: 1, percent: 5.2}); + var result = calcLength.multiply(3); - assert_not_equals(calcLength, result); - assert_equals(result.px, 3); - assert_approx_equals(result.percent, 15.6, 0.000001); + assert_not_equals(calcLength, result); + assert_equals(result.px, 3); + assert_approx_equals(result.percent, 15.6, 0.000001); }, 'Test that multiplying a CalcLength produces a new CalcLength with the correct values.'); test(function() { - var calcLength = new CalcLength({px: 3, percent: 15.6}); - var result = calcLength.divide(3); + var calcLength = new CalcLength({px: 3, percent: 15.6}); + var result = calcLength.divide(3); - assert_not_equals(calcLength, result); - assert_equals(result.px, 1); - assert_equals(result.percent, 5.2); + assert_not_equals(calcLength, result); + assert_equals(result.px, 1); + assert_equals(result.percent, 5.2); }, 'Test that dividing a CalcLength produces a new CalcLength with the correct values.'); +test(function() { + var values = [ + {input: new CalcLength({px: 1}), cssString: 'calc(1px)'}, + {input: new CalcLength({px: -1}), cssString: 'calc(-1px)'}, + {input: new CalcLength({px: 1, percent: 15.6}), cssString: 'calc(1px + 15.6%)'}, + {input: new CalcLength({px: 1, percent: -15.6}), cssString: 'calc(1px - 15.6%)'}, + {input: new CalcLength({px: -1, percent: -15.6}), cssString: 'calc(-1px - 15.6%)'}, + {input: new CalcLength({px: -1, percent: -15.6, vw: 5}), cssString: 'calc((-1px - 15.6%) + 5vw)'}, + {input: new CalcLength({px: -1, percent: -15.6, vw: -5}), cssString: 'calc((-1px - 15.6%) - 5vw)'}, + ]; + + for (var i = 0; i < values.length; ++i) { + assert_equals(values[i].input.cssString, values[i].cssString); + } + +}, 'Test that the CSS string method for a CalcLength produces the correct result'); + </script> <body>
diff --git a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt index e3ef48e..6bd31f1 100644 --- a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
@@ -857,7 +857,6 @@ property getDistributedNodes html element slot property getAssignedNodes - property getDistributedNodes property name html element small html element source
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index d7273edc..53a29bc6 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -2727,7 +2727,6 @@ getter name method constructor method getAssignedNodes - method getDistributedNodes setter name interface HTMLSourceElement : HTMLElement getter media
diff --git a/third_party/WebKit/Source/core/animation/DefaultSVGInterpolation.cpp b/third_party/WebKit/Source/core/animation/DefaultSVGInterpolation.cpp deleted file mode 100644 index 09a80a7..0000000 --- a/third_party/WebKit/Source/core/animation/DefaultSVGInterpolation.cpp +++ /dev/null
@@ -1,26 +0,0 @@ -// 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 "core/animation/DefaultSVGInterpolation.h" - -#include "core/svg/SVGElement.h" - -namespace blink { - -DefaultSVGInterpolation::DefaultSVGInterpolation(SVGPropertyBase* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute) - : SVGInterpolation(InterpolableBool::create(false), InterpolableBool::create(true), attribute) - , m_start(start) - , m_end(end) -{ -} - -PassRefPtrWillBeRawPtr<SVGPropertyBase> DefaultSVGInterpolation::interpolatedValue(SVGElement& element) const -{ - if (toInterpolableBool(m_cachedValue.get())->value()) - return m_end; - - return m_start; -} - -}
diff --git a/third_party/WebKit/Source/core/animation/DefaultSVGInterpolation.h b/third_party/WebKit/Source/core/animation/DefaultSVGInterpolation.h deleted file mode 100644 index 4999678..0000000 --- a/third_party/WebKit/Source/core/animation/DefaultSVGInterpolation.h +++ /dev/null
@@ -1,30 +0,0 @@ -// 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. - -#ifndef DefaultSVGInterpolation_h -#define DefaultSVGInterpolation_h - -#include "core/animation/SVGInterpolation.h" - -namespace blink { - -class DefaultSVGInterpolation : public SVGInterpolation { -public: - static PassRefPtr<DefaultSVGInterpolation> create(SVGPropertyBase* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute) - { - return adoptRef(new DefaultSVGInterpolation(start, end, attribute)); - } - - PassRefPtrWillBeRawPtr<SVGPropertyBase> interpolatedValue(SVGElement&) const final; - -private: - DefaultSVGInterpolation(SVGPropertyBase* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute); - - RefPtrWillBePersistent<SVGPropertyBase> m_start; - RefPtrWillBePersistent<SVGPropertyBase> m_end; -}; - -} - -#endif // DefaultSVGInterpolation_h
diff --git a/third_party/WebKit/Source/core/animation/Interpolation.h b/third_party/WebKit/Source/core/animation/Interpolation.h index 1c8c191..82828b6 100644 --- a/third_party/WebKit/Source/core/animation/Interpolation.h +++ b/third_party/WebKit/Source/core/animation/Interpolation.h
@@ -23,7 +23,6 @@ virtual bool isStyleInterpolation() const { return false; } virtual bool isInvalidatableInterpolation() const { return false; } virtual bool isLegacyStyleInterpolation() const { return false; } - virtual bool isSVGInterpolation() const { return false; } virtual PropertyHandle property() const = 0; @@ -44,8 +43,6 @@ friend class AnimationInterpolationEffectTest; friend class AnimationDoubleStyleInterpolationTest; friend class AnimationVisibilityStyleInterpolationTest; - friend class AnimationColorStyleInterpolationTest; - friend class AnimationSVGStrokeDasharrayStyleInterpolationTest; }; using ActiveInterpolations = Vector<RefPtr<Interpolation>, 1>;
diff --git a/third_party/WebKit/Source/core/animation/NumberSVGInterpolation.cpp b/third_party/WebKit/Source/core/animation/NumberSVGInterpolation.cpp deleted file mode 100644 index 34f98334..0000000 --- a/third_party/WebKit/Source/core/animation/NumberSVGInterpolation.cpp +++ /dev/null
@@ -1,17 +0,0 @@ -// 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 "core/animation/NumberSVGInterpolation.h" - -namespace blink { - -PassRefPtrWillBeRawPtr<SVGNumber> NumberSVGInterpolation::fromInterpolableValue(const InterpolableValue& value, SVGNumberNegativeValuesMode negativeValuesMode) -{ - double doubleValue = toInterpolableNumber(value).value(); - if (negativeValuesMode == ForbidNegativeNumbers && doubleValue < 0) - doubleValue = 0; - return SVGNumber::create(doubleValue); -} - -}
diff --git a/third_party/WebKit/Source/core/animation/NumberSVGInterpolation.h b/third_party/WebKit/Source/core/animation/NumberSVGInterpolation.h deleted file mode 100644 index 8344b00f..0000000 --- a/third_party/WebKit/Source/core/animation/NumberSVGInterpolation.h +++ /dev/null
@@ -1,58 +0,0 @@ -// 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. - -#ifndef NumberSVGInterpolation_h -#define NumberSVGInterpolation_h - -#include "core/animation/SVGInterpolation.h" -#include "core/svg/SVGNumber.h" -#include "core/svg/SVGNumberList.h" - -namespace blink { - -enum SVGNumberNegativeValuesMode { - AllowNegativeNumbers, - ForbidNegativeNumbers -}; - -class NumberSVGInterpolation : public SVGInterpolation { -public: - typedef SVGNumberList ListType; - typedef void NonInterpolableType; - - static PassRefPtr<NumberSVGInterpolation> create(SVGPropertyBase* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute, SVGNumberNegativeValuesMode negativeValuesMode) - { - return adoptRef(new NumberSVGInterpolation(toInterpolableValue(start), toInterpolableValue(end), attribute, negativeValuesMode)); - } - - static bool canCreateFrom(SVGPropertyBase* value) - { - return true; - } - - PassRefPtrWillBeRawPtr<SVGPropertyBase> interpolatedValue(SVGElement&) const final - { - return fromInterpolableValue(*m_cachedValue, m_negativeValuesMode); - } - - static PassOwnPtr<InterpolableNumber> toInterpolableValue(SVGPropertyBase* value) - { - return InterpolableNumber::create(toSVGNumber(value)->value()); - } - - static PassRefPtrWillBeRawPtr<SVGNumber> fromInterpolableValue(const InterpolableValue&, SVGNumberNegativeValuesMode = AllowNegativeNumbers); - -private: - NumberSVGInterpolation(PassOwnPtr<InterpolableValue> start, PassOwnPtr<InterpolableValue> end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute, SVGNumberNegativeValuesMode negativeValuesMode) - : SVGInterpolation(start, end, attribute) - , m_negativeValuesMode(negativeValuesMode) - { - } - - const SVGNumberNegativeValuesMode m_negativeValuesMode; -}; - -} - -#endif // NumberSVGInterpolation_h
diff --git a/third_party/WebKit/Source/core/animation/SVGInterpolation.h b/third_party/WebKit/Source/core/animation/SVGInterpolation.h deleted file mode 100644 index 986395b1..0000000 --- a/third_party/WebKit/Source/core/animation/SVGInterpolation.h +++ /dev/null
@@ -1,48 +0,0 @@ -// 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. - -#ifndef SVGInterpolation_h -#define SVGInterpolation_h - -#include "core/animation/Interpolation.h" -#include "core/animation/PropertyHandle.h" -#include "core/svg/properties/SVGAnimatedProperty.h" - -namespace blink { - -class SVGInterpolation : public Interpolation { -public: - bool isSVGInterpolation() const final { return true; } - - SVGAnimatedPropertyBase* attribute() const { return m_attribute.get(); } - - const QualifiedName& attributeName() const { return m_attribute->attributeName(); } - - PropertyHandle property() const final - { - return PropertyHandle(attributeName()); - } - - void apply(SVGElement& targetElement) const - { - targetElement.setWebAnimatedAttribute(attributeName(), interpolatedValue(targetElement)); - } - - virtual PassRefPtrWillBeRawPtr<SVGPropertyBase> interpolatedValue(SVGElement&) const = 0; - -protected: - SVGInterpolation(PassOwnPtr<InterpolableValue> start, PassOwnPtr<InterpolableValue> end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute) - : Interpolation(start, end) - , m_attribute(attribute) - { - } - - RefPtrWillBePersistent<SVGAnimatedPropertyBase> m_attribute; -}; - -DEFINE_TYPE_CASTS(SVGInterpolation, Interpolation, value, value->isSVGInterpolation(), value.isSVGInterpolation()); - -} - -#endif // SVGInterpolation_h
diff --git a/third_party/WebKit/Source/core/animation/SampledEffect.cpp b/third_party/WebKit/Source/core/animation/SampledEffect.cpp index dce57b16..30aee7ab 100644 --- a/third_party/WebKit/Source/core/animation/SampledEffect.cpp +++ b/third_party/WebKit/Source/core/animation/SampledEffect.cpp
@@ -4,11 +4,6 @@ #include "core/animation/SampledEffect.h" -#include "core/animation/InterpolationEnvironment.h" -#include "core/animation/InvalidatableInterpolation.h" -#include "core/animation/SVGInterpolation.h" -#include "core/svg/SVGElement.h" - namespace blink { SampledEffect::SampledEffect(KeyframeEffect* effect)
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp index 990b7f61..d2a373e 100644 --- a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp +++ b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
@@ -20,7 +20,6 @@ #include "core/animation/CSSVisibilityInterpolationType.h" #include "core/animation/CompositorAnimations.h" #include "core/animation/ConstantStyleInterpolation.h" -#include "core/animation/DefaultSVGInterpolation.h" #include "core/animation/DeferredLegacyStyleInterpolation.h" #include "core/animation/DoubleStyleInterpolation.h" #include "core/animation/FilterStyleInterpolation.h" @@ -625,58 +624,11 @@ return adoptPtr(new SVGPropertySpecificKeyframe(offset, easing, String(), EffectModel::CompositeAdd)); } -namespace { - -PassRefPtr<Interpolation> createSVGInterpolation(SVGPropertyBase* fromValue, SVGPropertyBase* toValue, SVGAnimatedPropertyBase* attribute) -{ - RefPtr<Interpolation> interpolation = nullptr; - ASSERT(fromValue->type() == toValue->type()); - switch (fromValue->type()) { - // Handled by SVGInterpolationTypes. - case AnimatedAngle: - case AnimatedInteger: - case AnimatedIntegerOptionalInteger: - case AnimatedLength: - case AnimatedLengthList: - case AnimatedNumber: - case AnimatedNumberList: - case AnimatedNumberOptionalNumber: - case AnimatedPath: - case AnimatedPoints: - case AnimatedRect: - case AnimatedTransformList: - ASSERT_NOT_REACHED(); - // Fallthrough. - - // TODO(ericwilligers): Support more animation types. - default: - break; - } - if (interpolation) - return interpolation.release(); - - return DefaultSVGInterpolation::create(fromValue, toValue, attribute); -} - -} // namespace - -PassRefPtr<Interpolation> SVGPropertySpecificKeyframe::maybeCreateInterpolation(PropertyHandle propertyHandle, Keyframe::PropertySpecificKeyframe& end, Element* element, const ComputedStyle* baseStyle) const +PassRefPtr<Interpolation> SVGPropertySpecificKeyframe::maybeCreateInterpolation(PropertyHandle propertyHandle, Keyframe::PropertySpecificKeyframe& end, Element*, const ComputedStyle*) const { const InterpolationTypes* applicableTypes = applicableTypesForProperty(propertyHandle); - if (applicableTypes) - return InvalidatableInterpolation::create(propertyHandle, *applicableTypes, *this, end); - - ASSERT(element); - SVGAnimatedPropertyBase* attribute = toSVGElement(element)->propertyFromAttribute(propertyHandle.svgAttribute()); - ASSERT(attribute); - - RefPtrWillBeRawPtr<SVGPropertyBase> fromValue = attribute->currentValueBase()->cloneForAnimation(m_value); - RefPtrWillBeRawPtr<SVGPropertyBase> toValue = attribute->currentValueBase()->cloneForAnimation(toSVGPropertySpecificKeyframe(end).value()); - - if (!fromValue || !toValue) - return nullptr; - - return createSVGInterpolation(fromValue.get(), toValue.get(), attribute); + ASSERT(applicableTypes); + return InvalidatableInterpolation::create(propertyHandle, *applicableTypes, *this, end); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index bfedd0d1..bf5c4b01 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -874,8 +874,6 @@ 'animation/ColorPropertyFunctions.cpp', 'animation/ColorPropertyFunctions.h', 'animation/ConstantStyleInterpolation.h', - 'animation/DefaultSVGInterpolation.cpp', - 'animation/DefaultSVGInterpolation.h', 'animation/DeferredLegacyStyleInterpolation.cpp', 'animation/DeferredLegacyStyleInterpolation.h', 'animation/DocumentAnimation.h', @@ -923,8 +921,6 @@ 'animation/NumberAttributeFunctions.h', 'animation/NumberPropertyFunctions.cpp', 'animation/NumberPropertyFunctions.h', - 'animation/NumberSVGInterpolation.cpp', - 'animation/NumberSVGInterpolation.h', 'animation/PaintPropertyFunctions.cpp', 'animation/PaintPropertyFunctions.h', 'animation/PathInterpolationFunctions.cpp', @@ -938,7 +934,6 @@ 'animation/SVGIntegerInterpolationType.h', 'animation/SVGIntegerOptionalIntegerInterpolationType.cpp', 'animation/SVGIntegerOptionalIntegerInterpolationType.h', - 'animation/SVGInterpolation.h', 'animation/SVGInterpolationType.cpp', 'animation/SVGInterpolationType.h', 'animation/SVGLengthInterpolationType.cpp', @@ -3651,6 +3646,7 @@ 'fileapi/FilePropertyBag.idl', 'frame/ScrollOptions.idl', 'frame/ScrollToOptions.idl', + 'html/AssignedNodesOptions.idl', 'html/MediaKeyEventInit.idl', 'html/canvas/CanvasContextCreationAttributes.idl', 'html/track/TrackEventInit.idl', @@ -3748,6 +3744,8 @@ '<(blink_core_output_dir)/frame/ScrollOptions.h', '<(blink_core_output_dir)/frame/ScrollToOptions.cpp', '<(blink_core_output_dir)/frame/ScrollToOptions.h', + '<(blink_core_output_dir)/html/AssignedNodesOptions.cpp', + '<(blink_core_output_dir)/html/AssignedNodesOptions.h', '<(blink_core_output_dir)/html/MediaKeyEventInit.cpp', '<(blink_core_output_dir)/html/MediaKeyEventInit.h', '<(blink_core_output_dir)/html/canvas/CanvasContextCreationAttributes.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp b/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp index 3bc875d..7ed12e9 100644 --- a/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
@@ -128,14 +128,14 @@ ASSERT(!isCachePending(deviceScaleFactor)); if (m_imageValue->isImageSetValue()) - return toCSSImageSetValue(*m_imageValue).cachedImageSet(deviceScaleFactor); + return toCSSImageSetValue(*m_imageValue).cachedImage(deviceScaleFactor); return m_cachedImage.get(); } StyleImage* CSSCursorImageValue::cacheImage(Document* document, float deviceScaleFactor) { if (m_imageValue->isImageSetValue()) - return toCSSImageSetValue(*m_imageValue).cacheImageSet(document, deviceScaleFactor); + return toCSSImageSetValue(*m_imageValue).cacheImage(document, deviceScaleFactor); if (m_isCachePending) { m_isCachePending = false;
diff --git a/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp b/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp index 7e25d92..b68a44a 100644 --- a/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
@@ -34,6 +34,7 @@ #include "core/fetch/ResourceFetcher.h" #include "core/fetch/ResourceLoaderOptions.h" #include "core/style/StyleFetchedImageSet.h" +#include "core/style/StyleInvalidImage.h" #include "platform/weborigin/KURL.h" #include "platform/weborigin/SecurityPolicy.h" #include "wtf/text/StringBuilder.h" @@ -43,7 +44,6 @@ CSSImageSetValue::CSSImageSetValue() : CSSValueList(ImageSetClass, CommaSeparator) - , m_isCachePending(true) , m_cachedScaleFactor(1) { } @@ -51,8 +51,8 @@ CSSImageSetValue::~CSSImageSetValue() { #if !ENABLE(OILPAN) - if (m_cachedImageSet) - m_cachedImageSet->clearImageSetValue(); + if (m_cachedImage && m_cachedImage->isImageResourceSet()) + toStyleFetchedImageSet(*m_cachedImage).clearImageSetValue(); #endif } @@ -95,23 +95,23 @@ bool CSSImageSetValue::isCachePending(float deviceScaleFactor) const { - return m_isCachePending || deviceScaleFactor != m_cachedScaleFactor; + return !m_cachedImage || deviceScaleFactor != m_cachedScaleFactor; } -StyleFetchedImageSet* CSSImageSetValue::cachedImageSet(float deviceScaleFactor) const +StyleImage* CSSImageSetValue::cachedImage(float deviceScaleFactor) const { ASSERT(!isCachePending(deviceScaleFactor)); - return m_cachedImageSet.get(); + return m_cachedImage.get(); } -StyleFetchedImageSet* CSSImageSetValue::cacheImageSet(Document* document, float deviceScaleFactor, CrossOriginAttributeValue crossOrigin) +StyleImage* CSSImageSetValue::cacheImage(Document* document, float deviceScaleFactor, CrossOriginAttributeValue crossOrigin) { ASSERT(document); if (!m_imagesInSet.size()) fillImageSet(); - if (m_isCachePending || deviceScaleFactor != m_cachedScaleFactor) { + if (isCachePending(deviceScaleFactor)) { // FIXME: In the future, we want to take much more than deviceScaleFactor into acount here. // All forms of scale should be included: Page::pageScaleFactor(), LocalFrame::pageZoomFactor(), // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698 @@ -122,14 +122,14 @@ if (crossOrigin != CrossOriginAttributeNotSet) request.setCrossOriginAccessControl(document->securityOrigin(), crossOrigin); - if (ResourcePtr<ImageResource> cachedImage = ImageResource::fetch(request, document->fetcher())) { - m_cachedImageSet = StyleFetchedImageSet::create(cachedImage.get(), image.scaleFactor, this, request.url()); - m_cachedScaleFactor = deviceScaleFactor; - m_isCachePending = false; - } + if (ResourcePtr<ImageResource> cachedImage = ImageResource::fetch(request, document->fetcher())) + m_cachedImage = StyleFetchedImageSet::create(cachedImage.get(), image.scaleFactor, this, request.url()); + else + m_cachedImage = StyleInvalidImage::create(image.imageURL); + m_cachedScaleFactor = deviceScaleFactor; } - return m_cachedImageSet.get(); + return m_cachedImage.get(); } String CSSImageSetValue::customCSSText() const @@ -164,16 +164,16 @@ bool CSSImageSetValue::hasFailedOrCanceledSubresources() const { - if (!m_cachedImageSet) + if (!m_cachedImage) return false; - if (Resource* cachedResource = m_cachedImageSet->cachedImage()) + if (Resource* cachedResource = m_cachedImage->cachedImage()) return cachedResource->loadFailedOrCanceled(); return true; } DEFINE_TRACE_AFTER_DISPATCH(CSSImageSetValue) { - visitor->trace(m_cachedImageSet); + visitor->trace(m_cachedImage); CSSValueList::traceAfterDispatch(visitor); }
diff --git a/third_party/WebKit/Source/core/css/CSSImageSetValue.h b/third_party/WebKit/Source/core/css/CSSImageSetValue.h index 6e339ea..d9c4336 100644 --- a/third_party/WebKit/Source/core/css/CSSImageSetValue.h +++ b/third_party/WebKit/Source/core/css/CSSImageSetValue.h
@@ -34,7 +34,7 @@ namespace blink { class Document; -class StyleFetchedImageSet; +class StyleImage; class CSSImageSetValue : public CSSValueList { public: @@ -46,8 +46,8 @@ ~CSSImageSetValue(); bool isCachePending(float deviceScaleFactor) const; - StyleFetchedImageSet* cachedImageSet(float deviceScaleFactor) const; - StyleFetchedImageSet* cacheImageSet(Document*, float deviceScaleFactor, CrossOriginAttributeValue = CrossOriginAttributeNotSet); + StyleImage* cachedImage(float deviceScaleFactor) const; + StyleImage* cacheImage(Document*, float deviceScaleFactor, CrossOriginAttributeValue = CrossOriginAttributeNotSet); String customCSSText() const; @@ -73,9 +73,8 @@ void fillImageSet(); static inline bool compareByScaleFactor(ImageWithScale first, ImageWithScale second) { return first.scaleFactor < second.scaleFactor; } - bool m_isCachePending; float m_cachedScaleFactor; - RefPtrWillBeMember<StyleFetchedImageSet> m_cachedImageSet; + RefPtrWillBeMember<StyleImage> m_cachedImage; Vector<ImageWithScale> m_imagesInSet; };
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.cpp b/third_party/WebKit/Source/core/css/CSSSelector.cpp index 2461434..f660e57f 100644 --- a/third_party/WebKit/Source/core/css/CSSSelector.cpp +++ b/third_party/WebKit/Source/core/css/CSSSelector.cpp
@@ -264,6 +264,7 @@ case PseudoFullScreenAncestor: case PseudoSpatialNavigationFocus: case PseudoListBox: + case PseudoSlotted: return NOPSEUDO; } @@ -367,6 +368,7 @@ {"nth-last-child", CSSSelector::PseudoNthLastChild}, {"nth-last-of-type", CSSSelector::PseudoNthLastOfType}, {"nth-of-type", CSSSelector::PseudoNthOfType}, +{"slotted", CSSSelector::PseudoSlotted}, }; class NameToPseudoCompare { @@ -481,6 +483,7 @@ case PseudoWebKitCustomElement: case PseudoContent: case PseudoShadow: + case PseudoSlotted: if (m_match != PseudoElement) m_pseudoType = PseudoUnknown; break; @@ -725,6 +728,7 @@ case SubSelector: ASSERT_NOT_REACHED(); case ShadowPseudo: + case ShadowSlot: return tagHistory->selectorText(str.toString() + rightSide); } }
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.h b/third_party/WebKit/Source/core/css/CSSSelector.h index 6982381..207ef44 100644 --- a/third_party/WebKit/Source/core/css/CSSSelector.h +++ b/third_party/WebKit/Source/core/css/CSSSelector.h
@@ -117,7 +117,8 @@ DirectAdjacent, // + combinator IndirectAdjacent, // ~ combinator ShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element - ShadowDeep // /deep/ combinator + ShadowDeep, // /deep/ combinator + ShadowSlot // slotted to <slot> element }; enum PseudoType { @@ -201,7 +202,8 @@ PseudoHostContext, PseudoShadow, PseudoSpatialNavigationFocus, - PseudoListBox + PseudoListBox, + PseudoSlotted }; enum AttributeMatchType { @@ -296,7 +298,7 @@ unsigned m_hasRareData : 1; unsigned m_isForPage : 1; unsigned m_tagIsImplicit : 1; - unsigned m_relationIsAffectedByPseudoContent : 1; + unsigned m_relationIsAffectedByPseudoContent : 1; void setPseudoType(PseudoType pseudoType) {
diff --git a/third_party/WebKit/Source/core/css/CSSSelectorList.cpp b/third_party/WebKit/Source/core/css/CSSSelectorList.cpp index 114fb84..7cba4aa1 100644 --- a/third_party/WebKit/Source/core/css/CSSSelectorList.cpp +++ b/third_party/WebKit/Source/core/css/CSSSelectorList.cpp
@@ -161,13 +161,20 @@ }, this); } -bool CSSSelectorList::selectorHasShadowDistributed(size_t index) const +bool CSSSelectorList::selectorHasContentPseudo(size_t index) const { return forEachTagSelector([](const CSSSelector& selector) -> bool { return selector.relationIsAffectedByPseudoContent(); }, selectorAt(index)); } +bool CSSSelectorList::selectorHasSlottedPseudo(size_t index) const +{ + return forEachTagSelector([](const CSSSelector& selector) -> bool { + return selector.pseudoType() == CSSSelector::PseudoSlotted; + }, selectorAt(index)); +} + bool CSSSelectorList::selectorUsesDeepCombinatorOrShadowPseudo(size_t index) const { return forEachTagSelector([](const CSSSelector& selector) -> bool {
diff --git a/third_party/WebKit/Source/core/css/CSSSelectorList.h b/third_party/WebKit/Source/core/css/CSSSelectorList.h index 94b371d..90a8f03 100644 --- a/third_party/WebKit/Source/core/css/CSSSelectorList.h +++ b/third_party/WebKit/Source/core/css/CSSSelectorList.h
@@ -79,9 +79,8 @@ bool selectorNeedsUpdatedDistribution(size_t index) const; - // TODO(kochi): "ShadowDistributed" means the selector has ::content pseudo element. - // Once ::slotted is introduced, come up with more readable name. - bool selectorHasShadowDistributed(size_t index) const; + bool selectorHasContentPseudo(size_t index) const; + bool selectorHasSlottedPseudo(size_t index) const; bool selectorUsesDeepCombinatorOrShadowPseudo(size_t index) const; String selectorsText() const;
diff --git a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp index 3839b51..d86c598 100644 --- a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp +++ b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
@@ -22,7 +22,7 @@ , m_fontLoader(fontLoader) , m_display(display) , m_period(display == FontDisplaySwap ? SwapPeriod : BlockPeriod) - , m_isInterventionEnabled(false) + , m_isInterventionTriggered(false) { #if ENABLE(OILPAN) ThreadState::current()->registerPreFinalizer(this); @@ -33,7 +33,7 @@ // TODO(crbug.com/515343): Consider to use better signals. if (networkStateNotifier().connectionType() == WebConnectionTypeCellular2G && display == FontDisplayAuto) { - m_isInterventionEnabled = true; + m_isInterventionTriggered = true; m_period = SwapPeriod; } } @@ -91,6 +91,7 @@ void RemoteFontFaceSource::fontLoaded(FontResource*) { m_histograms.recordRemoteFont(m_font.get()); + m_histograms.fontLoaded(m_isInterventionTriggered); m_font->ensureCustomFontData(); if (m_font->status() == Resource::DecodeError) @@ -101,6 +102,8 @@ m_fontLoader->fontFaceInvalidated(); m_face->fontLoaded(this); } + // Should not do anything after this line since the m_face->fontLoaded() + // above may trigger deleting this object. } void RemoteFontFaceSource::fontLoadShortLimitExceeded(FontResource*) @@ -113,10 +116,12 @@ void RemoteFontFaceSource::fontLoadLongLimitExceeded(FontResource*) { - if (m_display == FontDisplayBlock || (!m_isInterventionEnabled && m_display == FontDisplayAuto)) + if (m_display == FontDisplayBlock || (!m_isInterventionTriggered && m_display == FontDisplayAuto)) switchToSwapPeriod(); else if (m_display == FontDisplayFallback) switchToFailurePeriod(); + + m_histograms.longLimitExceeded(m_isInterventionTriggered); } void RemoteFontFaceSource::switchToSwapPeriod() @@ -197,6 +202,18 @@ m_fallbackPaintTime = currentTimeMS(); } +void RemoteFontFaceSource::FontLoadHistograms::fontLoaded(bool isInterventionTriggered) +{ + if (!m_isLongLimitExceeded) + recordInterventionResult(isInterventionTriggered); +} + +void RemoteFontFaceSource::FontLoadHistograms::longLimitExceeded(bool isInterventionTriggered) +{ + m_isLongLimitExceeded = true; + recordInterventionResult(isInterventionTriggered); +} + void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime(const FontResource* font) { if (m_fallbackPaintTime <= 0) @@ -242,4 +259,18 @@ return "WebFont.DownloadTime.4.Over1MB"; } +void RemoteFontFaceSource::FontLoadHistograms::recordInterventionResult(bool triggered) +{ + if (!RuntimeEnabledFeatures::webFontsInterventionEnabled()) + return; + // interventionResult takes 0-3 values. + int interventionResult = 0; + if (m_isLongLimitExceeded) + interventionResult |= 1 << 0; + if (triggered) + interventionResult |= 1 << 1; + const int boundary = 1 << 2; + Platform::current()->histogramEnumeration("WebFont.InterventionResult", interventionResult, boundary); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.h b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.h index 34327299..8b9ff7d9 100644 --- a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.h +++ b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.h
@@ -60,16 +60,20 @@ class FontLoadHistograms { DISALLOW_NEW(); public: - FontLoadHistograms() : m_loadStartTime(0), m_fallbackPaintTime(0) { } + FontLoadHistograms() : m_loadStartTime(0), m_fallbackPaintTime(0), m_isLongLimitExceeded(false) { } void loadStarted(); void fallbackFontPainted(); - void recordRemoteFont(const FontResource*); + void fontLoaded(bool isInterventionTriggered); + void longLimitExceeded(bool isInterventionTriggered); void recordFallbackTime(const FontResource*); + void recordRemoteFont(const FontResource*); bool hadBlankText() { return m_fallbackPaintTime; } private: const char* histogramName(const FontResource*); + void recordInterventionResult(bool triggered); double m_loadStartTime; double m_fallbackPaintTime; + bool m_isLongLimitExceeded; }; void switchToSwapPeriod(); @@ -80,7 +84,7 @@ const FontDisplay m_display; DisplayPeriod m_period; FontLoadHistograms m_histograms; - bool m_isInterventionEnabled; + bool m_isInterventionTriggered; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/RuleSet.cpp b/third_party/WebKit/Source/core/css/RuleSet.cpp index db68b88c..bc735aa 100644 --- a/third_party/WebKit/Source/core/css/RuleSet.cpp +++ b/third_party/WebKit/Source/core/css/RuleSet.cpp
@@ -260,8 +260,10 @@ for (size_t selectorIndex = 0; selectorIndex != kNotFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) { if (selectorList.selectorUsesDeepCombinatorOrShadowPseudo(selectorIndex)) { m_deepCombinatorOrShadowPseudoRules.append(MinimalRuleData(styleRule, selectorIndex, addRuleFlags)); - } else if (selectorList.selectorHasShadowDistributed(selectorIndex)) { + } else if (selectorList.selectorHasContentPseudo(selectorIndex)) { m_shadowDistributedRules.append(MinimalRuleData(styleRule, selectorIndex, addRuleFlags)); + } else if (selectorList.selectorHasSlottedPseudo(selectorIndex)) { + m_shadowSlottedRules.append(MinimalRuleData(styleRule, selectorIndex, addRuleFlags)); } else { addRule(styleRule, selectorIndex, addRuleFlags); } @@ -342,6 +344,7 @@ m_keyframesRules.shrinkToFit(); m_deepCombinatorOrShadowPseudoRules.shrinkToFit(); m_shadowDistributedRules.shrinkToFit(); + m_shadowSlottedRules.shrinkToFit(); } DEFINE_TRACE(MinimalRuleData) @@ -383,6 +386,7 @@ visitor->trace(m_keyframesRules); visitor->trace(m_deepCombinatorOrShadowPseudoRules); visitor->trace(m_shadowDistributedRules); + visitor->trace(m_shadowSlottedRules); visitor->trace(m_viewportDependentMediaQueryResults); visitor->trace(m_deviceDependentMediaQueryResults); visitor->trace(m_pendingRules);
diff --git a/third_party/WebKit/Source/core/css/RuleSet.h b/third_party/WebKit/Source/core/css/RuleSet.h index 57019eb..26fbc26 100644 --- a/third_party/WebKit/Source/core/css/RuleSet.h +++ b/third_party/WebKit/Source/core/css/RuleSet.h
@@ -146,6 +146,7 @@ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes>>& keyframesRules() const { return m_keyframesRules; } const WillBeHeapVector<MinimalRuleData>& deepCombinatorOrShadowPseudoRules() const { return m_deepCombinatorOrShadowPseudoRules; } const WillBeHeapVector<MinimalRuleData>& shadowDistributedRules() const { return m_shadowDistributedRules; } + const WillBeHeapVector<MinimalRuleData>& shadowSlottedRules() const { return m_shadowSlottedRules; } const MediaQueryResultList& viewportDependentMediaQueryResults() const { return m_viewportDependentMediaQueryResults; } const MediaQueryResultList& deviceDependentMediaQueryResults() const { return m_deviceDependentMediaQueryResults; } @@ -222,9 +223,8 @@ WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace>> m_fontFaceRules; WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes>> m_keyframesRules; WillBeHeapVector<MinimalRuleData> m_deepCombinatorOrShadowPseudoRules; - // TODO(kochi): "shadowDistributed" means the selector has ::content pseudo element. - // Once ::slotted is introduced, come up with more readable name. WillBeHeapVector<MinimalRuleData> m_shadowDistributedRules; + WillBeHeapVector<MinimalRuleData> m_shadowSlottedRules; MediaQueryResultList m_viewportDependentMediaQueryResults; MediaQueryResultList m_deviceDependentMediaQueryResults;
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp index 3b72243f..497e172 100644 --- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp +++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -451,6 +451,9 @@ } return SelectorFailsCompletely; } + case CSSSelector::ShadowSlot: + // TODO(kochi): Add this in later CL. + return SelectorFailsCompletely; case CSSSelector::SubSelector: ASSERT_NOT_REACHED(); @@ -1039,17 +1042,13 @@ break; } - if (!context.inRightmostCompound && m_mode == ResolvingStyle) - return false; - if (m_mode == QueryingRules) return false; + if (m_mode == SharingRules) + return true; - PseudoId pseudoId = CSSSelector::pseudoId(selector.pseudoType()); - if (pseudoId != NOPSEUDO && m_mode != SharingRules) - result.dynamicPseudo = pseudoId; - - // ::before, ::after, etc. + result.dynamicPseudo = CSSSelector::pseudoId(selector.pseudoType()); + ASSERT(result.dynamicPseudo != NOPSEUDO); return true; }
diff --git a/third_party/WebKit/Source/core/css/SelectorFilter.cpp b/third_party/WebKit/Source/core/css/SelectorFilter.cpp index 140ebaf..8286300 100644 --- a/third_party/WebKit/Source/core/css/SelectorFilter.cpp +++ b/third_party/WebKit/Source/core/css/SelectorFilter.cpp
@@ -162,6 +162,9 @@ skipOverSubselectors = false; collectDescendantSelectorIdentifierHashes(*current, hash); break; + case CSSSelector::ShadowSlot: + // TODO(kochi): Add this in later CL. + break; } if (hash == end) return;
diff --git a/third_party/WebKit/Source/core/css/cssom/KeywordValue.cpp b/third_party/WebKit/Source/core/css/cssom/KeywordValue.cpp index 7ed9cdc..abc8083 100644 --- a/third_party/WebKit/Source/core/css/cssom/KeywordValue.cpp +++ b/third_party/WebKit/Source/core/css/cssom/KeywordValue.cpp
@@ -30,11 +30,6 @@ } // namespace -String KeywordValue::cssString() const -{ - return m_keywordValue; -} - const String& KeywordValue::keywordValue() const { return m_keywordValue;
diff --git a/third_party/WebKit/Source/core/css/cssom/KeywordValue.h b/third_party/WebKit/Source/core/css/cssom/KeywordValue.h index 0c18809..1e628e1e 100644 --- a/third_party/WebKit/Source/core/css/cssom/KeywordValue.h +++ b/third_party/WebKit/Source/core/css/cssom/KeywordValue.h
@@ -27,7 +27,6 @@ const String& keywordValue() const; - String cssString() const override; PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const override; private:
diff --git a/third_party/WebKit/Source/core/css/cssom/LengthValue.cpp b/third_party/WebKit/Source/core/css/cssom/LengthValue.cpp index c08dc94..7b9bc8f 100644 --- a/third_party/WebKit/Source/core/css/cssom/LengthValue.cpp +++ b/third_party/WebKit/Source/core/css/cssom/LengthValue.cpp
@@ -161,6 +161,45 @@ } } +CSSPrimitiveValue::UnitType LengthValue::lengthTypeToPrimitiveType(LengthValue::LengthUnit unit) +{ + switch (unit) { + case Px: + return CSSPrimitiveValue::UnitType::Pixels; + case Percent: + return CSSPrimitiveValue::UnitType::Percentage; + case Em: + return CSSPrimitiveValue::UnitType::Ems; + case Ex: + return CSSPrimitiveValue::UnitType::Exs; + case Ch: + return CSSPrimitiveValue::UnitType::Chs; + case Rem: + return CSSPrimitiveValue::UnitType::Rems; + case Vw: + return CSSPrimitiveValue::UnitType::ViewportWidth; + case Vh: + return CSSPrimitiveValue::UnitType::ViewportHeight; + case Vmin: + return CSSPrimitiveValue::UnitType::ViewportMin; + case Vmax: + return CSSPrimitiveValue::UnitType::ViewportMax; + case Cm: + return CSSPrimitiveValue::UnitType::Centimeters; + case Mm: + return CSSPrimitiveValue::UnitType::Millimeters; + case In: + return CSSPrimitiveValue::UnitType::Inches; + case Pc: + return CSSPrimitiveValue::UnitType::Picas; + case Pt: + return CSSPrimitiveValue::UnitType::Points; + default: + ASSERT_NOT_REACHED(); + return CSSPrimitiveValue::UnitType::Pixels; + } +} + LengthValue* LengthValue::addInternal(const LengthValue*, ExceptionState&) { ASSERT_NOT_REACHED();
diff --git a/third_party/WebKit/Source/core/css/cssom/LengthValue.h b/third_party/WebKit/Source/core/css/cssom/LengthValue.h index f3c0326..24847ec 100644 --- a/third_party/WebKit/Source/core/css/cssom/LengthValue.h +++ b/third_party/WebKit/Source/core/css/cssom/LengthValue.h
@@ -50,7 +50,8 @@ LengthValue() {} static LengthUnit lengthUnitFromName(const String&); - static const String& lengthTypeToString(LengthUnit type); + static const String& lengthTypeToString(LengthUnit); + static CSSPrimitiveValue::UnitType lengthTypeToPrimitiveType(LengthUnit); virtual LengthValue* addInternal(const LengthValue* other, ExceptionState&); virtual LengthValue* subtractInternal(const LengthValue* other, ExceptionState&);
diff --git a/third_party/WebKit/Source/core/css/cssom/NumberValue.h b/third_party/WebKit/Source/core/css/cssom/NumberValue.h index b4c281d..142affb 100644 --- a/third_party/WebKit/Source/core/css/cssom/NumberValue.h +++ b/third_party/WebKit/Source/core/css/cssom/NumberValue.h
@@ -28,8 +28,6 @@ m_value = value; } - String cssString() const override { return String::number(m_value); } - PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const override { return cssValuePool().createValue(m_value, CSSPrimitiveValue::UnitType::
diff --git a/third_party/WebKit/Source/core/css/cssom/SimpleLength.cpp b/third_party/WebKit/Source/core/css/cssom/SimpleLength.cpp index 422ff07..49fa4bc 100644 --- a/third_party/WebKit/Source/core/css/cssom/SimpleLength.cpp +++ b/third_party/WebKit/Source/core/css/cssom/SimpleLength.cpp
@@ -10,18 +10,9 @@ namespace blink { -String SimpleLength::cssString() const -{ - StringBuilder s; - s.appendNumber(m_value); - s.append(unit()); - return s.toString(); -} - PassRefPtrWillBeRawPtr<CSSValue> SimpleLength::toCSSValue() const { - // TODO: Don't re-parse the unit. - return cssValuePool().createValue(m_value, CSSPrimitiveValue::fromName(unit())); + return cssValuePool().createValue(m_value, LengthValue::lengthTypeToPrimitiveType(m_unit)); } LengthValue* SimpleLength::addInternal(const LengthValue* other, ExceptionState& exceptionState)
diff --git a/third_party/WebKit/Source/core/css/cssom/SimpleLength.h b/third_party/WebKit/Source/core/css/cssom/SimpleLength.h index fa03539..295cbaeb 100644 --- a/third_party/WebKit/Source/core/css/cssom/SimpleLength.h +++ b/third_party/WebKit/Source/core/css/cssom/SimpleLength.h
@@ -39,7 +39,6 @@ StyleValueType type() const override { return StyleValueType::SimpleLengthType; } - String cssString() const override; PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const override; protected:
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleCalcLength.cpp b/third_party/WebKit/Source/core/css/cssom/StyleCalcLength.cpp index 45b75ef..a66b6e7 100644 --- a/third_party/WebKit/Source/core/css/cssom/StyleCalcLength.cpp +++ b/third_party/WebKit/Source/core/css/cssom/StyleCalcLength.cpp
@@ -124,29 +124,6 @@ return result; } -String StyleCalcLength::cssString() const -{ - StringBuilder builder; - builder.appendLiteral("calc("); - for (unsigned i = 0; i < LengthUnit::Count; ++i) { - LengthUnit lengthUnit = static_cast<LengthUnit>(i); - if (has(lengthUnit)) { - double value = get(lengthUnit); - if (value >= 0 && i > 0) { - builder.appendLiteral(" + "); - } else if (value < 0 && i > 0) { - builder.appendLiteral(" - "); - } else if (value < 0) { - builder.append('-'); - } - builder.appendNumber(std::abs(get(lengthUnit))); - builder.append(lengthTypeToString(lengthUnit)); - } - } - builder.append(')'); - return builder.toString(); -} - PassRefPtrWillBeRawPtr<CSSValue> StyleCalcLength::toCSSValue() const { // Create a CSS Calc Value, then put it into a CSSPrimitiveValue @@ -154,20 +131,14 @@ for (unsigned i = 0; i < LengthUnit::Count; ++i) { LengthUnit lengthUnit = static_cast<LengthUnit>(i); if (!has(lengthUnit)) - break; + continue; double value = get(lengthUnit); - CSSPrimitiveValue::UnitType primitiveUnit; - if (lengthUnit == LengthUnit::Percent) { - primitiveUnit = CSSPrimitiveValue::UnitType::Percentage; - } else { - // TODO: Don't re-parse the unit here. - primitiveUnit = CSSPrimitiveValue::fromName(lengthTypeToString(lengthUnit)); - } + CSSPrimitiveValue::UnitType primitiveUnit = lengthTypeToPrimitiveType(lengthUnit); if (node) { node = CSSCalcValue::createExpressionNode( node, - CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(value, primitiveUnit)), - CalcAdd); + CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(std::abs(value), primitiveUnit)), + value >= 0 ? CalcAdd : CalcSubtract); } else { node = CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(value, primitiveUnit)); }
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleCalcLength.h b/third_party/WebKit/Source/core/css/cssom/StyleCalcLength.h index d086926..64391c9 100644 --- a/third_party/WebKit/Source/core/css/cssom/StyleCalcLength.h +++ b/third_party/WebKit/Source/core/css/cssom/StyleCalcLength.h
@@ -44,7 +44,6 @@ #undef GETTER_MACRO - String cssString() const override; PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const override; StyleValueType type() const override { return CalcLengthType; }
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleValue.h b/third_party/WebKit/Source/core/css/cssom/StyleValue.h index 0d8ff3f..06e120f 100644 --- a/third_party/WebKit/Source/core/css/cssom/StyleValue.h +++ b/third_party/WebKit/Source/core/css/cssom/StyleValue.h
@@ -30,8 +30,11 @@ static StyleValue* create(const CSSValue&); static ScriptValue parse(ScriptState*, const String& property, const String& cssText); - virtual String cssString() const = 0; virtual PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const = 0; + virtual String cssString() const + { + return toCSSValue()->cssText(); + } DEFINE_INLINE_VIRTUAL_TRACE() { }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserSelector.h b/third_party/WebKit/Source/core/css/parser/CSSParserSelector.h index b852f72..af6b5884 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParserSelector.h +++ b/third_party/WebKit/Source/core/css/parser/CSSParserSelector.h
@@ -61,7 +61,7 @@ CSSSelector::PseudoType pseudoType() const { return m_selector->pseudoType(); } const CSSSelectorList* selectorList() const { return m_selector->selectorList(); } - bool needsImplicitShadowCrossingCombinatorForMatching() const { return pseudoType() == CSSSelector::PseudoWebKitCustomElement || pseudoType() == CSSSelector::PseudoCue || pseudoType() == CSSSelector::PseudoShadow; } + bool needsImplicitShadowCombinatorForMatching() const { return pseudoType() == CSSSelector::PseudoWebKitCustomElement || pseudoType() == CSSSelector::PseudoCue || pseudoType() == CSSSelector::PseudoShadow || pseudoType() == CSSSelector::PseudoSlotted; } bool isSimple() const;
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp index 8f8fa67..be1b17a2 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
@@ -23,6 +23,9 @@ case CSSSelector::PseudoUnresolved: feature = UseCounter::CSSSelectorPseudoUnresolved; break; + case CSSSelector::PseudoSlotted: + feature = UseCounter::CSSSelectorPseudoSlotted; + break; case CSSSelector::PseudoContent: feature = UseCounter::CSSSelectorPseudoContent; break; @@ -499,6 +502,19 @@ selector->adoptSelectorVector(selectorVector); return selector.release(); } + case CSSSelector::PseudoSlotted: + { + DisallowPseudoElementsScope scope(this); + + OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(block); + block.consumeWhitespace(); + if (!innerSelector || !block.atEnd() || !RuntimeEnabledFeatures::shadowDOMV1Enabled()) + return nullptr; + Vector<OwnPtr<CSSParserSelector>> selectorVector; + selectorVector.append(innerSelector.release()); + selector->adoptSelectorVector(selectorVector); + return selector.release(); + } case CSSSelector::PseudoLang: { // FIXME: CSS Selectors Level 4 allows :lang(*-foo) @@ -692,7 +708,7 @@ void CSSSelectorParser::prependTypeSelectorIfNeeded(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* compoundSelector) { - if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelector->needsImplicitShadowCrossingCombinatorForMatching()) + if (elementName.isNull() && defaultNamespace() == starAtom && !compoundSelector->needsImplicitShadowCombinatorForMatching()) return; AtomicString determinedElementName = elementName.isNull() ? starAtom : elementName; @@ -711,7 +727,7 @@ // ::cue, ::shadow), we need a universal selector to set the combinator // (relation) on in the cases where there are no simple selectors preceding // the pseudo element. - if (tag != anyQName() || compoundSelector->isHostPseudoSelector() || compoundSelector->needsImplicitShadowCrossingCombinatorForMatching()) + if (tag != anyQName() || compoundSelector->isHostPseudoSelector() || compoundSelector->needsImplicitShadowCombinatorForMatching()) compoundSelector->prependTagSelector(tag, elementName.isNull()); } @@ -735,17 +751,21 @@ // the selector parser as a single compound selector. // // Example: input#x::-webkit-clear-button -> [ ::-webkit-clear-button, input, #x ] - + // + // Likewise, ::slotted() pseudo element has an implicit ShadowSlot combinator to its left + // for finding matching slot element in other TreeScope. + // + // Example: slot[name=foo]::slotted(div) -> [ ::slotted(div), slot, [name=foo] ] CSSParserSelector* splitAfter = compoundSelector.get(); - while (splitAfter->tagHistory() && !splitAfter->tagHistory()->needsImplicitShadowCrossingCombinatorForMatching()) + while (splitAfter->tagHistory() && !splitAfter->tagHistory()->needsImplicitShadowCombinatorForMatching()) splitAfter = splitAfter->tagHistory(); if (!splitAfter || !splitAfter->tagHistory()) return compoundSelector; OwnPtr<CSSParserSelector> secondCompound = splitAfter->releaseTagHistory(); - secondCompound->appendTagHistory(CSSSelector::ShadowPseudo, compoundSelector); + secondCompound->appendTagHistory(secondCompound->pseudoType() == CSSSelector::PseudoSlotted ? CSSSelector::ShadowSlot : CSSSelector::ShadowPseudo, compoundSelector); return secondCompound.release(); }
diff --git a/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp b/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp index 9d1dbb9..1b1a8dfb 100644 --- a/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp +++ b/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp
@@ -81,7 +81,7 @@ m_pendingImageProperties.add(property); return StylePendingImage::create(value); } - return value.cachedImageSet(m_deviceScaleFactor); + return value.cachedImage(m_deviceScaleFactor); } PassRefPtrWillBeRawPtr<StyleImage> ElementStyleResources::cachedOrPendingFromValue(CSSPropertyID property, const CSSImageValue& value) @@ -149,7 +149,7 @@ return cursorImageValue->cacheImage(m_document, m_deviceScaleFactor); if (CSSImageSetValue* imageSetValue = pendingImage->cssImageSetValue()) - return imageSetValue->cacheImageSet(m_document, m_deviceScaleFactor, crossOrigin); + return imageSetValue->cacheImage(m_document, m_deviceScaleFactor, crossOrigin); ASSERT_NOT_REACHED(); return nullptr;
diff --git a/third_party/WebKit/Source/core/dom/AXObjectCache.h b/third_party/WebKit/Source/core/dom/AXObjectCache.h index c7ffe9a1..f6ea9cd 100644 --- a/third_party/WebKit/Source/core/dom/AXObjectCache.h +++ b/third_party/WebKit/Source/core/dom/AXObjectCache.h
@@ -40,7 +40,6 @@ class HTMLSelectElement; class LayoutMenuList; class Page; -class Widget; class CORE_EXPORT AXObjectCache : public GarbageCollectedFinalized<AXObjectCache> { WTF_MAKE_NONCOPYABLE(AXObjectCache); @@ -98,7 +97,6 @@ virtual void remove(LayoutObject*) = 0; virtual void remove(Node*) = 0; - virtual void remove(Widget*) = 0; virtual void remove(AbstractInlineTextBox*) = 0; virtual const Element* rootAXEditableElement(const Node*) = 0; @@ -130,7 +128,6 @@ virtual void handleScrollPositionChanged(LayoutObject*) = 0; // Called when scroll bars are added / removed (as the view resizes). - virtual void handleScrollbarUpdate(FrameView*) = 0; virtual void handleLayoutComplete(LayoutObject*) = 0; virtual void handleScrolledToAnchor(const Node* anchorNode) = 0;
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp index 141190a..5ff2ea2 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -221,7 +221,7 @@ if (position.isNull()) return 0; - ContainerNode* highestRoot = editableRootForPosition(position, editableType); + ContainerNode* highestRoot = editableRootElementForPosition(position, editableType); if (!highestRoot) return 0; @@ -258,6 +258,8 @@ if (isRenderedHTMLTableElement(node)) node = node->parentNode(); + if (node->isDocumentNode()) + return false; return node->hasEditableStyle(editableType); } @@ -269,7 +271,7 @@ bool isAtUnsplittableElement(const Position& pos) { Node* node = pos.anchorNode(); - return (node == editableRootForPosition(pos) || node == enclosingNodeOfType(pos, &isTableCell)); + return (node == editableRootElementForPosition(pos) || node == enclosingNodeOfType(pos, &isTableCell)); } @@ -285,7 +287,7 @@ return node->layoutObjectIsRichlyEditable(editableType); } -Element* editableRootForPosition(const Position& p, EditableType editableType) +Element* editableRootElementForPosition(const Position& p, EditableType editableType) { Node* node = p.computeContainerNode(); if (!node) @@ -297,9 +299,9 @@ return node->rootEditableElement(editableType); } -Element* editableRootForPosition(const PositionInComposedTree& p, EditableType editableType) +Element* editableRootElementForPosition(const PositionInComposedTree& p, EditableType editableType) { - return editableRootForPosition(toPositionInDOMTree(p), editableType); + return editableRootElementForPosition(toPositionInDOMTree(p), editableType); } // TODO(yosin) This does not handle [table, 0] correctly. @@ -320,7 +322,7 @@ if (enclosingCell) return enclosingCell; - return editableRootForPosition(p); + return editableRootElementForPosition(p); } template <typename Strategy> @@ -1584,17 +1586,20 @@ return layoutObject && ((layoutObject->isTable() && !layoutObject->isInline()) || (layoutObject->isImage() && !layoutObject->isInline()) || layoutObject->isHR()); } -bool areIdenticalElements(const Node* first, const Node* second) +bool areIdenticalElements(const Node& first, const Node& second) { - if (!first->isElementNode() || !second->isElementNode()) + if (!first.isElementNode() || !second.isElementNode()) return false; - const Element* firstElement = toElement(first); - const Element* secondElement = toElement(second); - if (!firstElement->hasTagName(secondElement->tagQName())) + const Element& firstElement = toElement(first); + const Element& secondElement = toElement(second); + if (!firstElement.hasTagName(secondElement.tagQName())) return false; - return firstElement->hasEquivalentAttributes(secondElement); + if (!firstElement.hasEquivalentAttributes(&secondElement)) + return false; + + return firstElement.hasEditableStyle() && secondElement.hasEditableStyle(); } bool isNonTableCellHTMLBlockElement(const Node* node)
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.h b/third_party/WebKit/Source/core/editing/EditingUtilities.h index ac9bcbc..7447cc0d 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.h +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.h
@@ -141,7 +141,9 @@ bool isNodeRendered(const Node&); bool isNodeVisiblyContainedWithin(Node&, const Range&); bool isRenderedAsNonInlineTableImageOrHR(const Node*); -bool areIdenticalElements(const Node*, const Node*); +// Returns true if specified nodes are elements, have identical tag names, +// have identical attributes, and are editable. +CORE_EXPORT bool areIdenticalElements(const Node&, const Node&); bool isNonTableCellHTMLBlockElement(const Node*); bool isBlockFlowElement(const Node&); bool nodeIsUserSelectAll(const Node*); @@ -212,7 +214,7 @@ // style to give proper results. They shouldn't update style by default, but // should make it clear that that is the contract. // FIXME: isRichlyEditablePosition should also take EUpdateStyle. -bool isEditablePosition(const Position&, EditableType = ContentIsEditable, EUpdateStyle = UpdateStyle); +CORE_EXPORT bool isEditablePosition(const Position&, EditableType = ContentIsEditable, EUpdateStyle = UpdateStyle); bool isEditablePosition(const PositionInComposedTree&, EditableType = ContentIsEditable, EUpdateStyle = UpdateStyle); bool isRichlyEditablePosition(const Position&, EditableType = ContentIsEditable); bool lineBreakExistsAtPosition(const Position&); @@ -279,8 +281,8 @@ PassRefPtrWillBeRawPtr<HTMLSpanElement> createTabSpanElement(Document&); PassRefPtrWillBeRawPtr<HTMLSpanElement> createTabSpanElement(Document&, const String& tabText); -Element* editableRootForPosition(const Position&, EditableType = ContentIsEditable); -Element* editableRootForPosition(const PositionInComposedTree&, EditableType = ContentIsEditable); +Element* editableRootElementForPosition(const Position&, EditableType = ContentIsEditable); +Element* editableRootElementForPosition(const PositionInComposedTree&, EditableType = ContentIsEditable); Element* rootEditableElementOf(const VisiblePosition&); Element* unsplittableElementForPosition(const Position&);
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp b/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp index 6448d2060..e5f73125 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp
@@ -4,6 +4,7 @@ #include "core/editing/EditingUtilities.h" +#include "core/dom/StaticNodeList.h" #include "core/editing/EditingTestBase.h" namespace blink { @@ -78,6 +79,24 @@ EXPECT_EQ(three, enclosingNodeOfType(PositionInComposedTree(one, 0), isEnclosingBlock)); } +TEST_F(EditingUtilitiesTest, isEditablePositionWithTable) +{ + // We would like to have below DOM tree without HTML, HEAD and BODY element. + // <table id=table><caption>foo</caption></table> + // However, |setBodyContent()| automatically creates HTML, HEAD and BODY + // element. So, we build DOM tree manually. + // Note: This is unusual HTML taken from http://crbug.com/574230 + RefPtrWillBeRawPtr<Element> table = document().createElement("table", ASSERT_NO_EXCEPTION); + table->setInnerHTML("<caption>foo</caption>", ASSERT_NO_EXCEPTION); + while (document().firstChild()) + document().firstChild()->remove(); + document().appendChild(table); + document().setDesignMode("on"); + updateLayoutAndStyleForPainting(); + + EXPECT_FALSE(isEditablePosition(Position(table.get(), 0))); +} + TEST_F(EditingUtilitiesTest, isFirstPositionAfterTable) { const char* bodyContent = "<div contenteditable id=host><table id=table><tr><td>1</td></tr></table><b id=two>22</b></div>"; @@ -156,4 +175,29 @@ EXPECT_EQ(PositionInComposedTree(three->firstChild(), 1), nextVisuallyDistinctCandidate(PositionInComposedTree(one, 1))); } +TEST_F(EditingUtilitiesTest, AreaIdenticalElements) +{ + setBodyContent("<style>li:nth-child(even) { -webkit-user-modify: read-write; }</style><ul><li>first item</li><li>second item</li><li class=foo>third</li><li>fourth</li></ul>"); + updateLayoutAndStyleForPainting(); + RefPtrWillBeRawPtr<StaticElementList> items = document().querySelectorAll("li", ASSERT_NO_EXCEPTION); + ASSERT(items->length() == 4); + + EXPECT_FALSE(areIdenticalElements(*items->item(0)->firstChild(), *items->item(1)->firstChild())) + << "Can't merge non-elements. e.g. Text nodes"; + + // Compare a LI and a UL. + EXPECT_FALSE(areIdenticalElements(*items->item(0), *items->item(0)->parentNode())) + << "Can't merge different tag names."; + + EXPECT_FALSE(areIdenticalElements(*items->item(0), *items->item(2))) + << "Can't merge a element with no attributes and another element with an attribute."; + + // We can't use contenteditable attribute to make editability difference + // because the hasEquivalentAttributes check is done earier. + EXPECT_FALSE(areIdenticalElements(*items->item(0), *items->item(1))) + << "Can't merge non-editable nodes."; + + EXPECT_TRUE(areIdenticalElements(*items->item(1), *items->item(3))); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/InputMethodController.cpp b/third_party/WebKit/Source/core/editing/InputMethodController.cpp index d1f22bb..93ce9ed 100644 --- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp +++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
@@ -349,11 +349,11 @@ return; const Position start = range.startPosition(); - if (editableRootForPosition(start) != editable) + if (editableRootElementForPosition(start) != editable) return; const Position end = range.endPosition(); - if (editableRootForPosition(end) != editable) + if (editableRootElementForPosition(end) != editable) return; clear();
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp index a88fba5..22543f46 100644 --- a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
@@ -859,7 +859,7 @@ if (p.isNull() && shadowAncestor) p = PositionTemplate<Strategy>::afterNode(shadowAncestor); while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerNode()) == baseEditableAncestor && !isEditablePosition(p))) { - Element* root = editableRootForPosition(p); + Element* root = editableRootElementForPosition(p); shadowAncestor = root ? root->shadowHost() : nullptr; p = isAtomicNode(p.computeContainerNode()) ? PositionTemplate<Strategy>::inParentBeforeNode(*p.computeContainerNode()) : previousVisuallyDistinctCandidate(p); if (p.isNull() && shadowAncestor) @@ -888,7 +888,7 @@ if (p.isNull() && shadowAncestor) p = PositionTemplate<Strategy>::beforeNode(shadowAncestor); while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerNode()) == baseEditableAncestor && !isEditablePosition(p))) { - Element* root = editableRootForPosition(p); + Element* root = editableRootElementForPosition(p); shadowAncestor = root ? root->shadowHost() : nullptr; p = isAtomicNode(p.computeContainerNode()) ? PositionTemplate<Strategy>::inParentAfterNode(*p.computeContainerNode()) : nextVisuallyDistinctCandidate(p); if (p.isNull() && shadowAncestor) @@ -962,7 +962,7 @@ template <typename Strategy> Element* VisibleSelectionTemplate<Strategy>::rootEditableElement() const { - return editableRootForPosition(start()); + return editableRootElementForPosition(start()); } template <typename Strategy>
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp index 22b0234..c0c782d0 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -126,7 +126,7 @@ if (node && node->document().documentElement() == node && !node->hasEditableStyle() && node->document().body() && node->document().body()->hasEditableStyle()) return next.isNotNull() ? next : prev; - Element* editingRoot = editableRootForPosition(position); + Element* editingRoot = editableRootElementForPosition(position); // If the html element is editable, descending into its body will look like // a descent from non-editable to editable content since @@ -134,8 +134,8 @@ if ((editingRoot && editingRoot->document().documentElement() == editingRoot) || position.anchorNode()->isDocumentNode()) return next.isNotNull() ? next : prev; - bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot; - bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next) == editingRoot; + bool prevIsInSameEditableElement = prevNode && editableRootElementForPosition(prev) == editingRoot; + bool nextIsInSameEditableElement = nextNode && editableRootElementForPosition(next) == editingRoot; if (prevIsInSameEditableElement && !nextIsInSameEditableElement) return prev; @@ -1316,11 +1316,11 @@ if (root) { // FIXME: Can be wrong for multi-column layout and with transforms. LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint); - LayoutObject& layoutObject = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->layoutObject(); - Node* node = layoutObject.node(); + LineLayoutItem lineLayoutItem = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->lineLayoutItem(); + Node* node = lineLayoutItem.node(); if (node && editingIgnoresContent(node)) return createVisiblePosition(positionInParentBeforeNode(*node)); - return createVisiblePosition(layoutObject.positionForPoint(pointInLine)); + return createVisiblePosition(lineLayoutItem.positionForPoint(pointInLine)); } // Could not find a previous line. This means we must already be on the first line. @@ -1372,11 +1372,11 @@ if (root) { // FIXME: Can be wrong for multi-column layout and with transforms. LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint); - LayoutObject& layoutObject = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->layoutObject(); - Node* node = layoutObject.node(); + LineLayoutItem lineLayoutItem = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->lineLayoutItem(); + Node* node = lineLayoutItem.node(); if (node && editingIgnoresContent(node)) return createVisiblePosition(positionInParentBeforeNode(*node)); - return createVisiblePosition(layoutObject.positionForPoint(pointInLine)); + return createVisiblePosition(lineLayoutItem.positionForPoint(pointInLine)); } // Could not find a next line. This means we must already be on the last line.
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp index a626143..362069ea 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
@@ -1305,7 +1305,7 @@ Node* previousSibling = startNode->previousSibling(); - if (previousSibling && areIdenticalElements(startNode, previousSibling)) { + if (previousSibling && areIdenticalElements(*startNode, *previousSibling)) { Element* previousElement = toElement(previousSibling); Element* element = toElement(startNode); Node* startChild = element->firstChild(); @@ -1341,7 +1341,7 @@ return false; Node* nextSibling = endNode->nextSibling(); - if (nextSibling && areIdenticalElements(endNode, nextSibling)) { + if (nextSibling && areIdenticalElements(*endNode, *nextSibling)) { Element* nextElement = toElement(nextSibling); Element* element = toElement(endNode); Node* nextChild = nextElement->firstChild(); @@ -1382,13 +1382,13 @@ RefPtrWillBeRawPtr<Node> nextSibling = element->nextSibling(); RefPtrWillBeRawPtr<Node> previousSibling = element->previousSibling(); if (nextSibling && nextSibling->isElementNode() && nextSibling->hasEditableStyle() - && areIdenticalElements(element.get(), toElement(nextSibling))) + && areIdenticalElements(*element, toElement(*nextSibling))) mergeIdenticalElements(element.get(), toElement(nextSibling)); if (previousSibling && previousSibling->isElementNode() && previousSibling->hasEditableStyle()) { Node* mergedElement = previousSibling->nextSibling(); if (mergedElement->isElementNode() && mergedElement->hasEditableStyle() - && areIdenticalElements(toElement(previousSibling), toElement(mergedElement))) + && areIdenticalElements(toElement(*previousSibling), toElement(*mergedElement))) mergeIdenticalElements(toElement(previousSibling), toElement(mergedElement)); }
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp index 1a82e526..8c76022 100644 --- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -943,7 +943,7 @@ if (isEnclosingBlock(upstreamStart.anchorNode())) { // If the block is the root editable element, always move content to a new block, // since it is illegal to modify attributes on the root editable element for editing. - if (upstreamStart.anchorNode() == editableRootForPosition(upstreamStart)) { + if (upstreamStart.anchorNode() == editableRootElementForPosition(upstreamStart)) { // If the block is the root editable element and it contains no visible content, create a new // block but don't try and move content into it, since there's nothing for moveParagraphs to move. if (!hasRenderedNonAnonymousDescendantsWithHeight(upstreamStart.anchorNode()->layoutObject())) @@ -1471,7 +1471,7 @@ } } - if (result.isNull() || !editableRootForPosition(result)) + if (result.isNull() || !editableRootElementForPosition(result)) result = original; return result;
diff --git a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp index 8bb8b85..84e35f31 100644 --- a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
@@ -180,8 +180,8 @@ m_upstreamEnd = mostBackwardCaretPosition(end); m_downstreamEnd = mostForwardCaretPosition(end); - m_startRoot = editableRootForPosition(start); - m_endRoot = editableRootForPosition(end); + m_startRoot = editableRootElementForPosition(start); + m_endRoot = editableRootElementForPosition(end); m_startTableRow = toHTMLTableRowElement(enclosingNodeOfType(start, &isHTMLTableRowElement)); m_endTableRow = toHTMLTableRowElement(enclosingNodeOfType(end, &isHTMLTableRowElement));
diff --git a/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.cpp b/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.cpp index f16db4d..5d28398 100644 --- a/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.cpp
@@ -69,7 +69,7 @@ void FormatBlockCommand::formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtrWillBeRawPtr<HTMLElement>& blockElement) { Element* refElement = enclosingBlockFlowElement(createVisiblePosition(end)); - Element* root = editableRootForPosition(start); + Element* root = editableRootElementForPosition(start); // Root is null for elements with contenteditable=false. if (!root || !refElement) return;
diff --git a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp index 2289b269..96668043 100644 --- a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp
@@ -111,7 +111,7 @@ else if (enclosingList(start.computeContainerNode())) elementToSplitTo = enclosingBlock(start.computeContainerNode()); else - elementToSplitTo = editableRootForPosition(start); + elementToSplitTo = editableRootElementForPosition(start); if (!elementToSplitTo) return;
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp index bb82696..eedb7d5 100644 --- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -541,7 +541,7 @@ } // FIXME: Tolerate differences in id, class, and style attributes. - if (element->parentNode() && isNonTableCellHTMLBlockElement(element) && areIdenticalElements(element, element->parentNode()) + if (element->parentNode() && isNonTableCellHTMLBlockElement(element) && areIdenticalElements(*element, *element->parentNode()) && createVisiblePosition(firstPositionInNode(element->parentNode())).deepEquivalent() == createVisiblePosition(firstPositionInNode(element)).deepEquivalent() && createVisiblePosition(lastPositionInNode(element->parentNode())).deepEquivalent() == createVisiblePosition(lastPositionInNode(element)).deepEquivalent()) { insertedNodes.willRemoveNodePreservingChildren(*element);
diff --git a/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp b/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp index 9d60f34..11ee7e0 100644 --- a/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp
@@ -414,7 +414,7 @@ return matchLength; } -static const TextIteratorBehaviorFlags iteratorFlagsForFindPlainText = TextIteratorEntersTextControls | TextIteratorEntersOpenShadowRoots | TextIteratorDoesNotBreakAtReplacedElement; +static const TextIteratorBehaviorFlags iteratorFlagsForFindPlainText = TextIteratorEntersTextControls | TextIteratorEntersOpenShadowRoots | TextIteratorDoesNotBreakAtReplacedElement | TextIteratorCollapseTrailingSpace; template <typename Strategy> static EphemeralRangeTemplate<Strategy> findPlainTextAlgorithm(const EphemeralRangeTemplate<Strategy>& inputRange, const String& target, FindOptions options)
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp index 1b85ca7..36f4570 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
@@ -458,8 +458,15 @@ if (!layoutObject->style()->collapseWhiteSpace()) { int runStart = m_offset; if (m_lastTextNodeEndedWithCollapsedSpace && hasVisibleTextNode(layoutObject)) { - emitCharacter(spaceCharacter, textNode, 0, runStart, runStart); - return false; + if (m_behavior & TextIteratorCollapseTrailingSpace) { + if (runStart > 0 && str[runStart - 1] == ' ') { + emitCharacter(spaceCharacter, textNode, 0, runStart, runStart); + return false; + } + } else { + emitCharacter(spaceCharacter, textNode, 0, runStart, runStart); + return false; + } } if (!m_handledFirstLetter && layoutObject->isTextFragment() && !m_offset) { handleTextNodeFirstLetter(toLayoutTextFragment(layoutObject)); @@ -671,7 +678,15 @@ return true; } - if (m_lastTextNodeEndedWithCollapsedSpace) { + if (m_behavior & TextIteratorCollapseTrailingSpace) { + if (m_lastTextNode) { + String str = m_lastTextNode->layoutObject()->text(); + if (m_lastTextNodeEndedWithCollapsedSpace && m_offset > 0 && str[m_offset - 1] == ' ') { + emitCharacter(spaceCharacter, Strategy::parent(*m_lastTextNode), m_lastTextNode, 1, 1); + return false; + } + } + } else if (m_lastTextNodeEndedWithCollapsedSpace) { emitCharacter(spaceCharacter, Strategy::parent(*m_lastTextNode), m_lastTextNode, 1, 1); return false; }
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorFlags.h b/third_party/WebKit/Source/core/editing/iterators/TextIteratorFlags.h index 0e9fde3..7828cd6 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIteratorFlags.h +++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorFlags.h
@@ -43,6 +43,7 @@ TextIteratorForSelectionToString = 1 << 10, TextIteratorForWindowFind = 1 << 11, TextIteratorExcludeAutofilledValue = 1 << 12, + TextIteratorCollapseTrailingSpace = 1 << 13, }; typedef unsigned TextIteratorBehaviorFlags;
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTest.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTest.cpp index f9436947..4a1890b 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTest.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTest.cpp
@@ -386,6 +386,14 @@ EXPECT_EQ(3, TextIterator::rangeLength(range->startPosition(), range->endPosition())); } +TEST_F(TextIteratorTest, WhitespaceCollapseForReplacedElements) +{ + static const char* bodyContent = "<span>Some text </span> <input type='button' value='Button text'/><span>Some more text</span>"; + setBodyContent(bodyContent); + EXPECT_EQ("[Some text ][][Some more text]", iterate<DOMTree>(TextIteratorCollapseTrailingSpace)); + EXPECT_EQ("[Some text ][][Button text][Some more text]", iterate<ComposedTree>(TextIteratorCollapseTrailingSpace)); +} + TEST_F(TextIteratorTest, copyTextTo) { const char* bodyContent = "<a id=host><b id=one>one</b> not appeared <b id=two>two</b></a>";
diff --git a/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp b/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp index ed10bcdb..84ffbf1 100644 --- a/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp
@@ -488,7 +488,7 @@ bool useClonesOfEnclosingBlock = block && !isHTMLBodyElement(*block) && !isHTMLHtmlElement(*block) - && block != editableRootForPosition(context.startPosition()); + && block != editableRootElementForPosition(context.startPosition()); bool useLineBreak = enclosingTextFormControl(context.startPosition()); Vector<String> list;
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index f92b88a..5d68ff0 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -245,10 +245,8 @@ void FrameView::removeFromAXObjectCache() { - if (AXObjectCache* cache = axObjectCache()) { - cache->remove(this); + if (AXObjectCache* cache = axObjectCache()) cache->childrenChanged(m_frame->pagePopupOwner()); - } } void FrameView::init() @@ -2999,8 +2997,6 @@ void FrameView::didAddScrollbar(Scrollbar& scrollbar, ScrollbarOrientation orientation) { ScrollableArea::didAddScrollbar(scrollbar, orientation); - if (AXObjectCache* cache = axObjectCache()) - cache->handleScrollbarUpdate(this); } void FrameView::setTopControlsViewportAdjustment(float adjustment) @@ -3038,8 +3034,6 @@ m_horizontalScrollbar->styleChanged(); } else { willRemoveScrollbar(*m_horizontalScrollbar, HorizontalScrollbar); - if (AXObjectCache* cache = axObjectCache()) - cache->remove(m_horizontalScrollbar.get()); // If the scrollbar has been marked as overlapping the window resizer, // then its removal should reduce the count. if (m_horizontalScrollbar->overlapsResizer()) @@ -3047,8 +3041,6 @@ removeChild(m_horizontalScrollbar.get()); m_horizontalScrollbar->disconnectFromScrollableArea(); m_horizontalScrollbar = nullptr; - if (AXObjectCache* cache = axObjectCache()) - cache->handleScrollbarUpdate(this); } setScrollCornerNeedsPaintInvalidation(); @@ -3066,8 +3058,6 @@ m_verticalScrollbar->styleChanged(); } else { willRemoveScrollbar(*m_verticalScrollbar, VerticalScrollbar); - if (AXObjectCache* cache = axObjectCache()) - cache->remove(m_verticalScrollbar.get()); // If the scrollbar has been marked as overlapping the window resizer, // then its removal should reduce the count. if (m_verticalScrollbar->overlapsResizer()) @@ -3075,8 +3065,6 @@ removeChild(m_verticalScrollbar.get()); m_verticalScrollbar->disconnectFromScrollableArea(); m_verticalScrollbar = nullptr; - if (AXObjectCache* cache = axObjectCache()) - cache->handleScrollbarUpdate(this); } setScrollCornerNeedsPaintInvalidation();
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index 76a54a4..363b105 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -970,6 +970,7 @@ SVG1DOMImageElement = 1115, SVG1DOMForeignObjectElement = 1116, AudioContextCreateIIRFilter = 1117, + CSSSelectorPseudoSlotted = 1118, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/html/AssignedNodesOptions.idl b/third_party/WebKit/Source/core/html/AssignedNodesOptions.idl new file mode 100644 index 0000000..5247c06 --- /dev/null +++ b/third_party/WebKit/Source/core/html/AssignedNodesOptions.idl
@@ -0,0 +1,9 @@ +// 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. + +// http://w3c.github.io/webcomponents/spec/shadow/#idl-def-AssignedNodesOptions + +dictionary AssignedNodesOptions { + boolean flatten = false; +};
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp index e18c443..521b2ad 100644 --- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -489,6 +489,13 @@ return m_owner->document(); } +enum StyleSheetCacheStatus { + StyleSheetNewEntry, + StyleSheetInDiskCache, + StyleSheetInMemoryCache, + StyleSheetCacheStatusCount, +}; + void LinkStyle::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* cachedStyleSheet) { if (!m_owner->inDocument()) { @@ -531,10 +538,14 @@ m_loading = false; restoredSheet->checkLoaded(); + Platform::current()->histogramEnumeration("Blink.RestoredCachedStyleSheet", true, 2); + Platform::current()->histogramEnumeration("Blink.RestoredCachedStyleSheet2", StyleSheetInMemoryCache, StyleSheetCacheStatusCount); return; } Platform::current()->histogramEnumeration("Blink.RestoredCachedStyleSheet", false, 2); + StyleSheetCacheStatus cacheStatus = cachedStyleSheet->response().wasCached() ? StyleSheetInDiskCache : StyleSheetNewEntry; + Platform::current()->histogramEnumeration("Blink.RestoredCachedStyleSheet2", cacheStatus, StyleSheetCacheStatusCount); RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(href, parserContext);
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp index ad4c1d65..0b439d85 100644 --- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -1250,7 +1250,7 @@ } option->setDirty(false); - if (!firstOption) + if (!firstOption && !option->isDisabledFormControl()) firstOption = option; } @@ -1984,9 +1984,9 @@ m_popupIsVisible = true; LayoutMenuList* menuList = toLayoutMenuList(layoutObject()); - FloatQuad quad(menuList->localToAbsoluteQuad(FloatQuad(menuList->borderBoundingBox()))); IntSize size = pixelSnappedIntRect(menuList->frameRect()).size(); - m_popup->show(quad, size, optionToListIndex(selectedIndex())); + // TODO(tkent): Remove show() arguments. They are unused. + m_popup->show(FloatQuad(), size, optionToListIndex(selectedIndex())); if (AXObjectCache* cache = document().existingAXObjectCache()) cache->didShowMenuListPopup(menuList); }
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp index c26907f..2546a72 100644 --- a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
@@ -34,6 +34,7 @@ #include "core/dom/NodeTraversal.h" #include "core/dom/shadow/ElementShadow.h" #include "core/dom/shadow/InsertionPoint.h" +#include "core/html/AssignedNodesOptions.h" namespace blink { @@ -46,6 +47,14 @@ DEFINE_NODE_FACTORY(HTMLSlotElement); +const WillBeHeapVector<RefPtrWillBeMember<Node>> HTMLSlotElement::getAssignedNodesForBinding(const AssignedNodesOptions& options) +{ + updateDistribution(); + if (options.hasFlatten() && options.flatten()) + return getDistributedNodes(); + return m_assignedNodes; +} + void HTMLSlotElement::appendAssignedNode(Node& node) { m_assignedNodes.append(&node);
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.h b/third_party/WebKit/Source/core/html/HTMLSlotElement.h index 69a5de4..b674bc75 100644 --- a/third_party/WebKit/Source/core/html/HTMLSlotElement.h +++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.h
@@ -36,6 +36,8 @@ namespace blink { +class AssignedNodesOptions; + class CORE_EXPORT HTMLSlotElement final : public HTMLElement { DEFINE_WRAPPERTYPEINFO(); public: @@ -44,8 +46,7 @@ const WillBeHeapVector<RefPtrWillBeMember<Node>>& getAssignedNodes() const { ASSERT(!needsDistributionRecalc()); return m_assignedNodes; } const WillBeHeapVector<RefPtrWillBeMember<Node>>& getDistributedNodes() const { ASSERT(!needsDistributionRecalc()); return m_distributedNodes; } - const WillBeHeapVector<RefPtrWillBeMember<Node>> getAssignedNodesForBinding() { updateDistribution(); return m_assignedNodes; } - const WillBeHeapVector<RefPtrWillBeMember<Node>> getDistributedNodesForBinding() { updateDistribution(); return m_distributedNodes; } + const WillBeHeapVector<RefPtrWillBeMember<Node>> getAssignedNodesForBinding(const AssignedNodesOptions&); Node* firstDistributedNode() const { return m_distributedNodes.isEmpty() ? nullptr : m_distributedNodes.first().get(); } Node* lastDistributedNode() const { return m_distributedNodes.isEmpty() ? nullptr : m_distributedNodes.last().get(); }
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.idl b/third_party/WebKit/Source/core/html/HTMLSlotElement.idl index af666c6..3dc032a 100644 --- a/third_party/WebKit/Source/core/html/HTMLSlotElement.idl +++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.idl
@@ -30,6 +30,5 @@ RuntimeEnabled=ShadowDOMV1, ] interface HTMLSlotElement : HTMLElement { [Reflect] attribute DOMString name; - [ImplementedAs=getAssignedNodesForBinding] sequence<Node> getAssignedNodes(); - [ImplementedAs=getDistributedNodesForBinding] sequence<Node> getDistributedNodes(); + [ImplementedAs=getAssignedNodesForBinding] sequence<Node> getAssignedNodes(optional AssignedNodesOptions options); };
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp index 479706bf..f44edda7 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -149,6 +149,7 @@ DEFINE_STRING_MAPPING(PseudoHost) DEFINE_STRING_MAPPING(PseudoHostContext) DEFINE_STRING_MAPPING(PseudoShadow) + DEFINE_STRING_MAPPING(PseudoSlotted) DEFINE_STRING_MAPPING(PseudoSpatialNavigationFocus) DEFINE_STRING_MAPPING(PseudoListBox) #undef DEFINE_STRING_MAPPING
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp index bc271cc..ae0385b 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -2658,10 +2658,10 @@ return strutToNextPage + flowThread->nextLogicalTopForUnbreakableContent(flowThreadOffset, contentLogicalHeight) - flowThreadOffset; } -void LayoutBlock::paginatedContentWasLaidOut(LayoutUnit logicalTopOffsetAfterPagination) +void LayoutBlock::paginatedContentWasLaidOut(LayoutUnit logicalBottomOffsetAfterPagination) { if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) - flowThread->contentWasLaidOut(offsetFromLogicalTopOfFirstPage() + logicalTopOffsetAfterPagination); + flowThread->contentWasLaidOut(offsetFromLogicalTopOfFirstPage() + logicalBottomOffsetAfterPagination); } LayoutUnit LayoutBlock::collapsedMarginBeforeForChild(const LayoutBox& child) const
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.h b/third_party/WebKit/Source/core/layout/LayoutBlock.h index f4af3ba..2a962d0 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlock.h +++ b/third_party/WebKit/Source/core/layout/LayoutBlock.h
@@ -473,9 +473,9 @@ LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule) const; // Paginated content inside this block was laid out. - // |logicalTopOffsetAfterPagination| is the logical top offset of the child content after - // applying any forced or unforced break, if needed. - void paginatedContentWasLaidOut(LayoutUnit logicalTopOffsetAfterPagination); + // |logicalBottomOffsetAfterPagination| is the logical bottom offset of the child content after + // applying any forced or unforced breaks as needed. + void paginatedContentWasLaidOut(LayoutUnit logicalBottomOffsetAfterPagination); // Adjust from painting offsets to the local coords of this layoutObject void offsetForContents(LayoutPoint&) const;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp index 934c729..a53a760 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -721,7 +721,7 @@ } } - paginatedContentWasLaidOut(newLogicalTop); + paginatedContentWasLaidOut(newLogicalTop + child.logicalHeight()); // Similar to how we apply clearance. Go ahead and boost height() to be the place where we're going to position the child. setLogicalHeight(logicalHeight() + (newLogicalTop - logicalTop)); @@ -781,7 +781,7 @@ // The new offset may require us to insert a new row for columns (fragmentainer group). // Give the multicol machinery an opportunity to do so (before checking the height of a // column that wouldn't have existed yet otherwise). - paginatedContentWasLaidOut(newLogicalOffset); + paginatedContentWasLaidOut(newLogicalOffset + lineHeight); // Moving to a different page or column may mean that its height is different. pageLogicalHeight = pageLogicalHeightForOffset(newLogicalOffset); if (lineHeight > pageLogicalHeight) { @@ -842,7 +842,7 @@ } } - paginatedContentWasLaidOut(logicalOffset); + paginatedContentWasLaidOut(logicalOffset + lineHeight); } LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(LayoutBox& child, LayoutUnit logicalOffset) const
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutFlowThread.h index a88592d9..0da1737 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlowThread.h +++ b/third_party/WebKit/Source/core/layout/LayoutFlowThread.h
@@ -87,7 +87,7 @@ LayoutUnit pageLogicalHeightForOffset(LayoutUnit); LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule); - virtual void contentWasLaidOut(LayoutUnit logicalTopInFlowThreadAfterPagination) = 0; + virtual void contentWasLaidOut(LayoutUnit logicalBottomInFlowThreadAfterPagination) = 0; // Find and return the next logical top after |flowThreadOffset| that can fit unbreakable // content as tall as |contentLogicalHeight|. |flowThreadOffset| is expected to be at the exact
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp index 7a4e583..3288356d 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
@@ -424,7 +424,7 @@ return view()->fragmentationContext(); } -void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit offsetInFlowThread) +void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit bottomOffsetInFlowThread) { if (!isPageLogicalHeightKnown()) { // If we have no clue about the height of the multicol container, bail. This situation @@ -434,7 +434,11 @@ // Its height is indefinite for now. return; } - LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(offsetInFlowThread); + // TODO(mstensho): bottomOffsetInFlowThread is an endpoint-exclusive offset, i.e. the offset + // just after the bottom of some object. So, ideally, columnSetAtBlockOffset() should be + // informed about this (i.e. take a PageBoundaryRule argument). This is not the only place with + // this issue; see also pageRemainingLogicalHeightForOffset(). + LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(bottomOffsetInFlowThread); if (columnSet->isInitialHeightCalculated()) { // We only insert additional fragmentainer groups in the initial layout pass. We only want // to balance columns in the last fragmentainer group (if we need to balance at all), so we @@ -442,7 +446,7 @@ return; } - if (!columnSet->hasFragmentainerGroupForColumnAt(offsetInFlowThread)) { + if (!columnSet->hasFragmentainerGroupForColumnAt(bottomOffsetInFlowThread)) { FragmentationContext* enclosingFragmentationContext = this->enclosingFragmentationContext(); if (!enclosingFragmentationContext) return; // Not nested. We'll never need more rows than the one we already have then. @@ -452,7 +456,7 @@ // multicol container. That in turn may mean that we've run out of columns there too. const MultiColumnFragmentainerGroup& newRow = columnSet->appendNewFragmentainerGroup(); if (LayoutMultiColumnFlowThread* enclosingFlowThread = enclosingFragmentationContext->associatedFlowThread()) - enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOffsetInEnclosingFragmentationContext()); + enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOffsetInEnclosingFragmentationContext() + newRow.logicalHeight()); } } @@ -908,7 +912,7 @@ m_lastSetWorkedOn = nullptr; } -void LayoutMultiColumnFlowThread::contentWasLaidOut(LayoutUnit logicalTopInFlowThreadAfterPagination) +void LayoutMultiColumnFlowThread::contentWasLaidOut(LayoutUnit logicalBottomInFlowThreadAfterPagination) { // Check if we need another fragmentainer group. If we've run out of columns in the last // fragmentainer group (column row), we need to insert another fragmentainer group to hold more @@ -924,7 +928,7 @@ bool mayBeNested = multiColumnBlockFlow()->isInsideFlowThread() || view()->fragmentationContext(); if (!mayBeNested) return; - appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination); + appendNewFragmentainerGroupIfNeeded(logicalBottomInFlowThreadAfterPagination); } }
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h index 1f518c02..65ee5a4 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
@@ -204,7 +204,7 @@ // If we've run out of columns in the last fragmentainer group (column row), we have to insert // another fragmentainer group in order to hold more columns. This means that we're moving to // the next outer column (in the enclosing fragmentation context). - void appendNewFragmentainerGroupIfNeeded(LayoutUnit offsetInFlowThread); + void appendNewFragmentainerGroupIfNeeded(LayoutUnit bottomOffsetInFlowThread); // Implementing FragmentationContext: bool isFragmentainerLogicalHeightKnown() final; @@ -236,7 +236,7 @@ void computePreferredLogicalWidths() override; void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override; void updateLogicalWidth() override; - void contentWasLaidOut(LayoutUnit logicalTopInFlowThreadAfterPagination) override; + void contentWasLaidOut(LayoutUnit logicalBottomInFlowThreadAfterPagination) override; // The last set we worked on. It's not to be used as the "current set". The concept of a // "current set" is difficult, since layout may jump back and forth in the tree, due to wrong
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp index dd3054c..7a7aa3d 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
@@ -99,7 +99,7 @@ LayoutUnit LayoutMultiColumnSet::nextLogicalTopForUnbreakableContent(LayoutUnit flowThreadOffset, LayoutUnit contentLogicalHeight) const { - ASSERT(pageLogicalTopForOffset(flowThreadOffset) == flowThreadOffset); + ASSERT(flowThreadOffset.mightBeSaturated() || pageLogicalTopForOffset(flowThreadOffset) == flowThreadOffset); FragmentationContext* enclosingFragmentationContext = multiColumnFlowThread()->enclosingFragmentationContext(); if (!enclosingFragmentationContext) { // If there's no enclosing fragmentation context, there'll ever be only one row, and all @@ -145,12 +145,12 @@ return nullptr; } -bool LayoutMultiColumnSet::hasFragmentainerGroupForColumnAt(LayoutUnit offsetInFlowThread) const +bool LayoutMultiColumnSet::hasFragmentainerGroupForColumnAt(LayoutUnit bottomOffsetInFlowThread) const { const MultiColumnFragmentainerGroup& lastRow = lastFragmentainerGroup(); - if (lastRow.logicalTopInFlowThread() > offsetInFlowThread) + if (lastRow.logicalTopInFlowThread() > bottomOffsetInFlowThread) return true; - return offsetInFlowThread - lastRow.logicalTopInFlowThread() < lastRow.logicalHeight() * usedColumnCount(); + return bottomOffsetInFlowThread - lastRow.logicalTopInFlowThread() <= lastRow.logicalHeight() * usedColumnCount(); } MultiColumnFragmentainerGroup& LayoutMultiColumnSet::appendNewFragmentainerGroup() @@ -163,7 +163,6 @@ LayoutUnit blockOffsetInFlowThread = previousGroup.logicalTopInFlowThread() + previousGroup.logicalHeight() * usedColumnCount(); previousGroup.setLogicalBottomInFlowThread(blockOffsetInFlowThread); newGroup.setLogicalTopInFlowThread(blockOffsetInFlowThread); - newGroup.setLogicalTop(previousGroup.logicalTop() + previousGroup.logicalHeight()); newGroup.resetColumnHeight(); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h index dae131a..24369746 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h
@@ -97,7 +97,7 @@ LayoutMultiColumnSet* previousSiblingMultiColumnSet() const; // Return true if we have a fragmentainer group that can hold a column at the specified flow thread block offset. - bool hasFragmentainerGroupForColumnAt(LayoutUnit offsetInFlowThread) const; + bool hasFragmentainerGroupForColumnAt(LayoutUnit bottomOffsetInFlowThread) const; MultiColumnFragmentainerGroup& appendNewFragmentainerGroup();
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp index 553056e5..3d88ac6 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -1244,10 +1244,18 @@ void LayoutObject::invalidateDisplayItemClients(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason invalidationReason) const { + // It's caller's responsibility to ensure enclosingLayer's needsRepaint is set. + // Don't set the flag here because enclosingLayer() has cost and the caller can use + // various ways (e.g. PaintInvalidatinState::enclosingLayer()) to reduce the cost. + ASSERT(!enclosingLayer() || enclosingLayer()->needsRepaint()); paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*this, invalidationReason); +} - if (PaintLayer* enclosingLayer = this->enclosingLayer()) - enclosingLayer->setNeedsRepaint(); +void LayoutObject::invalidateDisplayItemClientsWithPaintInvalidationState(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason invalidationReason) const +{ + ASSERT(&paintInvalidationState.enclosingLayer(*this) == enclosingLayer()); + paintInvalidationState.enclosingLayer(*this).setNeedsRepaint(); + invalidateDisplayItemClients(paintInvalidationContainer, invalidationReason); } LayoutRect LayoutObject::boundsRectForPaintInvalidation(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const @@ -1274,6 +1282,8 @@ void LayoutObject::invalidatePaintRectangle(const LayoutRect& rect) const { + if (PaintLayer* enclosingLayer = this->enclosingLayer()) + enclosingLayer->setNeedsRepaint(); const LayoutBoxModelObject* paintInvalidationContainer = invalidatePaintRectangleInternal(rect); if (paintInvalidationContainer) invalidateDisplayItemClients(*paintInvalidationContainer, PaintInvalidationRectangle); @@ -1348,7 +1358,7 @@ } // TODO(wangxianzhu): Remove this for slimming paint v2 because we won't care about paint invalidation rects. -inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason invalidationReason) +inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason invalidationReason) { // Update selection rect when we are doing full invalidation (in case that the object is moved, composite status changed, etc.) // or shouldInvalidationSelection is set (in case that the selection itself changed). @@ -1369,7 +1379,7 @@ setPreviousSelectionRectForPaintInvalidation(newSelectionRect); if (shouldInvalidateSelection()) - invalidateDisplayItemClients(paintInvalidationContainer, PaintInvalidationSelection); + invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationContainer, paintInvalidationState, PaintInvalidationSelection); if (fullInvalidation) return; @@ -1409,7 +1419,7 @@ // We need to invalidate the selection before checking for whether we are doing a full invalidation. // This is because we need to update the old rect regardless. - invalidateSelectionIfNeeded(paintInvalidationContainer, invalidationReason); + invalidateSelectionIfNeeded(paintInvalidationContainer, paintInvalidationState, invalidationReason); TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "LayoutObject::invalidatePaintIfNeeded()", "object", this->debugName().ascii(), @@ -1427,12 +1437,12 @@ // invalidation is issued. See crbug.com/508383 and crbug.com/515977. // This is a workaround to force display items to update paint offset. if (!RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled() && paintInvalidationState.forcedSubtreeInvalidationWithinContainer()) - invalidateDisplayItemClients(paintInvalidationContainer, invalidationReason); + invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationContainer, paintInvalidationState, invalidationReason); return invalidationReason; } - invalidateDisplayItemClients(paintInvalidationContainer, invalidationReason); + invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationContainer, paintInvalidationState, invalidationReason); if (invalidationReason == PaintInvalidationIncremental) { incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newBounds, newLocation); @@ -3400,12 +3410,19 @@ } traverseNonCompositingDescendants(const_cast<LayoutObject&>(*this), [&paintInvalidationContainer, paintInvalidationReason](LayoutObject& object) { + if (object.hasLayer()) + toLayoutBoxModelObject(object).layer()->setNeedsRepaint(); object.invalidateDisplayItemClients(*paintInvalidationContainer, paintInvalidationReason); }); } void LayoutObject::invalidatePaintOfPreviousPaintInvalidationRect(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason reason) { + // It's caller's responsibility to ensure enclosingLayer's needsRepaint is set. + // Don't set the flag here because enclosingLayer() has cost and the caller can use + // various ways (e.g. PaintInvalidatinState::enclosingLayer()) to reduce the cost. + ASSERT(!enclosingLayer() || enclosingLayer()->needsRepaint()); + // These disablers are valid because we want to use the current compositing/invalidation status. DisablePaintInvalidationStateAsserts invalidationDisabler; DisableCompositingQueryAsserts compositingDisabler; @@ -3427,6 +3444,8 @@ // Since we're only painting non-composited layers, we know that they all share the same paintInvalidationContainer. const LayoutBoxModelObject& paintInvalidationContainer = containerForPaintInvalidation(); traverseNonCompositingDescendants(*this, [&paintInvalidationContainer](LayoutObject& object) { + if (object.hasLayer()) + toLayoutBoxModelObject(object).layer()->setNeedsRepaint(); object.invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationContainer, PaintInvalidationLayer); }); } @@ -3441,15 +3460,24 @@ }); } -void LayoutObject::invalidatePaintIncludingNonSelfPaintingLayerDescendants(const LayoutBoxModelObject& paintInvalidationContainer) +void LayoutObject::invalidatePaintIncludingNonSelfPaintingLayerDescendantsInternal(const LayoutBoxModelObject& paintInvalidationContainer) { invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationContainer, PaintInvalidationLayer); for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibling()) { + if (child->hasLayer()) + toLayoutBoxModelObject(child)->layer()->setNeedsRepaint(); if (!child->hasLayer() || !toLayoutBoxModelObject(child)->layer()->isSelfPaintingLayer()) - child->invalidatePaintIncludingNonSelfPaintingLayerDescendants(paintInvalidationContainer); + child->invalidatePaintIncludingNonSelfPaintingLayerDescendantsInternal(paintInvalidationContainer); } } +void LayoutObject::invalidatePaintIncludingNonSelfPaintingLayerDescendants(const LayoutBoxModelObject& paintInvalidationContainer) +{ + if (PaintLayer* enclosingLayer = this->enclosingLayer()) + enclosingLayer->setNeedsRepaint(); + invalidatePaintIncludingNonSelfPaintingLayerDescendantsInternal(paintInvalidationContainer); +} + void LayoutObject::setIsBackgroundAttachmentFixedObject(bool isBackgroundAttachmentFixedObject) { ASSERT(frameView());
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h index ad307f07..3226576e5 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -1492,8 +1492,13 @@ // owned by this object, including the object itself, LayoutText/LayoutInline line boxes, etc., // not including children which will be invalidated normally during invalidateTreeIfNeeded() and // parts which are invalidated separately (e.g. scrollbars). + // The caller should ensure the enclosing layer has been setNeedsRepaint before calling this function. virtual void invalidateDisplayItemClients(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason) const; + // Sets enclosing layer needsRepaint, then calls invalidateDisplayItemClients(). + // Should use this version when PaintInvalidationState is available. + void invalidateDisplayItemClientsWithPaintInvalidationState(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState&, PaintInvalidationReason) const; + void setIsBackgroundAttachmentFixedObject(bool); void clearSelfNeedsOverflowRecalcAfterStyleChange() { m_bitfields.setSelfNeedsOverflowRecalcAfterStyleChange(false); } @@ -1541,10 +1546,13 @@ inline void markContainerChainForPaintInvalidation(); - inline void invalidateSelectionIfNeeded(const LayoutBoxModelObject&, PaintInvalidationReason); + inline void invalidateSelectionIfNeeded(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState&, PaintInvalidationReason); inline void invalidateContainerPreferredLogicalWidths(); + void invalidatePaintIncludingNonSelfPaintingLayerDescendantsInternal(const LayoutBoxModelObject& paintInvalidationContainer); + + // The caller should ensure the enclosing layer has been setNeedsRepaint before calling this function. void invalidatePaintOfPreviousPaintInvalidationRect(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason); LayoutRect previousSelectionRectForPaintInvalidation() const;
diff --git a/third_party/WebKit/Source/core/layout/LayoutObjectChildList.cpp b/third_party/WebKit/Source/core/layout/LayoutObjectChildList.cpp index 33b60942..768b3c05 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObjectChildList.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutObjectChildList.cpp
@@ -185,6 +185,7 @@ oldChild.view()->setShouldDoFullPaintInvalidation(); return; } + oldChild.enclosingLayer()->setNeedsRepaint(); oldChild.invalidatePaintOfPreviousPaintInvalidationRect(oldChild.containerForPaintInvalidation(), PaintInvalidationLayoutObjectRemoval); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.cpp b/third_party/WebKit/Source/core/layout/LayoutView.cpp index b84eba7..6a96778 100644 --- a/third_party/WebKit/Source/core/layout/LayoutView.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutView.cpp
@@ -429,7 +429,7 @@ const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationState.paintInvalidationContainer(); PaintLayer::mapRectToPaintInvalidationBacking(this, &paintInvalidationContainer, dirtyRect, &paintInvalidationState); invalidatePaintUsingContainer(paintInvalidationContainer, dirtyRect, PaintInvalidationFull); - invalidateDisplayItemClients(paintInvalidationContainer, PaintInvalidationFull); + invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationContainer, paintInvalidationState, PaintInvalidationFull); } LayoutBlock::invalidateTreeIfNeeded(paintInvalidationState); }
diff --git a/third_party/WebKit/Source/core/layout/OverflowModel.h b/third_party/WebKit/Source/core/layout/OverflowModel.h index 642e56c..08a8215 100644 --- a/third_party/WebKit/Source/core/layout/OverflowModel.h +++ b/third_party/WebKit/Source/core/layout/OverflowModel.h
@@ -84,8 +84,8 @@ { } - const LayoutRect layoutOverflowRect() const { return m_layoutOverflow; } - const LayoutRect visualOverflowRect() const { return m_visualOverflow; } + const LayoutRect& layoutOverflowRect() const { return m_layoutOverflow; } + const LayoutRect& visualOverflowRect() const { return m_visualOverflow; } LayoutRect contentsVisualOverflowRect() const { return m_contentsVisualOverflow; } void move(LayoutUnit dx, LayoutUnit dy);
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp index 86d5be2..23d8fa55 100644 --- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp +++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
@@ -20,6 +20,7 @@ , m_viewClippingAndScrollOffsetDisabled(false) , m_paintInvalidationContainer(layoutView.containerForPaintInvalidation()) , m_pendingDelayedPaintInvalidations(pendingDelayedPaintInvalidations) + , m_enclosingLayer(*layoutView.layer()) { bool establishesPaintInvalidationContainer = layoutView == m_paintInvalidationContainer; if (!establishesPaintInvalidationContainer) { @@ -46,6 +47,7 @@ , m_viewClippingAndScrollOffsetDisabled(false) , m_paintInvalidationContainer(paintInvalidationContainer) , m_pendingDelayedPaintInvalidations(next.pendingDelayedPaintInvalidationTargets()) + , m_enclosingLayer(next.enclosingLayer(layoutObject)) { // FIXME: SVG could probably benefit from a stack-based optimization like html does. crbug.com/391054 bool establishesPaintInvalidationContainer = layoutObject == m_paintInvalidationContainer; @@ -107,6 +109,7 @@ , m_paintOffset(next.m_paintOffset) , m_paintInvalidationContainer(next.m_paintInvalidationContainer) , m_pendingDelayedPaintInvalidations(next.pendingDelayedPaintInvalidationTargets()) + , m_enclosingLayer(next.enclosingLayer(layoutObject)) { ASSERT(layoutObject != m_paintInvalidationContainer); @@ -142,4 +145,19 @@ m_paintOffset -= box.scrolledContentOffset(); } +PaintLayer& PaintInvalidationState::enclosingLayer(const LayoutObject& layoutObject) const +{ + if (layoutObject.hasLayer()) + return *toLayoutBoxModelObject(layoutObject).layer(); + + // During paint invalidation, a multi-column spanner place holder invokes paint invalidation of + // its layoutObjectInFlowThread (which has a non-null spannerPlaceHolder) directly, skipping the + // parent of its layoutObjectInFlowThread which has a PaintLayer. + if (layoutObject.spannerPlaceholder()) + return *layoutObject.enclosingLayer(); + + ASSERT(layoutObject.enclosingLayer() == &m_enclosingLayer); + return m_enclosingLayer; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.h b/third_party/WebKit/Source/core/layout/PaintInvalidationState.h index 39d1c62c..d57ddf64 100644 --- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.h +++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.h
@@ -16,6 +16,7 @@ class LayoutObject; class LayoutSVGModelObject; class LayoutView; +class PaintLayer; // PaintInvalidationState is an optimization used during the paint // invalidation phase. @@ -67,6 +68,8 @@ bool viewClippingAndScrollOffsetDisabled() const { return m_viewClippingAndScrollOffsetDisabled; } void setViewClippingAndScrollOffsetDisabled(bool b) { m_viewClippingAndScrollOffsetDisabled = b; } + PaintLayer& enclosingLayer(const LayoutObject&) const; + private: PaintInvalidationState(const LayoutView&, Vector<LayoutObject*>& pendingDelayedPaintInvalidations, PaintInvalidationState* ownerPaintInvalidationState); @@ -97,6 +100,8 @@ AffineTransform m_svgTransform; Vector<LayoutObject*>& m_pendingDelayedPaintInvalidations; + + PaintLayer& m_enclosingLayer; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/style/ContentData.h b/third_party/WebKit/Source/core/style/ContentData.h index e4347a05..1947050 100644 --- a/third_party/WebKit/Source/core/style/ContentData.h +++ b/third_party/WebKit/Source/core/style/ContentData.h
@@ -76,7 +76,7 @@ public: const StyleImage* image() const { return m_image.get(); } StyleImage* image() { return m_image.get(); } - void setImage(PassRefPtrWillBeRawPtr<StyleImage> image) { m_image = image; } + void setImage(PassRefPtrWillBeRawPtr<StyleImage> image) { ASSERT(image); m_image = image; } bool isImage() const override { return true; } LayoutObject* createLayoutObject(Document&, ComputedStyle&) const override; @@ -94,6 +94,7 @@ ImageContentData(PassRefPtrWillBeRawPtr<StyleImage> image) : m_image(image) { + ASSERT(m_image); } PassOwnPtrWillBeRawPtr<ContentData> cloneInternal() const override
diff --git a/third_party/WebKit/Source/core/svg/SVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGElement.cpp index c7f4aec..ff9b791 100644 --- a/third_party/WebKit/Source/core/svg/SVGElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGElement.cpp
@@ -33,7 +33,6 @@ #include "core/animation/ElementAnimations.h" #include "core/animation/InterpolationEnvironment.h" #include "core/animation/InvalidatableInterpolation.h" -#include "core/animation/SVGInterpolation.h" #include "core/css/CSSCursorImageValue.h" #include "core/css/resolver/StyleResolver.h" #include "core/dom/Document.h" @@ -260,14 +259,8 @@ &elementAnimations()->animationStack(), nullptr, nullptr, KeyframeEffect::DefaultPriority, isSVGAttributeHandle); for (auto& entry : activeInterpolationsMap) { const QualifiedName& attribute = entry.key.svgAttribute(); - const Interpolation& interpolation = *entry.value.first(); - if (interpolation.isInvalidatableInterpolation()) { - InterpolationEnvironment environment(*this, propertyFromAttribute(attribute)->baseValueBase()); - InvalidatableInterpolation::applyStack(entry.value, environment); - } else { - // TODO(alancutter): Remove this old code path once animations have completely migrated to InterpolationTypes. - toSVGInterpolation(interpolation).apply(*this); - } + InterpolationEnvironment environment(*this, propertyFromAttribute(attribute)->baseValueBase()); + InvalidatableInterpolation::applyStack(entry.value, environment); } svgRareData()->setWebAnimatedAttributesDirty(false); }
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes index 4c578777..d3d6a60 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -2,7 +2,7 @@ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485", - "toolbarButtonGlyphs.svg": "55b01beb3c00d0f82b773216f990526d", + "toolbarButtonGlyphs.svg": "9cb447c4c5e8e65ae5c9a32983a6e515", "breakpoint.svg": "69cd92d807259c022791112809b97799", "responsiveDesign.svg": "1d6e963f88e5e448a7cff85f75a0e6b0" } \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes index 4c578777..d3d6a60 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -2,7 +2,7 @@ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485", - "toolbarButtonGlyphs.svg": "55b01beb3c00d0f82b773216f990526d", + "toolbarButtonGlyphs.svg": "9cb447c4c5e8e65ae5c9a32983a6e515", "breakpoint.svg": "69cd92d807259c022791112809b97799", "responsiveDesign.svg": "1d6e963f88e5e448a7cff85f75a0e6b0" } \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg index fe1e492..7046181 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
@@ -15,7 +15,7 @@ xml:space="preserve" id="svg3395" inkscape:version="0.48.4 r9939" - sodipodi:docname="toolbarButtonGlyphs.svg"><metadata + sodipodi:docname="out2.svg"><metadata id="metadata3773"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview @@ -24,10 +24,10 @@ inkscape:zoom="4.7448473" inkscape:cx="225.17445" inkscape:cy="59.825604" - inkscape:window-width="2495" - inkscape:window-height="1576" - inkscape:window-x="65" - inkscape:window-y="24" + inkscape:window-width="2560" + inkscape:window-height="1547" + inkscape:window-x="0" + inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="svg3395" inkscape:snap-global="false" @@ -1047,4 +1047,16 @@ inkscape:connector-curvature="0" d="m 10.624268,2.47 c 1.915481,0.9041667 3.286192,2.7533333 3.497071,4.9466667 l 0.878661,0 C 14.701255,3.8233333 11.684519,1 8,1 L 7.6133891,1.0175 9.8451883,3.24 10.624268,2.47 l 0,0 z M 6.9631799,2.0208333 c -0.3456067,-0.3441666 -0.902092,-0.3441666 -1.241841,0 l -3.725523,3.71 C 1.6502092,6.075 1.6502092,6.6291667 1.9958159,6.9675 l 7.0410042,7.011667 c 0.3456067,0.344166 0.902092,0.344166 1.2418409,0 l 3.725523,-3.71 c 0.345607,-0.344167 0.345607,-0.8983337 0,-1.236667 l -7.0410041,-7.0116667 0,0 z M 9.6577406,13.360833 2.6167364,6.3491667 l 3.725523,-3.71 7.0410046,7.0116666 -3.7255234,3.7099997 0,0 z M 5.3757322,13.53 C 3.4602511,12.631667 2.0895398,10.776667 1.8786611,8.5833333 L 1,8.5833333 C 1.2987448,12.176667 4.3154812,15 8,15 L 8.3866109,14.9825 6.1548117,12.76 l -0.7790795,0.77 0,0 z" id="rotate" + sketch:type="MSShapeGroup" /></g></g><g + style="fill:none;stroke:none" + id="Page-1-0" + sketch:type="MSPage" + transform="matrix(1.4,0,0,1.4,9,126)"><g + style="fill:#000000" + id="Forward-Right" + sketch:type="MSLayerGroup" + transform="translate(-3,-3)"><path + inkscape:connector-curvature="0" + d="m 8,13 c 2.761424,0 5,-2.238576 5,-5 C 13,5.2385763 10.761424,3 8,3 5.2385763,3 3,5.2385763 3,8 c 0,2.761424 2.2385763,5 5,5 z M 8,11 8,9 5,9 5,7 8,7 8,5 11,8 8,11 z" + id="forward-right" sketch:type="MSShapeGroup" /></g></g></svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png index f1e0e54..d3c07876 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png index 7ab785f..5c92936 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ComputedStyleWidget.js b/third_party/WebKit/Source/devtools/front_end/elements/ComputedStyleWidget.js index 8e46526..9aab9a7 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ComputedStyleWidget.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ComputedStyleWidget.js
@@ -29,11 +29,12 @@ /** * @constructor + * @extends {WebInspector.ThrottledWidget} * @param {!WebInspector.StylesSidebarPane} stylesSidebarPane * @param {!WebInspector.SharedSidebarModel} sharedModel - * @extends {WebInspector.ThrottledWidget} + * @param {function(!WebInspector.CSSProperty)} revealCallback */ -WebInspector.ComputedStyleWidget = function(stylesSidebarPane, sharedModel) +WebInspector.ComputedStyleWidget = function(stylesSidebarPane, sharedModel, revealCallback) { WebInspector.ThrottledWidget.call(this); this.element.classList.add("computed-style-sidebar-pane"); @@ -63,6 +64,7 @@ this._stylesSidebarPane = stylesSidebarPane; this._linkifier = new WebInspector.Linkifier(new WebInspector.Linkifier.DefaultCSSFormatter()); + this._revealCallback = revealCallback; /** * @param {?RegExp} regex @@ -78,11 +80,12 @@ /** * @param {!WebInspector.StylesSidebarPane} stylesSidebarPane * @param {!WebInspector.SharedSidebarModel} sharedModel + * @param {function(!WebInspector.CSSProperty)} revealCallback * @return {!WebInspector.ElementsSidebarViewWrapperPane} */ -WebInspector.ComputedStyleWidget.createSidebarWrapper = function(stylesSidebarPane, sharedModel) +WebInspector.ComputedStyleWidget.createSidebarWrapper = function(stylesSidebarPane, sharedModel, revealCallback) { - var widget = new WebInspector.ComputedStyleWidget(stylesSidebarPane, sharedModel); + var widget = new WebInspector.ComputedStyleWidget(stylesSidebarPane, sharedModel, revealCallback); return new WebInspector.ElementsSidebarViewWrapperPane(WebInspector.UIString("Computed Style"), widget) } @@ -185,10 +188,12 @@ var trace = propertyTraces.get(propertyName); if (trace) { - this._renderPropertyTrace(cssModel, matchedStyles, nodeStyle.node, treeElement, trace); + var activeProperty = this._renderPropertyTrace(cssModel, matchedStyles, nodeStyle.node, treeElement, trace); treeElement.listItemElement.addEventListener("mousedown", consumeEvent, false); treeElement.listItemElement.addEventListener("dblclick", consumeEvent, false); treeElement.listItemElement.addEventListener("click", handleClick.bind(null, treeElement), false); + var gotoSourceElement = propertyValueElement.createChild("div", "goto-source-icon"); + gotoSourceElement.addEventListener("click", this._navigateToSource.bind(this, activeProperty)); } } @@ -222,24 +227,45 @@ }, /** + * @param {!WebInspector.CSSProperty} cssProperty + * @param {!Event} event + */ + _navigateToSource: function(cssProperty, event) + { + if (this._revealCallback) + this._revealCallback.call(null, cssProperty); + event.consume(true); + }, + + /** * @param {!WebInspector.CSSStyleModel} cssModel * @param {!WebInspector.CSSStyleModel.MatchedStyleResult} matchedStyles * @param {!WebInspector.DOMNode} node * @param {!TreeElement} rootTreeElement * @param {!Array<!WebInspector.CSSProperty>} tracedProperties + * @return {!WebInspector.CSSProperty} */ _renderPropertyTrace: function(cssModel, matchedStyles, node, rootTreeElement, tracedProperties) { + var activeProperty = null; for (var property of tracedProperties) { var trace = createElement("div"); trace.classList.add("property-trace"); if (matchedStyles.propertyState(property) === WebInspector.CSSStyleModel.MatchedStyleResult.PropertyState.Overloaded) trace.classList.add("property-trace-inactive"); + else + activeProperty = property; var renderer = new WebInspector.StylesSidebarPropertyRenderer(null, node, property.name, /** @type {string} */(property.value)); renderer.setColorHandler(this._processColor.bind(this)); var valueElement = renderer.renderValue(); valueElement.classList.add("property-trace-value"); + valueElement.addEventListener("click", this._navigateToSource.bind(this, property), false); + var gotoSourceElement = createElement("div"); + gotoSourceElement.classList.add("goto-source-icon"); + gotoSourceElement.addEventListener("click", this._navigateToSource.bind(this, property)); + valueElement.insertBefore(gotoSourceElement, valueElement.firstChild); + trace.appendChild(valueElement); var rule = property.ownerStyle.parentRule; @@ -257,6 +283,7 @@ traceTreeElement.selectable = false; rootTreeElement.appendChild(traceTreeElement); } + return /** @type {!WebInspector.CSSProperty} */(activeProperty); }, /**
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js index 6b1ece1..d9d112a 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -74,7 +74,7 @@ var sharedSidebarModel = new WebInspector.SharedSidebarModel(); this.sidebarPanes.platformFonts = WebInspector.PlatformFontsWidget.createSidebarWrapper(sharedSidebarModel); this.sidebarPanes.styles = new WebInspector.StylesSidebarPane(); - this.sidebarPanes.computedStyle = WebInspector.ComputedStyleWidget.createSidebarWrapper(this.sidebarPanes.styles, sharedSidebarModel); + this.sidebarPanes.computedStyle = WebInspector.ComputedStyleWidget.createSidebarWrapper(this.sidebarPanes.styles, sharedSidebarModel, this._revealProperty.bind(this)); this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane(); this.sidebarPanes.properties = WebInspector.PropertiesWidget.createSidebarWrapper(); @@ -101,6 +101,17 @@ WebInspector.ElementsPanel.prototype = { /** + * @param {!WebInspector.CSSProperty} cssProperty + */ + _revealProperty: function(cssProperty) + { + var stylesSidebarPane = this.sidebarPanes.styles; + this.sidebarPaneView.selectTab(stylesSidebarPane.title()); + stylesSidebarPane.revealProperty(/** @type {!WebInspector.CSSProperty} */(cssProperty)); + return Promise.resolve(); + }, + + /** * @param {!WebInspector.StylesSidebarPane} ssp * @return {!Element} */
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/PropertyChangeHighlighter.js b/third_party/WebKit/Source/devtools/front_end/elements/PropertyChangeHighlighter.js index 74ec191..52de522 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/PropertyChangeHighlighter.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/PropertyChangeHighlighter.js
@@ -5,65 +5,50 @@ /** * @constructor * @param {!WebInspector.StylesSidebarPane} ssp + * @param {!WebInspector.CSSStyleModel} cssModel + * @param {!CSSAgent.StyleSheetId} styleSheetId + * @param {!WebInspector.TextRange} range */ -WebInspector.PropertyChangeHighlighter = function(ssp) +WebInspector.PropertyChangeHighlighter = function(ssp, cssModel, styleSheetId, range) { this._styleSidebarPane = ssp; - WebInspector.targetManager.addModelListener(WebInspector.CSSStyleModel, WebInspector.CSSStyleModel.Events.LayoutEditorChange, this._onLayoutEditorChange, this); + this._target = cssModel.target(); + this._styleSheetId = styleSheetId; + this._range = range; } WebInspector.PropertyChangeHighlighter.prototype = { /** - * @param {!WebInspector.Event} event */ - _onLayoutEditorChange: function(event) + perform: function() { - this._styleSidebarPane.runDecoratorAfterUpdate(this._updateHighlight.bind(this, event)); - this._styleSidebarPane.update(); - }, - - /** - * @param {!WebInspector.Event} event - */ - _updateHighlight: function(event) - { - var cssModel = /** @type {!WebInspector.CSSStyleModel} */(event.target); - var styleSheetId = event.data["id"]; - var changeRange = /** @type {!CSSAgent.SourceRange} */(event.data["range"]); - var changeRangeObject = WebInspector.TextRange.fromObject(changeRange); - var node = this._styleSidebarPane.node(); - if (!node || cssModel.target() !== node.target()) + if (!node || this._target !== node.target()) return; - var sectionBlocks = this._styleSidebarPane.sectionBlocks(); var foundSection = null; - for (var block of sectionBlocks) { - for (var section of block.sections) { - var declaration = section.style(); - if (declaration.styleSheetId !== styleSheetId) - continue; + for (var section of this._styleSidebarPane.allSections()) { + var declaration = section.style(); + if (declaration.styleSheetId !== this._styleSheetId) + continue; - var parentRule = declaration.parentRule; - var isInlineSelector = changeRangeObject.isEmpty(); - var isMatchingRule = parentRule && parentRule.selectorRange() && changeRangeObject.compareTo(parentRule.selectorRange()) === 0; - if (isInlineSelector || isMatchingRule) { - section.element.animate([ - { offset: 0, backgroundColor: "rgba(255, 227, 199, 1)" }, - { offset: 0.5, backgroundColor: "rgba(255, 227, 199, 1)" }, - { offset: 0.9, backgroundColor: "rgba(255, 227, 199, 0)" }, - { offset: 1, backgroundColor: "white" } - ], { duration : 400, easing: "cubic-bezier(0, 0, 0.2, 1)" }); - return; - } - - if (this._checkRanges(declaration.range, changeRange)) { - foundSection = section; - break; - } + var parentRule = declaration.parentRule; + var isInlineSelector = this._range.isEmpty(); + var isMatchingRule = parentRule && parentRule.selectorRange() && this._range.compareTo(parentRule.selectorRange()) === 0; + if (isInlineSelector || isMatchingRule) { + section.element.animate([ + { offset: 0, backgroundColor: "rgba(255, 227, 199, 1)" }, + { offset: 0.5, backgroundColor: "rgba(255, 227, 199, 1)" }, + { offset: 0.9, backgroundColor: "rgba(255, 227, 199, 0)" }, + { offset: 1, backgroundColor: "white" } + ], { duration : 400, easing: "cubic-bezier(0, 0, 0.2, 1)" }); + return; } - if (foundSection) + + if (this._checkRanges(declaration.range, this._range)) { + foundSection = section; break; + } } if (!foundSection) @@ -73,7 +58,7 @@ var treeElement = foundSection.propertiesTreeOutline.firstChild(); var foundTreeElement = null; while (!highlightElement && treeElement) { - if (treeElement.property.range && this._checkRanges(treeElement.property.range, changeRange)) { + if (treeElement.property.range && this._checkRanges(treeElement.property.range, this._range)) { highlightElement = treeElement.valueElement; break; } @@ -92,8 +77,8 @@ /** * - * @param {!CSSAgent.SourceRange} outterRange - * @param {!CSSAgent.SourceRange} innerRange + * @param {!WebInspector.TextRange} outterRange + * @param {!WebInspector.TextRange} innerRange * @return {boolean} */ _checkRanges: function(outterRange, innerRange) @@ -104,4 +89,50 @@ var endsAfter = outterRange.endLine > innerRange.endLine || (outterRange.endLine === innerRange.endLine && outterRange.endColumn + eps >= innerRange.endColumn); return startsBefore && endsAfter; } -} \ No newline at end of file +} + +/** + * @constructor + * @param {!WebInspector.StylesSidebarPane} ssp + * @param {!WebInspector.CSSProperty} cssProperty + */ +WebInspector.PropertyRevealHighlighter = function(ssp, cssProperty) +{ + this._styleSidebarPane = ssp; + this._cssProperty = cssProperty; +} + +WebInspector.PropertyRevealHighlighter.prototype = { + perform: function() + { + // Expand all shorthands. + for (var section of this._styleSidebarPane.allSections()) { + for (var treeElement = section.propertiesTreeOutline.firstChild(); treeElement; treeElement = treeElement.nextSibling) + treeElement.onpopulate(); + } + var highlightTreeElement = null; + for (var section of this._styleSidebarPane.allSections()) { + var treeElement = section.propertiesTreeOutline.firstChild(); + while (treeElement && !highlightTreeElement) { + if (treeElement.property === this._cssProperty) { + highlightTreeElement = treeElement; + break; + } + treeElement = treeElement.traverseNextTreeElement(false, null, true); + } + if (highlightTreeElement) + break; + } + + if (!highlightTreeElement) + return; + + highlightTreeElement.parent.expand(); + highlightTreeElement.listItemElement.scrollIntoViewIfNeeded(); + highlightTreeElement.listItemElement.animate([ + { offset: 0, backgroundColor: "rgba(255, 255, 0, 0.2)"}, + { offset: 0.1, backgroundColor: "rgba(255, 255, 0, 0.7)"}, + { offset: 1, backgroundColor: "transparent"} + ], { duration : 2000, easing: "cubic-bezier(0, 0, 0.2, 1)" }); + }, +}
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js index b13cba1..fa6a6e4 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -47,7 +47,8 @@ this.element.addEventListener("mousemove", this._mouseMovedOverElement.bind(this), false); this._keyDownBound = this._keyDown.bind(this); this._keyUpBound = this._keyUp.bind(this); - new WebInspector.PropertyChangeHighlighter(this); + + WebInspector.targetManager.addModelListener(WebInspector.CSSStyleModel, WebInspector.CSSStyleModel.Events.LayoutEditorChange, this._onLayoutEditorChange, this); } /** @@ -105,6 +106,29 @@ } WebInspector.StylesSidebarPane.prototype = { + /** + * @param {!WebInspector.Event} event + */ + _onLayoutEditorChange: function(event) + { + var cssModel = /** @type {!WebInspector.CSSStyleModel} */(event.target); + var styleSheetId = event.data["id"]; + var sourceRange = /** @type {!CSSAgent.SourceRange} */(event.data["range"]); + var range = WebInspector.TextRange.fromObject(sourceRange); + this._decorator = new WebInspector.PropertyChangeHighlighter(this, cssModel, styleSheetId, range); + this.update(); + }, + + /** + * @param {!WebInspector.CSSProperty} cssProperty + */ + revealProperty: function(cssProperty) + { + this._decorator = new WebInspector.PropertyRevealHighlighter(this, cssProperty); + this._decorator.perform(); + this.update(); + }, + onUndoOrRedoHappened: function() { this.setNode(this.node()); @@ -172,10 +196,8 @@ { if (!editedRule.styleSheetId) return; - for (var block of this._sectionBlocks) { - for (var section of block.sections) - section._styleSheetRuleEdited(editedRule, oldRange, newRange); - } + for (var section of this.allSections()) + section._styleSheetRuleEdited(editedRule, oldRange, newRange); }, /** @@ -186,10 +208,8 @@ { if (!oldMedia.parentStyleSheetId) return; - for (var block of this._sectionBlocks) { - for (var section of block.sections) - section._styleSheetMediaEdited(oldMedia, newMedia); - } + for (var section of this.allSections()) + section._styleSheetMediaEdited(oldMedia, newMedia); }, /** @@ -223,12 +243,10 @@ if (!node) return; - for (var block of this._sectionBlocks) { - for (var section of block.sections) { - if (section.isBlank) - continue; - section.update(section === editedSection); - } + for (var section of this.allSections()) { + if (section.isBlank) + continue; + section.update(section === editedSection); } if (this._filterRegex) @@ -248,14 +266,6 @@ .then(this._innerRebuildUpdate.bind(this)); }, - /** - * @param {function()} callback - */ - runDecoratorAfterUpdate: function(callback) - { - this._decoratorCallback = callback; - }, - _resetCache: function() { delete this._matchedCascadePromise; @@ -395,9 +405,9 @@ this._updateFilter(); this._nodeStylesUpdatedForTest(node, true); - if (this._decoratorCallback) { - this._decoratorCallback(); - delete this._decoratorCallback; + if (this._decorator) { + this._decorator.perform(); + delete this._decorator; } }, @@ -589,11 +599,14 @@ }, /** - * @return {!Array<!WebInspector.SectionBlock>} + * @return {!Array<!WebInspector.StylePropertiesSection>} */ - sectionBlocks: function() + allSections: function() { - return this._sectionBlocks || []; + var sections = []; + for (var block of this._sectionBlocks) + sections = sections.concat(block.sections); + return sections; }, __proto__: WebInspector.ElementsSidebarPane.prototype @@ -1129,7 +1142,7 @@ { var style = this._style; for (var property of style.leadingProperties()) { - var isShorthand = !!WebInspector.CSSMetadata.cssPropertiesMetainfo.longhands(property.name); + var isShorthand = !!style.longhandProperties(property.name).length; var inherited = this.isPropertyInherited(property.name); var overloaded = this._matchedStyles.propertyState(property) === WebInspector.CSSStyleModel.MatchedStyleResult.PropertyState.Overloaded; var item = new WebInspector.StylePropertyTreeElement(this._parentPane, this._matchedStyles, property, isShorthand, inherited, overloaded);
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/computedStyleSidebarPane.css b/third_party/WebKit/Source/devtools/front_end/elements/computedStyleSidebarPane.css index becf8327..84a06ad 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/computedStyleSidebarPane.css +++ b/third_party/WebKit/Source/devtools/front_end/elements/computedStyleSidebarPane.css
@@ -21,6 +21,28 @@ .computed-style-property .property-value { min-width: 5em; + position: relative; +} + +.tree-outline li:hover .goto-source-icon { + display: block; +} + +.goto-source-icon { + -webkit-mask-image: url(Images/toolbarButtonGlyphs.png); + -webkit-mask-position: 0 -120px; + background-color: #5a5a5a; + width: 28px; + height: 24px; + display: none; + position: absolute; + top: -6px; + left: -27px; + transform: scale(0.8); +} + +.goto-source-icon:hover { + background-color: #333; } .computed-style-property-inherited { @@ -53,6 +75,7 @@ .property-trace-value { position: relative; display: inline-block; + margin-left: 2em; } .property-trace-inactive .property-trace-value::before {
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js index 88c2fcf..7b25be3 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js
@@ -565,6 +565,16 @@ * @param {!WebInspector.TracingModel.Event} b * @return {number} */ +WebInspector.TracingModel.Event.compareStartAndEndTime = function (a, b) +{ + return a.startTime - b.startTime || (b.endTime != undefined && a.endTime !== undefined && b.endTime - a.endTime) || 0; +} + +/** + * @param {!WebInspector.TracingModel.Event} a + * @param {!WebInspector.TracingModel.Event} b + * @return {number} + */ WebInspector.TracingModel.Event.orderedCompareStartTime = function (a, b) { // Array.mergeOrdered coalesces objects if comparator returns 0. @@ -839,7 +849,7 @@ WebInspector.TracingModel.Thread.prototype = { tracingComplete: function() { - this._asyncEvents.stableSort(WebInspector.TracingModel.Event.compareStartTime); + this._asyncEvents.stableSort(WebInspector.TracingModel.Event.compareStartAndEndTime); this._events.stableSort(WebInspector.TracingModel.Event.compareStartTime); var phases = WebInspector.TracingModel.Phase; var stack = [];
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js index 3380e85..552503a 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
@@ -382,8 +382,8 @@ _appendThreadTimelineData: function(threadTitle, syncEvents, asyncEvents) { var firstLevel = this._currentLevel; + this._appendAsyncEvents(asyncEvents); this._appendSyncEvents(threadTitle, syncEvents); - this._appendAsyncEvents(this._currentLevel !== firstLevel ? null : threadTitle, asyncEvents); if (this._currentLevel !== firstLevel) ++this._currentLevel; }, @@ -423,6 +423,7 @@ this._appendHeaderRecord(headerName, this._currentLevel++); headerName = null; } + var level = this._currentLevel + openEvents.length; this._appendEvent(e, level); if (flowEventsEnabled) @@ -460,10 +461,9 @@ }, /** - * @param {?string} header * @param {!Map<!WebInspector.AsyncEventGroup, !Array<!WebInspector.TracingModel.AsyncEvent>>} asyncEvents */ - _appendAsyncEvents: function(header, asyncEvents) + _appendAsyncEvents: function(asyncEvents) { var groups = Object.values(WebInspector.TimelineUIUtils.asyncEventGroups()); @@ -478,14 +478,11 @@ var asyncEvent = events[i]; if (!this._isVisible(asyncEvent)) continue; - if (header) { - this._appendHeaderRecord(header, this._currentLevel++); - header = null; - } if (!groupHeaderAppended) { this._appendHeaderRecord(group.title, this._currentLevel++); groupHeaderAppended = true; } + var startTime = asyncEvent.startTime; var level; for (level = 0; level < lastUsedTimeByLevel.length && lastUsedTimeByLevel[level] > startTime; ++level) {} @@ -573,7 +570,7 @@ if (!event) return this._entryIndexToFrame[entryIndex] ? "white" : "#aaa"; if (WebInspector.TracingModel.isAsyncPhase(event.phase)) { - if (event.hasCategory(WebInspector.TimelineModel.Category.Console)) + if (event.hasCategory(WebInspector.TimelineModel.Category.Console) || event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) return this._consoleColorGenerator.colorForID(event.name); var category = WebInspector.TimelineUIUtils.eventStyle(event).category; var color = this._asyncColorByCategory[category.name];
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js index a9d4ddba..831a3cea 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
@@ -106,6 +106,7 @@ TimeStamp: "TimeStamp", ConsoleTime: "ConsoleTime", + UserTiming: "UserTiming", ResourceSendRequest: "ResourceSendRequest", ResourceReceiveResponse: "ResourceReceiveResponse", @@ -173,6 +174,7 @@ WebInspector.TimelineModel.Category = { Console: "blink.console", + UserTiming: "blink.user_timing", LatencyInfo: "latencyInfo" }; @@ -407,6 +409,8 @@ { if (event.hasCategory(WebInspector.TimelineModel.Category.Console)) return WebInspector.TimelineModel.RecordType.ConsoleTime; + if (event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) + return WebInspector.TimelineModel.RecordType.UserTiming; if (event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) return WebInspector.TimelineModel.RecordType.LatencyInfo; return /** @type !WebInspector.TimelineModel.RecordType */ (event.name); @@ -432,7 +436,8 @@ disabledByDefault("devtools.timeline"), disabledByDefault("devtools.timeline.frame"), WebInspector.TracingModel.TopLevelEventCategory, - WebInspector.TimelineModel.Category.Console + WebInspector.TimelineModel.Category.Console, + WebInspector.TimelineModel.Category.UserTiming ]; if (Runtime.experiments.isEnabled("timelineLatencyInfo")) categoriesArray.push(WebInspector.TimelineModel.Category.LatencyInfo) @@ -1261,6 +1266,8 @@ var groups = WebInspector.TimelineUIUtils.asyncEventGroups(); if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.Console)) return groups.console; + if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) + return groups.userTiming; if (asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) { if (!Runtime.experiments.isEnabled("timelineLatencyInfo")) return null;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js index d379445..1f8010c 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
@@ -95,6 +95,7 @@ eventStyles[recordTypes.MarkFirstPaint] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("First paint"), categories["painting"], true); eventStyles[recordTypes.TimeStamp] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Timestamp"), categories["scripting"]); eventStyles[recordTypes.ConsoleTime] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Console Time"), categories["scripting"]); + eventStyles[recordTypes.UserTiming] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("User Timing"), categories["scripting"]); eventStyles[recordTypes.ResourceSendRequest] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send Request"), categories["loading"]); eventStyles[recordTypes.ResourceReceiveResponse] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Response"), categories["loading"]); eventStyles[recordTypes.ResourceFinish] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Finish Loading"), categories["loading"]); @@ -157,7 +158,7 @@ WebInspector.TimelineUIUtils.eventStyle = function(event) { var eventStyles = WebInspector.TimelineUIUtils._initEventStyles(); - if (event.hasCategory(WebInspector.TimelineModel.Category.Console) || event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) + if (event.hasCategory(WebInspector.TimelineModel.Category.Console) || event.hasCategory(WebInspector.TimelineModel.Category.UserTiming) || event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) return { title: event.name, category: WebInspector.TimelineUIUtils.categories()["scripting"] }; var result = eventStyles[event.name]; @@ -1330,7 +1331,7 @@ eventDivider.className += " resources-red-divider"; else if (recordType === recordTypes.MarkFirstPaint) eventDivider.className += " resources-green-divider"; - else if (recordType === recordTypes.TimeStamp || recordType === recordTypes.ConsoleTime) + else if (recordType === recordTypes.TimeStamp || recordType === recordTypes.ConsoleTime || recordType === recordTypes.UserTiming) eventDivider.className += " resources-orange-divider"; else if (recordType === recordTypes.BeginFrame) eventDivider.className += " timeline-frame-divider"; @@ -1413,6 +1414,7 @@ return WebInspector.TimelineUIUtils._asyncEventGroups; WebInspector.TimelineUIUtils._asyncEventGroups = { console: new WebInspector.AsyncEventGroup(WebInspector.UIString("Console")), + userTiming: new WebInspector.AsyncEventGroup(WebInspector.UIString("User Timing")), input: new WebInspector.AsyncEventGroup(WebInspector.UIString("Input Events")) }; return WebInspector.TimelineUIUtils._asyncEventGroups; @@ -1718,7 +1720,7 @@ var title = WebInspector.TimelineUIUtils.eventTitle(event) - if (event.hasCategory(WebInspector.TimelineModel.Category.Console)) { + if (event.hasCategory(WebInspector.TimelineModel.Category.Console) || event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) { return { title: title, dashStyle: tallMarkerDashStyle,
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js index a6e2903d..f4c16c9 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
@@ -398,8 +398,8 @@ return this.pageUpKeyPressed(); case "PageDown": return this.pageDownKeyPressed(); - case "Enter": - return this.enterKeyPressed(); + case "U+0009": // Tab + return this.tabKeyPressed(); } return false; }, @@ -441,7 +441,7 @@ /** * @return {boolean} */ - enterKeyPressed: function() + tabKeyPressed: function() { var hasSelectedItem = !!this._selectedElement; this.acceptSuggestion();
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js index f882cfd0..06bdb2a 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
@@ -285,9 +285,6 @@ delete this._needUpdateAutocomplete; switch (event.keyIdentifier) { - case "U+0009": // Tab - handled = this.tabKeyPressed(event); - break; case "Left": case "Home": this._removeSuggestionAids();
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/toolbar.css b/third_party/WebKit/Source/devtools/front_end/ui/toolbar.css index efc1ede..b2bcdd4 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/toolbar.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/toolbar.css
@@ -454,6 +454,10 @@ -webkit-mask-position: -224px -144px; } +.goto-source-toolbar-item.toolbar-glyph { + -webkit-mask-position: 0 -120px; +} + .toolbar-state-on .record-toolbar-item.toolbar-glyph, .toolbar-state-active .filter-toolbar-item.toolbar-glyph, .toolbar-state-active .block-toolbar-item.toolbar-glyph {
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp index c4cfbc1..8ac1b847 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -41,9 +41,11 @@ #include "core/editing/VisibleUnits.h" #include "core/editing/iterators/CharacterIterator.h" #include "core/editing/iterators/TextIterator.h" +#include "core/frame/FrameOwner.h" #include "core/frame/FrameView.h" #include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" +#include "core/html/HTMLFrameOwnerElement.h" #include "core/html/HTMLImageElement.h" #include "core/html/HTMLLabelElement.h" #include "core/html/HTMLOptionElement.h" @@ -346,17 +348,6 @@ // Check object role or purpose. // -bool AXLayoutObject::isAttachment() const -{ - LayoutBoxModelObject* layoutObject = layoutBoxModelObject(); - if (!layoutObject) - return false; - // Widgets are the replaced elements that we represent to AX as attachments - bool isLayoutPart = layoutObject->isLayoutPart(); - ASSERT(!isLayoutPart || (layoutObject->isAtomicInlineLevel() && !isImage())); - return isLayoutPart; -} - static bool isLinkable(const AXObject& object) { if (!object.layoutObject()) @@ -575,9 +566,9 @@ return true; } - // TODO: we should refactor this - but right now this is necessary to make - // sure scroll areas stay in the tree. - if (isAttachment()) + // A LayoutPart is an iframe element or embedded object element or something like + // that. We don't want to ignore those. + if (m_layoutObject->isLayoutPart()) return false; // find out if this element is inside of a label element. @@ -656,6 +647,9 @@ if (hasContentEditableAttributeSet()) return false; + if (roleValue() == AbbrRole) + return false; + // List items play an important role in defining the structure of lists. They should not be ignored. if (roleValue() == ListItemRole) return false; @@ -1526,9 +1520,16 @@ if (parentObj) return axObjectCache().getOrCreate(parentObj); - // WebArea's parent should be the scroll view containing it. - if (isWebArea()) - return axObjectCache().getOrCreate(m_layoutObject->frame()->view()); + // A WebArea's parent should be the containing frame (if local) or page popup owner. + if (isWebArea()) { + LocalFrame* frame = m_layoutObject->frame(); + if (frame->owner() && frame->owner()->isLocal()) { + HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(frame->owner()); + if (owner && owner->layoutObject()) + return axObjectCache().getOrCreate(owner->layoutObject()); + } + return axObjectCache().getOrCreate(frame->pagePopupOwner()); + } return 0; } @@ -1552,9 +1553,16 @@ if (parentObj) return axObjectCache().get(parentObj); - // WebArea's parent should be the scroll view containing it. - if (isWebArea()) - return axObjectCache().get(m_layoutObject->frame()->view()); + // A WebArea's parent should be the containing frame (if local) or page popup owner. + if (isWebArea()) { + LocalFrame* frame = m_layoutObject->frame(); + if (frame->owner() && frame->owner()->isLocal()) { + HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(frame->owner()); + if (owner && owner->layoutObject()) + return axObjectCache().get(owner->layoutObject()); + } + return axObjectCache().get(frame->pagePopupOwner()); + } return 0; } @@ -1643,7 +1651,7 @@ } addHiddenChildren(); - addAttachmentChildren(); + addFrameChildren(); addPopupChildren(); addImageMapChildren(); addTextFieldChildren(); @@ -1756,13 +1764,6 @@ return 0; } -Widget* AXLayoutObject::widgetForAttachmentView() const -{ - if (!isAttachment()) - return 0; - return toLayoutPart(m_layoutObject)->widget(); -} - // // Functions that retrieve the current selection. // @@ -2439,19 +2440,22 @@ AXNodeObject::addChildren(); } -void AXLayoutObject::addAttachmentChildren() +void AXLayoutObject::addFrameChildren() { - if (!isAttachment()) + if (!m_layoutObject || !m_layoutObject->isLayoutPart()) return; - // FrameView's need to be inserted into the AX hierarchy when encountered. - Widget* widget = widgetForAttachmentView(); + Widget* widget = toLayoutPart(m_layoutObject)->widget(); if (!widget || !widget->isFrameView()) return; - AXObject* axWidget = axObjectCache().getOrCreate(widget); - if (!axWidget->accessibilityIsIgnored()) - m_children.append(axWidget); + Document* doc = toFrameView(widget)->frame().document(); + if (!doc || !doc->layoutView()) + return; + + AXObject* axChildFrame = axObjectCache().getOrCreate(doc); + if (!axChildFrame->accessibilityIsIgnored()) + m_children.append(axChildFrame); } void AXLayoutObject::addPopupChildren()
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h index d207fe17..3effa1e 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h
@@ -81,7 +81,6 @@ bool isAXLayoutObject() const override { return true; } // Check object role or purpose. - bool isAttachment() const override; bool isEditable() const override; bool isRichlyEditable() const override; bool isLinked() const override; @@ -181,7 +180,6 @@ Document* document() const override; FrameView* documentFrameView() const override; Element* anchorElement() const override; - Widget* widgetForAttachmentView() const override; void setValue(const String&) override; @@ -210,7 +208,7 @@ void addTextFieldChildren(); void addImageMapChildren(); void addCanvasChildren(); - void addAttachmentChildren(); + void addFrameChildren(); void addPopupChildren(); void addRemoteSVGChildren(); void addInlineTextBoxChildren(bool force);
diff --git a/third_party/WebKit/Source/modules/accessibility/AXMenuListOption.cpp b/third_party/WebKit/Source/modules/accessibility/AXMenuListOption.cpp index 79b691f1..f8b18a7 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXMenuListOption.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXMenuListOption.cpp
@@ -49,6 +49,18 @@ AXMockObject::detach(); } +AccessibilityRole AXMenuListOption::roleValue() const +{ + const AtomicString& ariaRole = getAttribute(roleAttr); + if (ariaRole.isEmpty()) + return MenuListOptionRole; + + AccessibilityRole role = ariaRoleToWebCoreRole(ariaRole); + if (role) + return role; + return MenuListOptionRole; +} + Element* AXMenuListOption::actionElement() const { return m_element;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXMenuListOption.h b/third_party/WebKit/Source/modules/accessibility/AXMenuListOption.h index 52f585ee..2ca40f3c 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXMenuListOption.h +++ b/third_party/WebKit/Source/modules/accessibility/AXMenuListOption.h
@@ -47,7 +47,7 @@ Node* node() const override { return m_element; } void detach() override; bool isDetached() const override { return !m_element; } - AccessibilityRole roleValue() const override { return MenuListOptionRole; } + AccessibilityRole roleValue() const override; bool canHaveChildren() const override { return false; } Element* actionElement() const override;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp index 28784db8..08f5888 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -430,6 +430,9 @@ if (isHTMLFormElement(*node())) return FormRole; + if (node()->hasTagName(abbrTag)) + return AbbrRole; + if (node()->hasTagName(articleTag)) return ArticleRole;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp index 2a0e968b..906d4e7 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp
@@ -135,6 +135,7 @@ const InternalRoleEntry internalRoles[] = { { UnknownRole, "Unknown" }, + { AbbrRole, "Abbr" }, { AlertDialogRole, "AlertDialog" }, { AlertRole, "Alert" }, { AnnotationRole, "Annotation" }, @@ -1109,18 +1110,16 @@ AXObject* AXObject::elementAccessibilityHitTest(const IntPoint& point) const { - // Send the hit test back into the sub-frame if necessary. - if (isAttachment()) { - Widget* widget = widgetForAttachmentView(); - // Normalize the point for the widget's bounds. - if (widget && widget->isFrameView()) - return axObjectCache().getOrCreate(widget)->accessibilityHitTest(IntPoint(point - widget->frameRect().location())); - } - - // Check if there are any mock elements that need to be handled. + // Check if there are any mock elements or child frames that need to be handled. for (const auto& child : m_children) { if (child->isMockObject() && child->elementRect().contains(point)) return child->elementAccessibilityHitTest(point); + + if (child->isWebArea()) { + FrameView* frameView = child->documentFrameView(); + if (frameView) + return child->accessibilityHitTest(IntPoint(point - frameView->frameRect().location())); + } } return const_cast<AXObject*>(this); @@ -1427,7 +1426,7 @@ ScrollableArea* scrollableArea = 0; while (scrollParent) { scrollableArea = scrollParent->getScrollableAreaIfScrollable(); - if (scrollableArea && !scrollParent->isAXScrollView()) + if (scrollableArea) break; scrollParent = scrollParent->parentObject(); } @@ -1476,7 +1475,7 @@ HeapVector<Member<const AXObject>> objects; AXObject* parentObject; for (parentObject = this->parentObject(); parentObject; parentObject = parentObject->parentObject()) { - if (parentObject->getScrollableAreaIfScrollable() && !parentObject->isAXScrollView()) + if (parentObject->getScrollableAreaIfScrollable()) objects.prepend(parentObject); } objects.append(this);
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.h b/third_party/WebKit/Source/modules/accessibility/AXObject.h index a88e925c..94b694d 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.h
@@ -51,12 +51,12 @@ class Node; class LayoutObject; class ScrollableArea; -class Widget; typedef unsigned AXID; enum AccessibilityRole { UnknownRole = 0, + AbbrRole, // No mapping to ARIA role AlertDialogRole, AlertRole, AnnotationRole, // No mapping to ARIA role @@ -547,8 +547,6 @@ virtual bool isAXLayoutObject() const { return false; } virtual bool isAXListBox() const { return false; } virtual bool isAXListBoxOption() const { return false; } - virtual bool isAXScrollbar() const { return false; } - virtual bool isAXScrollView() const { return false; } virtual bool isAXSVGRoot() const { return false; } // Check object role or purpose. @@ -557,7 +555,6 @@ virtual bool isARIATreeGridRow() const { return false; } virtual bool isAXTable() const { return false; } virtual bool isAnchor() const { return false; } - virtual bool isAttachment() const { return false; } bool isButton() const; bool isCanvas() const { return roleValue() == CanvasRole; } bool isCheckbox() const { return roleValue() == CheckBoxRole; } @@ -833,7 +830,6 @@ virtual FrameView* documentFrameView() const; virtual Element* anchorElement() const { return 0; } virtual Element* actionElement() const { return 0; } - virtual Widget* widgetForAttachmentView() const { return 0; } String language() const; bool hasAttribute(const QualifiedName&) const; const AtomicString& getAttribute(const QualifiedName&) const;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp index a6133ee..314bcaa 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
@@ -66,8 +66,6 @@ #include "modules/accessibility/AXMenuListPopup.h" #include "modules/accessibility/AXProgressIndicator.h" #include "modules/accessibility/AXSVGRoot.h" -#include "modules/accessibility/AXScrollView.h" -#include "modules/accessibility/AXScrollbar.h" #include "modules/accessibility/AXSlider.h" #include "modules/accessibility/AXSpinButton.h" #include "modules/accessibility/AXTable.h" @@ -185,19 +183,6 @@ return obj; } -AXObject* AXObjectCacheImpl::get(Widget* widget) -{ - if (!widget) - return 0; - - AXID axID = m_widgetObjectMapping.get(widget); - ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); - if (!axID) - return 0; - - return m_objects.get(axID); -} - AXObject* AXObjectCacheImpl::get(LayoutObject* layoutObject) { if (!layoutObject) @@ -352,44 +337,6 @@ return AXInlineTextBox::create(inlineTextBox, *this); } -AXObject* AXObjectCacheImpl::getOrCreate(Widget* widget) -{ - if (!widget) - return 0; - - if (AXObject* obj = get(widget)) - return obj; - - AXObject* newObj = nullptr; - if (widget->isFrameView()) { - FrameView* frameView = toFrameView(widget); - - // Don't create an AXScrollView for a FrameView that isn't attached to a frame, - // for example if it's in the process of being disposed. - if (frameView->frame().view() != frameView || !frameView->layoutView()) - return 0; - - newObj = AXScrollView::create(toFrameView(widget), *this); - } else if (widget->isScrollbar()) { - newObj = AXScrollbar::create(toScrollbar(widget), *this); - } - - // Will crash later if we have two objects for the same widget. - ASSERT(!get(widget)); - - // Catch the case if an (unsupported) widget type is used. Only FrameView and ScrollBar are supported now. - ASSERT(newObj); - if (!newObj) - return 0; - - getAXID(newObj); - - m_widgetObjectMapping.set(widget, newObj->axObjectID()); - m_objects.set(newObj->axObjectID(), newObj); - newObj->init(); - return newObj; -} - AXObject* AXObjectCacheImpl::getOrCreate(Node* node) { if (!node) @@ -478,7 +425,7 @@ if (!accessibilityEnabled()) return 0; - return getOrCreate(m_document->view()); + return getOrCreate(m_document); } AXObject* AXObjectCacheImpl::getOrCreate(AccessibilityRole role) @@ -565,16 +512,6 @@ } } -void AXObjectCacheImpl::remove(Widget* view) -{ - if (!view) - return; - - AXID axID = m_widgetObjectMapping.get(view); - remove(axID); - m_widgetObjectMapping.remove(view); -} - void AXObjectCacheImpl::remove(AbstractInlineTextBox* inlineTextBox) { if (!inlineTextBox) @@ -971,18 +908,6 @@ toAXListBox(obj)->activeIndexChanged(); } -void AXObjectCacheImpl::handleScrollbarUpdate(FrameView* view) -{ - if (!view) - return; - - // We don't want to create a scroll view from this method, only update an existing one. - if (AXObject* scrollViewObject = get(view)) { - m_modificationCount++; - scrollViewObject->updateChildrenIfNecessary(); - } -} - void AXObjectCacheImpl::handleLayoutComplete(LayoutObject* layoutObject) { if (!layoutObject) @@ -1164,17 +1089,6 @@ void AXObjectCacheImpl::postPlatformNotification(AXObject* obj, AXNotification notification) { - if (obj && obj->isAXScrollbar() && notification == AXValueChanged) { - // Send document value changed on scrollbar value changed notification. - Scrollbar* scrollBar = toAXScrollbar(obj)->scrollbar(); - if (!scrollBar || !scrollBar->parent() || !scrollBar->parent()->isFrameView()) - return; - Document* document = toFrameView(scrollBar->parent())->frame().document(); - if (document != document->topDocument()) - return; - obj = get(document->layoutView()); - } - if (!obj || !obj->document() || !obj->documentFrameView() || !obj->documentFrameView()->frame().page()) return; @@ -1279,10 +1193,7 @@ void AXObjectCacheImpl::handleScrollPositionChanged(FrameView* frameView) { - // Prefer to fire the scroll position changed event on the frame view's child web area, if possible. - AXObject* targetAXObject = getOrCreate(frameView); - if (targetAXObject && !targetAXObject->children().isEmpty()) - targetAXObject = targetAXObject->children()[0].get(); + AXObject* targetAXObject = getOrCreate(frameView->frame().document()); postPlatformNotification(targetAXObject, AXScrollPositionChanged); } @@ -1328,7 +1239,6 @@ { #if ENABLE(OILPAN) visitor->trace(m_document); - visitor->trace(m_widgetObjectMapping); visitor->trace(m_nodeObjectMapping); #endif
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.h b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.h index 73ad0f3..ebc8efaf 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.h +++ b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.h
@@ -43,7 +43,6 @@ class AbstractInlineTextBox; class HTMLAreaElement; class FrameView; -class Widget; // This class should only be used from inside the accessibility directory. class MODULES_EXPORT AXObjectCacheImpl : public AXObjectCache { @@ -69,7 +68,6 @@ void remove(LayoutObject*) override; void remove(Node*) override; - void remove(Widget*) override; void remove(AbstractInlineTextBox*) override; const Element* rootAXEditableElement(const Node*) override; @@ -100,7 +98,6 @@ void handleScrollPositionChanged(LayoutObject*) override; // Called when scroll bars are added / removed (as the view resizes). - void handleScrollbarUpdate(FrameView*) override; void handleLayoutComplete(LayoutObject*) override; void handleScrolledToAnchor(const Node* anchorNode) override; @@ -118,14 +115,12 @@ // used for objects without backing elements AXObject* getOrCreate(AccessibilityRole); AXObject* getOrCreate(LayoutObject*); - AXObject* getOrCreate(Widget*); AXObject* getOrCreate(Node*); AXObject* getOrCreate(AbstractInlineTextBox*); // will only return the AXObject if it already exists AXObject* get(Node*); AXObject* get(LayoutObject*); - AXObject* get(Widget*); AXObject* get(AbstractInlineTextBox*); AXObject* firstAccessibleObjectFromNode(const Node*); @@ -195,7 +190,6 @@ // LayoutObject and AbstractInlineTextBox are not on the Oilpan heap so we // do not use HeapHashMap for those mappings. HashMap<LayoutObject*, AXID> m_layoutObjectMapping; - WillBeHeapHashMap<RawPtrWillBeMember<Widget>, AXID> m_widgetObjectMapping; WillBeHeapHashMap<RawPtrWillBeMember<Node>, AXID> m_nodeObjectMapping; HashMap<AbstractInlineTextBox*, AXID> m_inlineTextBoxObjectMapping; int m_modificationCount;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXScrollView.cpp b/third_party/WebKit/Source/modules/accessibility/AXScrollView.cpp deleted file mode 100644 index eb1478d5..0000000 --- a/third_party/WebKit/Source/modules/accessibility/AXScrollView.cpp +++ /dev/null
@@ -1,260 +0,0 @@ -/* - * Copyright (C) 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "modules/accessibility/AXScrollView.h" - -#include "core/frame/FrameView.h" -#include "core/frame/LocalFrame.h" -#include "core/html/HTMLFrameOwnerElement.h" -#include "modules/accessibility/AXObjectCacheImpl.h" -#include "modules/accessibility/AXScrollbar.h" - -namespace blink { - -AXScrollView::AXScrollView(FrameView* view, AXObjectCacheImpl& axObjectCache) - : AXObject(axObjectCache) - , m_scrollView(view) - , m_childrenDirty(false) -{ -} - -AXScrollView::~AXScrollView() -{ - ASSERT(!m_scrollView); -} - -void AXScrollView::detach() -{ - AXObject::detach(); - m_scrollView = nullptr; -} - -AXScrollView* AXScrollView::create(FrameView* view, AXObjectCacheImpl& axObjectCache) -{ - return new AXScrollView(view, axObjectCache); -} - -AXObject* AXScrollView::scrollBar(AccessibilityOrientation orientation) -{ - updateScrollbars(); - - switch (orientation) { - case AccessibilityOrientationVertical: - return m_verticalScrollbar ? m_verticalScrollbar.get() : 0; - case AccessibilityOrientationHorizontal: - return m_horizontalScrollbar ? m_horizontalScrollbar.get() : 0; - case AccessibilityOrientationUndefined: - return 0; - } - - return 0; -} - -// If this is WebKit1 then the native scroll view needs to return the -// AX information (because there are no scroll bar children in the FrameView object in WK1). -// In WebKit2, the FrameView object will return the AX information (because there are no platform widgets). -bool AXScrollView::isAttachment() const -{ - return false; -} - -Widget* AXScrollView::widgetForAttachmentView() const -{ - return m_scrollView; -} - -void AXScrollView::updateChildrenIfNecessary() -{ - if (m_childrenDirty) - clearChildren(); - - if (!m_haveChildren) - addChildren(); - - updateScrollbars(); -} - -void AXScrollView::updateScrollbars() -{ - if (!m_scrollView) - return; - - if (m_scrollView->horizontalScrollbar() && !m_horizontalScrollbar) { - m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar()); - } else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) { - removeChildScrollbar(m_horizontalScrollbar.get()); - m_horizontalScrollbar = nullptr; - } - - if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar) { - m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar()); - } else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) { - removeChildScrollbar(m_verticalScrollbar.get()); - m_verticalScrollbar = nullptr; - } -} - -void AXScrollView::removeChildScrollbar(AXObject* scrollbar) -{ - size_t pos = m_children.find(scrollbar); - if (pos != kNotFound) { - m_children[pos]->detachFromParent(); - m_children.remove(pos); - } -} - -AXScrollbar* AXScrollView::addChildScrollbar(Scrollbar* scrollbar) -{ - if (!scrollbar) - return 0; - - AXScrollbar* scrollBarObject = toAXScrollbar(axObjectCache().getOrCreate(scrollbar)); - scrollBarObject->setParent(this); - m_children.append(scrollBarObject); - return scrollBarObject; -} - -void AXScrollView::clearChildren() -{ - AXObject::clearChildren(); - m_verticalScrollbar = nullptr; - m_horizontalScrollbar = nullptr; -} - -bool AXScrollView::computeAccessibilityIsIgnored(IgnoredReasons* ignoredReasons) const -{ - // We just want to match whatever's returned by our web area, which is a child of this - // object. Normally cached attribute values may only search up the tree. We can't just - // call accessibilityIsIgnored on the web area, because the web area may search up its - // ancestors and call this function recursively, and we'd loop until a stack overflow. - - // Instead, we first update the cached accessibilityIsIgnored value for this node to - // false, call accessibilityIsIgnored on the web area, then return the mathcing value. - m_cachedIsIgnored = false; - m_lastModificationCount = axObjectCache().modificationCount(); - - AXObject* webArea = webAreaObject(); - if (!webArea) - return true; - - if (!webArea->accessibilityIsIgnored()) - return false; - - if (ignoredReasons) - return webArea->computeAccessibilityIsIgnored(ignoredReasons); - - return true; -} - -void AXScrollView::addChildren() -{ - ASSERT(!isDetached()); - ASSERT(!m_haveChildren); - m_haveChildren = true; - - AXObject* webArea = webAreaObject(); - if (webArea && !webArea->accessibilityIsIgnored()) - m_children.append(webArea); - - updateScrollbars(); -} - -AXObject* AXScrollView::webAreaObject() const -{ - if (!m_scrollView || !m_scrollView->isFrameView()) - return 0; - - Document* doc = m_scrollView->frame().document(); - if (!doc || !doc->layoutView()) - return 0; - - return axObjectCache().getOrCreate(doc); -} - -AXObject* AXScrollView::accessibilityHitTest(const IntPoint& point) const -{ - AXObject* webArea = webAreaObject(); - if (!webArea) - return 0; - - if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(point)) - return m_horizontalScrollbar.get(); - if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point)) - return m_verticalScrollbar.get(); - - return webArea->accessibilityHitTest(point); -} - -LayoutRect AXScrollView::elementRect() const -{ - if (!m_scrollView) - return LayoutRect(); - - return LayoutRect(m_scrollView->frameRect()); -} - -FrameView* AXScrollView::documentFrameView() const -{ - if (!m_scrollView || !m_scrollView->isFrameView()) - return 0; - - return m_scrollView; -} - -AXObject* AXScrollView::computeParent() const -{ - ASSERT(!isDetached()); - if (!m_scrollView || !m_scrollView->isFrameView()) - return 0; - - // FIXME: Broken for OOPI. - HTMLFrameOwnerElement* owner = m_scrollView->frame().deprecatedLocalOwner(); - if (owner && owner->layoutObject()) - return axObjectCache().getOrCreate(owner); - - return axObjectCache().getOrCreate(m_scrollView->frame().pagePopupOwner()); -} - -AXObject* AXScrollView::computeParentIfExists() const -{ - if (!m_scrollView || !m_scrollView->isFrameView()) - return 0; - - HTMLFrameOwnerElement* owner = m_scrollView->frame().deprecatedLocalOwner(); - if (owner && owner->layoutObject()) - return axObjectCache().get(owner); - - return axObjectCache().get(m_scrollView->frame().pagePopupOwner()); -} - -DEFINE_TRACE(AXScrollView) -{ - visitor->trace(m_scrollView); - visitor->trace(m_horizontalScrollbar); - visitor->trace(m_verticalScrollbar); - AXObject::trace(visitor); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/modules/accessibility/AXScrollView.h b/third_party/WebKit/Source/modules/accessibility/AXScrollView.h deleted file mode 100644 index 9612355..0000000 --- a/third_party/WebKit/Source/modules/accessibility/AXScrollView.h +++ /dev/null
@@ -1,83 +0,0 @@ -/* - * Copyright (C) 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef AXScrollView_h -#define AXScrollView_h - -#include "modules/accessibility/AXObject.h" - -namespace blink { - -class AXObjectCacheImpl; -class AXScrollbar; -class Scrollbar; -class FrameView; - -class AXScrollView final : public AXObject { -public: - static AXScrollView* create(FrameView*, AXObjectCacheImpl&); - AccessibilityRole roleValue() const override { return ScrollAreaRole; } - - ~AXScrollView() override; - DECLARE_VIRTUAL_TRACE(); - void detach() override; - -private: - AXScrollView(FrameView*, AXObjectCacheImpl&); - - bool computeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override; - bool isAXScrollView() const override { return true; } - bool isEnabled() const override { return true; } - - bool isAttachment() const override; - Widget* widgetForAttachmentView() const override; - - AXObject* scrollBar(AccessibilityOrientation) override; - void addChildren() override; - void clearChildren() override; - AXObject* accessibilityHitTest(const IntPoint&) const override; - void updateChildrenIfNecessary() override; - void setNeedsToUpdateChildren() override { m_childrenDirty = true; } - void updateScrollbars(); - - FrameView* documentFrameView() const override; - LayoutRect elementRect() const override; - AXObject* computeParent() const override; - AXObject* computeParentIfExists() const override; - - AXObject* webAreaObject() const; - AXObject* rawFirstChild() const override { return webAreaObject(); } - AXScrollbar* addChildScrollbar(Scrollbar*); - void removeChildScrollbar(AXObject*); - - RawPtrWillBeMember<FrameView> m_scrollView; - Member<AXObject> m_horizontalScrollbar; - Member<AXObject> m_verticalScrollbar; - bool m_childrenDirty; -}; - -} // namespace blink - -#endif // AXScrollView_h
diff --git a/third_party/WebKit/Source/modules/accessibility/AXScrollbar.cpp b/third_party/WebKit/Source/modules/accessibility/AXScrollbar.cpp deleted file mode 100644 index 3f7bf170..0000000 --- a/third_party/WebKit/Source/modules/accessibility/AXScrollbar.cpp +++ /dev/null
@@ -1,124 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "modules/accessibility/AXScrollbar.h" - -#include "modules/accessibility/AXObjectCacheImpl.h" -#include "platform/scroll/ScrollableArea.h" -#include "platform/scroll/Scrollbar.h" - -namespace blink { - -AXScrollbar::AXScrollbar(Scrollbar* scrollbar, AXObjectCacheImpl& axObjectCache) - : AXMockObject(axObjectCache) - , m_scrollbar(scrollbar) -{ - ASSERT(scrollbar); -} - -AXScrollbar::~AXScrollbar() -{ - ASSERT(!m_scrollbar); -} - -void AXScrollbar::detachFromParent() -{ - m_scrollbar = nullptr; - AXMockObject::detachFromParent(); -} - -AXScrollbar* AXScrollbar::create(Scrollbar* scrollbar, AXObjectCacheImpl& axObjectCache) -{ - return new AXScrollbar(scrollbar, axObjectCache); -} - -LayoutRect AXScrollbar::elementRect() const -{ - if (!m_scrollbar) - return LayoutRect(); - - return LayoutRect(m_scrollbar->frameRect()); -} - -Document* AXScrollbar::document() const -{ - AXObject* parent = parentObject(); - if (!parent) - return 0; - return parent->document(); -} - -AccessibilityOrientation AXScrollbar::orientation() const -{ - if (!m_scrollbar) - return AccessibilityOrientationHorizontal; - - if (m_scrollbar->orientation() == HorizontalScrollbar) - return AccessibilityOrientationHorizontal; - if (m_scrollbar->orientation() == VerticalScrollbar) - return AccessibilityOrientationVertical; - - return AccessibilityOrientationVertical; -} - -bool AXScrollbar::isEnabled() const -{ - if (!m_scrollbar) - return false; - return m_scrollbar->enabled(); -} - -float AXScrollbar::valueForRange() const -{ - if (!m_scrollbar) - return 0; - - return m_scrollbar->currentPos() / m_scrollbar->maximum(); -} - -void AXScrollbar::setValue(float value) -{ - if (!m_scrollbar) - return; - - if (!m_scrollbar->scrollableArea()) - return; - - float newValue = value * m_scrollbar->maximum(); - - // TODO(bokan): This should potentially be a UserScroll. - m_scrollbar->scrollableArea()->setScrollPositionSingleAxis(m_scrollbar->orientation(), newValue, ProgrammaticScroll); -} - -DEFINE_TRACE(AXScrollbar) -{ - visitor->trace(m_scrollbar); - AXMockObject::trace(visitor); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/modules/accessibility/AXScrollbar.h b/third_party/WebKit/Source/modules/accessibility/AXScrollbar.h deleted file mode 100644 index 97cc22a..0000000 --- a/third_party/WebKit/Source/modules/accessibility/AXScrollbar.h +++ /dev/null
@@ -1,74 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef AXScrollbar_h -#define AXScrollbar_h - -#include "modules/accessibility/AXMockObject.h" - -namespace blink { - -class AXObjectCacheImpl; -class Scrollbar; - -class AXScrollbar final : public AXMockObject { -public: - static AXScrollbar* create(Scrollbar*, AXObjectCacheImpl&); - ~AXScrollbar() override; - DECLARE_VIRTUAL_TRACE(); - - Scrollbar* scrollbar() const { return m_scrollbar.get(); } - -private: - AXScrollbar(Scrollbar*, AXObjectCacheImpl&); - - void detachFromParent() override; - - bool canSetValueAttribute() const override { return true; } - - bool isAXScrollbar() const override { return true; } - LayoutRect elementRect() const override; - - AccessibilityRole roleValue() const override { return ScrollBarRole; } - AccessibilityOrientation orientation() const override; - Document* document() const override; - - bool isEnabled() const override; - - // Assumes float [0..1] - void setValue(float) override; - float valueForRange() const override; - - RefPtrWillBeMember<Scrollbar> m_scrollbar; -}; - -DEFINE_AX_OBJECT_TYPE_CASTS(AXScrollbar, isAXScrollbar()); - -} // namespace blink - -#endif // AXScrollbar_h
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi index 24620eb..47a7a4d6 100644 --- a/third_party/WebKit/Source/modules/modules.gypi +++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -733,10 +733,6 @@ 'accessibility/AXProgressIndicator.h', 'accessibility/AXSVGRoot.cpp', 'accessibility/AXSVGRoot.h', - 'accessibility/AXScrollView.cpp', - 'accessibility/AXScrollView.h', - 'accessibility/AXScrollbar.cpp', - 'accessibility/AXScrollbar.h', 'accessibility/AXSlider.cpp', 'accessibility/AXSlider.h', 'accessibility/AXSpinButton.cpp',
diff --git a/third_party/WebKit/Source/platform/transforms/TransformOperations.cpp b/third_party/WebKit/Source/platform/transforms/TransformOperations.cpp index 36d13311..6c428073 100644 --- a/third_party/WebKit/Source/platform/transforms/TransformOperations.cpp +++ b/third_party/WebKit/Source/platform/transforms/TransformOperations.cpp
@@ -25,6 +25,7 @@ #include "platform/geometry/FloatBox.h" #include "platform/transforms/IdentityTransformOperation.h" #include "platform/transforms/InterpolatedTransformOperation.h" +#include "platform/transforms/Matrix3DTransformOperation.h" #include "platform/transforms/RotateTransformOperation.h" #include <algorithm> @@ -90,11 +91,18 @@ return result; } -TransformOperations TransformOperations::blendByUsingMatrixInterpolation(const TransformOperations& from, double progress) const +PassRefPtr<TransformOperation> TransformOperations::blendByUsingMatrixInterpolation(const TransformOperations& from, double progress) const { - TransformOperations result; - result.operations().append(InterpolatedTransformOperation::create(from, *this, progress)); - return result; + if (dependsOnBoxSize() || from.dependsOnBoxSize()) + return InterpolatedTransformOperation::create(from, *this, progress); + + // Evaluate blended matrix here to avoid creating a nested data structure of unbounded depth. + TransformationMatrix fromTransform; + TransformationMatrix toTransform; + from.apply(FloatSize(), fromTransform); + apply(FloatSize(), toTransform); + toTransform.blend(fromTransform, progress); + return Matrix3DTransformOperation::create(toTransform); } TransformOperations TransformOperations::blend(const TransformOperations& from, double progress) const @@ -106,7 +114,9 @@ if (!from.size() || !size() || from.operationsMatch(*this)) return blendByMatchingOperations(from, progress); - return blendByUsingMatrixInterpolation(from, progress); + TransformOperations result; + result.operations().append(blendByUsingMatrixInterpolation(from, progress)); + return result; } static void findCandidatesInPlane(double px, double py, double nz, double* candidates, int* numCandidates)
diff --git a/third_party/WebKit/Source/platform/transforms/TransformOperations.h b/third_party/WebKit/Source/platform/transforms/TransformOperations.h index c7ec2fd..75090bc 100644 --- a/third_party/WebKit/Source/platform/transforms/TransformOperations.h +++ b/third_party/WebKit/Source/platform/transforms/TransformOperations.h
@@ -90,7 +90,7 @@ bool blendedBoundsForBox(const FloatBox&, const TransformOperations& from, const double& minProgress, const double& maxProgress, FloatBox* bounds) const; TransformOperations blendByMatchingOperations(const TransformOperations& from, const double& progress) const; - TransformOperations blendByUsingMatrixInterpolation(const TransformOperations& from, double progress) const; + PassRefPtr<TransformOperation> blendByUsingMatrixInterpolation(const TransformOperations& from, double progress) const; TransformOperations blend(const TransformOperations& from, double progress) const; TransformOperations add(const TransformOperations& addend) const; TransformOperations zoom(double factor) const;
diff --git a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp index a4432a4f..a0b74d9 100644 --- a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp +++ b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
@@ -178,6 +178,7 @@ STATIC_ASSERT_MATCHING_ENUM(WebAXEventTextRemoved, AXObjectCache::AXTextRemoved); STATIC_ASSERT_MATCHING_ENUM(WebAXEventValueChanged, AXObjectCache::AXValueChanged); +STATIC_ASSERT_MATCHING_ENUM(WebAXRoleAbbr, AbbrRole); STATIC_ASSERT_MATCHING_ENUM(WebAXRoleAlertDialog, AlertDialogRole); STATIC_ASSERT_MATCHING_ENUM(WebAXRoleAlert, AlertRole); STATIC_ASSERT_MATCHING_ENUM(WebAXRoleAnnotation, AnnotationRole);
diff --git a/third_party/WebKit/Source/web/ExternalPopupMenu.cpp b/third_party/WebKit/Source/web/ExternalPopupMenu.cpp index 939127f..e1eafc7 100644 --- a/third_party/WebKit/Source/web/ExternalPopupMenu.cpp +++ b/third_party/WebKit/Source/web/ExternalPopupMenu.cpp
@@ -30,12 +30,14 @@ #include "web/ExternalPopupMenu.h" +#include "core/dom/ExecutionContextTask.h" #include "core/dom/NodeComputedStyle.h" #include "core/frame/FrameHost.h" #include "core/frame/FrameView.h" #include "core/frame/LocalFrame.h" #include "core/html/HTMLOptionElement.h" #include "core/html/HTMLSelectElement.h" +#include "core/layout/LayoutBox.h" #include "core/page/Page.h" #include "core/style/ComputedStyle.h" #include "platform/geometry/FloatQuad.h" @@ -71,11 +73,10 @@ PopupMenu::trace(visitor); } -void ExternalPopupMenu::show(const FloatQuad& controlPosition, const IntSize&, int index) +bool ExternalPopupMenu::showInternal() { - IntRect rect(controlPosition.enclosingBoundingBox()); - // WebCore reuses the PopupMenu of an element. - // For simplicity, we do recreate the actual external popup everytime. + // Blink core reuses the PopupMenu of an element. For simplicity, we do + // recreate the actual external popup everytime. if (m_webExternalPopupMenu) { m_webExternalPopupMenu->close(); m_webExternalPopupMenu = 0; @@ -84,31 +85,46 @@ WebPopupMenuInfo info; getPopupMenuInfo(info, *m_ownerElement); if (info.items.isEmpty()) - return; + return false; WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(m_localFrame.get()); m_webExternalPopupMenu = webframe->client()->createExternalPopupMenu(info, this); if (m_webExternalPopupMenu) { + LayoutObject* layoutObject = m_ownerElement->layoutObject(); + if (!layoutObject || !layoutObject->isBox()) + return false; + FloatQuad quad(toLayoutBox(layoutObject)->localToAbsoluteQuad(FloatQuad(toLayoutBox(layoutObject)->borderBoundingBox()))); + IntRect rect(quad.enclosingBoundingBox()); IntRect rectInViewport = m_localFrame->view()->soonToBeRemovedContentsToUnscaledViewport(rect); + // TODO(tkent): If the anchor rectangle is not visible, we should not + // show a popup. m_webExternalPopupMenu->show(rectInViewport); -#if OS(MACOSX) - const WebInputEvent* currentEvent = WebViewImpl::currentInputEvent(); - if (currentEvent && currentEvent->type == WebInputEvent::MouseDown) { - m_syntheticEvent = adoptPtr(new WebMouseEvent); - *m_syntheticEvent = *static_cast<const WebMouseEvent*>(currentEvent); - m_syntheticEvent->type = WebInputEvent::MouseUp; - m_dispatchEventTimer.startOneShot(0, BLINK_FROM_HERE); - // FIXME: show() is asynchronous. If preparing a popup is slow and - // a user released the mouse button before showing the popup, - // mouseup and click events are correctly dispatched. Dispatching - // the synthetic mouseup event is redundant in this case. - } -#endif + return true; } else { // The client might refuse to create a popup (when there is already one pending to be shown for example). didCancel(); + return false; } } +void ExternalPopupMenu::show(const FloatQuad&, const IntSize&, int) +{ + if (!showInternal()) + return; +#if OS(MACOSX) + const WebInputEvent* currentEvent = WebViewImpl::currentInputEvent(); + if (currentEvent && currentEvent->type == WebInputEvent::MouseDown) { + m_syntheticEvent = adoptPtr(new WebMouseEvent); + *m_syntheticEvent = *static_cast<const WebMouseEvent*>(currentEvent); + m_syntheticEvent->type = WebInputEvent::MouseUp; + m_dispatchEventTimer.startOneShot(0, BLINK_FROM_HERE); + // FIXME: show() is asynchronous. If preparing a popup is slow and a + // user released the mouse button before showing the popup, mouseup and + // click events are correctly dispatched. Dispatching the synthetic + // mouseup event is redundant in this case. + } +#endif +} + void ExternalPopupMenu::dispatchEvent(Timer<ExternalPopupMenu>*) { m_webView.handleInputEvent(*m_syntheticEvent); @@ -127,6 +143,26 @@ void ExternalPopupMenu::updateFromElement() { + if (m_needsUpdate) + return; + m_needsUpdate = true; + m_ownerElement->document().postTask(BLINK_FROM_HERE, createSameThreadTask(&ExternalPopupMenu::update, PassRefPtrWillBeRawPtr<ExternalPopupMenu>(this))); +} + +void ExternalPopupMenu::update() +{ + if (!m_webExternalPopupMenu || !m_ownerElement) + return; + m_ownerElement->document().updateLayoutTreeIfNeeded(); + // disconnectClient() might have been called. + if (!m_ownerElement) + return; + m_needsUpdate = false; + + if (showInternal()) + return; + // We failed to show a popup. Notify it to the owner. + hide(); } void ExternalPopupMenu::disconnectClient()
diff --git a/third_party/WebKit/Source/web/ExternalPopupMenu.h b/third_party/WebKit/Source/web/ExternalPopupMenu.h index 902d7f3..e892ee2 100644 --- a/third_party/WebKit/Source/web/ExternalPopupMenu.h +++ b/third_party/WebKit/Source/web/ExternalPopupMenu.h
@@ -78,7 +78,9 @@ void didAcceptIndices(const WebVector<int>& indices) override; void didCancel() override; + bool showInternal(); void dispatchEvent(Timer<ExternalPopupMenu>*); + void update(); RawPtrWillBeMember<HTMLSelectElement> m_ownerElement; RefPtrWillBeMember<LocalFrame> m_localFrame; @@ -87,6 +89,7 @@ Timer<ExternalPopupMenu> m_dispatchEventTimer; // The actual implementor of the show menu. WebExternalPopupMenu* m_webExternalPopupMenu; + bool m_needsUpdate = false; }; } // namespace blink
diff --git a/third_party/WebKit/public/web/WebAXEnums.h b/third_party/WebKit/public/web/WebAXEnums.h index 6aa0a805..5778654d 100644 --- a/third_party/WebKit/public/web/WebAXEnums.h +++ b/third_party/WebKit/public/web/WebAXEnums.h
@@ -75,6 +75,7 @@ // Enforced in AssertMatchingEnums.cpp. enum WebAXRole { WebAXRoleUnknown = 0, + WebAXRoleAbbr, WebAXRoleAlertDialog, WebAXRoleAlert, WebAXRoleAnnotation,
diff --git a/third_party/wayland/wayland.gyp b/third_party/wayland/wayland.gyp index 7bb4c79c..df72c99 100644 --- a/third_party/wayland/wayland.gyp +++ b/third_party/wayland/wayland.gyp
@@ -27,7 +27,7 @@ { 'target_name': 'wayland_private', 'type': 'static_library', - 'dependencies' : [ + 'dependencies': [ '../../build/linux/system.gyp:libffi', ], 'sources': [ @@ -43,16 +43,38 @@ ], }, { + 'target_name': 'wayland_protocol', + 'type': 'static_library', + 'dependencies': [ + 'wayland_util', + ], + 'sources': [ + 'protocol/wayland-protocol.c', + ], + 'include_dirs': [ + 'include/src', + 'include/protocol', + 'src/src', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + 'include/src', + 'include/protocol', + 'src/src', + ], + }, + }, + { 'target_name': 'wayland_server', 'type': 'static_library', - 'dependencies' : [ + 'dependencies': [ '../../build/linux/system.gyp:libffi', 'wayland_private', + 'wayland_protocol', 'wayland_util', ], 'sources': [ 'include/protocol/wayland-server-protocol.h', - 'protocol/wayland-protocol.c', 'src/src/event-loop.c', 'src/src/wayland-server.c', 'src/src/wayland-shm.c', @@ -70,5 +92,31 @@ ], }, }, + { + 'target_name': 'wayland_client', + 'type': 'static_library', + 'dependencies': [ + '../../build/linux/system.gyp:libffi', + 'wayland_private', + 'wayland_protocol', + 'wayland_util', + ], + 'sources': [ + 'include/protocol/wayland-client-protocol.h', + 'src/src/wayland-client.c', + ], + 'include_dirs': [ + 'include/src', + 'include/protocol', + 'src/src', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + 'include/src', + 'include/protocol', + 'src/src', + ], + }, + }, ], }
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b9b2423..582f038 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -3032,6 +3032,9 @@ <histogram name="Blink.RestoredCachedStyleSheet" enum="RestoredCachedStyleSheet"> + <obsolete> + Deprecated 01/2016 and replaced by Blink.RestoredCachedStyleSheet2 + </obsolete> <owner>kouhei@chromium.org</owner> <summary> On each link stylesheet tag resolve, record whether a Blink MemoryCached @@ -3039,6 +3042,13 @@ </summary> </histogram> +<histogram name="Blink.RestoredCachedStyleSheet2" enum="StyleSheetCacheStatus"> + <owner>kouhei@chromium.org</owner> + <summary> + On each link stylesheet tag resolve, record which cache Blink hit. + </summary> +</histogram> + <histogram name="Blink.XHR.setRequestHeader.HeaderValueCategoryInRFC7230" enum="XMLHttpRequestHeaderValueCategoryInRFC7230"> <owner>hiroshige@chromium.org</owner> @@ -3149,6 +3159,39 @@ </summary> </histogram> +<histogram name="Bluetooth.Android.GATTConnection.Disconnected.Result" + enum="AndroidGATTConnectionErrorCodes"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary> + Disconnected GATT connection status codes. Used to better understand errors + seen in Android. + </summary> +</histogram> + +<histogram name="Bluetooth.Android.GATTConnection.Failure.Result" + enum="AndroidGATTConnectionErrorCodes"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary> + Failed GATT connection error codes. Used to better understand errors seen in + Android. + </summary> +</histogram> + +<histogram name="Bluetooth.Android.GATTConnection.Success.Result" + enum="AndroidGATTConnectionErrorCodes"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary> + Successful GATT connection result codes. Used to better understand Android + results. + </summary> +</histogram> + <histogram name="Bluetooth.ConnectedDeviceCount" units="devices"> <owner>keybuk@chromium.org</owner> <summary> @@ -19071,6 +19114,11 @@ <summary>The final status of MidiManager on browser shutdown.</summary> </histogram> +<histogram name="Media.Midi.SysExMessageSizeUpTo1MB" units="bytes"> + <owner>toyoshim@chromium.org</owner> + <summary>Reports sysex message size.</summary> +</histogram> + <histogram name="Media.Midi.Usage" enum="MidiUsage"> <owner>toyoshim@chromium.org</owner> <summary>MidiManager usages to understand the API use case.</summary> @@ -54437,6 +54485,17 @@ </summary> </histogram> +<histogram name="WebFont.InterventionResult" enum="WebFontInterventionResult"> + <owner>toyoshim@chromium.org</owner> + <owner>kenjibaheux@chromium.org</owner> + <summary> + For each WebFont load attempt, records whether User Agent Intervention was + triggered, and whether the request (would have) timed out or not. The + intervention takes adaptive behaviors to handle loading timeouts to improve + user experiences on slow networks. + </summary> +</histogram> + <histogram name="WebFont.LayoutLatency" units="ms"> <obsolete> Renamed to WebFont.StyleRecalcToDownloadLatency for clarity. @@ -56355,6 +56414,91 @@ <int value="4" label="EvictAll"/> </enum> +<enum name="AndroidGATTConnectionErrorCodes" type="int"> + <summary> + This list includes all errors from the Bluetooth Specification Version 4.2 + [Vol 2, Part D] as well as an error from Android's BluetoothGatt (0x101 + GATT_FAILURE) and an error from Bluedroid's gatt_api.h (0x100 L2CAP + connection cancelled). + </summary> + <int value="0" label="0x00 Success"/> + <int value="1" label="0x01 Unknown HCI Command"/> + <int value="2" label="0x02 Unknown Connection Identifier"/> + <int value="3" label="0x03 Hardware Failure"/> + <int value="4" label="0x04 Page Timeout"/> + <int value="5" label="0x05 Authentication Failure"/> + <int value="6" label="0x06 PIN or Key Missing"/> + <int value="7" label="0x07 Memory Capacity Exceeded"/> + <int value="8" label="0x08 Connection Timeout"/> + <int value="9" label="0x09 Connection Limit Exceeded"/> + <int value="10" + label="0x0A Synchronous Connection Limit To A Device Exceeded"/> + <int value="11" label="0x0B ACL Connection Already Exists"/> + <int value="12" label="0x0C Command Disallowed"/> + <int value="13" label="0x0D Connection Rejected due to Limited Resources"/> + <int value="14" label="0x0E Connection Rejected Due To Security Reasons"/> + <int value="15" label="0x0F Connection Rejected due to Unacceptable BD_ADDR"/> + <int value="16" label="0x10 Connection Accept Timeout Exceeded"/> + <int value="17" label="0x11 Unsupported Feature or Parameter Value"/> + <int value="18" label="0x12 Invalid HCI Command Parameters"/> + <int value="19" label="0x13 Remote User Terminated Connection"/> + <int value="20" + label="0x14 Remote Device Terminated Connection due to Low Resources"/> + <int value="21" + label="0x15 Remote Device Terminated Connection due to Power Off"/> + <int value="22" label="0x16 Connection Terminated By Local Host"/> + <int value="23" label="0x17 Repeated Attempts"/> + <int value="24" label="0x18 Pairing Not Allowed"/> + <int value="25" label="0x19 Unknown LMP PDU"/> + <int value="26" + label="0x1A Unsupported Remote Feature / Unsupported LMP Feature"/> + <int value="27" label="0x1B SCO Offset Rejected"/> + <int value="28" label="0x1C SCO Interval Rejected"/> + <int value="29" label="0x1D SCO Air Mode Rejected"/> + <int value="30" label="0x1E Invalid LMP Parameters / Invalid LL Parameters"/> + <int value="31" label="0x1F Unspecified Error"/> + <int value="32" + label="0x20 Unsupported LMP Parameter Value / Unsupported LL Parameter + Value"/> + <int value="33" label="0x21 Role Change Not Allowed"/> + <int value="34" label="0x22 LMP Response Timeout / LL Response Timeout"/> + <int value="35" label="0x23 LMP Error Transaction Collision"/> + <int value="36" label="0x24 LMP PDU Not Allowed"/> + <int value="37" label="0x25 Encryption Mode Not Acceptable"/> + <int value="38" label="0x26 Link Key cannot be Changed"/> + <int value="39" label="0x27 Requested QoS Not Supported"/> + <int value="40" label="0x28 Instant Passed"/> + <int value="41" label="0x29 Pairing With Unit Key Not Supported"/> + <int value="42" label="0x2A Different Transaction Collision"/> + <int value="43" label="0x2B Reserved"/> + <int value="44" label="0x2C QoS Unacceptable Parameter"/> + <int value="45" label="0x2D QoS Rejected"/> + <int value="46" label="0x2E Channel Classification Not Supported"/> + <int value="47" label="0x2F Insufficient Security"/> + <int value="48" label="0x30 Parameter Out Of Mandatory Range"/> + <int value="49" label="0x31 Reserved"/> + <int value="50" label="0x32 Role Switch Pending"/> + <int value="51" label="0x33 Reserved"/> + <int value="52" label="0x34 Reserved Slot Violation"/> + <int value="53" label="0x35 Role Switch Failed"/> + <int value="54" label="0x36 Extended Inquiry Response Too Large"/> + <int value="55" label="0x37 Secure Simple Pairing Not Supported By Host"/> + <int value="56" label="0x38 Host Busy - Pairing"/> + <int value="57" + label="0x39 Connection Rejected due to No Suitable Channel Found"/> + <int value="58" label="0x3A Controller Busy"/> + <int value="59" label="0x3B Unacceptable Connection Parameters"/> + <int value="60" label="0x3C Directed Advertising Timeout"/> + <int value="61" label="0x3D Connection Terminated due to MIC Failure"/> + <int value="62" label="0x3E Connection Failed to be Established"/> + <int value="63" label="0x3F MAC Connection Failed"/> + <int value="64" + label="0x40 Coarse Clock Adjustment Rejected but Will Try to Adjust + Using Clock Dragging"/> + <int value="256" label="0x100 Bluedroid L2CAP connection cancelled"/> + <int value="257" label="0x101 Android GATT Failure"/> +</enum> + <enum name="AndroidKernelVersion" type="int"> <int value="131078" label="2.6"/> <int value="196608" label="3.0"/> @@ -56428,8 +56572,8 @@ <int value="0" label="Undo Shown (Cold)"/> <int value="1" label="Undo Shown (Warm)"/> <int value="2" label="Undo Pressed"/> - <int value="3" label="Undos Dismissed (Timeout)"/> - <int value="4" label="Undos Dismissed (Action)"/> + <int value="3" label="Undos Dismissed (Timeout) (Deprecated)"/> + <int value="4" label="Undos Dismissed (Action) (Deprecated)"/> </enum> <enum name="AppBannersDismissEvent" type="int"> @@ -61715,8 +61859,12 @@ <int value="308" label="Default printer selection rules"/> <int value="309" label="Allow Dinosaur Easter Egg Game"/> <int value="310" label="Whether RC4 cipher suites in TLS are enabled"/> - <int value="311" label="Default value for Display Rotation"/> - <int value="312" label="Allow export of supervised user data"/> + <int value="311" + label="Set default display rotation, reapplied on every reboot"/> + <int value="312" label="Enable the supervised user content provider"/> + <int value="313" label="Default key generation setting"/> + <int value="314" label="Allow key generation on these sites"/> + <int value="315" label="Block key generation on these sites"/> </enum> <enum name="EnterprisePolicyInvalidations" type="int"> @@ -63607,7 +63755,6 @@ <int value="1101" label="WEBRTCLOGGINGPRIVATE_STOPAUDIODEBUGRECORDINGS"/> <int value="1102" label="TERMINALPRIVATE_ACKOUTPUT"/> <int value="1103" label="INPUT_IME_CREATEWINDOW"/> - <int value="1104" label="ACCESSIBILITY_PRIVATE_SETKEYBOARDLISTENER"/> </enum> <enum name="ExtensionInstallCause" type="int"> @@ -69584,6 +69731,7 @@ <int value="-378033324" label="disable-win32k-renderer-lockdown"/> <int value="-360038744" label="invert-viewport-scroll-order"/> <int value="-351552989" label="disable-hosted-apps-in-windows"/> + <int value="-351127770" label="enable-offline-pages-as-bookmarks"/> <int value="-349057743" label="extensions-on-chrome-urls"/> <int value="-345838366" label="enable-hosted-apps-in-windows"/> <int value="-344343842" label="disable-experimental-app-list"/> @@ -69623,6 +69771,7 @@ <int value="-23090520" label="disable-search-button-in-omnibox"/> <int value="-22544408" label="enable-video-player-chromecast-support"/> <int value="-13918890" label="disable-download-notification"/> + <int value="-11260186" label="enable-offline-pages-as-saved-pages"/> <int value="-5052940" label="enable-simplified-fullscreen"/> <int value="-2371418" label="disable-display-list-2d-canvas"/> <int value="0" label="BAD_FLAG_FORMAT"> @@ -78654,6 +78803,12 @@ <int value="3" label="No pref change: was equal to platform-specific store"/> </enum> +<enum name="StyleSheetCacheStatus" type="int"> + <int value="0" label="No usable cache found"/> + <int value="1" label="DiskCache served the CSS source"/> + <int value="2" label="MemoryCached StyleSheetContents was reused"/> +</enum> + <enum name="SuggestAppsDialogCloseReason" type="int"> <int value="0" label="Unknown error"/> <int value="1" label="Item installed"/> @@ -80551,6 +80706,13 @@ <int value="2" label="Previously in the cache"/> </enum> +<enum name="WebFontInterventionResult" type="int"> + <int value="0" label="Wasn't triggered, and does not time out"/> + <int value="1" label="Wasn't triggered, but time out"/> + <int value="2" label="Was triggered, but would not time out"/> + <int value="3" label="Was triggered, and would time out"/> +</enum> + <enum name="WebFontPackageFormat" type="int"> <int value="0" label="Unknown / Decode error"/> <int value="1" label="SFNT"/>
diff --git a/tools/perf/benchmarks/jitter.py b/tools/perf/benchmarks/jitter.py new file mode 100644 index 0000000..3481a4652 --- /dev/null +++ b/tools/perf/benchmarks/jitter.py
@@ -0,0 +1,33 @@ +# 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. + +from core import perf_benchmark + +from telemetry.timeline import tracing_category_filter +from telemetry.web_perf import timeline_based_measurement +from telemetry.web_perf.metrics import jitter_timeline + +import page_sets + + +JITTER_CATEGORY = 'cdp.perf' +TIMELINE_REQUIRED_CATEGORY = 'blink.console' + +class Jitter(perf_benchmark.PerfBenchmark): + """Timeline based measurement benchmark for jitter.""" + + page_set = page_sets.JitterPageSet + + def CreateTimelineBasedMeasurementOptions(self): + cat_filter = tracing_category_filter.CreateMinimalOverheadFilter() + cat_filter.AddIncludedCategory(JITTER_CATEGORY) + cat_filter.AddIncludedCategory(TIMELINE_REQUIRED_CATEGORY) + options = timeline_based_measurement.Options( + overhead_level=cat_filter) + options.SetTimelineBasedMetrics([jitter_timeline.JitterTimelineMetric()]) + return options + + @classmethod + def Name(cls): + return 'jitter'
diff --git a/tools/perf/page_sets/jitter_pages.py b/tools/perf/page_sets/jitter_pages.py new file mode 100644 index 0000000..f56a9d9c --- /dev/null +++ b/tools/perf/page_sets/jitter_pages.py
@@ -0,0 +1,42 @@ +# 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. +from telemetry import page as page_module +from telemetry import story +from telemetry.page import shared_page_state + + +def _IssueMarkerAndScroll(action_runner): + with action_runner.CreateGestureInteraction('ScrollAction'): + action_runner.ScrollPage() + +class JitterPage(page_module.Page): + + def __init__(self, url, page_set, name=''): + super(JitterPage, self).__init__( + url=url, page_set=page_set, name=name, + shared_page_state_class=shared_page_state.SharedDesktopPageState) + + def RunPageInteractions(self, action_runner): + _IssueMarkerAndScroll(action_runner) + +class JitterPageSet(story.StorySet): + + def __init__(self): + super(JitterPageSet, self).__init__() + + urls = [ + # one fixed layer with no jitter + 'file://jitter_test_cases/fixed.html', + # one layer that jitters + 'file://jitter_test_cases/one_layer_jitter.html', + # one layer inside another, both jitter together + 'file://jitter_test_cases/child_jitter_with_parent.html', + # two non overlapping layers jitter + 'file://jitter_test_cases/two_layers_jitter.html', + # jittering layer size bigger + 'file://jitter_test_cases/big_layer_jitter.html', + ] + + for url in urls: + self.AddStory(JitterPage(url, self))
diff --git a/tools/perf/page_sets/jitter_test_cases/big_layer_jitter.html b/tools/perf/page_sets/jitter_test_cases/big_layer_jitter.html new file mode 100644 index 0000000..3ffffd64 --- /dev/null +++ b/tools/perf/page_sets/jitter_test_cases/big_layer_jitter.html
@@ -0,0 +1,77 @@ +<!DOCTYPE html> +<!-- saved from url=(0048)http://fiddle.jshell.net/bt8dhkrn/24/show/light/ --> +<!-- here we have three divs that jitter together and the size of fixed-parent + div is bigger than in other test cases --> + +<style> + #jitter-big-parent { + width: 500px; + height: 500px; + background: papayawhip; + border: 1px solid black; + will-change: transform; + } + + #jitter-child { + width: 250px; + height: 250px; + background: green; + border: 1px solid black; + will-change: transform; + } + + #jitter-grand-child { + width: 100px; + height: 100px; + background: blue; + border: 1px solid black; + will-change: transform; + } + + #scrolled1 { + width: 500px; + height: 500px; + background: red; + border: 1px solid black; + will-change: transform; + } + + #scrolled2 { + width: 500px; + height: 500px; + background: green; + border: 1px solid black; + will-change: transform; + } + + body { + height: 2500px; + } +</style> + +<script> +window.onload=function(){ +tick = function(timestamp) { + document.getElementById("jitter-big-parent").style.transform = "translate(0px, " + document.body.scrollTop + "px)"; + window.requestAnimationFrame(tick); +} +window.requestAnimationFrame(tick); + +jank = function(timestamp) { + for (var i = 0; i < 10; ++i) { + Date.now(); + } + window.setTimeout(jank, 50); +} +window.setTimeout(jank, 50); +} +</script> + +<div id="jitter-big-parent" style="transform: translate(0px, 0px);"> + <div id="jitter-child"> + <div id="jitter-grand-child"></div> + </div> +</div> +<div id="scrolled1"></div> +<div id="scrolled2"></div> +</html>
diff --git a/tools/perf/page_sets/jitter_test_cases/child_jitter_with_parent.html b/tools/perf/page_sets/jitter_test_cases/child_jitter_with_parent.html new file mode 100644 index 0000000..b2409f77 --- /dev/null +++ b/tools/perf/page_sets/jitter_test_cases/child_jitter_with_parent.html
@@ -0,0 +1,57 @@ +<!DOCTYPE html> +<!-- saved from url=(0048)http://fiddle.jshell.net/bt8dhkrn/10/show/light/ --> +<!-- here we have two divs that jitter together --> + +<style> + #jitter-parent { + width: 100px; + height: 100px; + background: papayawhip; + border: 1px solid black; + will-change: transform; + } + + #jitter-child { + width: 50px; + height: 50px; + background: green; + border: 1px solid black; + will-change: transform; + } + + #scrolled { + width: 100px; + height: 100px; + background: red; + border: 1px solid black; + will-change: transform; + } + + body { + height: 2500px; + } +</style> + +<script> +window.onload=function(){ +tick = function(timestamp) { + document.getElementById("jitter-parent").style.transform = "translate(0px, " + document.body.scrollTop + "px)"; + window.requestAnimationFrame(tick); +} +window.requestAnimationFrame(tick); + +jank = function(timestamp) { + for (var i = 0; i < 10; ++i) { + Date.now(); + } + window.setTimeout(jank, 50); +} +window.setTimeout(jank, 50); +} +</script> + +<div id="jitter-parent" style="transform: translate(0px, 0px);"> + <div id="jitter-child"></div> +</div> +<div id="scrolled"></div> +</html>
diff --git a/tools/perf/page_sets/jitter_test_cases/fixed.html b/tools/perf/page_sets/jitter_test_cases/fixed.html new file mode 100644 index 0000000..df97e8e6 --- /dev/null +++ b/tools/perf/page_sets/jitter_test_cases/fixed.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<!-- saved from url=(0048)http://fiddle.jshell.net/bt8dhkrn/28/show/light/ --> +<!-- here we have a fixed div that doesn't jitter --> + +<style> + #fixed { + width: 100px; + height: 100px; + background: papayawhip; + border: 1px solid black; + will-change: transform; + position : fixed; + } + + body { + height: 2500px; + } +</style> + +<script> +window.onload=function(){ +} +</script> + +<div id="fixed"></div> +</html>
diff --git a/tools/perf/page_sets/jitter_test_cases/one_layer_jitter.html b/tools/perf/page_sets/jitter_test_cases/one_layer_jitter.html new file mode 100644 index 0000000..d61116d --- /dev/null +++ b/tools/perf/page_sets/jitter_test_cases/one_layer_jitter.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- saved from url=(0048)http://fiddle.jshell.net/bt8dhkrn/29/show/light/ --> +<!-- here we have a single div that jitters --> + +<style> + #jitter { + width: 100px; + height: 100px; + background: papayawhip; + border: 1px solid black; + will-change: transform; + } + + body { + height: 2500px; + } +</style> + +<script> +window.onload=function(){ +tick = function(timestamp) { + document.getElementById("jitter").style.transform = "translate(0px, " + document.body.scrollTop + "px)"; + window.requestAnimationFrame(tick); +} +window.requestAnimationFrame(tick); + +jank = function(timestamp) { + for (var i = 0; i < 10; ++i) { + Date.now(); + } + window.setTimeout(jank, 50); +} +window.setTimeout(jank, 50); +} +</script> + +<div id="jitter" style="transform: translate(0px, 0px);"></div> +</html>
diff --git a/tools/perf/page_sets/jitter_test_cases/two_layers_jitter.html b/tools/perf/page_sets/jitter_test_cases/two_layers_jitter.html new file mode 100644 index 0000000..57d0d4a --- /dev/null +++ b/tools/perf/page_sets/jitter_test_cases/two_layers_jitter.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<!-- saved from url=(0048)http://fiddle.jshell.net/bt8dhkrn/26/show/light/ --> +<!-- here we have two divs that jitter --> + +<style type="text/css"> + #jitter1 { + width: 100px; + height: 100px; + background: papayawhip; + border: 1px solid black; + will-change: transform; + } + + #jitter2 { + width: 100px; + height: 100px; + background: red; + border: 1px solid black; + will-change: transform; + } + + body { + height: 2500px; + } + </style> + +<script> +window.onload=function(){ +tick = function(timestamp) { + document.getElementById("jitter1").style.transform = "translate(0px, " + document.body.scrollTop + "px)"; + document.getElementById("jitter2").style.transform = "translate(0px, " + document.body.scrollTop + "px)"; + window.requestAnimationFrame(tick); +} +window.requestAnimationFrame(tick); + +jank = function(timestamp) { + for (var i = 0; i < 10; ++i) { + Date.now(); + } + window.setTimeout(jank, 50); +} +window.setTimeout(jank, 50); +} +</script> + +<div id="jitter1" style="transform: translate(0px, 318px);"></div> +<div id="jitter2" style="transform: translate(0px, 318px);"></div> +</html>
diff --git a/tools/telemetry/telemetry/web_perf/metrics/jitter_timeline.py b/tools/telemetry/telemetry/web_perf/metrics/jitter_timeline.py new file mode 100644 index 0000000..cc1879d --- /dev/null +++ b/tools/telemetry/telemetry/web_perf/metrics/jitter_timeline.py
@@ -0,0 +1,51 @@ +# 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. + +from telemetry.value import improvement_direction +from telemetry.value import list_of_scalar_values +from telemetry.web_perf.metrics import timeline_based_metric + + +JITTER_EVENT_NAME = 'jitter' + + +class JitterTimelineMetric(timeline_based_metric.TimelineBasedMetric): + """JitterTimelineMetric reports jitter in composited layers. + + This jitter is due to the main thread attempting to fix the position of a + scrolling composited layer. 'jitter-amount' is the metric added to the + results. + """ + + def __init__(self): + super(JitterTimelineMetric, self).__init__() + + @staticmethod + def IsJitterEvent(event): + return event.name == JITTER_EVENT_NAME + + def AddResults(self, model, renderer_thread, interactions, results): + assert interactions + + jitter_events = [] + for event in model.IterAllEvents( + event_predicate=self.IsJitterEvent): + jitter_events.append(event) + + self._AddJitterResultsInternal(jitter_events, interactions, results) + + def _AddJitterResultsInternal(self, events, interactions, results): + jitters = [] + for event in events: + if timeline_based_metric.IsEventInInteractions(event, interactions): + jitters.append(event.args['value']) + if jitters: + results.AddValue(list_of_scalar_values.ListOfScalarValues( + page=results.current_page, + tir_label=interactions[0].label, + name='jitter-amount', + units='score', + values=jitters, + description='Jitter each frame', + improvement_direction=improvement_direction.DOWN))
diff --git a/tools/telemetry/telemetry/web_perf/metrics/jitter_timeline_unittest.py b/tools/telemetry/telemetry/web_perf/metrics/jitter_timeline_unittest.py new file mode 100644 index 0000000..d2a93dc --- /dev/null +++ b/tools/telemetry/telemetry/web_perf/metrics/jitter_timeline_unittest.py
@@ -0,0 +1,50 @@ +# 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. + +import unittest + +from collections import namedtuple +from telemetry.internal.results import page_test_results +from telemetry.page import page +from telemetry.web_perf.metrics import jitter_timeline +from telemetry.web_perf import timeline_interaction_record + + +FakeEvent = namedtuple('Event', 'name, start, end, thread_duration, args') +Interaction = timeline_interaction_record.TimelineInteractionRecord +TEST_INTERACTION_LABEL = 'Action_TestInteraction' +JITTER_EVENT_NAME = 'jitter' + +def GetJitterMetrics(events, interactions): + results = page_test_results.PageTestResults() + test_page = page.Page('file://blank.html') + results.WillRunPage(test_page) + jitter_timeline.JitterTimelineMetric()._AddJitterResultsInternal( + events, interactions, results) + return_dict = dict((value.name, value.values) for value in + results.current_page_run.values) + results.DidRunPage(test_page) + return return_dict + +def FakeJitterEvent(start, end, value, thread_duration=None): + if not thread_duration: + thread_duration = end - start + return FakeEvent(jitter_timeline.JITTER_EVENT_NAME, + start, end, thread_duration, {'value':value}) + +def TestInteraction(start, end): + return Interaction(TEST_INTERACTION_LABEL, start, end) + + +class JitterTimelineMetricUnitTest(unittest.TestCase): + def testJitterMetric(self): + events = [FakeJitterEvent(0, 1, 10), + FakeJitterEvent(5, 10, 5), + FakeJitterEvent(15, 34, 45)] + interactions = [TestInteraction(4, 14)] + # The first and the last event do not start during the interaction, so + # they are ignored. The second event starts during the interaction, and its + # value is 5. + self.assertEqual({'jitter-amount': [5]}, + GetJitterMetrics(events, interactions))
diff --git a/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py b/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py index f208d3f..fe547bf 100644 --- a/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py +++ b/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py
@@ -11,6 +11,7 @@ from telemetry.value import trace from telemetry.web_perf.metrics import timeline_based_metric from telemetry.web_perf.metrics import blob_timeline +from telemetry.web_perf.metrics import jitter_timeline from telemetry.web_perf.metrics import webrtc_rendering_timeline from telemetry.web_perf.metrics import gpu_timeline from telemetry.web_perf.metrics import indexeddb_timeline @@ -47,6 +48,7 @@ layout.LayoutMetric(), gpu_timeline.GPUTimelineMetric(), blob_timeline.BlobTimelineMetric(), + jitter_timeline.JitterTimelineMetric(), memory_timeline.MemoryTimelineMetric(), text_selection.TextSelectionMetric(), indexeddb_timeline.IndexedDBTimelineMetric(),
diff --git a/ui/accessibility/ax_enums.idl b/ui/accessibility/ax_enums.idl index 4bb7d9f..7470199 100644 --- a/ui/accessibility/ax_enums.idl +++ b/ui/accessibility/ax_enums.idl
@@ -64,6 +64,7 @@ }; enum AXRole { + abbr, alert_dialog, alert, annotation,
diff --git a/ui/accessibility/platform/ax_platform_node_mac.mm b/ui/accessibility/platform/ax_platform_node_mac.mm index a4384f9..141a5454 100644 --- a/ui/accessibility/platform/ax_platform_node_mac.mm +++ b/ui/accessibility/platform/ax_platform_node_mac.mm
@@ -24,6 +24,7 @@ RoleMap BuildRoleMap() { const MapEntry roles[] = { + {ui::AX_ROLE_ABBR, NSAccessibilityGroupRole}, {ui::AX_ROLE_ALERT, NSAccessibilityGroupRole}, {ui::AX_ROLE_ALERT_DIALOG, NSAccessibilityGroupRole}, {ui::AX_ROLE_ANNOTATION, NSAccessibilityUnknownRole},
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn index 9cf4606b..468b626 100644 --- a/ui/base/ime/BUILD.gn +++ b/ui/base/ime/BUILD.gn
@@ -67,6 +67,8 @@ "input_method_factory.h", "input_method_initializer.cc", "input_method_initializer.h", + "input_method_log_collector.cc", + "input_method_log_collector.h", "input_method_mac.h", "input_method_mac.mm", "input_method_minimal.cc",
diff --git a/ui/base/ime/input_method.h b/ui/base/ime/input_method.h index 598fd4f..77f5317 100644 --- a/ui/base/ime/input_method.h +++ b/ui/base/ime/input_method.h
@@ -11,6 +11,7 @@ #include "base/event_types.h" #include "build/build_config.h" +#include "ui/base/ime/input_method_log_collector.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" @@ -152,6 +153,8 @@ // Management of the observer list. virtual void AddObserver(InputMethodObserver* observer) = 0; virtual void RemoveObserver(InputMethodObserver* observer) = 0; + + virtual InputMethodLogCollector* GetLogCollector() = 0; }; } // namespace ui
diff --git a/ui/base/ime/input_method_auralinux.cc b/ui/base/ime/input_method_auralinux.cc index ca9931f..d6ceeaa 100644 --- a/ui/base/ime/input_method_auralinux.cc +++ b/ui/base/ime/input_method_auralinux.cc
@@ -46,6 +46,19 @@ void InputMethodAuraLinux::DispatchKeyEvent(ui::KeyEvent* event) { DCHECK(event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED); DCHECK(system_toplevel_window_focused()); + if (!system_toplevel_window_focused()) { + GetLogCollector()->AddString( + "Unexpected DispatchKeyEvent: InputMethod is not active."); + GetLogCollector()->DumpLogs(); + // There are random issues that the keyboard typing doesn't work. + // The root cause might be the InputMethod::OnFocus() is not correctly + // called when the top-level window is activated + // (in DNWA::HandleActivationChanged). + // Calls OnFocus here to unblock the keyboard typing. + OnFocus(); + } else { + GetLogCollector()->ClearLogs(); + } // If no text input client, do nothing. if (!GetTextInputClient()) {
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc index 3441f928..9702454 100644 --- a/ui/base/ime/input_method_base.cc +++ b/ui/base/ime/input_method_base.cc
@@ -15,10 +15,10 @@ namespace ui { InputMethodBase::InputMethodBase() - : delegate_(NULL), - text_input_client_(NULL), - system_toplevel_window_focused_(false) { -} + : delegate_(NULL), + text_input_client_(NULL), + system_toplevel_window_focused_(false), + log_collector_(new InputMethodLogCollector()) {} InputMethodBase::~InputMethodBase() { FOR_EACH_OBSERVER(InputMethodObserver, @@ -36,6 +36,8 @@ void InputMethodBase::OnBlur() { system_toplevel_window_focused_ = false; + log_collector_->ClearLogs(); + log_collector_->AddString("Input method is blurred."); } void InputMethodBase::SetFocusedTextInputClient(TextInputClient* client) { @@ -90,6 +92,10 @@ observer_list_.RemoveObserver(observer); } +InputMethodLogCollector* InputMethodBase::GetLogCollector() { + return log_collector_.get(); +} + bool InputMethodBase::IsTextInputClientFocused(const TextInputClient* client) { return client && (client == GetTextInputClient()); }
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h index e9efb3a..dfa0b20 100644 --- a/ui/base/ime/input_method_base.h +++ b/ui/base/ime/input_method_base.h
@@ -56,6 +56,8 @@ void AddObserver(InputMethodObserver* observer) override; void RemoveObserver(InputMethodObserver* observer) override; + InputMethodLogCollector* GetLogCollector() override; + protected: virtual void OnWillChangeFocusedClient(TextInputClient* focused_before, TextInputClient* focused) {} @@ -101,6 +103,8 @@ bool system_toplevel_window_focused_; + scoped_ptr<InputMethodLogCollector> log_collector_; + DISALLOW_COPY_AND_ASSIGN(InputMethodBase); };
diff --git a/ui/base/ime/input_method_log_collector.cc b/ui/base/ime/input_method_log_collector.cc new file mode 100644 index 0000000..daa3396 --- /dev/null +++ b/ui/base/ime/input_method_log_collector.cc
@@ -0,0 +1,56 @@ +// 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 "ui/base/ime/input_method_log_collector.h" + +#include <string.h> + +#include "base/debug/alias.h" +#include "base/debug/dump_without_crashing.h" +#include "base/macros.h" + +namespace { + +const size_t kMaxLogCount = 50; + +} + +namespace ui { + +InputMethodLogCollector::InputMethodLogCollector() {} + +InputMethodLogCollector::~InputMethodLogCollector() {} + +void InputMethodLogCollector::AddString(const char* str_val) { + if (logs_.size() >= kMaxLogCount) + logs_.erase(logs_.begin()); + logs_.push_back(str_val); +} + +void InputMethodLogCollector::AddBoolean(bool bool_val) { + AddString(bool_val ? "true" : "false"); +} + +void InputMethodLogCollector::DumpLogs() { + static int dump_times = 0; + if (dump_times > 5) { + ClearLogs(); + return; + } + const char* logs_copy[kMaxLogCount]; + size_t log_count = logs_.size(); + for (size_t i = 0; i < log_count && i < arraysize(logs_copy); ++i) + logs_copy[i] = logs_[i]; + base::debug::Alias(&log_count); + base::debug::Alias(&logs_copy); + base::debug::DumpWithoutCrashing(); + dump_times++; + ClearLogs(); +} + +void InputMethodLogCollector::ClearLogs() { + logs_.clear(); +} + +} // namespace ui
diff --git a/ui/base/ime/input_method_log_collector.h b/ui/base/ime/input_method_log_collector.h new file mode 100644 index 0000000..bdc8b4d5 --- /dev/null +++ b/ui/base/ime/input_method_log_collector.h
@@ -0,0 +1,36 @@ +// 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 UI_BASE_IME_INPUT_METHOD_LOG_COLLECTOR_H_ +#define UI_BASE_IME_INPUT_METHOD_LOG_COLLECTOR_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "ui/base/ime/ui_base_ime_export.h" + +namespace ui { + +// The class to gather some logs and dump it through +// base::debug::DumpWithoutCrashing when InputMethod processing a key event. +// This is for tracing the issue that hardly repros: crbug.com/569339. +class UI_BASE_IME_EXPORT InputMethodLogCollector { + public: + InputMethodLogCollector(); + ~InputMethodLogCollector(); + void AddString(const char* str_val); + void AddBoolean(bool bool_val); + void DumpLogs(); + void ClearLogs(); + + private: + std::vector<const char*> logs_; + + DISALLOW_COPY_AND_ASSIGN(InputMethodLogCollector); +}; + +} // namespace ui + +#endif // UI_BASE_IME_INPUT_METHOD_LOG_COLLECTOR_H_
diff --git a/ui/base/ime/input_method_win.cc b/ui/base/ime/input_method_win.cc index 56bbac1..a50d877 100644 --- a/ui/base/ime/input_method_win.cc +++ b/ui/base/ime/input_method_win.cc
@@ -262,6 +262,22 @@ BOOL* handled) { *handled = TRUE; + if (!system_toplevel_window_focused()) { + GetLogCollector()->AddString( + "Unexpected OnChar: InputMethod is not active. Window focused: "); + GetLogCollector()->AddBoolean( + ::GetActiveWindow() == toplevel_window_handle_); + GetLogCollector()->DumpLogs(); + // There are random issues that the keyboard typing doesn't work. + // The root cause might be the InputMethod::OnFocus() is not correctly + // called when the top-level window is activated + // (in DNWA::HandleActivationChanged). + // Calls OnFocus here to unblock the keyboard typing. + OnFocus(); + } else { + GetLogCollector()->ClearLogs(); + } + // We need to send character events to the focused text input client event if // its text input type is ui::TEXT_INPUT_TYPE_NONE. if (GetTextInputClient()) { @@ -295,6 +311,7 @@ WPARAM wparam, LPARAM lparam, BOOL* handled) { + GetLogCollector()->AddString("WM_IME_SETCONTEXT"); if (!!wparam) { imm32_manager_.CreateImeWindow(window_handle); if (system_toplevel_window_focused()) {
diff --git a/ui/base/ime/mock_input_method.cc b/ui/base/ime/mock_input_method.cc index f2cf8eb..e09e2a8 100644 --- a/ui/base/ime/mock_input_method.cc +++ b/ui/base/ime/mock_input_method.cc
@@ -5,6 +5,7 @@ #include "ui/base/ime/mock_input_method.h" #include "ui/base/ime/input_method_delegate.h" +#include "ui/base/ime/input_method_log_collector.h" #include "ui/events/event.h" namespace ui { @@ -116,4 +117,8 @@ observer_list_.RemoveObserver(observer); } +InputMethodLogCollector* MockInputMethod::GetLogCollector() { + return nullptr; +} + } // namespace ui
diff --git a/ui/base/ime/mock_input_method.h b/ui/base/ime/mock_input_method.h index 96d2c47..a6a68b4 100644 --- a/ui/base/ime/mock_input_method.h +++ b/ui/base/ime/mock_input_method.h
@@ -16,6 +16,7 @@ namespace ui { +class InputMethodLogCollector; class KeyEvent; class TextInputClient; @@ -52,6 +53,7 @@ void ShowImeIfNeeded() override; void AddObserver(InputMethodObserver* observer) override; void RemoveObserver(InputMethodObserver* observer) override; + InputMethodLogCollector* GetLogCollector() override; private: TextInputClient* text_input_client_;
diff --git a/ui/base/ime/ui_base_ime.gyp b/ui/base/ime/ui_base_ime.gyp index 9c3eb388..b00f78e 100644 --- a/ui/base/ime/ui_base_ime.gyp +++ b/ui/base/ime/ui_base_ime.gyp
@@ -89,6 +89,8 @@ 'input_method_factory.h', 'input_method_initializer.cc', 'input_method_initializer.h', + 'input_method_log_collector.cc', + 'input_method_log_collector.h', 'input_method_mac.h', 'input_method_mac.mm', 'input_method_minimal.cc',
diff --git a/ui/file_manager/image_loader/request.js b/ui/file_manager/image_loader/request.js index 65d0ea06..7988a3c 100644 --- a/ui/file_manager/image_loader/request.js +++ b/ui/file_manager/image_loader/request.js
@@ -288,7 +288,7 @@ * Creates a video thumbnail data url from video file. * * @param {!Blob} blob Blob object of video file - * @return {!Promise<!String>} Promise that resolves with the data url of video + * @return {!Promise<!string>} Promise that resolves with the data url of video * thumbnail. * @private */
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index 79b8c16..4318d13b 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc
@@ -397,8 +397,8 @@ g_use_direct_composition = HasEGLExtension("EGL_ANGLE_direct_composition") && HasEGLExtension("EGL_ANGLE_flexible_surface_compatibility") && - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUseDirectComposition); + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableDirectComposition); // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary // workaround, since code written for Android WebView takes different paths
diff --git a/ui/gl/gl_switches.cc b/ui/gl/gl_switches.cc index fd80ff4..2fbde37 100644 --- a/ui/gl/gl_switches.cc +++ b/ui/gl/gl_switches.cc
@@ -67,8 +67,8 @@ // context will never be lost in any situations, say, a GPU reset. const char kGpuNoContextLost[] = "gpu-no-context-lost"; -// Turns on the use of DirectComposition to draw to the screen. -const char kUseDirectComposition[] = "use-direct-composition"; +// Disables the use of DirectComposition to draw to the screen. +const char kDisableDirectComposition[] = "disable-direct-composition"; // Indicates whether the dual GPU switching is supported or not. const char kSupportsDualGpus[] = "supports-dual-gpus"; @@ -98,16 +98,16 @@ // GpuProcessHost to the GPU Process. Add your switch to this list if you need // to read it in the GPU process, else don't add it. const char* kGLSwitchesCopiedFromGpuProcessHost[] = { - kDisableGpuVsync, - kDisableD3D11, - kEnableGPUServiceLogging, - kEnableGPUServiceTracing, - kEnableUnsafeES3APIs, - kGpuNoContextLost, - kDisableGLDrawingForTests, - kOverrideUseGLWithOSMesaForTests, - kUseANGLE, - kUseDirectComposition, + kDisableGpuVsync, + kDisableD3D11, + kEnableGPUServiceLogging, + kEnableGPUServiceTracing, + kEnableUnsafeES3APIs, + kGpuNoContextLost, + kDisableGLDrawingForTests, + kOverrideUseGLWithOSMesaForTests, + kUseANGLE, + kDisableDirectComposition, }; const int kGLSwitchesCopiedFromGpuProcessHostNumSwitches = arraysize(kGLSwitchesCopiedFromGpuProcessHost);
diff --git a/ui/gl/gl_switches.h b/ui/gl/gl_switches.h index 2c6122b..8c51d063 100644 --- a/ui/gl/gl_switches.h +++ b/ui/gl/gl_switches.h
@@ -36,7 +36,7 @@ GL_EXPORT extern const char kEnableGPUServiceLogging[]; GL_EXPORT extern const char kEnableGPUServiceTracing[]; GL_EXPORT extern const char kGpuNoContextLost[]; -GL_EXPORT extern const char kUseDirectComposition[]; +GL_EXPORT extern const char kDisableDirectComposition[]; GL_EXPORT extern const char kSupportsDualGpus[];
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 618d774..1e4f71f 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -369,8 +369,11 @@ native_widget_delegate_->OnNativeWidgetActivationChanged(active); aura::client::ActivationClient* activation_client = aura::client::GetActivationClient(host_->window()); - if (!activation_client) + if (!activation_client) { + GetInputMethod()->GetLogCollector()->AddString( + "Missing OnFocus call when activating due to no activation client."); return; + } if (active) { if (GetWidget()->HasFocusManager()) { // This function can be called before the focus manager has had a @@ -387,6 +390,9 @@ // Refreshes the focus info to IMF in case that IMF cached the old info // about focused text input client when it was "inactive". GetInputMethod()->OnFocus(); + } else { + GetInputMethod()->GetLogCollector()->AddString( + "Missing OnFocus call when activating due to no focus manager."); } } else { // If we're not active we need to deactivate the corresponding
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index c354154..77fbb26d 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -916,6 +916,14 @@ compositor()->size()); } +void DesktopWindowTreeHostWin::AddStringLog(const char* log_string) { + GetInputMethod()->GetLogCollector()->AddString(log_string); +} + +void DesktopWindowTreeHostWin::AddBooleanLog(bool bool_val) { + GetInputMethod()->GetLogCollector()->AddBoolean(bool_val); +} + //////////////////////////////////////////////////////////////////////////////// // DesktopWindowTreeHostWin, private:
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h index ad82485..cab1428 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -193,6 +193,8 @@ bool HandleScrollEvent(const ui::ScrollEvent& event) override; void HandleWindowSizeChanging() override; void HandleWindowSizeChanged() override; + void AddStringLog(const char* log_string) override; + void AddBooleanLog(bool bool_val) override; Widget* GetWidget(); const Widget* GetWidget() const;
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index f61ff817..4d02124 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -484,7 +484,7 @@ } void NativeWidgetMac::SetOpacity(unsigned char opacity) { - NOTIMPLEMENTED(); + [GetNativeWindow() setAlphaValue:opacity / 255.0]; } void NativeWidgetMac::SetUseDragFrame(bool use_drag_frame) {
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 5a48f025..b8d29dd 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -1089,6 +1089,19 @@ EXPECT_TRUE(NSIsEmptyRect(actual)); } +// Test that Widget opacity can be changed. +TEST_F(NativeWidgetMacTest, ChangeOpacity) { + Widget* widget = CreateTopLevelPlatformWidget(); + NSWindow* ns_window = widget->GetNativeWindow(); + + CGFloat old_opacity = [ns_window alphaValue]; + widget->SetOpacity(0xAA); + EXPECT_NE(old_opacity, [ns_window alphaValue]); + EXPECT_DOUBLE_EQ(0xAA / 255.0, [ns_window alphaValue]); + + widget->CloseNow(); +} + } // namespace test } // namespace views
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 0cacffe4..d5e972a 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -928,8 +928,12 @@ delegate_->HandleDestroyed(); } - if (message == WM_ACTIVATE && IsTopLevelWindow(window)) - PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param)); + if (message == WM_ACTIVATE) { + if (IsTopLevelWindow(window)) + PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param)); + else + delegate_->AddStringLog("WM_ACTIVATE on non-top-level window."); + } return result; } @@ -1033,6 +1037,8 @@ const bool active = activation_state != WA_INACTIVE && !minimized; if (delegate_->CanActivate()) delegate_->HandleActivationChanged(active); + else + delegate_->AddStringLog("Missing call to HandleActivationChanged."); } void HWNDMessageHandler::RestoreEnabledIfNecessary() { @@ -1231,6 +1237,8 @@ // Message handlers ------------------------------------------------------------ void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) { + delegate_->AddStringLog("WM_ACTIVATEAPP: "); + delegate_->AddBooleanLog(active ? true : false); if (delegate_->IsWidgetWindow() && !active && thread_id != GetCurrentThreadId()) { delegate_->HandleAppDeactivated(); @@ -1486,6 +1494,8 @@ LRESULT HWNDMessageHandler::OnKeyEvent(UINT message, WPARAM w_param, LPARAM l_param) { + if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN) + delegate_->AddStringLog("WM_KEYDOWN || WM_SYSKEYDOWN"); MSG msg = { hwnd(), message, w_param, l_param, static_cast<DWORD>(GetMessageTime())}; ui::KeyEvent key(msg); @@ -1503,6 +1513,7 @@ LRESULT HWNDMessageHandler::OnMouseActivate(UINT message, WPARAM w_param, LPARAM l_param) { + delegate_->AddStringLog("WM_MOUSEACTIVATE"); // Please refer to the comments in the header for the touch_down_contexts_ // member for the if statement below. if (touch_down_contexts_) @@ -1567,6 +1578,8 @@ LRESULT HWNDMessageHandler::OnNCActivate(UINT message, WPARAM w_param, LPARAM l_param) { + delegate_->AddStringLog("WM_NCACTIVATE: "); + delegate_->AddBooleanLog(w_param ? true : false); // Per MSDN, w_param is either TRUE or FALSE. However, MSDN also hints that: // "If the window is minimized when this message is received, the application // should pass the message to the DefWindowProc function."
diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h index 55ac440..174a7ca 100644 --- a/ui/views/win/hwnd_message_handler_delegate.h +++ b/ui/views/win/hwnd_message_handler_delegate.h
@@ -228,6 +228,9 @@ // Called when the window size has finished changing. virtual void HandleWindowSizeChanged() = 0; + virtual void AddStringLog(const char* log_string) = 0; + virtual void AddBooleanLog(bool bool_val) = 0; + protected: virtual ~HWNDMessageHandlerDelegate() {} };