diff --git a/DEPS b/DEPS index 9f33847..7c5287a 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # 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': '4a0f180211dbcf5c400f797aafe6cc3ff6fc021f', + 'skia_revision': '9c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '8ff4cb255b571e8d39ad09deb32e22fbd4a19fe8', + 'v8_revision': '69a568f8902f3ef7bb88b7ee946482c5288af646', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '1ef2f828f71e40437d82bb039dcb087c1beb7bd6', + 'pdfium_revision': 'f1eae2c37cb4bbf7a536cf251706147bbac51880', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '56836f4aacdc15e1284ef9c09afdbb9f9bd92cda', + 'catapult_revision': 'ee25754a916e2df9d0d2c33e2e067e27f1360212', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -235,7 +235,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '08fc06e0c0ab20d64b5283a7d6bf698fa72189c5', # commit position 18824 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '675c61ecddf34a2073b0715adf15205fa3d42856', # commit position 18836 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'), @@ -382,6 +382,10 @@ 'src/third_party/google_toolbox_for_mac/src': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), + + 'src/third_party/material_design_icons/src': + Var('chromium_git') + '/external/github.com/google/material-design-icons.git' + '@' + + 'a6145e167b4a3a65640dd6279319cbc77a7e4e96', }, 'mac': { 'src/chrome/installer/mac/third_party/xz/xz':
diff --git a/WATCHLISTS b/WATCHLISTS index ac3b7238..9d7a0012 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1723,8 +1723,7 @@ 'blink_bindings_serialization': ['jbroman+watch@chromium.org'], 'blink_bluetooth': ['ortuno+watch@chromium.org', 'scheib+watch@chromium.org'], - 'blink_canvas2d': ['cabanier@adobe.com', - 'dongseong.hwang@intel.com', + 'blink_canvas2d': ['dongseong.hwang@intel.com', 'junov@chromium.org'], 'blink_client_hints': ['yoav@yoav.ws'], 'blink_clipboard': ['dcheng@chromium.org'], @@ -1820,7 +1819,6 @@ 'blink_permissions': ['mlamouri+watch-blink@chromium.org'], 'blink_platform': ['kinuko+watch@chromium.org'], 'blink_platform_graphics': ['blink-reviews-platform-graphics@chromium.org', - 'cabanier@adobe.com', 'dongseong.hwang@intel.com', 'drott+blinkwatch@chromium.org', 'dschulze@chromium.org',
diff --git a/base/memory/weak_ptr.cc b/base/memory/weak_ptr.cc index b6e997b..04c9ad6 100644 --- a/base/memory/weak_ptr.cc +++ b/base/memory/weak_ptr.cc
@@ -4,50 +4,55 @@ #include "base/memory/weak_ptr.h" +#include "base/debug/leak_annotations.h" + namespace base { namespace internal { -WeakReference::Flag::Flag() : is_valid_(true) { +static constexpr uintptr_t kTrueMask = ~static_cast<uintptr_t>(0); + +WeakReference::Flag::Flag() : is_valid_(kTrueMask) { +#if DCHECK_IS_ON() // Flags only become bound when checked for validity, or invalidated, // so that we can check that later validity/invalidation operations on // the same Flag take place on the same sequenced thread. sequence_checker_.DetachFromSequence(); +#endif } -void WeakReference::Flag::Invalidate() { - // The flag being invalidated with a single ref implies that there are no - // weak pointers in existence. Allow deletion on other thread in this case. - DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) - << "WeakPtrs must be invalidated on the same sequenced thread."; - is_valid_ = false; +WeakReference::Flag::Flag(WeakReference::Flag::NullFlagTag) : is_valid_(false) { + // There is no need for sequence_checker_.DetachFromSequence() because the + // null flag doesn't participate in the sequence checks. See DCHECK in + // Invalidate() and IsValid(). + + // Keep the object alive perpetually, even when there are no references to it. + AddRef(); } -bool WeakReference::Flag::IsValid() const { - DCHECK(sequence_checker_.CalledOnValidSequence()) - << "WeakPtrs must be checked on the same sequenced thread."; - return is_valid_; +WeakReference::Flag* WeakReference::Flag::NullFlag() { + ANNOTATE_SCOPED_MEMORY_LEAK; + static Flag* g_null_flag = new Flag(kNullFlagTag); + return g_null_flag; } -WeakReference::Flag::~Flag() { -} +WeakReference::Flag::~Flag() {} -WeakReference::WeakReference() { -} - -WeakReference::WeakReference(const Flag* flag) : flag_(flag) { -} +WeakReference::WeakReference() : flag_(Flag::NullFlag()) {} WeakReference::~WeakReference() { } -WeakReference::WeakReference(WeakReference&& other) = default; +WeakReference::WeakReference(const Flag* flag) : flag_(flag) {} + +WeakReference::WeakReference(WeakReference&& other) + : flag_(std::move(other.flag_)) { + other.flag_ = Flag::NullFlag(); +} WeakReference::WeakReference(const WeakReference& other) = default; -bool WeakReference::is_valid() const { return flag_.get() && flag_->IsValid(); } - -WeakReferenceOwner::WeakReferenceOwner() { -} +WeakReferenceOwner::WeakReferenceOwner() + : flag_(WeakReference::Flag::NullFlag()) {} WeakReferenceOwner::~WeakReferenceOwner() { Invalidate(); @@ -62,10 +67,8 @@ } void WeakReferenceOwner::Invalidate() { - if (flag_.get()) { - flag_->Invalidate(); - flag_ = NULL; - } + flag_->Invalidate(); + flag_ = WeakReference::Flag::NullFlag(); } WeakPtrBase::WeakPtrBase() {
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h index d7d590b..dec5153 100644 --- a/base/memory/weak_ptr.h +++ b/base/memory/weak_ptr.h
@@ -96,16 +96,59 @@ public: Flag(); - void Invalidate(); - bool IsValid() const; + // Get a pointer to the "Null Flag", a sentinel object used by WeakReference + // objects that don't point to a valid Flag, either because they're default + // constructed or because they have been invalidated. This can be used like + // any other Flag object, but it is invalidated already from the start, and + // its refcount will never reach zero. + static Flag* NullFlag(); + + void Invalidate() { +#if DCHECK_IS_ON() + if (this == NullFlag()) { + // The Null Flag does not participate in the sequence checks below. + // Since its state never changes, it can be accessed from any thread. + DCHECK(!is_valid_); + return; + } + // The flag being invalidated with a single ref implies that there are no + // weak pointers in existence. Allow deletion on other thread in this + // case. + DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) + << "WeakPtrs must be invalidated on the same sequenced thread."; +#endif + is_valid_ = 0; + } + + // Returns a pointer-sized bitmask of all 1s if valid or all 0s otherwise. + uintptr_t IsValid() const { +#if DCHECK_IS_ON() + if (this == NullFlag()) { + // The Null Flag does not participate in the sequence checks below. + // Since its state never changes, it can be accessed from any thread. + DCHECK(!is_valid_); + return 0; + } + DCHECK(sequence_checker_.CalledOnValidSequence()) + << "WeakPtrs must be checked on the same sequenced thread."; +#endif + return is_valid_; + } private: friend class base::RefCountedThreadSafe<Flag>; + enum NullFlagTag { kNullFlagTag }; + Flag(NullFlagTag); + ~Flag(); + uintptr_t is_valid_; +#if DCHECK_IS_ON() + // Even if SequenceChecker is an empty class in non-dcheck builds, it still + // takes up space in the class. SequenceChecker sequence_checker_; - bool is_valid_; +#endif }; WeakReference(); @@ -117,9 +160,11 @@ WeakReference& operator=(WeakReference&& other) = default; WeakReference& operator=(const WeakReference& other) = default; - bool is_valid() const; + uintptr_t is_valid() const { return flag_->IsValid(); } private: + // Note: To avoid null-checks, flag_ always points to either Flag::NullFlag() + // or some other object. scoped_refptr<const Flag> flag_; }; @@ -131,7 +176,7 @@ WeakReference GetRef() const; bool HasRefs() const { - return flag_.get() && !flag_->HasOneRef(); + return flag_ != WeakReference::Flag::NullFlag() && !flag_->HasOneRef(); } void Invalidate(); @@ -222,7 +267,13 @@ WeakPtr(WeakPtr<U>&& other) : WeakPtrBase(std::move(other)), ptr_(other.ptr_) {} - T* get() const { return ref_.is_valid() ? ptr_ : nullptr; } + T* get() const { + // Intentionally bitwise and; see command on Flag::IsValid(). This provides + // a fast way of conditionally retrieving the pointer, and conveniently sets + // EFLAGS for any null-check performed by the caller. + return reinterpret_cast<T*>(ref_.is_valid() & + reinterpret_cast<uintptr_t>(ptr_)); + } T& operator*() const { DCHECK(get() != nullptr);
diff --git a/base/message_loop/message_loop_test.cc b/base/message_loop/message_loop_test.cc index de607002..b764596 100644 --- a/base/message_loop/message_loop_test.cc +++ b/base/message_loop/message_loop_test.cc
@@ -368,7 +368,7 @@ std::unique_ptr<MessagePump> pump(factory()); MessageLoop loop(std::move(pump)); - int depth = 100; + int depth = 50; ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, BindOnce(&NestingFunc, &depth)); RunLoop().Run();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 63010bdf..304ff5a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -84,7 +84,6 @@ import org.chromium.chrome.browser.multiwindow.MultiInstanceChromeTabbedActivity; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; -import org.chromium.chrome.browser.ntp.ChromeHomeNewTabPage; import org.chromium.chrome.browser.ntp.NativePageAssassin; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.ntp.NewTabPageUma; @@ -1713,12 +1712,11 @@ if (!mUIInitialized) return false; final Tab currentTab = getActivityTab(); - // Close the bottom sheet before trying to navigate back. If the tab is on the NTP, fall - // through to decide if the browser should be sent into the background. + // Close the bottom sheet before trying to navigate back. if (getBottomSheet() != null - && getBottomSheet().getSheetState() != BottomSheet.SHEET_STATE_PEEK - && (currentTab == null - || !(currentTab.getNativePage() instanceof ChromeHomeNewTabPage))) { + && getBottomSheet().getSheetState() != BottomSheet.SHEET_STATE_PEEK) { + getBottomSheet().getBottomSheetMetrics().setSheetCloseReason( + BottomSheetMetrics.CLOSED_BY_BACK_PRESS); getBottomSheet().setSheetState(BottomSheet.SHEET_STATE_PEEK, true); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeIncognitoNewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeIncognitoNewTabPage.java deleted file mode 100644 index 55f379e..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeIncognitoNewTabPage.java +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.ntp; - -import android.content.Context; -import android.content.res.Resources; -import android.support.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; - -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; - -/** - * The incognito new tab page to display when Chrome Home is enabled. - */ -public class ChromeHomeIncognitoNewTabPage extends ChromeHomeNewTabPageBase { - private final View mView; - private final int mBackgroundColor; - private final int mThemeColor; - - /** - * Constructs a ChromeHomeIncognitoNewTabPage. - * @param context The context used to inflate the view. - * @param tab The {@link Tab} that is showing this new tab page. - * @param tabModelSelector The {@link TabModelSelector} used to open tabs. - * @param layoutManager The {@link LayoutManagerChrome} used to observe overview mode changes. - * This may be null if the NTP is created on startup due to - * PartnerBrowserCustomizations. - */ - public ChromeHomeIncognitoNewTabPage(final Context context, final Tab tab, - final TabModelSelector tabModelSelector, - @Nullable final LayoutManagerChrome layoutManager) { - super(context, tab, tabModelSelector, layoutManager); - - mView = LayoutInflater.from(context).inflate( - R.layout.chrome_home_incognito_new_tab_page, null); - initializeCloseButton(mView.findViewById(R.id.close_button)); - - Resources res = context.getResources(); - mBackgroundColor = ApiCompatibilityUtils.getColor(res, R.color.ntp_bg_incognito); - mThemeColor = ApiCompatibilityUtils.getColor(res, R.color.incognito_primary_color); - } - - @Override - public View getView() { - return mView; - } - - @Override - public int getBackgroundColor() { - return mBackgroundColor; - } - - @Override - public int getThemeColor() { - return mThemeColor; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java deleted file mode 100644 index d31f9617..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java +++ /dev/null
@@ -1,120 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.ntp; - -import android.content.Context; -import android.content.res.Resources; -import android.support.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; - -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; -import org.chromium.chrome.browser.ntp.LogoBridge.Logo; -import org.chromium.chrome.browser.ntp.LogoBridge.LogoObserver; -import org.chromium.chrome.browser.search_engines.TemplateUrlService; -import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrlServiceObserver; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; - -/** - * The new tab page to display when Chrome Home is enabled. - */ -public class ChromeHomeNewTabPage - extends ChromeHomeNewTabPageBase implements TemplateUrlServiceObserver { - private final LogoDelegateImpl mLogoDelegate; - - private final View mView; - private final LogoView mLogoView; - - private final int mBackgroundColor; - private final int mThemeColor; - - /** - * Constructs a ChromeHomeNewTabPage. - * @param context The context used to inflate the view. - * @param tab The {@link Tab} that is showing this new tab page. - * @param tabModelSelector The {@link TabModelSelector} used to open tabs. - * @param layoutManager The {@link LayoutManagerChrome} used to observe overview mode changes. - * This may be null if the NTP is created on startup due to - * PartnerBrowserCustomizations. - */ - public ChromeHomeNewTabPage(final Context context, final Tab tab, - final TabModelSelector tabModelSelector, - @Nullable final LayoutManagerChrome layoutManager) { - super(context, tab, tabModelSelector, layoutManager); - - mView = LayoutInflater.from(context).inflate(R.layout.chrome_home_new_tab_page, null); - mLogoView = (LogoView) mView.findViewById(R.id.search_provider_logo); - initializeCloseButton(mView.findViewById(R.id.close_button)); - - Resources res = context.getResources(); - mBackgroundColor = ApiCompatibilityUtils.getColor(res, R.color.ntp_bg); - mThemeColor = ApiCompatibilityUtils.getColor(res, R.color.default_primary_color); - - mLogoDelegate = initializeLogoView(); - - } - - @Override - public View getView() { - return mView; - } - - @Override - public int getBackgroundColor() { - return mBackgroundColor; - } - - @Override - public int getThemeColor() { - return mThemeColor; - } - - @Override - public boolean needsToolbarShadow() { - return false; - } - - @Override - public void updateForUrl(String url) {} - - @Override - public void destroy() { - super.destroy(); - mLogoDelegate.destroy(); - } - - private void updateSearchProviderLogoVisibility() { - boolean hasLogo = TemplateUrlService.getInstance().doesDefaultSearchEngineHaveLogo(); - mLogoView.setVisibility(hasLogo ? View.VISIBLE : View.GONE); - } - - private LogoDelegateImpl initializeLogoView() { - TemplateUrlService.getInstance().addObserver(this); - - final LogoDelegateImpl logoDelegate = new LogoDelegateImpl(mTab, mLogoView); - logoDelegate.getSearchProviderLogo(new LogoObserver() { - @Override - public void onLogoAvailable(Logo logo, boolean fromCache) { - if (logo == null && fromCache) return; - mLogoView.setDelegate(logoDelegate); - mLogoView.updateLogo(logo); - // TODO(twellington): The new logo may be taller than the default logo. Adjust - // the view positioning. - } - }); - updateSearchProviderLogoVisibility(); - return logoDelegate; - } - - // TemplateUrlServiceObserver overrides. - - @Override - public void onTemplateURLServiceChanged() { - updateSearchProviderLogoVisibility(); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java deleted file mode 100644 index be47bd46..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java +++ /dev/null
@@ -1,211 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.ntp; - -import android.content.Context; -import android.support.annotation.CallSuper; -import android.support.annotation.Nullable; -import android.text.TextUtils; -import android.view.View; -import android.view.View.OnClickListener; - -import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeTabbedActivity; -import org.chromium.chrome.browser.NativePage; -import org.chromium.chrome.browser.UrlConstants; -import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; -import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; -import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; -import org.chromium.chrome.browser.tab.EmptyTabObserver; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetMetrics; -import org.chromium.content_public.browser.LoadUrlParams; - -/** - * The base class for the new tab pages displayed in Chrome Home. - */ -public abstract class ChromeHomeNewTabPageBase implements NativePage { - final Tab mTab; - final TabObserver mTabObserver; - final TabModelSelector mTabModelSelector; - final OverviewModeObserver mOverviewModeObserver; - @Nullable - final LayoutManagerChrome mLayoutManager; - BottomSheet mBottomSheet; - final String mTitle; - - private boolean mShowOverviewOnClose; - private View mCloseButton; - - /** - * Constructs a ChromeHomeNewTabPageBase. - * @param context The context used to inflate the view. - * @param tab The {@link Tab} that is showing this new tab page. - * @param tabModelSelector The {@link TabModelSelector} used to open tabs. - * @param layoutManager The {@link LayoutManagerChrome} used to observe overview mode changes. - * This may be null if the NTP is created on startup due to - * PartnerBrowserCustomizations. - */ - public ChromeHomeNewTabPageBase(final Context context, final Tab tab, - final TabModelSelector tabModelSelector, - @Nullable final LayoutManagerChrome layoutManager) { - mTab = tab; - mTabModelSelector = tabModelSelector; - mLayoutManager = layoutManager; - mBottomSheet = mTab.getActivity().getBottomSheet(); - mTitle = context.getResources().getString(R.string.button_new_tab); - - // A new tab may be created on startup due to PartnerBrowserCustomizations before the - // LayoutManagerChrome has been created (see ChromeTabbedActivity#initializeState()). - if (mLayoutManager != null) { - mShowOverviewOnClose = mLayoutManager.overviewVisible(); - - // TODO(twellington): Long term we will not allow NTPs to remain open after the user - // navigates away from them. Remove this observer after that happens. - mOverviewModeObserver = new EmptyOverviewModeObserver() { - @Override - public void onOverviewModeFinishedHiding() { - mShowOverviewOnClose = mTabModelSelector.getCurrentTab() == mTab; - } - }; - mLayoutManager.addOverviewModeObserver(mOverviewModeObserver); - } else { - mOverviewModeObserver = null; - } - - mTabObserver = new EmptyTabObserver() { - @Override - public void onShown(Tab tab) { - onNewTabPageShown(); - } - - @Override - public void onHidden(Tab tab) { - if (mTab.getActivity().getFadingBackgroundView() != null) { - mTab.getActivity().getFadingBackgroundView().setEnabled(true); - } - if (!mTab.isClosing()) mShowOverviewOnClose = false; - } - - @Override - public void onLoadUrl(Tab tab, LoadUrlParams params, int loadType) { - // If the NTP is loading, the sheet state will be set to SHEET_STATE_HALF. - if (TextUtils.equals(tab.getUrl(), getUrl())) return; - - mBottomSheet = mTab.getActivity().getBottomSheet(); - if (mBottomSheet != null) { - mBottomSheet.getBottomSheetMetrics().setSheetCloseReason( - BottomSheetMetrics.CLOSED_BY_NAVIGATION); - mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_PEEK, true); - } - } - }; - mTab.addObserver(mTabObserver); - - // If the tab is already showing TabObserver#onShown() won't be called, so we need to call - // #onNewTabPageShown() directly. - boolean tabAlreadyShowing = mTabModelSelector.getCurrentTab() == mTab; - if (tabAlreadyShowing) onNewTabPageShown(); - - if (mBottomSheet != null) { - mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_HALF, true); - mBottomSheet.getBottomSheetMetrics().recordSheetOpenReason( - BottomSheetMetrics.OPENED_BY_NEW_TAB_CREATION); - } - - // TODO(twellington): disallow moving the NTP to the other window in Android N+ - // multi-window mode. - } - - @Override - public String getTitle() { - return mTitle; - } - - @Override - public String getUrl() { - return UrlConstants.NTP_URL; - } - - @Override - public String getHost() { - return UrlConstants.NTP_HOST; - } - - @Override - public boolean needsToolbarShadow() { - return false; - } - - @Override - public void updateForUrl(String url) {} - - @Override - @CallSuper - public void destroy() { - // The next tab will be selected before this one is destroyed. If the currently selected - // tab is a Chrome Home new tab page, the FadingBackgroundView should not be enabled. - if (mTab.getActivity().getFadingBackgroundView() != null) { - mTab.getActivity().getFadingBackgroundView().setEnabled( - !isTabChromeHomeNewTabPage(mTabModelSelector.getCurrentTab())); - } - - if (mLayoutManager != null) { - mLayoutManager.removeOverviewModeObserver(mOverviewModeObserver); - } - mTab.removeObserver(mTabObserver); - } - - private void onNewTabPageShown() { - if (mTab.getActivity().getFadingBackgroundView() != null) { - mTab.getActivity().getFadingBackgroundView().setEnabled(false); - } - } - - private boolean isTabChromeHomeNewTabPage(Tab tab) { - return tab != null && tab.getUrl().equals(getUrl()); - } - - void initializeCloseButton(View closeButton) { - mCloseButton = closeButton; - mCloseButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mBottomSheet = mTab.getActivity().getBottomSheet(); - if (mBottomSheet != null) { - mBottomSheet.getBottomSheetMetrics().setSheetCloseReason( - BottomSheetMetrics.CLOSED_BY_NTP_CLOSE_BUTTON); - mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_PEEK, true); - } - - if (mShowOverviewOnClose && getLayoutManager() != null) { - getLayoutManager().showOverview(false); - } - - // Close the tab after showing the overview mode so the bottom sheet doesn't open - // if another NTP is selected when this one is closed. - // TODO(twellington): remove this comment after only one NTP may be open at a time. - mTabModelSelector.closeTab(mTab); - } - }); - } - - private LayoutManagerChrome getLayoutManager() { - if (mLayoutManager != null) return mLayoutManager; - - return ((ChromeTabbedActivity) mTab.getActivity()).getLayoutManager(); - } - - // Methods for testing. - - @VisibleForTesting - public View getCloseButtonForTests() { - return mCloseButton; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java index c423cab..ac108f9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java
@@ -10,7 +10,6 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.NativePage; import org.chromium.chrome.browser.NativePageHost; import org.chromium.chrome.browser.TabLoadStatus; @@ -22,7 +21,8 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.util.FeatureUtilities; +import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; +import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetMetrics; import org.chromium.content_public.browser.LoadUrlParams; /** @@ -35,14 +35,13 @@ static class NativePageBuilder { protected NativePage buildNewTabPage(ChromeActivity activity, Tab tab, TabModelSelector tabModelSelector) { - if (FeatureUtilities.isChromeHomeEnabled()) { - if (tab.isIncognito()) { - return new ChromeHomeIncognitoNewTabPage(activity, tab, tabModelSelector, - ((ChromeTabbedActivity) activity).getLayoutManager()); - } else { - return new ChromeHomeNewTabPage(activity, tab, tabModelSelector, - ((ChromeTabbedActivity) activity).getLayoutManager()); - } + if (activity.getBottomSheet() != null) { + BottomSheet sheet = activity.getBottomSheet(); + sheet.getBottomSheetMetrics().recordNativeNewTabPageShown(); + sheet.getBottomSheetMetrics().recordSheetOpenReason( + BottomSheetMetrics.OPENED_BY_NEW_TAB_CREATION); + sheet.setSheetState(BottomSheet.SHEET_STATE_FULL, true); + return null; } else if (tab.isIncognito()) { return new IncognitoNewTabPage(activity); } else { @@ -164,7 +163,7 @@ assert false; return null; } - page.updateForUrl(url); + if (page != null) page.updateForUrl(url); return page; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java index 9e859e6..0eab84b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; import org.chromium.chrome.browser.suggestions.TileGrid; import org.chromium.chrome.browser.suggestions.TileGroup; +import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import java.util.List; @@ -182,7 +183,7 @@ /** Resets suggestions, pulling the current state as known by the backend. */ public void refreshSuggestions() { - if (ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME)) { + if (FeatureUtilities.isChromeHomeEnabled()) { mSections.synchroniseWithSource(); } else { mSections.refreshSuggestions();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java index 773e7a67..ccd6938 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
@@ -6,7 +6,6 @@ import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ntp.snippets.CategoryInt; import org.chromium.chrome.browser.ntp.snippets.CategoryStatus; import org.chromium.chrome.browser.ntp.snippets.KnownCategories; @@ -17,6 +16,7 @@ import org.chromium.chrome.browser.suggestions.DestructionObserver; import org.chromium.chrome.browser.suggestions.SuggestionsRanker; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; +import org.chromium.chrome.browser.util.FeatureUtilities; import java.util.Arrays; import java.util.HashSet; @@ -189,7 +189,7 @@ @Override public boolean isResetAllowed() { - if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME)) return false; + if (!FeatureUtilities.isChromeHomeEnabled()) return false; // TODO(dgn): Also check if the bottom sheet is closed and how long since it has been closed // or opened, so that we don't refresh content while the user still cares about it.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditText.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditText.java index ce6e3eea5..1edaf88d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditText.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditText.java
@@ -33,9 +33,9 @@ private final AccessibilityManager mAccessibilityManager; - // This contains most of the logic. Lazily initialized in ensureModel() because View constructor - // may call its methods, so always call ensureModel() before accessing it. private AutocompleteEditTextModelBase mModel; + private boolean mIgnoreTextChangesForAutocomplete = true; + private boolean mLastEditWasPaste; /** * Whether default TextView scrolling should be disabled because autocomplete has been added. @@ -52,9 +52,18 @@ } private void ensureModel() { - // Lazy initialization here to ensure that model methods get called even in View's - // constructor. - if (mModel == null) mModel = new AutocompleteEditTextModel(this); + if (mModel == null) { + mModel = new AutocompleteEditTextModel(this); + // Feed initial values. + mModel.setIgnoreTextChangeFromAutocomplete(true); + mModel.onFocusChanged(hasFocus()); + mModel.onSetText(getText()); + mModel.onTextChanged(getText(), 0, 0, getText().length()); + mModel.onSelectionChanged(getSelectionStart(), getSelectionEnd()); + if (mLastEditWasPaste) mModel.onPaste(); + mModel.setIgnoreTextChangeFromAutocomplete(false); + mModel.setIgnoreTextChangeFromAutocomplete(mIgnoreTextChangesForAutocomplete); + } } /** @@ -64,28 +73,28 @@ * triggered. */ public void setIgnoreTextChangesForAutocomplete(boolean ignoreAutocomplete) { - ensureModel(); - mModel.setIgnoreTextChangeFromAutocomplete(ignoreAutocomplete); + mIgnoreTextChangesForAutocomplete = ignoreAutocomplete; + if (mModel != null) mModel.setIgnoreTextChangeFromAutocomplete(ignoreAutocomplete); } /** * @return The user text without the autocomplete text. */ public String getTextWithoutAutocomplete() { - ensureModel(); + if (mModel == null) return ""; return mModel.getTextWithoutAutocomplete(); } /** @return Text that includes autocomplete. */ public String getTextWithAutocomplete() { - ensureModel(); + if (mModel == null) return ""; return mModel.getTextWithAutocomplete(); } /** @return Whether any autocomplete information is specified on the current text. */ @VisibleForTesting public boolean hasAutocomplete() { - ensureModel(); + if (mModel == null) return false; return mModel.hasAutocomplete(); } @@ -96,21 +105,19 @@ * @return Whether we want to be showing inline autocomplete results. */ public boolean shouldAutocomplete() { - ensureModel(); + if (mModel == null) return false; return mModel.shouldAutocomplete(); } @Override protected void onSelectionChanged(int selStart, int selEnd) { - ensureModel(); - mModel.onSelectionChanged(selStart, selEnd); + if (mModel != null) mModel.onSelectionChanged(selStart, selEnd); super.onSelectionChanged(selStart, selEnd); } @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { - ensureModel(); - mModel.onFocusChanged(focused); + if (mModel != null) mModel.onFocusChanged(focused); super.onFocusChanged(focused, direction, previouslyFocusedRect); } @@ -136,8 +143,8 @@ /** Call this when text is pasted. */ public void onPaste() { - ensureModel(); - mModel.onPaste(); + mLastEditWasPaste = true; + if (mModel != null) mModel.onPaste(); } /** @@ -149,8 +156,7 @@ public void setAutocompleteText(CharSequence userText, CharSequence inlineAutocompleteText) { boolean emptyAutocomplete = TextUtils.isEmpty(inlineAutocompleteText); if (!emptyAutocomplete) mDisableTextScrollingFromAutocomplete = true; - ensureModel(); - mModel.setAutocompleteText(userText, inlineAutocompleteText); + if (mModel != null) mModel.setAutocompleteText(userText, inlineAutocompleteText); } /** @@ -158,15 +164,15 @@ * currently displayed. */ public int getAutocompleteLength() { - ensureModel(); + if (mModel == null) return 0; return mModel.getAutocompleteText().length(); } @Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { super.onTextChanged(text, start, lengthBefore, lengthAfter); - ensureModel(); - mModel.onTextChanged(text, start, lengthBefore, lengthAfter); + mLastEditWasPaste = false; + if (mModel != null) mModel.onTextChanged(text, start, lengthBefore, lengthAfter); } @Override @@ -187,14 +193,12 @@ StrictMode.setThreadPolicy(oldPolicy); } } - ensureModel(); - mModel.onSetText(text); + if (mModel != null) mModel.onSetText(text); } @Override public void sendAccessibilityEventUnchecked(AccessibilityEvent event) { - ensureModel(); - if (mModel.shouldIgnoreTextChangeFromAutocomplete()) { + if (mIgnoreTextChangesForAutocomplete) { if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED || event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) { if (DEBUG) Log.i(TAG, "Ignoring accessibility event from autocomplete."); @@ -218,7 +222,7 @@ @VisibleForTesting public InputConnection getInputConnection() { - ensureModel(); + if (mModel == null) return null; return mModel.getInputConnection(); } @@ -234,6 +238,11 @@ @VisibleForTesting public InputConnection createInputConnection(InputConnection target) { + // Initially, target is null until View gets the focus. + if (target == null && mModel == null) { + if (DEBUG) Log.i(TAG, "createInputConnection - ignoring null target."); + return null; + } ensureModel(); InputConnection retVal = mModel.onCreateInputConnection(target); if (mIgnoreImeForTest) return null; @@ -249,9 +258,8 @@ /** * @return Whether the current UrlBar input has been pasted from the clipboard. */ - public boolean isPastedText() { - ensureModel(); - return mModel.isPastedText(); + public boolean wasLastEditPaste() { + return mLastEditWasPaste; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModel.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModel.java index 23b5fb8c..2c669ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModel.java
@@ -35,9 +35,10 @@ private boolean mIgnoreTextChangeFromAutocomplete = true; private boolean mLastEditWasDelete; - private boolean mIsPastedText; + private boolean mLastEditWasPaste; public AutocompleteEditTextModel(AutocompleteEditTextModel.Delegate delegate) { + if (DEBUG) Log.i(TAG, "constructor"); mDelegate = delegate; mAutocompleteSpan = new AutocompleteSpan(); } @@ -92,7 +93,7 @@ public boolean shouldAutocomplete() { if (mLastEditWasDelete) return false; Editable text = mDelegate.getText(); - return isCursorAtEndOfTypedText() && !isPastedText() && mBatchEditNestCount == 0 + return isCursorAtEndOfTypedText() && !mLastEditWasPaste && mBatchEditNestCount == 0 && BaseInputConnection.getComposingSpanEnd(text) == BaseInputConnection.getComposingSpanStart(text); } @@ -251,7 +252,7 @@ } else { mTextDeletedInBatchMode = textDeleted; } - mIsPastedText = false; + mLastEditWasPaste = false; } @Override @@ -432,19 +433,9 @@ } @Override - public boolean shouldIgnoreTextChangeFromAutocomplete() { - return mIgnoreTextChangeFromAutocomplete; - } - - @Override public void onPaste() { if (DEBUG) Log.i(TAG, "onPaste"); - mIsPastedText = true; - } - - @Override - public boolean isPastedText() { - return mIsPastedText; + mLastEditWasPaste = true; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModelBase.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModelBase.java index 674300d5..3e2ed62 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModelBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextModelBase.java
@@ -92,11 +92,6 @@ void onPaste(); /** - * @return Whether or not the user just pasted text. - */ - boolean isPastedText(); - - /** * @return The whole text including both user text and autocomplete text. */ String getTextWithAutocomplete(); @@ -118,9 +113,6 @@ */ void setIgnoreTextChangeFromAutocomplete(boolean ignore); - /** @return Whether we should ignore text change from autocomplete. */ - boolean shouldIgnoreTextChangeFromAutocomplete(); - /** * Autocompletes the text and selects the text that was not entered by the user. Using append() * instead of setText() to preserve the soft-keyboard layout.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 20f0722..b1becb8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -412,8 +412,9 @@ // omnibox results. There is one special case where the suggestion text was pasted, // where we want the transition type to be LINK. int transition = suggestionMatch.getType() == OmniboxSuggestionType.URL_WHAT_YOU_TYPED - && mUrlBar.isPastedText() ? PageTransition.LINK - : suggestionMatch.getTransition(); + && mUrlBar.wasLastEditPaste() + ? PageTransition.LINK + : suggestionMatch.getTransition(); loadUrlFromOmniboxMatch(suggestionMatchUrl, transition, suggestionMatchPosition, suggestionMatch.getType());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSitesBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSitesBridge.java index ad5ff12..0d0fe2c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSitesBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSitesBridge.java
@@ -6,10 +6,10 @@ import org.chromium.base.ContextUtils; import org.chromium.base.annotations.JNIAdditionalImport; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.util.FeatureUtilities; /** * Methods to bridge into native history to provide most recent urls, titles and thumbnails. @@ -28,7 +28,7 @@ mNativeMostVisitedSitesBridge = nativeInit(profile); // The first tile replaces the home page button (only) in Chrome Home. To support that, // provide information about the home page. - if (ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME)) { + if (FeatureUtilities.isChromeHomeEnabled()) { nativeSetHomePageClient(mNativeMostVisitedSitesBridge, new HomePageClient() { @Override public boolean isHomePageEnabled() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java index 6257c64..cd0a7f2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.tabmodel; +import android.support.annotation.Nullable; + import org.chromium.base.TraceEvent; import org.chromium.chrome.browser.TabState; import org.chromium.chrome.browser.UrlConstants; @@ -33,8 +35,9 @@ * @param loadUrlParams parameters of the url load. * @param type Information about how the tab was launched. * @param parent the parent tab, if present. - * @return The new tab. + * @return The new tab or null if no tab was created. */ + @Nullable public abstract Tab createNewTab( LoadUrlParams loadUrlParams, TabModel.TabLaunchType type, Tab parent); @@ -54,8 +57,9 @@ * @param url the URL to open. * @param type the type of action that triggered that launch. Determines how the tab is * opened (for example, in the foreground or background). - * @return the created tab. + * @return The new tab or null if no tab was created. */ + @Nullable public abstract Tab launchUrl(String url, TabModel.TabLaunchType type); /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java index fbd11b8..6847e8f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -604,6 +604,9 @@ Log.w(TAG, "Failed to restore TabState; creating Tab with last known URL."); Tab fallbackTab = mTabCreatorManager.getTabCreator(isIncognito).createNewTab( new LoadUrlParams(tabToRestore.url), TabModel.TabLaunchType.FROM_RESTORE, null); + + if (fallbackTab == null) return; + tabId = fallbackTab.getId(); model.moveTab(tabId, restoredIndex); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index 570a7ae..b13b6bae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -42,6 +42,7 @@ import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; import org.chromium.chrome.browser.ntp.NativePageFactory; +import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -752,6 +753,11 @@ @Override public int loadUrl(LoadUrlParams params, boolean incognito) { + if (NewTabPage.isNTPUrl(params.getUrl())) { + displayNewTabUi(incognito); + return TabLoadStatus.PAGE_LOAD_FAILED; + } + boolean isShowingNtp = isShowingNewTab(); for (BottomSheetObserver o : mObservers) o.onLoadUrl(params.getUrl());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java index 05e8a147b..9fb1154 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java
@@ -33,12 +33,12 @@ private static final int OPENED_BY_BOUNDARY = 4; /** The different ways that the bottom sheet can be closed. */ - @IntDef({CLOSED_BY_NONE, CLOSED_BY_SWIPE, CLOSED_BY_NTP_CLOSE_BUTTON, CLOSED_BY_TAP_SCRIM, + @IntDef({CLOSED_BY_NONE, CLOSED_BY_SWIPE, CLOSED_BY_BACK_PRESS, CLOSED_BY_TAP_SCRIM, CLOSED_BY_NAVIGATION}) public @interface SheetCloseReason {} private static final int CLOSED_BY_NONE = -1; public static final int CLOSED_BY_SWIPE = 0; - public static final int CLOSED_BY_NTP_CLOSE_BUTTON = 1; + public static final int CLOSED_BY_BACK_PRESS = 1; public static final int CLOSED_BY_TAP_SCRIM = 2; public static final int CLOSED_BY_NAVIGATION = 3; @@ -176,8 +176,8 @@ case CLOSED_BY_SWIPE: RecordUserAction.record("Android.ChromeHome.ClosedBySwipe"); break; - case CLOSED_BY_NTP_CLOSE_BUTTON: - RecordUserAction.record("Android.ChromeHome.ClosedByNTPCloseButton"); + case CLOSED_BY_BACK_PRESS: + RecordUserAction.record("Android.ChromeHome.ClosedByBackPress"); break; case CLOSED_BY_TAP_SCRIM: RecordUserAction.record("Android.ChromeHome.ClosedByTapScrim"); @@ -192,4 +192,12 @@ assert false; } } + + /** + * Records that a user navigation instructed the NativePageFactory to create a native page for + * the NTP. This may occur if the user has NTP URLs in a tab's navigation history. + */ + public void recordNativeNewTabPageShown() { + RecordUserAction.record("Android.ChromeHome.NativeNTPShown"); + } }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 3b1bc49..83f1a16 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -606,9 +606,6 @@ "java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializer.java", "java/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdater.java", "java/src/org/chromium/chrome/browser/notifications/channels/SiteChannelsManager.java", - "java/src/org/chromium/chrome/browser/ntp/ChromeHomeIncognitoNewTabPage.java", - "java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java", - "java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java", "java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java", "java/src/org/chromium/chrome/browser/ntp/ContextMenuManager.java", "java/src/org/chromium/chrome/browser/ntp/FakeRecentlyClosedTabManager.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java index 9b6f9af..38105ad 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
@@ -87,6 +87,13 @@ }); } + private static final OnSuggestionsReceivedListener sEmptySuggestionListener = + new OnSuggestionsReceivedListener() { + @Override + public void onSuggestionsReceived( + List<OmniboxSuggestion> suggestions, String inlineAutocompleteText) {} + }; + /** * Sanity check of Omnibox. The problem in http://b/5021723 would * cause this to fail (hang or crash). @@ -168,8 +175,8 @@ } }); - final TestAutocompleteController controller = new TestAutocompleteController( - locationBar, null, null); + final TestAutocompleteController controller = new TestAutocompleteController(locationBar, + sEmptySuggestionListener, new HashMap<String, List<SuggestionsResult>>()); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override @@ -208,17 +215,8 @@ final ImageButton deleteButton = (ImageButton) mActivityTestRule.getActivity().findViewById(R.id.delete_button); - final OnSuggestionsReceivedListener emptySuggestionListener = - new OnSuggestionsReceivedListener() { - @Override - public void onSuggestionsReceived( - List<OmniboxSuggestion> suggestions, String inlineAutocompleteText) { - } - }; - - final TestAutocompleteController controller = new TestAutocompleteController( - locationBar, emptySuggestionListener, - new HashMap<String, List<SuggestionsResult>>()); + final TestAutocompleteController controller = new TestAutocompleteController(locationBar, + sEmptySuggestionListener, new HashMap<String, List<SuggestionsResult>>()); OmniboxTestUtils.toggleUrlBarFocus(urlBar, true); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @@ -260,17 +258,8 @@ (LocationBarLayout) mActivityTestRule.getActivity().findViewById(R.id.location_bar); final UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar); - final OnSuggestionsReceivedListener emptySuggestionListener = - new OnSuggestionsReceivedListener() { - @Override - public void onSuggestionsReceived(List<OmniboxSuggestion> suggestions, - String inlineAutocompleteText) { - } - }; - - final TestAutocompleteController controller = new TestAutocompleteController( - locationBar, emptySuggestionListener, - new HashMap<String, List<SuggestionsResult>>()); + final TestAutocompleteController controller = new TestAutocompleteController(locationBar, + sEmptySuggestionListener, new HashMap<String, List<SuggestionsResult>>()); OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java index c43be51..80ae4b39 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java
@@ -26,9 +26,7 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.LauncherShortcutActivity; -import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; -import org.chromium.chrome.browser.ntp.ChromeHomeNewTabPageBase; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; @@ -45,8 +43,7 @@ import java.util.concurrent.TimeoutException; /** - * Tests for the NTP UI displayed when Chrome Home is enabled. TODO(twellington): Remove remaining - * tests for ChromeHomeNewTabPage after it's completely removed. + * Tests for the NTP UI displayed when Chrome Home is enabled. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({BottomSheetTestRule.ENABLE_CHROME_HOME, @@ -519,72 +516,6 @@ assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected()); } - @Test - @SmallTest - public void testCloseNTP() - throws IllegalArgumentException, InterruptedException, TimeoutException { - // Create a new tab. - createNewBlankTab(false); - loadChromeHomeNewTab(); - - // Close the new tab. - closeNewTab(); - assertEquals(1, mTabModelSelector.getTotalTabCount()); - } - - @Test - @SmallTest - public void testCloseNTP_Incognito() - throws IllegalArgumentException, InterruptedException, TimeoutException { - // Create new incognito NTP. - createNewBlankTab(true); - loadChromeHomeNewTab(); - - // Close the new tab. - closeNewTab(); - assertEquals(1, mTabModelSelector.getTotalTabCount()); - } - - private void loadChromeHomeNewTab() throws InterruptedException { - final Tab tab = mActivity.getActivityTab(); - ChromeTabUtils.loadUrlOnUiThread(tab, UrlConstants.NTP_URL); - ChromeTabUtils.waitForTabPageLoaded(tab, UrlConstants.NTP_URL); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - } - - private void createNewBlankTab(final boolean incognito) { - MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), - mActivity, incognito ? R.id.new_incognito_tab_menu_id : R.id.new_tab_menu_id); - - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - mBottomSheet.loadUrl(new LoadUrlParams("about:blank"), incognito); - mActivity.getLayoutManager().getActiveLayout().finishAnimationsForTests(); - } - }); - } - - private void closeNewTab() throws InterruptedException, TimeoutException { - Tab tab = mActivity.getActivityTab(); - TestTabModelObserver observer = - tab.isIncognito() ? mIncognitoTabModelObserver : mNormalTabModelObserver; - int currentCallCount = observer.mDidCloseTabCallbackHelper.getCallCount(); - final ChromeHomeNewTabPageBase newTabPage = (ChromeHomeNewTabPageBase) tab.getNativePage(); - - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - newTabPage.getCloseButtonForTests().callOnClick(); - mActivity.getLayoutManager().getActiveLayout().finishAnimationsForTests(); - } - }); - - observer.mDidCloseTabCallbackHelper.waitForCallback(currentCallCount, 1); - - validateState(false, BottomSheet.SHEET_STATE_PEEK); - } - private void validateState(boolean chromeHomeTabPageSelected, int expectedEndState) { ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java index a1ebffd4..109ae734 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java
@@ -81,13 +81,14 @@ MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; mEmbedder = spy(new AutocompleteEmbedder()); - mAutocomplete = spy(new TestAutocompleteEditText(mEmbedder, mContext, null)); + mAutocomplete = new TestAutocompleteEditText(mEmbedder, mContext, null); assertNotNull(mAutocomplete); // Note: this cannot catch the first {@link // AutocompleteEditText#onAutocompleteTextStateChanged(boolean)}, which is caused // by View constructor's call to setText(). mInOrder = inOrder(mEmbedder); - mAutocomplete.onCreateInputConnection(new EditorInfo()); + assertTrue(mAutocomplete.requestFocus()); + assertNotNull(mAutocomplete.onCreateInputConnection(new EditorInfo())); mInputConnection = mAutocomplete.getInputConnection(); assertNotNull(mInputConnection); mInOrder.verifyNoMoreInteractions();
diff --git a/chrome/browser/android/compositor/tab_content_manager.h b/chrome/browser/android/compositor/tab_content_manager.h index 331330b..e5e7763f 100644 --- a/chrome/browser/android/compositor/tab_content_manager.h +++ b/chrome/browser/android/compositor/tab_content_manager.h
@@ -7,11 +7,11 @@ #include <jni.h> -#include <unordered_map> +#include <map> #include "base/android/jni_android.h" #include "base/android/jni_weak_ref.h" -#include "base/containers/hash_tables.h" +#include "base/containers/flat_map.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "cc/layers/ui_resource_layer.h" @@ -105,10 +105,12 @@ private: class TabReadbackRequest; - using LayerMap = base::hash_map<int, scoped_refptr<cc::Layer>>; - using ThumbnailLayerMap = base::hash_map<int, scoped_refptr<ThumbnailLayer>>; + // TODO(bug 714384) check sizes and consider using base::flat_map if these + // layer maps are small. + using LayerMap = std::map<int, scoped_refptr<cc::Layer>>; + using ThumbnailLayerMap = std::map<int, scoped_refptr<ThumbnailLayer>>; using TabReadbackRequestMap = - std::unordered_map<int, std::unique_ptr<TabReadbackRequest>>; + base::flat_map<int, std::unique_ptr<TabReadbackRequest>>; void PutThumbnailIntoCache(int tab_id, float thumbnail_scale,
diff --git a/chrome/browser/android/data_usage/data_use_tab_model.h b/chrome/browser/android/data_usage/data_use_tab_model.h index cf15558..2e5877b 100644 --- a/chrome/browser/android/data_usage/data_use_tab_model.h +++ b/chrome/browser/android/data_usage/data_use_tab_model.h
@@ -7,13 +7,13 @@ #include <stddef.h> +#include <map> #include <memory> #include <string> #include <vector> #include "base/callback.h" #include "base/callback_forward.h" -#include "base/containers/hash_tables.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -239,7 +239,7 @@ FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, MatchingRuleFetchOnControlAppInstall); - typedef base::hash_map<SessionID::id_type, TabDataUseEntry> TabEntryMap; + using TabEntryMap = std::map<SessionID::id_type, TabDataUseEntry>; // Gets the current label of a tab, and the new label if a navigation event // occurs in the tab. |tab_id| is the source tab of the generated event,
diff --git a/chrome/browser/android/data_usage/data_use_ui_tab_model.h b/chrome/browser/android/data_usage/data_use_ui_tab_model.h index fe33bd4..c57a2d3 100644 --- a/chrome/browser/android/data_usage/data_use_ui_tab_model.h +++ b/chrome/browser/android/data_usage/data_use_ui_tab_model.h
@@ -5,10 +5,10 @@ #ifndef CHROME_BROWSER_ANDROID_DATA_USAGE_DATA_USE_UI_TAB_MODEL_H_ #define CHROME_BROWSER_ANDROID_DATA_USAGE_DATA_USE_UI_TAB_MODEL_H_ +#include <map> #include <memory> #include <string> -#include "base/containers/hash_tables.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -136,7 +136,7 @@ const std::string package; }; - typedef base::hash_map<SessionID::id_type, DataUseTrackingEvent> TabEvents; + typedef std::map<SessionID::id_type, DataUseTrackingEvent> TabEvents; // DataUseTabModel::TabDataUseObserver implementation: void NotifyTrackingStarting(SessionID::id_type tab_id) override;
diff --git a/chrome/browser/android/data_usage/external_data_use_reporter.h b/chrome/browser/android/data_usage/external_data_use_reporter.h index 22e1207..c0592776 100644 --- a/chrome/browser/android/data_usage/external_data_use_reporter.h +++ b/chrome/browser/android/data_usage/external_data_use_reporter.h
@@ -10,10 +10,10 @@ #include <memory> #include <string> +#include <unordered_map> #include <vector> #include "base/callback.h" -#include "base/containers/hash_tables.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/threading/thread_checker.h" @@ -171,8 +171,9 @@ size_t operator()(const DataUseReportKey& k) const; }; - typedef base::hash_map<DataUseReportKey, DataUseReport, DataUseReportKeyHash> - DataUseReports; + typedef std:: + unordered_map<DataUseReportKey, DataUseReport, DataUseReportKeyHash> + DataUseReports; // Maximum size of the data use report buffer. Once this limit is reached, new // reports will be ignored.
diff --git a/chrome/browser/android/history_report/data_provider.cc b/chrome/browser/android/history_report/data_provider.cc index 7fa938b..ce89fe2 100644 --- a/chrome/browser/android/history_report/data_provider.cc +++ b/chrome/browser/android/history_report/data_provider.cc
@@ -6,8 +6,9 @@ #include <stddef.h> +#include <map> + #include "base/bind.h" -#include "base/containers/hash_tables.h" #include "base/logging.h" #include "base/synchronization/waitable_event.h" #include "chrome/browser/android/history_report/delta_file_commons.h" @@ -27,7 +28,7 @@ namespace { static bool g_is_debug = false; -typedef base::hash_map<std::string, BookmarkModel::URLAndTitle*> BookmarkMap; +using BookmarkMap = std::map<std::string, BookmarkModel::URLAndTitle*>; struct Context { history::HistoryService* history_service;
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.h b/chrome/browser/android/thumbnail/thumbnail_cache.h index cd0378f..4422743 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.h +++ b/chrome/browser/android/thumbnail/thumbnail_cache.h
@@ -8,11 +8,11 @@ #include <stddef.h> #include <list> +#include <map> #include <set> #include <string> #include "base/bind.h" -#include "base/containers/hash_tables.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/memory_pressure_listener.h" @@ -90,8 +90,8 @@ GURL url_; }; - typedef ScopedPtrExpiringCache<TabId, Thumbnail> ExpiringThumbnailCache; - typedef base::hash_map<TabId, ThumbnailMetaData> ThumbnailMetaDataMap; + using ExpiringThumbnailCache = ScopedPtrExpiringCache<TabId, Thumbnail>; + using ThumbnailMetaDataMap = std::map<TabId, ThumbnailMetaData>; void RemoveFromDisk(TabId tab_id); static void RemoveFromDiskTask(TabId tab_id);
diff --git a/chrome/browser/android/vr_shell/BUILD.gn b/chrome/browser/android/vr_shell/BUILD.gn index b9716ae..cbf1cf07 100644 --- a/chrome/browser/android/vr_shell/BUILD.gn +++ b/chrome/browser/android/vr_shell/BUILD.gn
@@ -56,6 +56,10 @@ "textures/ui_texture.h", "textures/url_bar_texture.cc", "textures/url_bar_texture.h", + "toolbar_helper.cc", + "toolbar_helper.h", + "toolbar_state.cc", + "toolbar_state.h", "ui_browser_interface.h", "ui_elements/button.cc", "ui_elements/button.h", @@ -95,7 +99,7 @@ "//chrome/app:generated_resources", "//components/security_state/core", "//components/strings", - "//components/toolbar:vector_icons", + "//components/toolbar", "//components/url_formatter", "//components/vector_icons", "//skia", @@ -213,6 +217,7 @@ "//base/test:test_support", "//components:components_tests_pak", "//components/security_state/core", + "//components/toolbar:vector_icons", "//skia", "//testing/gmock", "//testing/gtest",
diff --git a/chrome/browser/android/vr_shell/textures/url_bar_texture.cc b/chrome/browser/android/vr_shell/textures/url_bar_texture.cc index 1e1a85c4..e4e8111 100644 --- a/chrome/browser/android/vr_shell/textures/url_bar_texture.cc +++ b/chrome/browser/android/vr_shell/textures/url_bar_texture.cc
@@ -8,10 +8,7 @@ #include "cc/paint/skia_paint_canvas.h" #include "chrome/browser/android/vr_shell/color_scheme.h" #include "chrome/browser/android/vr_shell/textures/render_text_wrapper.h" -#include "components/strings/grit/components_strings.h" -#include "components/toolbar/vector_icons.h" #include "components/url_formatter/url_formatter.h" -#include "ui/base/l10n/l10n_util.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font.h" #include "ui/gfx/font_list.h" @@ -19,7 +16,6 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/render_text.h" -#include "ui/gfx/vector_icon_types.h" #include "ui/vector_icons/vector_icons.h" namespace vr_shell { @@ -33,35 +29,13 @@ static constexpr float kBackIconHeight = 0.0375; static constexpr float kBackIconOffset = 0.005; static constexpr float kFieldSpacing = 0.014; -static constexpr float kSecurityIconHeight = 0.03; +static constexpr float kSecurityIconSize = 0.03; static constexpr float kUrlRightMargin = 0.02; static constexpr float kSeparatorWidth = 0.002; static constexpr float kChipTextLineMargin = kHeight * 0.3; using security_state::SecurityLevel; -// See ToolbarModelImpl::GetVectorIcon(). -const struct gfx::VectorIcon& GetSecurityIcon(SecurityLevel level) { - switch (level) { - case security_state::NONE: - case security_state::HTTP_SHOW_WARNING: - return toolbar::kHttpIcon; - case security_state::EV_SECURE: - case security_state::SECURE: - return toolbar::kHttpsValidIcon; - case security_state::SECURITY_WARNING: - // Surface Dubious as Neutral. - return toolbar::kHttpIcon; - case security_state::SECURE_WITH_POLICY_INSTALLED_CERT: // ChromeOS only. - return ui::kBusinessIcon; - case security_state::DANGEROUS: - return toolbar::kHttpsInvalidIcon; - default: - NOTREACHED(); - return toolbar::kHttpsInvalidIcon; - } -} - // See LocationBarView::GetSecureTextColor(). SkColor GetSchemeColor(SecurityLevel level, const ColorScheme& color_scheme) { switch (level) { @@ -83,21 +57,6 @@ } } -// See ToolbarModelImpl::GetSecureVerboseText(). -int GetSecurityTextId(SecurityLevel level, bool malware) { - switch (level) { - case security_state::HTTP_SHOW_WARNING: - return IDS_NOT_SECURE_VERBOSE_STATE; - case security_state::SECURE: - return IDS_SECURE_VERBOSE_STATE; - case security_state::DANGEROUS: - return (malware ? IDS_DANGEROUS_VERBOSE_STATE - : IDS_NOT_SECURE_VERBOSE_STATE); - default: - return 0; - } -} - void setEmphasis(vr_shell::RenderTextWrapper* render_text, bool emphasis, const gfx::Range& range, @@ -120,17 +79,17 @@ UrlBarTexture::UrlBarTexture( bool web_vr, const base::Callback<void(UiUnsupportedMode)>& failure_callback) - : security_level_(SecurityLevel::DANGEROUS), - has_back_button_(!web_vr), + : has_back_button_(!web_vr), has_security_chip_(false), failure_callback_(failure_callback) {} UrlBarTexture::~UrlBarTexture() = default; -void UrlBarTexture::SetURL(const GURL& gurl) { - if (gurl_ != gurl) - set_dirty(); - gurl_ = gurl; +void UrlBarTexture::SetToolbarState(const ToolbarState& state) { + if (state_ == state) + return; + state_ = state; + set_dirty(); } void UrlBarTexture::SetHistoryButtonsEnabled(bool can_go_back) { @@ -139,13 +98,6 @@ can_go_back_ = can_go_back; } -void UrlBarTexture::SetSecurityInfo(SecurityLevel level, bool malware) { - if (security_level_ != level || malware_ != malware) - set_dirty(); - security_level_ = level; - malware_ = malware; -} - float UrlBarTexture::ToPixels(float meters) const { return meters * size_.width() / kWidth; } @@ -266,36 +218,35 @@ } // Site security state icon. - if (!gurl_.is_empty()) { - left_edge += kFieldSpacing; - - gfx::RectF icon_region(left_edge, kHeight / 2 - kSecurityIconHeight / 2, - kSecurityIconHeight, kSecurityIconHeight); + left_edge += kFieldSpacing; + if (state_.security_level != security_state::NONE && + state_.vector_icon != nullptr) { + gfx::RectF icon_region(left_edge, kHeight / 2 - kSecurityIconSize / 2, + kSecurityIconSize, kSecurityIconSize); canvas->save(); canvas->translate(icon_region.x(), icon_region.y()); - const gfx::VectorIcon& icon = GetSecurityIcon(security_level_); - float icon_scale = kSecurityIconHeight / GetDefaultSizeOfVectorIcon(icon); + const gfx::VectorIcon& icon = *state_.vector_icon; + float icon_scale = kSecurityIconSize / GetDefaultSizeOfVectorIcon(icon); canvas->scale(icon_scale, icon_scale); PaintVectorIcon(&gfx_canvas, icon, - GetSchemeColor(security_level_, color_scheme())); + GetSchemeColor(state_.security_level, color_scheme())); canvas->restore(); security_hit_region_ = icon_region; - left_edge += kSecurityIconHeight + kFieldSpacing; + left_edge += kSecurityIconSize + kFieldSpacing; } canvas->restore(); // Draw security chip text (eg. "Not secure") next to the security icon. - int chip_string_id = GetSecurityTextId(security_level_, malware_); - if (has_security_chip_ && !gurl_.is_empty() && chip_string_id != 0) { + if (has_security_chip_ && state_.should_display_url) { float chip_max_width = kWidth - left_edge - kUrlRightMargin; gfx::Rect text_bounds(ToPixels(left_edge), 0, ToPixels(chip_max_width), ToPixels(kHeight)); int pixel_font_height = texture_size.height() * kFontHeight / kHeight; - SkColor chip_color = GetSchemeColor(security_level_, color_scheme()); - auto chip_text = l10n_util::GetStringUTF16(chip_string_id); + SkColor chip_color = GetSchemeColor(state_.security_level, color_scheme()); + const base::string16& chip_text = state_.secure_verbose_text; DCHECK(!chip_text.empty()); gfx::FontList font_list; @@ -330,16 +281,16 @@ left_edge += kFieldSpacing + kSeparatorWidth; } - if (!gurl_.is_empty()) { - if (last_drawn_gurl_ != gurl_ || - last_drawn_security_level_ != security_level_) { + if (state_.should_display_url) { + if (!url_render_text_ || last_drawn_gurl_ != state_.gurl || + last_drawn_security_level_ != state_.security_level) { float url_x = left_edge; float url_width = kWidth - url_x - kUrlRightMargin; gfx::Rect text_bounds(ToPixels(url_x), 0, ToPixels(url_width), ToPixels(kHeight)); RenderUrl(texture_size, text_bounds); - last_drawn_gurl_ = gurl_; - last_drawn_security_level_ = security_level_; + last_drawn_gurl_ = state_.gurl; + last_drawn_security_level_ = state_.security_level; } url_render_text_->Draw(&gfx_canvas); } @@ -349,7 +300,7 @@ const gfx::Rect& bounds) { url::Parsed parsed; const base::string16 text = url_formatter::FormatUrl( - gurl_, url_formatter::kFormatUrlOmitAll, net::UnescapeRule::NORMAL, + state_.gurl, url_formatter::kFormatUrlOmitAll, net::UnescapeRule::NORMAL, &parsed, nullptr, nullptr); int pixel_font_height = texture_size.height() * kFontHeight / kHeight; @@ -384,7 +335,7 @@ } vr_shell::RenderTextWrapper vr_render_text(render_text.get()); - ApplyUrlStyling(text, parsed, security_level_, &vr_render_text, + ApplyUrlStyling(text, parsed, state_.security_level, &vr_render_text, color_scheme()); url_render_text_ = std::move(render_text);
diff --git a/chrome/browser/android/vr_shell/textures/url_bar_texture.h b/chrome/browser/android/vr_shell/textures/url_bar_texture.h index 11e18d0..bc24715 100644 --- a/chrome/browser/android/vr_shell/textures/url_bar_texture.h +++ b/chrome/browser/android/vr_shell/textures/url_bar_texture.h
@@ -12,6 +12,8 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/android/vr_shell/textures/ui_texture.h" +#include "chrome/browser/android/vr_shell/toolbar_state.h" +#include "chrome/browser/android/vr_shell/ui_interface.h" #include "chrome/browser/android/vr_shell/ui_unsupported_mode.h" #include "components/security_state/core/security_state.h" #include "ui/gfx/geometry/rect_f.h" @@ -41,9 +43,8 @@ gfx::Size GetPreferredTextureSize(int width) const override; gfx::SizeF GetDrawnSize() const override; - void SetURL(const GURL& gurl); + void SetToolbarState(const ToolbarState& state); void SetHistoryButtonsEnabled(bool can_go_back); - void SetSecurityInfo(security_state::SecurityLevel level, bool malware); bool HitsBackButton(const gfx::PointF& position) const; bool HitsUrlBar(const gfx::PointF& position) const; @@ -76,10 +77,7 @@ bool back_pressed_ = false; bool can_go_back_ = false; - GURL gurl_; - security_state::SecurityLevel security_level_ = - security_state::SecurityLevel::NONE; - bool malware_ = false; + ToolbarState state_; GURL last_drawn_gurl_; bool has_back_button_ = true;
diff --git a/chrome/browser/android/vr_shell/textures/url_bar_texture_unittest.cc b/chrome/browser/android/vr_shell/textures/url_bar_texture_unittest.cc index 01709d4511..452a5920 100644 --- a/chrome/browser/android/vr_shell/textures/url_bar_texture_unittest.cc +++ b/chrome/browser/android/vr_shell/textures/url_bar_texture_unittest.cc
@@ -9,7 +9,9 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/android/vr_shell/textures/render_text_wrapper.h" +#include "chrome/browser/android/vr_shell/toolbar_state.h" #include "components/security_state/core/security_state.h" +#include "components/toolbar/vector_icons.h" #include "components/url_formatter/url_formatter.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -44,7 +46,11 @@ void DrawURL(const GURL& gurl) { unsupported_mode_ = UiUnsupportedMode::kCount; - SetURL(gurl); + ToolbarState state(gurl, SecurityLevel::HTTP_SHOW_WARNING, + &toolbar::kHttpsInvalidIcon, + base::UTF8ToUTF16("Not secure"), true); + ASSERT_TRUE(state.should_display_url); + SetToolbarState(state); sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul( texture_size_.width(), texture_size_.height()); DrawAndLayout(surface->getCanvas(), texture_size_); @@ -280,4 +286,10 @@ EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); } +TEST(UrlBarTexture, EmptyURL) { + TestUrlBarTexture texture; + texture.DrawURL(GURL()); + EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); +} + } // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/toolbar_helper.cc b/chrome/browser/android/vr_shell/toolbar_helper.cc new file mode 100644 index 0000000..3e1bbd7 --- /dev/null +++ b/chrome/browser/android/vr_shell/toolbar_helper.cc
@@ -0,0 +1,41 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/android/vr_shell/toolbar_helper.h" + +#include "base/memory/ptr_util.h" +#include "components/toolbar/toolbar_model_impl.h" + +class ToolbarModelDelegate; + +namespace vr_shell { + +namespace { + +// This number is arbitrary. For VR, use a number smaller than desktop's 32K, as +// the URL indicator does not show long URLs. +constexpr int kMaxURLDisplayChars = 1024; + +} // namespace + +ToolbarHelper::ToolbarHelper(UiInterface* ui, ToolbarModelDelegate* delegate) + : ui_(ui), + toolbar_model_( + base::MakeUnique<ToolbarModelImpl>(delegate, kMaxURLDisplayChars)) {} + +ToolbarHelper::~ToolbarHelper() {} + +void ToolbarHelper::Update() { + ToolbarState state( + toolbar_model_->GetURL(), toolbar_model_->GetSecurityLevel(true), + &toolbar_model_->GetVectorIcon(), toolbar_model_->GetSecureVerboseText(), + toolbar_model_->ShouldDisplayURL()); + + if (current_state_ == state) + return; + current_state_ = state; + ui_->SetToolbarState(state); +} + +} // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/toolbar_helper.h b/chrome/browser/android/vr_shell/toolbar_helper.h new file mode 100644 index 0000000..c87491d8 --- /dev/null +++ b/chrome/browser/android/vr_shell/toolbar_helper.h
@@ -0,0 +1,36 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ANDROID_VR_SHELL_TOOLBAR_HELPER_H_ +#define CHROME_BROWSER_ANDROID_VR_SHELL_TOOLBAR_HELPER_H_ + +#include "chrome/browser/android/vr_shell/toolbar_state.h" +#include "chrome/browser/android/vr_shell/ui_interface.h" + +class ToolbarModel; +class ToolbarModelDelegate; + +namespace vr_shell { + +class UiInterface; + +// This class houses an instance of ToolbarModel, and queries it when requested, +// passing a snapshot of the toolbar state to the UI when necessary. +class ToolbarHelper { + public: + ToolbarHelper(UiInterface* ui, ToolbarModelDelegate* delegate); + virtual ~ToolbarHelper(); + + // Poll ToolbarModel and post an update to the UI if state has changed. + void Update(); + + private: + UiInterface* ui_; + std::unique_ptr<ToolbarModel> toolbar_model_; + ToolbarState current_state_; +}; + +} // namespace vr_shell + +#endif // CHROME_BROWSER_ANDROID_VR_SHELL_TOOLBAR_HELPER_H_
diff --git a/chrome/browser/android/vr_shell/toolbar_state.cc b/chrome/browser/android/vr_shell/toolbar_state.cc new file mode 100644 index 0000000..d752f7f2 --- /dev/null +++ b/chrome/browser/android/vr_shell/toolbar_state.cc
@@ -0,0 +1,37 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/android/vr_shell/toolbar_state.h" + +namespace vr_shell { + +ToolbarState::ToolbarState() + : gurl(GURL()), + security_level(security_state::SecurityLevel::NONE), + vector_icon(nullptr), + should_display_url(true) {} + +ToolbarState::ToolbarState(const GURL& url, + security_state::SecurityLevel level, + const gfx::VectorIcon* icon, + base::string16 verbose_text, + bool display_url) + : gurl(url), + security_level(level), + vector_icon(icon), + secure_verbose_text(verbose_text), + should_display_url(display_url) {} + +bool ToolbarState::operator==(const ToolbarState& other) const { + return (gurl == other.gurl && security_level == other.security_level && + vector_icon == other.vector_icon && + should_display_url == other.should_display_url && + secure_verbose_text == other.secure_verbose_text); +} + +bool ToolbarState::operator!=(const ToolbarState& other) const { + return !(*this == other); +} + +} // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/toolbar_state.h b/chrome/browser/android/vr_shell/toolbar_state.h new file mode 100644 index 0000000..a39de5f6 --- /dev/null +++ b/chrome/browser/android/vr_shell/toolbar_state.h
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ANDROID_VR_SHELL_TOOLBAR_STATE_H_ +#define CHROME_BROWSER_ANDROID_VR_SHELL_TOOLBAR_STATE_H_ + +#include "components/security_state/core/security_state.h" +#include "url/gurl.h" + +namespace gfx { +struct VectorIcon; +} + +namespace vr_shell { + +// Passes information obtained from ToolbarModel to the VR UI framework. +struct ToolbarState { + public: + ToolbarState(); + ToolbarState(const GURL& url, + security_state::SecurityLevel level, + const gfx::VectorIcon* icon, + base::string16 verbose_text, + bool display_url); + + bool operator==(const ToolbarState& other) const; + bool operator!=(const ToolbarState& other) const; + + GURL gurl; + security_state::SecurityLevel security_level; + const gfx::VectorIcon* vector_icon; + base::string16 secure_verbose_text; + bool should_display_url; +}; + +} // namespace vr_shell + +#endif // CHROME_BROWSER_ANDROID_VR_SHELL_TOOLBAR_STATE_H_
diff --git a/chrome/browser/android/vr_shell/ui_elements/transient_url_bar.cc b/chrome/browser/android/vr_shell/ui_elements/transient_url_bar.cc index 6c960ca6..b6a8819 100644 --- a/chrome/browser/android/vr_shell/ui_elements/transient_url_bar.cc +++ b/chrome/browser/android/vr_shell/ui_elements/transient_url_bar.cc
@@ -21,15 +21,8 @@ return texture_.get(); } -void TransientUrlBar::SetURL(const GURL& gurl) { - texture_->SetURL(gurl); - UpdateTexture(); -} - -void TransientUrlBar::SetSecurityInfo(security_state::SecurityLevel level, - bool malware) { - texture_->SetSecurityInfo(level, malware); - UpdateTexture(); +void TransientUrlBar::SetToolbarState(const ToolbarState& state) { + texture_->SetToolbarState(state); } } // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/ui_elements/transient_url_bar.h b/chrome/browser/android/vr_shell/ui_elements/transient_url_bar.h index 9978cea..da311bf 100644 --- a/chrome/browser/android/vr_shell/ui_elements/transient_url_bar.h +++ b/chrome/browser/android/vr_shell/ui_elements/transient_url_bar.h
@@ -18,6 +18,7 @@ namespace vr_shell { class UrlBarTexture; +struct ToolbarState; // The non-interactive URL bar that shows for some time when WebVR content is // autopresented. @@ -28,8 +29,7 @@ const base::Callback<void(UiUnsupportedMode)>& failure_callback); ~TransientUrlBar() override; - void SetURL(const GURL& gurl); - void SetSecurityInfo(security_state::SecurityLevel level, bool malware); + void SetToolbarState(const ToolbarState& state); private: UiTexture* GetTexture() const override;
diff --git a/chrome/browser/android/vr_shell/ui_elements/url_bar.cc b/chrome/browser/android/vr_shell/ui_elements/url_bar.cc index 3ad755b..40dede3 100644 --- a/chrome/browser/android/vr_shell/ui_elements/url_bar.cc +++ b/chrome/browser/android/vr_shell/ui_elements/url_bar.cc
@@ -88,8 +88,8 @@ set_visible(enabled); } -void UrlBar::SetURL(const GURL& gurl) { - texture_->SetURL(gurl); +void UrlBar::SetToolbarState(const ToolbarState& state) { + texture_->SetToolbarState(state); } void UrlBar::SetHistoryButtonsEnabled(bool can_go_back) { @@ -97,11 +97,6 @@ texture_->SetHistoryButtonsEnabled(can_go_back_); } -void UrlBar::SetSecurityInfo(security_state::SecurityLevel level, - bool malware) { - texture_->SetSecurityInfo(level, malware); -} - void UrlBar::OnStateUpdated(const gfx::PointF& position) { const bool hovered = texture_->HitsBackButton(position); const bool pressed = hovered ? down_ : false;
diff --git a/chrome/browser/android/vr_shell/ui_elements/url_bar.h b/chrome/browser/android/vr_shell/ui_elements/url_bar.h index 730c2b1..f5e116d 100644 --- a/chrome/browser/android/vr_shell/ui_elements/url_bar.h +++ b/chrome/browser/android/vr_shell/ui_elements/url_bar.h
@@ -18,6 +18,7 @@ namespace vr_shell { class UrlBarTexture; +struct ToolbarState; class UrlBar : public TexturedElement { public: @@ -38,8 +39,7 @@ void SetEnabled(bool enabled) override; void SetHistoryButtonsEnabled(bool can_go_back); - void SetURL(const GURL& gurl); - void SetSecurityInfo(security_state::SecurityLevel level, bool malware); + void SetToolbarState(const ToolbarState& state); private: void UpdateTexture() override;
diff --git a/chrome/browser/android/vr_shell/ui_interface.h b/chrome/browser/android/vr_shell/ui_interface.h index f46ccce..29c3bf3 100644 --- a/chrome/browser/android/vr_shell/ui_interface.h +++ b/chrome/browser/android/vr_shell/ui_interface.h
@@ -7,11 +7,12 @@ #include "components/security_state/core/security_state.h" -class GURL; class SkBitmap; namespace vr_shell { +struct ToolbarState; + // This class manages the communication of browser state from VR shell to the // HTML UI. State information is asynchronous and unidirectional. class UiInterface { @@ -27,10 +28,8 @@ virtual ~UiInterface() {} virtual void SetWebVrMode(bool enabled, bool show_toast) = 0; - virtual void SetURL(const GURL& url) = 0; virtual void SetFullscreen(bool enabled) = 0; - virtual void SetSecurityInfo(security_state::SecurityLevel level, - bool fails_malware_check) = 0; + virtual void SetToolbarState(const ToolbarState& state) = 0; virtual void SetIncognito(bool enabled) = 0; virtual void SetWebVrSecureOrigin(bool secure) = 0; virtual void SetLoading(bool loading) = 0;
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.cc b/chrome/browser/android/vr_shell/ui_scene_manager.cc index 3dd3b77..46d6d35 100644 --- a/chrome/browser/android/vr_shell/ui_scene_manager.cc +++ b/chrome/browser/android/vr_shell/ui_scene_manager.cc
@@ -770,15 +770,9 @@ OnUnsupportedMode(UiUnsupportedMode::kUnhandledPageInfo); } -void UiSceneManager::SetURL(const GURL& gurl) { - url_bar_->SetURL(gurl); - transient_url_bar_->SetURL(gurl); -} - -void UiSceneManager::SetSecurityInfo(security_state::SecurityLevel level, - bool malware) { - url_bar_->SetSecurityInfo(level, malware); - transient_url_bar_->SetSecurityInfo(level, malware); +void UiSceneManager::SetToolbarState(const ToolbarState& state) { + url_bar_->SetToolbarState(state); + transient_url_bar_->SetToolbarState(state); } void UiSceneManager::SetLoading(bool loading) {
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.h b/chrome/browser/android/vr_shell/ui_scene_manager.h index 5581043..45be0ac2 100644 --- a/chrome/browser/android/vr_shell/ui_scene_manager.h +++ b/chrome/browser/android/vr_shell/ui_scene_manager.h
@@ -38,10 +38,9 @@ void SetFullscreen(bool fullscreen); void SetIncognito(bool incognito); - void SetURL(const GURL& gurl); + void SetToolbarState(const ToolbarState& state); void SetWebVrSecureOrigin(bool secure); void SetWebVrMode(bool web_vr, bool show_toast); - void SetSecurityInfo(security_state::SecurityLevel level, bool malware); void SetLoading(bool loading); void SetLoadProgress(float progress); void SetIsExiting();
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc index 2762eca..a703d1b3 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.cc +++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "chrome/browser/android/vr_shell/toolbar_state.h" #include "chrome/browser/android/vr_shell/ui_interface.h" #include "chrome/browser/android/vr_shell/ui_scene.h" #include "chrome/browser/android/vr_shell/ui_scene_manager.h" @@ -179,18 +180,11 @@ weak_scene_manager_, loading)); } -void VrGLThread::SetSecurityInfo(security_state::SecurityLevel level, - bool malware) { +void VrGLThread::SetToolbarState(const ToolbarState& state) { WaitUntilThreadStarted(); - task_runner()->PostTask(FROM_HERE, - base::Bind(&UiSceneManager::SetSecurityInfo, - weak_scene_manager_, level, malware)); -} - -void VrGLThread::SetURL(const GURL& gurl) { - WaitUntilThreadStarted(); - task_runner()->PostTask(FROM_HERE, base::Bind(&UiSceneManager::SetURL, - weak_scene_manager_, gurl)); + task_runner()->PostTask( + FROM_HERE, + base::Bind(&UiSceneManager::SetToolbarState, weak_scene_manager_, state)); } void VrGLThread::SetWebVrMode(bool enabled, bool show_toast) {
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.h b/chrome/browser/android/vr_shell/vr_gl_thread.h index 538d89c..5bbcde9 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.h +++ b/chrome/browser/android/vr_shell/vr_gl_thread.h
@@ -16,8 +16,6 @@ #include "chrome/browser/android/vr_shell/ui_interface.h" #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" -class GURL; - namespace vr_shell { class UiScene; @@ -75,9 +73,7 @@ void SetHistoryButtonsEnabled(bool can_go_back, bool can_go_forward) override; void SetLoadProgress(float progress) override; void SetLoading(bool loading) override; - void SetSecurityInfo(security_state::SecurityLevel level, - bool malware) override; - void SetURL(const GURL& gurl) override; + void SetToolbarState(const ToolbarState& state) override; void SetWebVrMode(bool enabled, bool show_toast) override; void SetWebVrSecureOrigin(bool secure) override; void SetVideoCapturingIndicator(bool enabled) override;
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc index 07e04bf..b659625 100644 --- a/chrome/browser/android/vr_shell/vr_shell.cc +++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -21,6 +21,7 @@ #include "base/values.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/android/vr_shell/android_ui_gesture_target.h" +#include "chrome/browser/android/vr_shell/toolbar_helper.h" #include "chrome/browser/android/vr_shell/ui_interface.h" #include "chrome/browser/android/vr_shell/ui_scene_manager.h" #include "chrome/browser/android/vr_shell/vr_compositor.h" @@ -117,6 +118,7 @@ for_web_vr, web_vr_autopresentation_expected, in_cct, reprojected_rendering_, HasDaydreamSupport(env)); ui_ = gl_thread_.get(); + toolbar_ = base::MakeUnique<ToolbarHelper>(ui_, this); base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT, 0); options.priority = base::ThreadPriority::DISPLAY; @@ -163,8 +165,8 @@ return; } input_manager_ = base::MakeUnique<VrInputManager>(web_contents_); - vr_web_contents_observer_ = - base::MakeUnique<VrWebContentsObserver>(web_contents_, ui_, this); + vr_web_contents_observer_ = base::MakeUnique<VrWebContentsObserver>( + web_contents_, this, ui_, toolbar_.get()); // TODO(billorr): Make VrMetricsHelper tab-aware and able to track multiple // tabs. crbug.com/684661 metrics_helper_ = base::MakeUnique<VrMetricsHelper>(web_contents_); @@ -173,14 +175,13 @@ } void VrShell::SetUiState() { + toolbar_->Update(); + if (!web_contents_) { - // TODO(mthiesse): Properly handle native page URLs. - ui_->SetURL(GURL()); ui_->SetLoading(false); ui_->SetFullscreen(false); ui_->SetIncognito(false); } else { - ui_->SetURL(web_contents_->GetVisibleURL()); ui_->SetLoading(web_contents_->IsLoading()); ui_->SetFullscreen(web_contents_->IsFullscreen()); ui_->SetIncognito(web_contents_->GetBrowserContext()->IsOffTheRecord()); @@ -714,6 +715,10 @@ return Java_VrShellImpl_hasDaydreamSupport(env, j_vr_shell_.obj()); } +content::WebContents* VrShell::GetActiveWebContents() const { + return web_contents_; +} + // ---------------------------------------------------------------------------- // Native JNI methods // ----------------------------------------------------------------------------
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h index 2d2a627f..df45efc 100644 --- a/chrome/browser/android/vr_shell/vr_shell.h +++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -17,6 +17,7 @@ #include "chrome/browser/android/vr_shell/ui_interface.h" #include "chrome/browser/android/vr_shell/ui_unsupported_mode.h" #include "chrome/browser/android/vr_shell/vr_controller_model.h" +#include "chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "device/vr/android/gvr/cardboard_gamepad_data_provider.h" #include "device/vr/android/gvr/gvr_delegate.h" @@ -39,6 +40,7 @@ namespace vr_shell { class AndroidUiGestureTarget; +class ToolbarHelper; class UiInterface; class VrCompositor; class VrGLThread; @@ -62,7 +64,8 @@ // must only be used on the UI thread. class VrShell : public device::GvrDelegate, device::GvrGamepadDataProvider, - device::CardboardGamepadDataProvider { + device::CardboardGamepadDataProvider, + public ChromeToolbarModelDelegate { public: VrShell(JNIEnv* env, jobject obj, @@ -175,6 +178,9 @@ void RegisterCardboardGamepadDataFetcher( device::CardboardGamepadDataFetcher*) override; + // ChromeToolbarModelDelegate implementation. + content::WebContents* GetActiveWebContents() const override; + private: ~VrShell() override; void WaitForGlThread(); @@ -221,9 +227,11 @@ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; std::unique_ptr<VrGLThread> gl_thread_; bool thread_started_ = false; - UiInterface* ui_; bool reprojected_rendering_; + UiInterface* ui_; + std::unique_ptr<ToolbarHelper> toolbar_; + jobject content_surface_ = nullptr; bool taken_surface_ = false; base::CancelableClosure poll_capturing_media_task_;
diff --git a/chrome/browser/android/vr_shell/vr_web_contents_observer.cc b/chrome/browser/android/vr_shell/vr_web_contents_observer.cc index 0a60565..aec6c6f 100644 --- a/chrome/browser/android/vr_shell/vr_web_contents_observer.cc +++ b/chrome/browser/android/vr_shell/vr_web_contents_observer.cc
@@ -4,11 +4,9 @@ #include "chrome/browser/android/vr_shell/vr_web_contents_observer.h" +#include "chrome/browser/android/vr_shell/toolbar_helper.h" #include "chrome/browser/android/vr_shell/ui_interface.h" #include "chrome/browser/android/vr_shell/vr_shell.h" -#include "chrome/browser/ssl/security_state_tab_helper.h" -#include "components/security_state/core/security_state.h" -#include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -16,13 +14,14 @@ namespace vr_shell { VrWebContentsObserver::VrWebContentsObserver(content::WebContents* web_contents, + VrShell* vr_shell, UiInterface* ui_interface, - VrShell* vr_shell) + ToolbarHelper* toolbar) : WebContentsObserver(web_contents), + vr_shell_(vr_shell), ui_interface_(ui_interface), - vr_shell_(vr_shell) { - ui_interface_->SetURL(web_contents->GetVisibleURL()); - DidChangeVisibleSecurityState(); + toolbar_(toolbar) { + toolbar_->Update(); } VrWebContentsObserver::~VrWebContentsObserver() {} @@ -41,33 +40,21 @@ void VrWebContentsObserver::DidStartNavigation( content::NavigationHandle* navigation_handle) { - if (navigation_handle->IsInMainFrame()) { - ui_interface_->SetURL(navigation_handle->GetURL()); - } + toolbar_->Update(); } void VrWebContentsObserver::DidRedirectNavigation( content::NavigationHandle* navigation_handle) { - if (navigation_handle->IsInMainFrame()) { - ui_interface_->SetURL(navigation_handle->GetURL()); - } + toolbar_->Update(); } void VrWebContentsObserver::DidFinishNavigation( content::NavigationHandle* navigation_handle) { - if (navigation_handle->IsInMainFrame()) { - ui_interface_->SetURL(navigation_handle->GetURL()); - } + toolbar_->Update(); } void VrWebContentsObserver::DidChangeVisibleSecurityState() { - const auto* helper = SecurityStateTabHelper::FromWebContents(web_contents()); - DCHECK(helper); - security_state::SecurityInfo security_info; - helper->GetSecurityInfo(&security_info); - bool malware = (security_info.malicious_content_status != - security_state::MALICIOUS_CONTENT_STATUS_NONE); - ui_interface_->SetSecurityInfo(security_info.security_level, malware); + toolbar_->Update(); } void VrWebContentsObserver::DidToggleFullscreenModeForTab(
diff --git a/chrome/browser/android/vr_shell/vr_web_contents_observer.h b/chrome/browser/android/vr_shell/vr_web_contents_observer.h index 12b4bd6b..ac10b059 100644 --- a/chrome/browser/android/vr_shell/vr_web_contents_observer.h +++ b/chrome/browser/android/vr_shell/vr_web_contents_observer.h
@@ -16,13 +16,15 @@ class UiInterface; class VrShell; +class ToolbarHelper; class CONTENT_EXPORT VrWebContentsObserver : public content::WebContentsObserver { public: VrWebContentsObserver(content::WebContents* web_contents, + VrShell* vr_shell, UiInterface* ui_interface, - VrShell* vr_shell); + ToolbarHelper* toolbar); ~VrWebContentsObserver() override; void SetUiInterface(UiInterface* ui_interface); @@ -47,9 +49,10 @@ void RenderViewHostChanged(content::RenderViewHost* old_host, content::RenderViewHost* new_host) override; - // This class does not own the UI interface. - UiInterface* ui_interface_; + // This class does not own these pointers. VrShell* vr_shell_; + UiInterface* ui_interface_; + ToolbarHelper* toolbar_; DISALLOW_COPY_AND_ASSIGN(VrWebContentsObserver); };
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 100d4117..54f9e542 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -273,6 +273,8 @@ <include name="IDR_MD_BOOKMARKS_COMMAND_MANAGER_JS" file="resources\md_bookmarks\command_manager.js" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_CONSTANTS_HTML" file="resources\md_bookmarks\constants.html" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_CONSTANTS_JS" file="resources\md_bookmarks\constants.js" type="BINDATA" /> + <include name="IDR_MD_BOOKMARKS_DIALOG_FOCUS_MANAGER_HTML" file="resources\md_bookmarks\dialog_focus_manager.html" type="BINDATA" /> + <include name="IDR_MD_BOOKMARKS_DIALOG_FOCUS_MANAGER_JS" file="resources\md_bookmarks\dialog_focus_manager.js" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_DND_MANAGER_HTML" file="resources\md_bookmarks\dnd_manager.html" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_DND_MANAGER_JS" file="resources\md_bookmarks\dnd_manager.js" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_EDIT_DIALOG_HTML" file="resources\md_bookmarks\edit_dialog.html" type="BINDATA" />
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h index 4ef6942a..a3f4eba8 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h
@@ -10,7 +10,6 @@ #include <string> #include <vector> -#include "base/containers/hash_tables.h" #include "base/macros.h" #include "base/memory/linked_ptr.h" #include "base/memory/weak_ptr.h" @@ -178,8 +177,7 @@ friend class WallpaperManager; friend class WallpaperManagerTest; - using UserImageManagerMap = - base::hash_map<AccountId, linked_ptr<UserImageManager> >; + using UserImageManagerMap = std::map<AccountId, linked_ptr<UserImageManager>>; ChromeUserManagerImpl();
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h index 20d66f63..f2618ad 100644 --- a/chrome/browser/chromeos/login/wizard_controller.h +++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -10,7 +10,6 @@ #include <string> #include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/linked_ptr.h" @@ -431,7 +430,7 @@ std::unique_ptr<pairing_chromeos::HostPairingController> remora_controller_; // Maps screen names to last time of their shows. - base::hash_map<std::string, base::Time> screen_show_times_; + std::map<std::string, base::Time> screen_show_times_; // Tests check result of timezone resolve. bool timezone_resolved_ = false;
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.h b/chrome/browser/chromeos/net/network_portal_detector_impl.h index c28afefd..84aa5f24 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_impl.h +++ b/chrome/browser/chromeos/net/network_portal_detector_impl.h
@@ -5,12 +5,12 @@ #ifndef CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_ #define CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_IMPL_H_ +#include <map> #include <memory> #include <string> #include "base/cancelable_callback.h" #include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" @@ -75,7 +75,7 @@ friend class NetworkPortalDetectorImplTest; friend class NetworkPortalDetectorImplBrowserTest; - using CaptivePortalStateMap = base::hash_map<std::string, CaptivePortalState>; + using CaptivePortalStateMap = std::map<std::string, CaptivePortalState>; enum State { // No portal check is running.
diff --git a/chrome/browser/chromeos/net/network_portal_detector_test_impl.h b/chrome/browser/chromeos/net/network_portal_detector_test_impl.h index 91fef887..8701d5d4 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_test_impl.h +++ b/chrome/browser/chromeos/net/network_portal_detector_test_impl.h
@@ -5,11 +5,11 @@ #ifndef CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_TEST_IMPL_H_ #define CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_TEST_IMPL_H_ +#include <map> #include <memory> #include <string> #include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" #include "base/macros.h" #include "base/observer_list.h" #include "chromeos/network/portal_detector/network_portal_detector.h" @@ -44,8 +44,8 @@ } private: - typedef std::string NetworkId; - typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap; + using NetworkId = std::string; + using CaptivePortalStateMap = std::map<NetworkId, CaptivePortalState>; base::ObserverList<Observer> observers_; std::unique_ptr<NetworkState> default_network_;
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc index d03c07c..78375691 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
@@ -14,10 +14,12 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" +#include "base/sequenced_task_runner.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_runner_util.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/printing/cups_print_job.h" #include "chrome/browser/chromeos/printing/printers_manager.h" @@ -102,13 +104,6 @@ return State::STATE_NONE; } -chromeos::QueryResult QueryCups(::printing::CupsConnection* connection, - const std::vector<std::string>& printer_ids) { - chromeos::QueryResult result; - result.success = connection->GetJobs(printer_ids, &result.queues); - return result; -} - // Returns true if |printer_status|.reasons contains |reason|. bool ContainsReason(const printing::PrinterStatus printer_status, PrinterReason::Reason reason) { @@ -172,6 +167,43 @@ return pages_updated; } +// Updates the state of a print job based on |printer_status| and |job|. +// Returns true if observers need to be notified of an update. +bool UpdatePrintJob(const ::printing::PrinterStatus& printer_status, + const ::printing::CupsJob& job, + chromeos::CupsPrintJob* print_job) { + DCHECK_EQ(job.id, print_job->job_id()); + + State old_state = print_job->state(); + + bool pages_updated = false; + switch (job.state) { + case ::printing::CupsJob::PROCESSING: + if (ContainsReason(printer_status, PrinterReason::CONNECTING_TO_DEVICE)) { + if (EnforceTimeout(job, print_job)) { + LOG(WARNING) << "Connecting to printer timed out"; + print_job->set_expired(true); + } + } else { + pages_updated = UpdateCurrentPage(job, print_job); + } + break; + case ::printing::CupsJob::COMPLETED: + DCHECK_GE(job.current_pages, print_job->total_page_number()); + print_job->set_state(State::STATE_DOCUMENT_DONE); + break; + case ::printing::CupsJob::ABORTED: + case ::printing::CupsJob::CANCELED: + print_job->set_error_code(ErrorCodeFromReasons(printer_status)); + // fall through + default: + print_job->set_state(ConvertState(job.state)); + break; + } + + return print_job->state() != old_state || pages_updated; +} + } // namespace namespace chromeos { @@ -182,9 +214,47 @@ QueryResult::~QueryResult() = default; +CupsWrapper::CupsWrapper() + : cups_connection_(GURL(), HTTP_ENCRYPT_NEVER, false) { + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +CupsWrapper::~CupsWrapper() = default; + +void CupsWrapper::QueryCups(const std::vector<std::string>& printer_ids, + QueryResult* result) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::ThreadRestrictions::AssertIOAllowed(); + + result->success = cups_connection_.GetJobs(printer_ids, &result->queues); +} + +void CupsWrapper::CancelJobImpl(const std::string& printer_id, + const int job_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::ThreadRestrictions::AssertIOAllowed(); + + std::unique_ptr<::printing::CupsPrinter> printer = + cups_connection_.GetPrinter(printer_id); + if (!printer) { + LOG(WARNING) << "Printer not found: " << printer_id; + return; + } + + if (!printer->CancelJob(job_id)) { + // This is not expected to fail but log it if it does. + LOG(WARNING) << "Cancelling job failed. Job may be stuck in queue."; + } +} + CupsPrintJobManagerImpl::CupsPrintJobManagerImpl(Profile* profile) : CupsPrintJobManager(profile), - cups_connection_(GURL(), HTTP_ENCRYPT_NEVER, false), + query_runner_(base::CreateSequencedTaskRunnerWithTraits( + base::TaskTraits(base::TaskPriority::BACKGROUND, + base::MayBlock(), + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN))), + cups_wrapper_(new CupsWrapper(), + base::OnTaskRunnerDeleter(query_runner_)), weak_ptr_factory_(this) { registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, content::NotificationService::AllSources()); @@ -203,12 +273,10 @@ // Stop montioring jobs after we cancel them. The user no longer cares. jobs_.erase(job->GetUniqueId()); - // Be sure to copy out all relevant fields. |job| may be destroyed after we - // exit this scope. - content::BrowserThread::GetBlockingPool()->PostTask( + query_runner_->PostTask( FROM_HERE, - base::Bind(&CupsPrintJobManagerImpl::CancelJobImpl, - weak_ptr_factory_.GetWeakPtr(), printer_id, job_id)); + base::Bind(&CupsWrapper::CancelJobImpl, + base::Unretained(cups_wrapper_.get()), printer_id, job_id)); } bool CupsPrintJobManagerImpl::SuspendPrintJob(CupsPrintJob* job) { @@ -244,6 +312,8 @@ const std::string& title, int job_id, int total_page_number) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + auto printer = PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinter( printer_name); @@ -281,18 +351,22 @@ } void CupsPrintJobManagerImpl::ScheduleQuery(const base::TimeDelta& delay) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!in_query_) { in_query_ = true; - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::Bind(&CupsPrintJobManagerImpl::PostQuery, - weak_ptr_factory_.GetWeakPtr()), - delay); + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) + ->PostDelayedTask(FROM_HERE, + base::Bind(&CupsPrintJobManagerImpl::PostQuery, + weak_ptr_factory_.GetWeakPtr()), + delay); } } void CupsPrintJobManagerImpl::PostQuery() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // The set of active printers is expected to be small. std::set<std::string> printer_ids; for (const auto& entry : jobs_) { @@ -300,60 +374,31 @@ } std::vector<std::string> ids{printer_ids.begin(), printer_ids.end()}; - content::BrowserThread::PostTaskAndReplyWithResult( - content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE, - base::Bind(&QueryCups, &cups_connection_, ids), + auto result = base::MakeUnique<QueryResult>(); + QueryResult* result_ptr = result.get(); + // Runs a query on query_runner_ which will rejoin this sequnece on + // completion. + query_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&CupsWrapper::QueryCups, base::Unretained(cups_wrapper_.get()), + ids, result_ptr), base::Bind(&CupsPrintJobManagerImpl::UpdateJobs, - weak_ptr_factory_.GetWeakPtr())); -} - -bool CupsPrintJobManagerImpl::UpdatePrintJob( - const ::printing::PrinterStatus& printer_status, - const ::printing::CupsJob& job, - CupsPrintJob* print_job) { - DCHECK_EQ(job.id, print_job->job_id()); - - State old_state = print_job->state(); - - bool pages_updated = false; - switch (job.state) { - case ::printing::CupsJob::PROCESSING: - if (ContainsReason(printer_status, PrinterReason::CONNECTING_TO_DEVICE)) { - if (EnforceTimeout(job, print_job)) { - LOG(WARNING) << "Connecting to printer timed out"; - print_job->set_expired(true); - } - } else { - pages_updated = UpdateCurrentPage(job, print_job); - } - break; - case ::printing::CupsJob::COMPLETED: - DCHECK_GE(job.current_pages, print_job->total_page_number()); - print_job->set_state(State::STATE_DOCUMENT_DONE); - break; - case ::printing::CupsJob::ABORTED: - case ::printing::CupsJob::CANCELED: - print_job->set_error_code(ErrorCodeFromReasons(printer_status)); - // fall through - default: - print_job->set_state(ConvertState(job.state)); - break; - } - - return print_job->state() != old_state || pages_updated; + weak_ptr_factory_.GetWeakPtr(), base::Passed(&result))); } // Use job information to update local job states. Previously completed jobs -// could be in |jobs| but those are ignored as we will not emit updates for them -// after they are completed. -void CupsPrintJobManagerImpl::UpdateJobs(const QueryResult& result) { - const std::vector<::printing::QueueStatus>& queues = result.queues; +// could be in |jobs| but those are ignored as we will not emit updates for +// them after they are completed. +void CupsPrintJobManagerImpl::UpdateJobs(std::unique_ptr<QueryResult> result) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + const std::vector<::printing::QueueStatus>& queues = result->queues; // Query has completed. Allow more queries. in_query_ = false; // If the query failed, either retry or purge. - if (!result.success) { + if (!result->success) { retry_count_++; LOG(WARNING) << "Failed to query CUPS for queue status. Schedule retry (" << retry_count_ << ")"; @@ -407,14 +452,16 @@ // During normal operations, we poll at the default rate. ScheduleQuery(); } else if (!jobs_.empty()) { - // We're tracking jobs that we didn't receive an update for. Something bad - // has happened. + // We're tracking jobs that we didn't receive an update for. Something + // bad has happened. LOG(ERROR) << "Lost track of (" << jobs_.size() << ") jobs"; PurgeJobs(); } } void CupsPrintJobManagerImpl::PurgeJobs() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + for (const auto& entry : jobs_) { // Declare all lost jobs errors. RecordJobResult(LOST); @@ -426,22 +473,9 @@ jobs_.clear(); } -void CupsPrintJobManagerImpl::CancelJobImpl(const std::string& printer_id, - const int job_id) { - std::unique_ptr<::printing::CupsPrinter> printer = - cups_connection_.GetPrinter(printer_id); - if (!printer) { - LOG(WARNING) << "Printer not found: " << printer_id; - return; - } - - if (!printer->CancelJob(job_id)) { - // This is not expected to fail but log it if it does. - LOG(WARNING) << "Cancelling job failed. Job may be stuck in queue."; - } -} - void CupsPrintJobManagerImpl::NotifyJobStateUpdate(CupsPrintJob* job) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + switch (job->state()) { case State::STATE_NONE: // State does not require notification.
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h index cdf72369..804ddb1 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h
@@ -8,10 +8,12 @@ #include <map> #include <memory> #include <string> -#include <unordered_map> #include <vector> +#include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/sequenced_task_runner.h" #include "chrome/browser/chromeos/printing/cups_print_job.h" #include "chrome/browser/chromeos/printing/cups_print_job_manager.h" #include "chrome/browser/chromeos/printing/printers_manager.h" @@ -32,6 +34,28 @@ std::vector<::printing::QueueStatus> queues; }; +// A wrapper around the CUPS connection to ensure that it's always accessed on +// the same sequence. +class CupsWrapper { + public: + CupsWrapper(); + ~CupsWrapper(); + + // Query CUPS for the current jobs for the given |printer_ids|. Writes result + // to |result|. + void QueryCups(const std::vector<std::string>& printer_ids, + QueryResult* result); + + // Cancel the print job on the blocking thread. + void CancelJobImpl(const std::string& printer_id, const int job_id); + + private: + ::printing::CupsConnection cups_connection_; + SEQUENCE_CHECKER(sequence_checker_); + + DISALLOW_COPY_AND_ASSIGN(CupsWrapper); +}; + class CupsPrintJobManagerImpl : public CupsPrintJobManager, public content::NotificationObserver { public: @@ -65,21 +89,12 @@ // to UpdateJobs. void PostQuery(); - // Updates the state of a print job based on |printer_status| and |job|. - // Returns true if observers need to be notified of an update. - bool UpdatePrintJob(const ::printing::PrinterStatus& printer_status, - const ::printing::CupsJob& job, - CupsPrintJob* print_job); - // Process jobs from CUPS and perform notifications. - void UpdateJobs(const QueryResult& results); + void UpdateJobs(std::unique_ptr<QueryResult> results); // Mark remaining jobs as errors and remove active jobs. void PurgeJobs(); - // Cancel the print job on the blocking thread. - void CancelJobImpl(const std::string& printer_id, const int job_id); - // Notify observers that a state update has occured for |job|. void NotifyJobStateUpdate(CupsPrintJob* job); @@ -92,8 +107,10 @@ // Records the number of consecutive times the GetJobs query has failed. int retry_count_ = 0; - ::printing::CupsConnection cups_connection_; content::NotificationRegistrar registrar_; + // Task runner for queries to CUPS. + scoped_refptr<base::SequencedTaskRunner> query_runner_; + std::unique_ptr<CupsWrapper, base::OnTaskRunnerDeleter> cups_wrapper_; base::WeakPtrFactory<CupsPrintJobManagerImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(CupsPrintJobManagerImpl);
diff --git a/chrome/browser/chromeos/settings/cros_settings.h b/chrome/browser/chromeos/settings/cros_settings.h index 77d5c1d..519a804 100644 --- a/chrome/browser/chromeos/settings/cros_settings.h +++ b/chrome/browser/chromeos/settings/cros_settings.h
@@ -5,13 +5,13 @@ #ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_CROS_SETTINGS_H_ #define CHROME_BROWSER_CHROMEOS_SETTINGS_CROS_SETTINGS_H_ +#include <map> #include <memory> #include <string> #include <vector> #include "base/callback_forward.h" #include "base/callback_list.h" -#include "base/containers/hash_tables.h" #include "base/macros.h" #include "base/sequence_checker.h" #include "chromeos/settings/cros_settings_names.h" @@ -131,7 +131,7 @@ // A map from settings names to a list of observers. Observers get fired in // the order they are added. - base::hash_map<std::string, std::unique_ptr<base::CallbackList<void(void)>>> + std::map<std::string, std::unique_ptr<base::CallbackList<void(void)>>> settings_observers_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chrome/browser/command_updater.h b/chrome/browser/command_updater.h index 31a4e913..035d250 100644 --- a/chrome/browser/command_updater.h +++ b/chrome/browser/command_updater.h
@@ -6,8 +6,8 @@ #define CHROME_BROWSER_COMMAND_UPDATER_H_ #include <memory> +#include <unordered_map> -#include "base/containers/hash_tables.h" #include "base/macros.h" #include "ui/base/window_open_disposition.h" @@ -77,7 +77,7 @@ CommandUpdaterDelegate* delegate_; // This is a map of command IDs to states and observer lists - base::hash_map<int, std::unique_ptr<Command>> commands_; + std::unordered_map<int, std::unique_ptr<Command>> commands_; DISALLOW_COPY_AND_ASSIGN(CommandUpdater); };
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc b/chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc index 11e58907..08c6d098 100644 --- a/chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc +++ b/chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc
@@ -379,9 +379,11 @@ NotifyPageLoadCommit(old_frame_entry); if (is_same_page_navigation) { - for (auto& request : entry->pending_url_requests()) { - AscribeRecorderWithRequest(request.first, old_frame_entry); - old_frame_entry->MovePendingURLRequest(&(*entry), request.first); + std::vector<net::URLRequest*> pending_url_requests; + entry->GetPendingURLRequests(&pending_url_requests); + for (net::URLRequest* request : pending_url_requests) { + AscribeRecorderWithRequest(request, old_frame_entry); + entry->MovePendingURLRequestTo(&(*old_frame_entry), request); } data_use_recorders_.erase(entry); } else {
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_ascriber.h b/chrome/browser/data_use_measurement/chrome_data_use_ascriber.h index 9e2c30bf..9dc1530 100644 --- a/chrome/browser/data_use_measurement/chrome_data_use_ascriber.h +++ b/chrome/browser/data_use_measurement/chrome_data_use_ascriber.h
@@ -6,13 +6,12 @@ #define CHROME_BROWSER_DATA_USE_MEASUREMENT_CHROME_DATA_USE_ASCRIBER_H_ #include <list> +#include <map> #include <memory> #include <string> #include <tuple> -#include <unordered_map> #include <utility> -#include "base/containers/hash_tables.h" #include "base/hash.h" #include "base/macros.h" #include "base/supports_user_data.h" @@ -119,13 +118,6 @@ typedef std::list<ChromeDataUseRecorder> DataUseRecorderList; typedef DataUseRecorderList::iterator DataUseRecorderEntry; - struct GlobalRequestIDHash { - public: - std::size_t operator()(const content::GlobalRequestID& x) const { - return base::HashInts(x.child_id, x.request_id); - } - }; - class DataUseRecorderEntryAsUserData : public base::SupportsUserData::Data { public: explicit DataUseRecorderEntryAsUserData(DataUseRecorderEntry entry); @@ -192,20 +184,17 @@ // Map from RenderFrameHost to the MainRenderFrameEntry which contains all // details of the main frame. New entry is added on main render frame creation // and removed on its deletion. - base::hash_map<RenderFrameHostID, MainRenderFrameEntry> + std::map<RenderFrameHostID, MainRenderFrameEntry> main_render_frame_entry_map_; // Maps subframe IDs to the mainframe ID, so the mainframe lifetime can have // ownership over the lifetime of entries in |data_use_recorders_|. Mainframes // are mapped to themselves. - base::hash_map<RenderFrameHostID, RenderFrameHostID> - subframe_to_mainframe_map_; + std::map<RenderFrameHostID, RenderFrameHostID> subframe_to_mainframe_map_; // Map from pending navigations to the DataUseRecorderEntry in // |data_use_recorders_| that the navigation ascribes data use to. - std::unordered_map<content::GlobalRequestID, - DataUseRecorderEntry, - GlobalRequestIDHash> + std::map<content::GlobalRequestID, DataUseRecorderEntry> pending_navigation_data_use_map_; DISALLOW_COPY_AND_ASSIGN(ChromeDataUseAscriber);
diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h index 2eaf5f4..b19c7fa 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.h +++ b/chrome/browser/download/chrome_download_manager_delegate.h
@@ -12,7 +12,7 @@ #include <vector> #include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" +#include "base/containers/flat_map.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -181,8 +181,9 @@ #if BUILDFLAG(ENABLE_EXTENSIONS) // Maps from pending extension installations to DownloadItem IDs. - typedef base::hash_map<extensions::CrxInstaller*, - content::DownloadOpenDelayedCallback> CrxInstallerMap; + typedef base::flat_map<extensions::CrxInstaller*, + content::DownloadOpenDelayedCallback> + CrxInstallerMap; CrxInstallerMap crx_installers_; #endif
diff --git a/chrome/browser/engagement/important_sites_util.cc b/chrome/browser/engagement/important_sites_util.cc index d79b9f7..a9133c9 100644 --- a/chrome/browser/engagement/important_sites_util.cc +++ b/chrome/browser/engagement/important_sites_util.cc
@@ -137,7 +137,7 @@ const GURL& origin, std::set<GURL>* visited_origins, ImportantReason reason, - base::hash_map<std::string, ImportantDomainInfo>* output) { + std::map<std::string, ImportantDomainInfo>* output) { if (!origin.is_valid() || !visited_origins->insert(origin).second) return; std::string registerable_domain = @@ -227,7 +227,7 @@ Profile* profile, blink::mojom::EngagementLevel minimum_engagement, std::map<GURL, double>* engagement_map, - base::hash_map<std::string, ImportantDomainInfo>* output) { + std::map<std::string, ImportantDomainInfo>* output) { SiteEngagementService* service = SiteEngagementService::Get(profile); *engagement_map = service->GetScoreMap(); // We can have multiple origins for a single domain, so we record the one @@ -254,7 +254,7 @@ Profile* profile, ContentSettingsType content_type, ImportantReason reason, - base::hash_map<std::string, ImportantDomainInfo>* output) { + std::map<std::string, ImportantDomainInfo>* output) { // Grab our content settings list. ContentSettingsForOneType content_settings_list; HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType( @@ -274,7 +274,7 @@ void PopulateInfoMapWithBookmarks( Profile* profile, const std::map<GURL, double>& engagement_map, - base::hash_map<std::string, ImportantDomainInfo>* output) { + std::map<std::string, ImportantDomainInfo>* output) { SiteEngagementService* service = SiteEngagementService::Get(profile); BookmarkModel* model = BookmarkModelFactory::GetForBrowserContextIfExists(profile); @@ -321,7 +321,7 @@ void PopulateInfoMapWithHomeScreen( Profile* profile, - base::hash_map<std::string, ImportantDomainInfo>* output) { + std::map<std::string, ImportantDomainInfo>* output) { ContentSettingsForOneType content_settings_list; HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType( CONTENT_SETTINGS_TYPE_APP_BANNER, content_settings::ResourceIdentifier(), @@ -370,7 +370,7 @@ std::vector<ImportantDomainInfo> ImportantSitesUtil::GetImportantRegisterableDomains(Profile* profile, size_t max_results) { - base::hash_map<std::string, ImportantDomainInfo> important_info; + std::map<std::string, ImportantDomainInfo> important_info; std::map<GURL, double> engagement_map; PopulateInfoMapWithSiteEngagement(
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc index 085fd949..7098da67 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api.cc
@@ -14,6 +14,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" +#include "base/containers/flat_map.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/json/json_writer.h" @@ -362,49 +363,69 @@ } } -typedef base::hash_map<std::string, DownloadQuery::FilterType> FilterTypeMap; - -void InitFilterTypeMap(FilterTypeMap* filter_types_ptr) { - FilterTypeMap& filter_types = *filter_types_ptr; - filter_types[kBytesReceivedKey] = DownloadQuery::FILTER_BYTES_RECEIVED; - filter_types[kExistsKey] = DownloadQuery::FILTER_EXISTS; - filter_types[kFilenameKey] = DownloadQuery::FILTER_FILENAME; - filter_types[kFilenameRegexKey] = DownloadQuery::FILTER_FILENAME_REGEX; - filter_types[kMimeKey] = DownloadQuery::FILTER_MIME; - filter_types[kPausedKey] = DownloadQuery::FILTER_PAUSED; - filter_types[kQueryKey] = DownloadQuery::FILTER_QUERY; - filter_types[kEndedAfterKey] = DownloadQuery::FILTER_ENDED_AFTER; - filter_types[kEndedBeforeKey] = DownloadQuery::FILTER_ENDED_BEFORE; - filter_types[kEndTimeKey] = DownloadQuery::FILTER_END_TIME; - filter_types[kStartedAfterKey] = DownloadQuery::FILTER_STARTED_AFTER; - filter_types[kStartedBeforeKey] = DownloadQuery::FILTER_STARTED_BEFORE; - filter_types[kStartTimeKey] = DownloadQuery::FILTER_START_TIME; - filter_types[kTotalBytesKey] = DownloadQuery::FILTER_TOTAL_BYTES; - filter_types[kTotalBytesGreaterKey] = - DownloadQuery::FILTER_TOTAL_BYTES_GREATER; - filter_types[kTotalBytesLessKey] = DownloadQuery::FILTER_TOTAL_BYTES_LESS; - filter_types[kUrlKey] = DownloadQuery::FILTER_ORIGINAL_URL; - filter_types[kUrlRegexKey] = DownloadQuery::FILTER_ORIGINAL_URL_REGEX; - filter_types[kFinalUrlKey] = DownloadQuery::FILTER_URL; - filter_types[kFinalUrlRegexKey] = DownloadQuery::FILTER_URL_REGEX; +using FilterTypeMap = base::flat_map<std::string, DownloadQuery::FilterType>; +void AppendFilter(const char* name, + DownloadQuery::FilterType type, + std::vector<FilterTypeMap::value_type>* v) { + v->emplace_back(name, type); } -typedef base::hash_map<std::string, DownloadQuery::SortType> SortTypeMap; +void InitFilterTypeMap(FilterTypeMap* filter_types_ptr) { + // Initialize the map in one shot by storing to a vector and assigning. + std::vector<FilterTypeMap::value_type> v; + + AppendFilter(kBytesReceivedKey, DownloadQuery::FILTER_BYTES_RECEIVED, &v); + + AppendFilter(kBytesReceivedKey, DownloadQuery::FILTER_BYTES_RECEIVED, &v); + AppendFilter(kExistsKey, DownloadQuery::FILTER_EXISTS, &v); + AppendFilter(kFilenameKey, DownloadQuery::FILTER_FILENAME, &v); + AppendFilter(kFilenameRegexKey, DownloadQuery::FILTER_FILENAME_REGEX, &v); + AppendFilter(kMimeKey, DownloadQuery::FILTER_MIME, &v); + AppendFilter(kPausedKey, DownloadQuery::FILTER_PAUSED, &v); + AppendFilter(kQueryKey, DownloadQuery::FILTER_QUERY, &v); + AppendFilter(kEndedAfterKey, DownloadQuery::FILTER_ENDED_AFTER, &v); + AppendFilter(kEndedBeforeKey, DownloadQuery::FILTER_ENDED_BEFORE, &v); + AppendFilter(kEndTimeKey, DownloadQuery::FILTER_END_TIME, &v); + AppendFilter(kStartedAfterKey, DownloadQuery::FILTER_STARTED_AFTER, &v); + AppendFilter(kStartedBeforeKey, DownloadQuery::FILTER_STARTED_BEFORE, &v); + AppendFilter(kStartTimeKey, DownloadQuery::FILTER_START_TIME, &v); + AppendFilter(kTotalBytesKey, DownloadQuery::FILTER_TOTAL_BYTES, &v); + AppendFilter(kTotalBytesGreaterKey, DownloadQuery::FILTER_TOTAL_BYTES_GREATER, + &v); + AppendFilter(kTotalBytesLessKey, DownloadQuery::FILTER_TOTAL_BYTES_LESS, &v); + AppendFilter(kUrlKey, DownloadQuery::FILTER_ORIGINAL_URL, &v); + AppendFilter(kUrlRegexKey, DownloadQuery::FILTER_ORIGINAL_URL_REGEX, &v); + AppendFilter(kFinalUrlKey, DownloadQuery::FILTER_URL, &v); + AppendFilter(kFinalUrlRegexKey, DownloadQuery::FILTER_URL_REGEX, &v); + + *filter_types_ptr = FilterTypeMap(std::move(v), base::KEEP_FIRST_OF_DUPES); +} + +using SortTypeMap = base::flat_map<std::string, DownloadQuery::SortType>; +void AppendFilter(const char* name, + DownloadQuery::SortType type, + std::vector<SortTypeMap::value_type>* v) { + v->emplace_back(name, type); +} void InitSortTypeMap(SortTypeMap* sorter_types_ptr) { - SortTypeMap& sorter_types = *sorter_types_ptr; - sorter_types[kBytesReceivedKey] = DownloadQuery::SORT_BYTES_RECEIVED; - sorter_types[kDangerKey] = DownloadQuery::SORT_DANGER; - sorter_types[kEndTimeKey] = DownloadQuery::SORT_END_TIME; - sorter_types[kExistsKey] = DownloadQuery::SORT_EXISTS; - sorter_types[kFilenameKey] = DownloadQuery::SORT_FILENAME; - sorter_types[kMimeKey] = DownloadQuery::SORT_MIME; - sorter_types[kPausedKey] = DownloadQuery::SORT_PAUSED; - sorter_types[kStartTimeKey] = DownloadQuery::SORT_START_TIME; - sorter_types[kStateKey] = DownloadQuery::SORT_STATE; - sorter_types[kTotalBytesKey] = DownloadQuery::SORT_TOTAL_BYTES; - sorter_types[kUrlKey] = DownloadQuery::SORT_ORIGINAL_URL; - sorter_types[kFinalUrlKey] = DownloadQuery::SORT_URL; + // Initialize the map in one shot by storing to a vector and assigning. + std::vector<SortTypeMap::value_type> v; + + AppendFilter(kBytesReceivedKey, DownloadQuery::SORT_BYTES_RECEIVED, &v); + AppendFilter(kDangerKey, DownloadQuery::SORT_DANGER, &v); + AppendFilter(kEndTimeKey, DownloadQuery::SORT_END_TIME, &v); + AppendFilter(kExistsKey, DownloadQuery::SORT_EXISTS, &v); + AppendFilter(kFilenameKey, DownloadQuery::SORT_FILENAME, &v); + AppendFilter(kMimeKey, DownloadQuery::SORT_MIME, &v); + AppendFilter(kPausedKey, DownloadQuery::SORT_PAUSED, &v); + AppendFilter(kStartTimeKey, DownloadQuery::SORT_START_TIME, &v); + AppendFilter(kStateKey, DownloadQuery::SORT_STATE, &v); + AppendFilter(kTotalBytesKey, DownloadQuery::SORT_TOTAL_BYTES, &v); + AppendFilter(kUrlKey, DownloadQuery::SORT_ORIGINAL_URL, &v); + AppendFilter(kFinalUrlKey, DownloadQuery::SORT_URL, &v); + + *sorter_types_ptr = SortTypeMap(std::move(v), base::KEEP_FIRST_OF_DUPES); } bool IsNotTemporaryDownloadFilter(const DownloadItem& download_item) {
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index 0a4e9ba..00258b0 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -1258,9 +1258,9 @@ items[1]->GetTargetFilePath().value()); // The order of results when orderBy is empty is unspecified. When there are // no sorters, DownloadQuery does not call sort(), so the order of the results - // depends on the order of the items in base::hash_map<uint32_t,...> - // DownloadManagerImpl::downloads_, which is unspecified and differs between - // libc++ and libstdc++. http://crbug.com/365334 + // depends on the order of the items in DownloadManagerImpl::downloads_, + // which is unspecified and differs between libc++ and libstdc++. + // http://crbug.com/365334 } // Test the |danger| option for search().
diff --git a/chrome/browser/feedback/system_logs/system_logs_fetcher.cc b/chrome/browser/feedback/system_logs/system_logs_fetcher.cc index 97dc689..fe9e2ba 100644 --- a/chrome/browser/feedback/system_logs/system_logs_fetcher.cc +++ b/chrome/browser/feedback/system_logs/system_logs_fetcher.cc
@@ -15,6 +15,29 @@ namespace system_logs { +namespace { + +// List of keys in the SystemLogsResponse map whose corresponding values will +// not be anonymized. +constexpr const char* const kWhitelistedKeysOfUUIDs[] = { + "CHROMEOS_BOARD_APPID", + "CHROMEOS_CANARY_APPID", + "CHROMEOS_RELEASE_APPID", + "CLIENT_ID", +}; + +// Returns true if the given |key| is anonymizer-whitelisted and whose +// corresponding value should not be anonymized. +bool IsKeyWhitelisted(const std::string& key) { + for (auto* const whitelisted_key : kWhitelistedKeysOfUUIDs) { + if (key == whitelisted_key) + return true; + } + return false; +} + +} // namespace + SystemLogsSource::SystemLogsSource(const std::string& source_name) : source_name_(source_name) {} @@ -56,8 +79,10 @@ VLOG(1) << "Received SystemLogSource: " << source_name; if (anonymizer_) { - for (auto& element : *response) - element.second = anonymizer_->Anonymize(element.second); + for (auto& element : *response) { + if (!IsKeyWhitelisted(element.first)) + element.second = anonymizer_->Anonymize(element.second); + } } AddResponse(source_name, response); }
diff --git a/chrome/browser/feedback/system_logs/system_logs_fetcher.h b/chrome/browser/feedback/system_logs/system_logs_fetcher.h index 8fe6af7..427b3fc 100644 --- a/chrome/browser/feedback/system_logs/system_logs_fetcher.h +++ b/chrome/browser/feedback/system_logs/system_logs_fetcher.h
@@ -80,9 +80,6 @@ // AddResponse(). void OnFetched(const std::string& source_name, SystemLogsResponse* response); - // Anonymizes the response data. - void Scrub(SystemLogsResponse* response); - // Merges the |response| it receives into response_. When all the data sources // have responded, it deletes their objects and returns the response to the // callback_. After this it deletes this instance of the object.
diff --git a/chrome/browser/font_family_cache.cc b/chrome/browser/font_family_cache.cc index bf23590..94611c66 100644 --- a/chrome/browser/font_family_cache.cc +++ b/chrome/browser/font_family_cache.cc
@@ -91,17 +91,15 @@ void FontFamilyCache::OnPrefsChanged(const std::string& pref_name) { const size_t delimiter_length = 1; const char delimiter = '.'; - for (FontFamilyMap::iterator it = font_family_map_.begin(); - it != font_family_map_.end(); - ++it) { - const char* map_name = it->first; + for (auto& it : font_family_map_) { + const char* map_name = it.first; size_t map_name_length = strlen(map_name); // If the map name doesn't match, move on. if (pref_name.compare(0, map_name_length, map_name) != 0) continue; - ScriptFontMap& map = it->second; + ScriptFontMap& map = it.second; for (ScriptFontMap::iterator it2 = map.begin(); it2 != map.end(); ++it2) { const char* script = it2->first; size_t script_length = strlen(script);
diff --git a/chrome/browser/font_family_cache.h b/chrome/browser/font_family_cache.h index 743448d..2961f37 100644 --- a/chrome/browser/font_family_cache.h +++ b/chrome/browser/font_family_cache.h
@@ -5,7 +5,8 @@ #ifndef CHROME_BROWSER_FONT_FAMILY_CACHE_H_ #define CHROME_BROWSER_FONT_FAMILY_CACHE_H_ -#include "base/containers/hash_tables.h" +#include <unordered_map> + #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/strings/string16.h" @@ -23,7 +24,7 @@ // Caches font family preferences associated with a PrefService. This class // relies on the assumption that each concatenation of map_name + '.' + script // is a unique string. It also relies on the assumption that the (const char*) -// keys used in both inner and outer hash_maps are compile time constants. +// keys used in both inner and outer maps are compile time constants. class FontFamilyCache : public base::SupportsUserData::Data, public content::NotificationObserver { public: @@ -49,11 +50,11 @@ // Map from script to font. // Key comparison uses pointer equality. - typedef base::hash_map<const char*, base::string16> ScriptFontMap; + using ScriptFontMap = std::unordered_map<const char*, base::string16>; // Map from font family to ScriptFontMap. // Key comparison uses pointer equality. - typedef base::hash_map<const char*, ScriptFontMap> FontFamilyMap; + using FontFamilyMap = std::unordered_map<const char*, ScriptFontMap>; // Checks the cache for the font. If not present, fetches the font and stores // the result in the cache. @@ -63,7 +64,7 @@ // of std::string. // |script| and |map_name| must be compile time constants. Two behaviors rely // on this: key comparison uses pointer equality, and keys must outlive the - // hash_maps. + // maps. base::string16 FetchAndCacheFont(const char* script, const char* map_name); // Called when font family preferences changed.
diff --git a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc index 331aa7ee..163d31e 100644 --- a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc +++ b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <map> #include <set> #include <string> #include <utility> @@ -13,7 +14,6 @@ #include "base/bind.h" #include "base/command_line.h" -#include "base/containers/hash_tables.h" #include "base/gtest_prod_util.h" #include "base/id_map.h" #include "base/memory/ptr_util.h" @@ -210,7 +210,7 @@ // A map between renderer child id and a pair represending the bridge id and // whether the requested permission was allowed. - base::hash_map<int, std::pair<int, bool> > responses_; + std::map<int, std::pair<int, bool>> responses_; // For testing the PermissionRequestManager on Android base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/chrome/browser/media/router/discovery/dial/dial_registry.h b/chrome/browser/media/router/discovery/dial/dial_registry.h index f981fbb..1091e18 100644 --- a/chrome/browser/media/router/discovery/dial/dial_registry.h +++ b/chrome/browser/media/router/discovery/dial/dial_registry.h
@@ -12,7 +12,6 @@ #include <string> #include <vector> -#include "base/containers/hash_tables.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/singleton.h" @@ -100,8 +99,7 @@ std::unique_ptr<DialService> dial_; private: - using DeviceByIdMap = - base::hash_map<std::string, std::unique_ptr<DialDeviceData>>; + using DeviceByIdMap = std::map<std::string, std::unique_ptr<DialDeviceData>>; using DeviceByLabelMap = std::map<std::string, DialDeviceData*>; friend class MockDialRegistry;
diff --git a/chrome/browser/media_galleries/fileapi/media_path_filter.h b/chrome/browser/media_galleries/fileapi/media_path_filter.h index 6e9fe5b3..ce87605 100644 --- a/chrome/browser/media_galleries/fileapi/media_path_filter.h +++ b/chrome/browser/media_galleries/fileapi/media_path_filter.h
@@ -7,10 +7,10 @@ #include <stddef.h> +#include <map> #include <string> #include <vector> -#include "base/containers/hash_tables.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/sequence_checker.h" @@ -45,7 +45,7 @@ // Key: .extension // Value: MediaGalleryFileType, but stored as an int to allow "|=" - typedef base::hash_map<base::FilePath::StringType, int> MediaFileExtensionMap; + using MediaFileExtensionMap = std::map<base::FilePath::StringType, int>; void EnsureInitialized();
diff --git a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h index 37e41665..e169b3b 100644 --- a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h +++ b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h
@@ -12,7 +12,6 @@ #include <memory> #include <vector> -#include "base/containers/hash_tables.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/macros.h" @@ -156,8 +155,7 @@ std::unique_ptr<DeviceListener> camera_interface_; // Stores a map from filename to file metadata received from the camera. - base::hash_map<base::FilePath::StringType, - base::File::Info> file_info_; + std::map<base::FilePath::StringType, base::File::Info> file_info_; // List of filenames received from the camera. std::vector<base::FilePath> file_paths_;
diff --git a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm index ce31c826..5b7a959 100644 --- a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm +++ b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm
@@ -297,9 +297,7 @@ base::File::Info* file_info, base::File::Error* error) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::hash_map<base::FilePath::StringType, - base::File::Info>::const_iterator i = - file_info_.find(file_path.value()); + auto i = file_info_.find(file_path.value()); if (i == file_info_.end()) { *error = base::File::FILE_ERROR_NOT_FOUND; return;
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc index 362e0fa..fe2a9ba 100644 --- a/chrome/browser/net/predictor_browsertest.cc +++ b/chrome/browser/net/predictor_browsertest.cc
@@ -6,6 +6,7 @@ #include <stdint.h> #include <algorithm> +#include <map> #include <memory> #include <set> @@ -255,7 +256,7 @@ // This lock protects all the members below, which each are used on both the // IO and UI thread. Members declared after the lock are protected by it. mutable base::Lock lock_; - typedef base::hash_map<uint16_t, SocketStatus> SocketContainer; + typedef std::map<uint16_t, SocketStatus> SocketContainer; SocketContainer sockets_; // If |num_accepted_connections_needed_| is non zero, then the object is
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 28410322..2a3cda54b 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -4,6 +4,7 @@ #include <stddef.h> +#include <map> #include <vector> #include "base/base_paths.h" @@ -607,7 +608,7 @@ // Create a string representation of the tree starting with the embedded // object. std::string ax_tree_dump; - base::hash_map<int32_t, int> id_to_indentation; + std::map<int32_t, int> id_to_indentation; bool found_embedded_object = false; for (auto& node : ax_tree.nodes) { if (node.role == ui::AX_ROLE_EMBEDDED_OBJECT)
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc index 122f6bd7..b4ca7b5 100644 --- a/chrome/browser/resource_coordinator/tab_manager.cc +++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -8,13 +8,11 @@ #include <algorithm> #include <set> -#include <vector> #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" #include "base/feature_list.h" -#include "base/macros.h" #include "base/memory/memory_pressure_monitor.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" @@ -97,31 +95,6 @@ return -1; } -class BoundsList { - public: - BoundsList() = default; - - // Returns false if a previously inserted gfx::Rect covers |bounds|. - // Otherwise, returns true and adds |bounds| to the list. - // - // TODO(fdoray): Handle the case where no previously inserted gfx::Rect covers - // |bounds| by itself but the union of all previously inserted gfx::Rects - // covers |bounds|. - bool AddBoundsIfNotCoveredByPreviousBounds(const gfx::Rect& bounds) { - for (const gfx::Rect& previous_bounds : bounds_list_) { - if (previous_bounds.Contains(bounds)) - return false; - } - bounds_list_.push_back(bounds); - return true; - } - - private: - std::vector<gfx::Rect> bounds_list_; - - DISALLOW_COPY_AND_ASSIGN(BoundsList); -}; - } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -391,19 +364,8 @@ TabStatsList stats_list; stats_list.reserve(32); // 99% of users have < 30 tabs open. - BoundsList bounds_list; - - // GetBrowserInfoList() returns a list sorted in z-order from top to bottom. - // This is important for the visibility calculations below. - for (const BrowserInfo& browser_info : GetBrowserInfoList()) { - const bool window_is_visible = - !browser_info.window_is_minimized && - bounds_list.AddBoundsIfNotCoveredByPreviousBounds( - browser_info.window_bounds); - AddTabStats(browser_info.tab_strip_model, window_is_visible, - browser_info.window_is_active, browser_info.browser_is_app, - &stats_list); - } + for (const BrowserInfo& browser_info : GetBrowserInfoList()) + AddTabStats(browser_info, &stats_list); return stats_list; } @@ -632,21 +594,23 @@ return tab_count; } -void TabManager::AddTabStats(const TabStripModel* tab_strip_model, - bool window_is_visible, - bool window_is_active, - bool browser_is_app, +void TabManager::AddTabStats(const BrowserInfo& browser_info, TabStatsList* stats_list) const { + TabStripModel* tab_strip_model = browser_info.tab_strip_model; for (int i = 0; i < tab_strip_model->count(); i++) { WebContents* contents = tab_strip_model->GetWebContentsAt(i); if (!contents->IsCrashed()) { TabStats stats; - stats.is_app = browser_is_app; + stats.is_app = browser_info.browser_is_app; stats.is_internal_page = IsInternalPage(contents->GetLastCommittedURL()); stats.is_media = IsMediaTab(contents); stats.is_pinned = tab_strip_model->IsTabPinned(i); - stats.is_selected = window_is_active && tab_strip_model->IsTabSelected(i); - stats.is_in_visible_window = window_is_visible; + stats.is_selected = + browser_info.window_is_active && tab_strip_model->IsTabSelected(i); + // Only consider the window non-visible if it is minimized. The consumer + // of the constructed TabStatsList may update this after performing more + // advanced window visibility checks. + stats.is_in_visible_window = !browser_info.window_is_minimized; stats.is_discarded = GetWebContentsData(contents)->IsDiscarded(); stats.has_form_entry = contents->GetPageImportanceSignals().had_form_interaction; @@ -935,7 +899,6 @@ browser_info.tab_strip_model = browser->tab_strip_model(); browser_info.window_is_active = browser->window()->IsActive(); browser_info.window_is_minimized = browser->window()->IsMinimized(); - browser_info.window_bounds = browser->window()->GetBounds(); browser_info.browser_is_app = browser->is_app(); browser_info_list.push_back(browser_info); }
diff --git a/chrome/browser/resource_coordinator/tab_manager.h b/chrome/browser/resource_coordinator/tab_manager.h index 414b743..bdb0452 100644 --- a/chrome/browser/resource_coordinator/tab_manager.h +++ b/chrome/browser/resource_coordinator/tab_manager.h
@@ -27,7 +27,6 @@ #include "chrome/browser/sessions/session_restore_observer.h" #include "chrome/browser/ui/browser_tab_strip_tracker.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" -#include "ui/gfx/geometry/rect.h" class BrowserList; class GURL; @@ -190,7 +189,6 @@ TabStripModel* tab_strip_model; bool window_is_active; bool window_is_minimized; - gfx::Rect window_bounds; bool browser_is_app; }; @@ -244,15 +242,8 @@ // Returns the number of tabs open in all browser instances. int GetTabCount() const; - // Adds all the stats of the tabs in |tab_strip_model| into |stats_list|. - // |window_is_visible| indicates whether |tab_strip_model| lives in a window - // which is visible to the user. |window_is_active| indicates whether - // |tab_strip_model| lives in the currently active window. |browser_is_app| - // indicates whether |tab_strip_model| is in a Browser running an app. - void AddTabStats(const TabStripModel* tab_strip_model, - bool window_is_visible, - bool window_is_active, - bool browser_is_app, + // Adds all the stats of the tabs in |browser_info| into |stats_list|. + void AddTabStats(const BrowserInfo& browser_info, TabStatsList* stats_list) const; // Callback for when |update_timer_| fires. Takes care of executing the tasks
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h index 025fcea..8c51eb6 100644 --- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h +++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h
@@ -10,7 +10,7 @@ #include <utility> #include <vector> -#include "base/containers/hash_tables.h" +#include "base/containers/flat_map.h" #include "base/gtest_prod_util.h" #include "base/logging.h" #include "base/macros.h" @@ -126,10 +126,10 @@ typedef std::pair<int, base::ProcessHandle> ProcessInfo; // Cache OOM scores in memory. - typedef base::hash_map<base::ProcessHandle, int> ProcessScoreMap; + typedef base::flat_map<base::ProcessHandle, int> ProcessScoreMap; // A map from an ARC process name to a monotonic timestamp when it's killed. - typedef base::hash_map<std::string, base::TimeTicks> KilledArcProcessesMap; + typedef base::flat_map<std::string, base::TimeTicks> KilledArcProcessesMap; // Get the list of candidates to kill, sorted by descending importance. static std::vector<Candidate> GetSortedCandidates(
diff --git a/chrome/browser/resource_coordinator/tab_manager_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_unittest.cc index 238610c..1c91624 100644 --- a/chrome/browser/resource_coordinator/tab_manager_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
@@ -468,7 +468,6 @@ browser_info.tab_strip_model = &tabstrip; browser_info.window_is_active = true; browser_info.window_is_minimized = false; - browser_info.window_bounds = gfx::Rect(0, 0, 0, 0); browser_info.browser_is_app = false; tab_manager.test_browser_info_list_.push_back(browser_info); @@ -511,10 +510,8 @@ WebContents* web_contents1b = CreateWebContents(); WebContents* web_contents2a = CreateWebContents(); WebContents* web_contents2b = CreateWebContents(); - WebContents* web_contents3a = CreateWebContents(); - WebContents* web_contents3b = CreateWebContents(); - // Create 3 TabStripModels. + // Create 2 TabStripModels. TabStripModel tab_strip1(&delegate, profile()); tab_strip1.AppendWebContents(web_contents1a, true); tab_strip1.AppendWebContents(web_contents1b, false); @@ -523,42 +520,28 @@ tab_strip2.AppendWebContents(web_contents2a, true); tab_strip2.AppendWebContents(web_contents2b, false); - TabStripModel tab_strip3(&delegate, profile()); - tab_strip3.AppendWebContents(web_contents3a, true); - tab_strip3.AppendWebContents(web_contents3b, false); - - // Add the 3 TabStripModels to the TabManager. - // The window for |tab_strip1| covers the window for |tab_strip2|. The window - // for |tab_strip3| is minimized. + // Add the 2 TabStripModels to the TabManager. + // The window for |tab_strip1| is visible while the window for |tab_strip2| is + // minimized. TabManager::BrowserInfo browser_info1; browser_info1.tab_strip_model = &tab_strip1; browser_info1.window_is_active = true; browser_info1.window_is_minimized = false; - browser_info1.window_bounds = gfx::Rect(0, 0, 100, 100); browser_info1.browser_is_app = false; tab_manager.test_browser_info_list_.push_back(browser_info1); TabManager::BrowserInfo browser_info2; browser_info2.tab_strip_model = &tab_strip2; browser_info2.window_is_active = false; - browser_info2.window_is_minimized = false; - browser_info2.window_bounds = gfx::Rect(10, 10, 50, 50); + browser_info2.window_is_minimized = true; browser_info2.browser_is_app = false; tab_manager.test_browser_info_list_.push_back(browser_info2); - TabManager::BrowserInfo browser_info3; - browser_info3.tab_strip_model = &tab_strip3; - browser_info3.window_is_active = false; - browser_info3.window_is_minimized = true; - browser_info3.window_bounds = gfx::Rect(); - browser_info3.browser_is_app = false; - tab_manager.test_browser_info_list_.push_back(browser_info3); - // Get TabStats and verify the the |is_in_visible_window| field of each // TabStats is set correctly. auto tab_stats = tab_manager.GetUnsortedTabStats(); - ASSERT_EQ(6U, tab_stats.size()); + ASSERT_EQ(4U, tab_stats.size()); EXPECT_EQ(tab_stats[0].tab_contents_id, tab_manager.IdFromWebContents(web_contents1a)); @@ -568,17 +551,11 @@ tab_manager.IdFromWebContents(web_contents2a)); EXPECT_EQ(tab_stats[3].tab_contents_id, tab_manager.IdFromWebContents(web_contents2b)); - EXPECT_EQ(tab_stats[4].tab_contents_id, - tab_manager.IdFromWebContents(web_contents3a)); - EXPECT_EQ(tab_stats[5].tab_contents_id, - tab_manager.IdFromWebContents(web_contents3b)); EXPECT_TRUE(tab_stats[0].is_in_visible_window); EXPECT_TRUE(tab_stats[1].is_in_visible_window); EXPECT_FALSE(tab_stats[2].is_in_visible_window); EXPECT_FALSE(tab_stats[3].is_in_visible_window); - EXPECT_FALSE(tab_stats[4].is_in_visible_window); - EXPECT_FALSE(tab_stats[5].is_in_visible_window); } TEST_F(TabManagerTest, OnSessionRestoreStartedAndFinishedLoadingTabs) {
diff --git a/chrome/browser/resources/md_bookmarks/app.html b/chrome/browser/resources/md_bookmarks/app.html index 9cc1c358..df448d36 100644 --- a/chrome/browser/resources/md_bookmarks/app.html +++ b/chrome/browser/resources/md_bookmarks/app.html
@@ -5,13 +5,13 @@ <link rel="import" href="chrome://bookmarks/command_manager.html"> <link rel="import" href="chrome://bookmarks/constants.html"> <link rel="import" href="chrome://bookmarks/dnd_manager.html"> +<link rel="import" href="chrome://bookmarks/folder_node.html"> <link rel="import" href="chrome://bookmarks/list.html"> <link rel="import" href="chrome://bookmarks/router.html"> <link rel="import" href="chrome://bookmarks/shared_vars.html"> <link rel="import" href="chrome://bookmarks/store.html"> <link rel="import" href="chrome://bookmarks/toast_manager.html"> <link rel="import" href="chrome://bookmarks/toolbar.html"> -<link rel="import" href="chrome://bookmarks/folder_node.html"> <link rel="import" href="chrome://bookmarks/util.html"> <dom-module id="bookmarks-app">
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.html b/chrome/browser/resources/md_bookmarks/command_manager.html index d83d555..49cd2a9c 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.html +++ b/chrome/browser/resources/md_bookmarks/command_manager.html
@@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="chrome://resources/html/cr/ui/command.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> +<link rel="import" href="chrome://bookmarks/dialog_focus_manager.html"> <link rel="import" href="chrome://bookmarks/edit_dialog.html"> <link rel="import" href="chrome://bookmarks/shared_style.html"> <link rel="import" href="chrome://bookmarks/store_client.html">
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.js b/chrome/browser/resources/md_bookmarks/command_manager.js index 790fb62d..f0b37bf 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.js +++ b/chrome/browser/resources/md_bookmarks/command_manager.js
@@ -109,11 +109,15 @@ */ openCommandMenuAtPosition: function(x, y, items) { this.menuIds_ = items || this.getState().selection.items; + var dropdown = /** @type {!CrActionMenuElement} */ (this.$.dropdown.get()); // Ensure that the menu is fully rendered before trying to position it. Polymer.dom.flush(); - dropdown.showAtPosition({top: y, left: x}); + bookmarks.DialogFocusManager.getInstance().showDialog( + dropdown, function() { + dropdown.showAtPosition({top: y, left: x}); + }); }, /** @@ -123,11 +127,15 @@ */ openCommandMenuAtElement: function(target) { this.menuIds_ = this.getState().selection.items; + var dropdown = /** @type {!CrActionMenuElement} */ (this.$.dropdown.get()); // Ensure that the menu is fully rendered before trying to position it. Polymer.dom.flush(); - dropdown.showAt(target); + bookmarks.DialogFocusManager.getInstance().showDialog( + dropdown, function() { + dropdown.showAt(target); + }); }, closeCommandMenu: function() { @@ -384,7 +392,9 @@ var dialog = this.$.openDialog.get(); dialog.querySelector('.body').textContent = loadTimeData.getStringF('openDialogBody', urls.length); - dialog.showModal(); + + bookmarks.DialogFocusManager.getInstance().showDialog( + this.$.openDialog.get()); }, /**
diff --git a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp index 5c5d2a4..a22067e6 100644 --- a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp +++ b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
@@ -47,6 +47,7 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:command', '<(EXTERNS_GYP):bookmark_manager_private', + 'dialog_focus_manager', 'edit_dialog', 'store_client', 'toast_manager' @@ -58,6 +59,14 @@ 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'] }, { + 'target_name': 'dialog_focus_manager', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + 'mouse_focus_behavior', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'dnd_manager', 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', @@ -77,6 +86,7 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', '<(EXTERNS_GYP):chrome_extensions', + 'dialog_focus_manager', 'types', ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi']
diff --git a/chrome/browser/resources/md_bookmarks/dialog_focus_manager.html b/chrome/browser/resources/md_bookmarks/dialog_focus_manager.html new file mode 100644 index 0000000..9e0ea5a7 --- /dev/null +++ b/chrome/browser/resources/md_bookmarks/dialog_focus_manager.html
@@ -0,0 +1,3 @@ +<link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="chrome://bookmarks/mouse_focus_behavior.html"> +<script src="chrome://bookmarks/dialog_focus_manager.js"></script>
diff --git a/chrome/browser/resources/md_bookmarks/dialog_focus_manager.js b/chrome/browser/resources/md_bookmarks/dialog_focus_manager.js new file mode 100644 index 0000000..5b3879d --- /dev/null +++ b/chrome/browser/resources/md_bookmarks/dialog_focus_manager.js
@@ -0,0 +1,102 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +cr.define('bookmarks', function() { + /** + * Manages focus restoration for modal dialogs. After the final dialog in a + * stack is closed, restores focus to the element which was focused when the + * first dialog was opened. + * @constructor + */ + function DialogFocusManager() { + /** @private {HTMLElement} */ + this.previousFocusElement_ = null; + + /** @private {boolean} */ + this.previousMouseFocus_ = false; + + /** @private {Set<HTMLDialogElement>} */ + this.dialogs_ = new Set(); + } + + DialogFocusManager.prototype = { + /** + * @param {HTMLDialogElement} dialog + * @param {function()=} showFn + */ + showDialog: function(dialog, showFn) { + if (!showFn) { + showFn = function() { + dialog.showModal(); + }; + } + + // Update the focus if there are no open dialogs or if this is the only + // dialog and it's getting reshown. + if (!this.dialogs_.size || + (this.dialogs_.has(dialog) && this.dialogs_.size == 1)) { + this.updatePreviousFocus_(); + } + + if (!this.dialogs_.has(dialog)) { + dialog.addEventListener('close', this.getCloseListener_(dialog)); + this.dialogs_.add(dialog); + } + + showFn(); + }, + + /** @private */ + updatePreviousFocus_: function() { + this.previousFocusElement_ = this.getFocusedElement_(); + this.previousMouseFocus_ = bookmarks.MouseFocusBehavior.isMouseFocused( + this.previousFocusElement_); + }, + + /** + * @return {HTMLElement} + * @private + */ + getFocusedElement_: function() { + var focus = document.activeElement; + while (focus.root && focus.root.activeElement) + focus = focus.root.activeElement; + + return focus; + }, + + /** + * @param {HTMLDialogElement} dialog + * @return {function(Event)} + * @private + */ + getCloseListener_: function(dialog) { + var closeListener = function(e) { + // If the dialog is open, then it got reshown immediately and we + // shouldn't clear it until it is closed again. + if (dialog.open) + return; + + assert(this.dialogs_.delete(dialog)); + // Focus the originally focused element if there are no more dialogs. + if (!this.dialogs_.size) { + this.previousFocusElement_.focus(); + if (this.previousMouseFocus_) { + bookmarks.MouseFocusBehavior.addMouseFocusClass( + this.previousFocusElement_); + } + } + dialog.removeEventListener('close', closeListener); + }.bind(this); + + return closeListener; + }, + }; + + cr.addSingletonGetter(DialogFocusManager); + + return { + DialogFocusManager: DialogFocusManager, + }; +});
diff --git a/chrome/browser/resources/md_bookmarks/edit_dialog.html b/chrome/browser/resources/md_bookmarks/edit_dialog.html index 416f417..733b76e2 100644 --- a/chrome/browser/resources/md_bookmarks/edit_dialog.html +++ b/chrome/browser/resources/md_bookmarks/edit_dialog.html
@@ -5,6 +5,7 @@ <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> +<link rel="import" href="chrome://bookmarks/dialog_focus_manager.html"> <dom-module id="bookmarks-edit-dialog"> <template>
diff --git a/chrome/browser/resources/md_bookmarks/edit_dialog.js b/chrome/browser/resources/md_bookmarks/edit_dialog.js index 06f916a..582417e7 100644 --- a/chrome/browser/resources/md_bookmarks/edit_dialog.js +++ b/chrome/browser/resources/md_bookmarks/edit_dialog.js
@@ -43,7 +43,7 @@ this.isFolder_ = isFolder; this.parentId_ = parentId; - this.$.dialog.showModal(); + bookmarks.DialogFocusManager.getInstance().showDialog(this.$.dialog); }, /** @@ -60,7 +60,7 @@ if (!this.isFolder_) this.urlValue_ = assert(editItem.url); - this.$.dialog.showModal(); + bookmarks.DialogFocusManager.getInstance().showDialog(this.$.dialog); }, /**
diff --git a/chrome/browser/resources/md_bookmarks/item.js b/chrome/browser/resources/md_bookmarks/item.js index 50fa1cd..06b29a68 100644 --- a/chrome/browser/resources/md_bookmarks/item.js +++ b/chrome/browser/resources/md_bookmarks/item.js
@@ -67,6 +67,7 @@ */ onContextMenu_: function(e) { e.preventDefault(); + this.focus(); if (!this.isSelectedItem_) this.selectThisItem_();
diff --git a/chrome/browser/resources/md_bookmarks/mouse_focus_behavior.js b/chrome/browser/resources/md_bookmarks/mouse_focus_behavior.js index 2aec0e9..ce62e2a 100644 --- a/chrome/browser/resources/md_bookmarks/mouse_focus_behavior.js +++ b/chrome/browser/resources/md_bookmarks/mouse_focus_behavior.js
@@ -3,6 +3,9 @@ // found in the LICENSE file. cr.define('bookmarks', function() { + /** @const */ + var MOUSE_FOCUS_CLASS = 'mouse-focus'; + /** * Behavior which adds the 'mouse-focus' class to a target element when it * gains focus from the mouse, allowing the outline to be hidden without @@ -16,12 +19,14 @@ var target = this.getFocusTarget(); target.addEventListener('mousedown', this.boundOnMousedown_); + target.addEventListener('contextmenu', this.boundOnMousedown_); target.addEventListener('blur', this.boundClearMouseFocus_); }, detached: function() { var target = this.getFocusTarget(); target.removeEventListener('mousedown', this.boundOnMousedown_); + target.removeEventListener('contextmenu', this.boundOnMousedown_); target.removeEventListener('blur', this.boundClearMouseFocus_); }, @@ -37,12 +42,25 @@ /** Reset the focus state when focus leaves the target element. */ clearMouseFocus: function() { - this.getFocusTarget().classList.remove('mouse-focus'); + this.getFocusTarget().classList.remove(MOUSE_FOCUS_CLASS); }, /** @private */ onMousedown_: function() { - this.getFocusTarget().classList.add('mouse-focus'); + this.addMouseFocusClass(this.getFocusTarget()); + }, + + /** + * @param {HTMLElement} element + * @return {boolean} + */ + isMouseFocused: function(element) { + return element.classList.contains(MOUSE_FOCUS_CLASS); + }, + + /** @param {HTMLElement} element */ + addMouseFocusClass: function(element) { + element.classList.add(MOUSE_FOCUS_CLASS); }, };
diff --git a/chrome/browser/resources_util.cc b/chrome/browser/resources_util.cc index 7dd7f4b..d74bc7f 100644 --- a/chrome/browser/resources_util.cc +++ b/chrome/browser/resources_util.cc
@@ -8,7 +8,7 @@ #include <utility> -#include "base/containers/hash_tables.h" +#include "base/containers/flat_map.h" #include "base/lazy_instance.h" #include "build/build_config.h" #include "chrome/grit/theme_resources_map.h" @@ -21,30 +21,39 @@ namespace { -// A wrapper class that holds a hash_map between resource strings and resource +// A wrapper class that holds a map between resource strings and resource // ids. This is done so we can use base::LazyInstance which takes care of -// thread safety in initializing the hash_map for us. +// thread safety in initializing the map for us. class ThemeMap { public: - typedef base::hash_map<std::string, int> StringIntMap; + typedef base::flat_map<std::string, int> StringIntMap; ThemeMap() { + // Construct in one-shot from a moved vector. + std::vector<StringIntMap::value_type> storage; + for (size_t i = 0; i < kComponentsScaledResourcesSize; ++i) { - id_map_[kComponentsScaledResources[i].name] = - kComponentsScaledResources[i].value; + storage.emplace_back(kComponentsScaledResources[i].name, + kComponentsScaledResources[i].value); } - for (size_t i = 0; i < kThemeResourcesSize; ++i) - id_map_[kThemeResources[i].name] = kThemeResources[i].value; - for (size_t i = 0; i < kUiResourcesSize; ++i) - id_map_[kUiResources[i].name] = kUiResources[i].value; + for (size_t i = 0; i < kThemeResourcesSize; ++i) { + storage.emplace_back(kThemeResources[i].name, kThemeResources[i].value); + } + for (size_t i = 0; i < kUiResourcesSize; ++i) { + storage.emplace_back(kUiResources[i].name, kUiResources[i].value); + } #if defined(OS_CHROMEOS) - for (size_t i = 0; i < kUiChromeosResourcesSize; ++i) - id_map_[kUiChromeosResources[i].name] = kUiChromeosResources[i].value; + for (size_t i = 0; i < kUiChromeosResourcesSize; ++i) { + storage.emplace_back(kUiChromeosResources[i].name, + kUiChromeosResources[i].value); + } #endif + + id_map_ = StringIntMap(std::move(storage), base::KEEP_FIRST_OF_DUPES); } int GetId(const std::string& resource_name) { - StringIntMap::const_iterator it = id_map_.find(resource_name); + auto it = id_map_.find(resource_name); if (it == id_map_.end()) return -1; return it->second;
diff --git a/chrome/browser/safe_browsing/local_database_manager.h b/chrome/browser/safe_browsing/local_database_manager.h index eb5f242..604bf3977b 100644 --- a/chrome/browser/safe_browsing/local_database_manager.h +++ b/chrome/browser/safe_browsing/local_database_manager.h
@@ -18,7 +18,6 @@ #include <vector> #include "base/callback.h" -#include "base/containers/hash_tables.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -166,7 +165,7 @@ ServiceStopWithPendingChecks); typedef std::vector<SafeBrowsingCheck*> GetHashRequestors; - typedef base::hash_map<SBPrefix, GetHashRequestors> GetHashRequests; + typedef std::map<SBPrefix, GetHashRequestors> GetHashRequests; // Clients that we've queued up for checking later once the database is ready. struct QueuedCheck {
diff --git a/chrome/browser/safe_browsing/protocol_manager.h b/chrome/browser/safe_browsing/protocol_manager.h index 8878df62..125d7e25 100644 --- a/chrome/browser/safe_browsing/protocol_manager.h +++ b/chrome/browser/safe_browsing/protocol_manager.h
@@ -334,8 +334,8 @@ // All chunk requests that need to be made. std::deque<ChunkUrl> chunk_request_urls_; - base::hash_map<const net::URLFetcher*, - std::pair<std::unique_ptr<net::URLFetcher>, FullHashDetails>> + std::map<const net::URLFetcher*, + std::pair<std::unique_ptr<net::URLFetcher>, FullHashDetails>> hash_requests_; // True if the service has been given an add/sub chunk but it hasn't been
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 4107743..ac80a07 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -7,6 +7,7 @@ // "goback" or "proceed" commands and verifies they work. #include <algorithm> +#include <map> #include "base/bind.h" #include "base/command_line.h" @@ -158,7 +159,7 @@ private: ~FakeSafeBrowsingDatabaseManager() override {} - base::hash_map<std::string, SBThreatType> badurls; + std::map<std::string, SBThreatType> badurls; DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager); };
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index e0e00872..2855832 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -8,6 +8,8 @@ #include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include <map> +#include <set> #include <utility> #include "base/bind.h" @@ -303,13 +305,11 @@ std::vector<SBPrefix>* prefix_hits) { bool hit = false; for (const GURL& url : urls) { - base::hash_map<std::string, Hits>::const_iterator badurls_it = - badurls_.find(url.spec()); - + const auto badurls_it = badurls_.find(url.spec()); if (badurls_it == badurls_.end()) continue; - std::vector<int> list_ids_for_url = badurls_it->second.list_ids; + const std::vector<int>& list_ids_for_url = badurls_it->second.list_ids; if (base::ContainsValue(list_ids_for_url, list_id0) || base::ContainsValue(list_ids_for_url, list_id1)) { prefix_hits->insert(prefix_hits->end(), @@ -349,9 +349,9 @@ return hit; } - base::hash_map<std::string, Hits> badurls_; - base::hash_set<std::pair<int, SBPrefix>> bad_prefixes_; - base::hash_map<std::string, GURL> urls_by_hash_; + std::map<std::string, Hits> badurls_; + std::set<std::pair<int, SBPrefix>> bad_prefixes_; + std::map<std::string, GURL> urls_by_hash_; DISALLOW_COPY_AND_ASSIGN(TestSafeBrowsingDatabase); }; @@ -396,7 +396,7 @@ // This function is called when there is a prefix hit in local safebrowsing // database and safebrowsing service issues a get hash request to backends. - // We return a result from the prefilled full_hashes_ hash_map to simulate + // We return a result from the prefilled full_hashes_ map to simulate // server's response. At the same time, latency is added to simulate real // life network issues. void GetFullHash(const std::vector<SBPrefix>& prefixes,
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc index 144b16d2..a9cc9f4 100644 --- a/chrome/browser/safe_browsing/threat_details_unittest.cc +++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -270,7 +270,7 @@ ASSERT_EQ(expected_pb.resources_size(), report_pb.resources_size()); // Put the actual resources in a map, then iterate over the expected // resources, making sure each exists and is equal. - base::hash_map<int, const ClientSafeBrowsingReportRequest::Resource*> + std::map<int, const ClientSafeBrowsingReportRequest::Resource*> actual_resource_map; for (const ClientSafeBrowsingReportRequest::Resource& resource : report_pb.resources()) { @@ -290,7 +290,7 @@ ASSERT_EQ(expected_pb.dom_size(), report_pb.dom_size()); // Put the actual elements in a map, then iterate over the expected // elements, making sure each exists and is equal. - base::hash_map<int, const HTMLElement*> actual_dom_map; + std::map<int, const HTMLElement*> actual_dom_map; for (const HTMLElement& element : report_pb.dom()) { actual_dom_map[element.id()] = &element; } @@ -352,7 +352,7 @@ EXPECT_THAT(element.child_ids(), UnorderedPointwise(Eq(), expected.child_ids())); ASSERT_EQ(expected.attribute_size(), element.attribute_size()); - base::hash_map<std::string, std::string> actual_attributes_map; + std::map<std::string, std::string> actual_attributes_map; for (const HTMLElement::Attribute& attribute : element.attribute()) { actual_attributes_map[attribute.name()] = attribute.value(); }
diff --git a/chrome/browser/site_details.h b/chrome/browser/site_details.h index f9201a59..fbc1b92 100644 --- a/chrome/browser/site_details.h +++ b/chrome/browser/site_details.h
@@ -7,7 +7,8 @@ #include <stdint.h> -#include "base/containers/hash_tables.h" +#include <map> + #include "base/macros.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/site_instance.h" @@ -23,7 +24,7 @@ std::set<GURL> sites; }; using ScenarioBrowsingInstanceMap = - base::hash_map<int32_t, ScenarioBrowsingInstanceInfo>; + std::map<int32_t, ScenarioBrowsingInstanceInfo>; // Collects metrics about an actual browsing instance in the current session. struct BrowsingInstanceInfo { @@ -35,7 +36,7 @@ int proxy_count = 0; }; using BrowsingInstanceMap = - base::hash_map<content::SiteInstance*, BrowsingInstanceInfo>; + std::map<content::SiteInstance*, BrowsingInstanceInfo>; // This enum represents various alternative process model policies that we want // to evaluate. We'll estimate the process cost of each scenario. @@ -80,8 +81,7 @@ }; // Maps a BrowserContext to information about the sites it contains. -typedef base::hash_map<content::BrowserContext*, SiteData> - BrowserContextSiteDataMap; +typedef std::map<content::BrowserContext*, SiteData> BrowserContextSiteDataMap; class SiteDetails { public:
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_index.h b/chrome/browser/sync_file_system/drive_backend/metadata_database_index.h index 38ff499..fedf07b 100644 --- a/chrome/browser/sync_file_system/drive_backend/metadata_database_index.h +++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_index.h
@@ -12,9 +12,9 @@ #include <set> #include <string> #include <unordered_map> +#include <unordered_set> #include <vector> -#include "base/containers/hash_tables.h" #include "base/hash.h" #include "base/macros.h" #include "chrome/browser/sync_file_system/drive_backend/metadata_database_index_interface.h" @@ -31,7 +31,7 @@ } // namespace drive_backend } // namespace sync_file_system -namespace BASE_HASH_NAMESPACE { +namespace std { template<> struct hash<sync_file_system::drive_backend::ParentIDAndTitle> { std::size_t operator()( @@ -40,7 +40,7 @@ } }; -} // namespace BASE_HASH_NAMESPACE +} // namespace std namespace sync_file_system { namespace drive_backend { @@ -106,12 +106,12 @@ typedef std::unordered_map<std::string, std::unique_ptr<FileMetadata>> MetadataByID; typedef std::unordered_map<int64_t, std::unique_ptr<FileTracker>> TrackerByID; - typedef base::hash_map<std::string, TrackerIDSet> TrackerIDsByFileID; - typedef base::hash_map<std::string, TrackerIDSet> TrackerIDsByTitle; + typedef std::unordered_map<std::string, TrackerIDSet> TrackerIDsByFileID; + typedef std::unordered_map<std::string, TrackerIDSet> TrackerIDsByTitle; typedef std::map<int64_t, TrackerIDsByTitle> TrackerIDsByParentAndTitle; - typedef base::hash_map<std::string, int64_t> TrackerIDByAppID; - typedef base::hash_set<std::string> FileIDSet; - typedef base::hash_set<ParentIDAndTitle> PathSet; + typedef std::unordered_map<std::string, int64_t> TrackerIDByAppID; + typedef std::unordered_set<std::string> FileIDSet; + typedef std::unordered_set<ParentIDAndTitle> PathSet; typedef std::set<int64_t> DirtyTrackers; friend class MetadataDatabaseTest;
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc index 814220b..e0ea089 100644 --- a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
@@ -104,8 +104,8 @@ } template <typename Key, typename Value> -void ExpectEquivalent(const base::hash_map<Key, Value>& left, - const base::hash_map<Key, Value>& right) { +void ExpectEquivalent(const std::unordered_map<Key, Value>& left, + const std::unordered_map<Key, Value>& right) { // Convert from a hash container to an ordered container for comparison. ExpectEquivalentMaps(std::map<Key, Value>(left.begin(), left.end()), std::map<Key, Value>(right.begin(), right.end())); @@ -136,8 +136,8 @@ } template <typename Value> -void ExpectEquivalent(const base::hash_set<Value>& left, - const base::hash_set<Value>& right) { +void ExpectEquivalent(const std::unordered_set<Value>& left, + const std::unordered_set<Value>& right) { // Convert from a hash container to an ordered container for comparison. return ExpectEquivalentSets(std::set<Value>(left.begin(), left.end()), std::set<Value>(right.begin(), right.end()));
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_worker.h b/chrome/browser/sync_file_system/drive_backend/sync_worker.h index fa4d4bf..b27575c 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_worker.h +++ b/chrome/browser/sync_file_system/drive_backend/sync_worker.h
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include <unordered_map> #include "base/files/file_path.h" #include "base/macros.h" @@ -110,7 +111,7 @@ APP_STATUS_UNINSTALLED, }; - typedef base::hash_map<std::string, AppStatus> AppStatusMap; + using AppStatusMap = std::unordered_map<std::string, AppStatus>; void DoDisableApp(const std::string& app_id, const SyncStatusCallback& callback);
diff --git a/chrome/browser/sync_file_system/subtree_set.h b/chrome/browser/sync_file_system/subtree_set.h index 40e232b2..190165f 100644 --- a/chrome/browser/sync_file_system/subtree_set.h +++ b/chrome/browser/sync_file_system/subtree_set.h
@@ -7,6 +7,8 @@ #include <stddef.h> +#include <unordered_map> + #include "base/containers/hash_tables.h" #include "base/files/file_path.h" @@ -49,7 +51,7 @@ }; typedef base::FilePath::StringType StringType; - typedef base::hash_map<StringType, Node> Subtrees; + typedef std::unordered_map<StringType, Node> Subtrees; // Contains the root of subtrees and all upward node to root. // Each subtree root has |contained_as_subtree_root| flag true.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index a91f1ba..db47135 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1612,6 +1612,8 @@ "views/permission_bubble/chooser_bubble_ui.h", "views/permission_bubble/permission_prompt_impl.cc", "views/permission_bubble/permission_prompt_impl.h", + "views/simple_message_box_views.cc", + "views/simple_message_box_views.h", "views/subtle_notification_view.cc", "views/subtle_notification_view.h", "views/sync/bubble_sync_promo_view.cc", @@ -1882,7 +1884,6 @@ "views/proximity_auth/proximity_auth_error_bubble_view.h", "views/session_crashed_bubble_view.cc", "views/session_crashed_bubble_view.h", - "views/simple_message_box_views.cc", "views/ssl_client_certificate_selector.cc", "views/ssl_client_certificate_selector.h", "views/status_bubble_views.cc", @@ -3012,7 +3013,9 @@ "cocoa/screen_capture_notification_ui_cocoa.h", "cocoa/screen_capture_notification_ui_cocoa.mm", "cocoa/session_crashed_bubble.mm", - "cocoa/simple_message_box_mac.mm", + "cocoa/simple_message_box_bridge_views.mm", + "cocoa/simple_message_box_cocoa.h", + "cocoa/simple_message_box_cocoa.mm", "cocoa/single_web_contents_dialog_manager_cocoa.h", "cocoa/single_web_contents_dialog_manager_cocoa.mm", "cocoa/spinner_view.h",
diff --git a/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.cc b/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.cc index 13f85f2..ae8a004 100644 --- a/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.cc +++ b/chrome/browser/ui/bluetooth/bluetooth_chooser_controller.cc
@@ -23,7 +23,7 @@ Browser* GetBrowser() { chrome::ScopedTabbedBrowserDisplayer browser_displayer( - ProfileManager::GetActiveUserProfile()); + ProfileManager::GetLastUsedProfileAllowedByPolicy()); DCHECK(browser_displayer.browser()); return browser_displayer.browser(); }
diff --git a/chrome/browser/ui/cocoa/simple_message_box_bridge_views.mm b/chrome/browser/ui/cocoa/simple_message_box_bridge_views.mm new file mode 100644 index 0000000..2d08ddd1 --- /dev/null +++ b/chrome/browser/ui/cocoa/simple_message_box_bridge_views.mm
@@ -0,0 +1,70 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/callback.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "chrome/browser/ui/cocoa/simple_message_box_cocoa.h" +#include "chrome/browser/ui/simple_message_box.h" +#include "chrome/browser/ui/views/simple_message_box_views.h" +#include "ui/base/material_design/material_design_controller.h" +#include "ui/base/resource/resource_bundle.h" + +namespace { + +chrome::MessageBoxResult ShowMessageBoxImpl( + gfx::NativeWindow parent, + const base::string16& title, + const base::string16& message, + chrome::MessageBoxType type, + const base::string16& yes_text, + const base::string16& no_text, + const base::string16& checkbox_text) { + // These functions may be called early in browser startup, in which case the + // UI thread may not be ready to run or configured fully. In that case, fall + // back to native Cocoa message boxes. + if (base::MessageLoopForUI::IsCurrent() && + base::RunLoop::IsRunningOnCurrentThread() && + ResourceBundle::HasSharedInstance() && + ui::MaterialDesignController::IsSecondaryUiMaterial()) { + return SimpleMessageBoxViews::Show(parent, title, message, type, yes_text, + no_text, checkbox_text); + } + // ShowMessageBoxCocoa() and NSAlerts in general don't support most of the + // above options at all. + return chrome::ShowMessageBoxCocoa(message, type, checkbox_text); +} + +} // namespace + +namespace chrome { + +void ShowWarningMessageBox(gfx::NativeWindow parent, + const base::string16& title, + const base::string16& message) { + ShowMessageBoxImpl(parent, title, message, MESSAGE_BOX_TYPE_WARNING, + base::string16(), base::string16(), base::string16()); +} + +void ShowWarningMessageBoxWithCheckbox( + gfx::NativeWindow parent, + const base::string16& title, + const base::string16& message, + const base::string16& checkbox_text, + base::OnceCallback<void(bool checked)> callback) { + MessageBoxResult result = + ShowMessageBoxImpl(parent, title, message, MESSAGE_BOX_TYPE_WARNING, + base::string16(), base::string16(), checkbox_text); + std::move(callback).Run(result == MESSAGE_BOX_RESULT_YES); +} + +MessageBoxResult ShowQuestionMessageBox(gfx::NativeWindow parent, + const base::string16& title, + const base::string16& message) { + return ShowMessageBoxImpl(parent, title, message, MESSAGE_BOX_TYPE_QUESTION, + base::string16(), base::string16(), + base::string16()); +} + +} // namespace chrome
diff --git a/chrome/browser/ui/cocoa/simple_message_box_cocoa.h b/chrome/browser/ui/cocoa/simple_message_box_cocoa.h new file mode 100644 index 0000000..087c867 --- /dev/null +++ b/chrome/browser/ui/cocoa/simple_message_box_cocoa.h
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_COCOA_SIMPLE_MESSAGE_BOX_COCOA_H_ +#define CHROME_BROWSER_UI_COCOA_SIMPLE_MESSAGE_BOX_COCOA_H_ + +#include "chrome/browser/ui/simple_message_box.h" + +namespace chrome { + +MessageBoxResult ShowMessageBoxCocoa(const base::string16& message, + MessageBoxType type, + const base::string16& checkbox_text); + +} // namespace chrome + +#endif // CHROME_BROWSER_UI_COCOA_SIMPLE_MESSAGE_BOX_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/simple_message_box_cocoa.mm b/chrome/browser/ui/cocoa/simple_message_box_cocoa.mm new file mode 100644 index 0000000..76db36a --- /dev/null +++ b/chrome/browser/ui/cocoa/simple_message_box_cocoa.mm
@@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/simple_message_box.h" + +#import <Cocoa/Cocoa.h> + +#include <utility> + +#include "base/callback.h" +#include "base/mac/scoped_nsobject.h" +#include "base/strings/sys_string_conversions.h" +#include "chrome/browser/ui/simple_message_box_internal.h" +#include "chrome/grit/generated_resources.h" +#include "components/startup_metric_utils/browser/startup_metric_utils.h" +#include "components/strings/grit/components_strings.h" +#include "ui/base/l10n/l10n_util_mac.h" + +namespace chrome { + +MessageBoxResult ShowMessageBoxCocoa(const base::string16& message, + MessageBoxType type, + const base::string16& checkbox_text) { + startup_metric_utils::SetNonBrowserUIDisplayed(); + if (internal::g_should_skip_message_box_for_test) + return MESSAGE_BOX_RESULT_YES; + + NSAlert* alert = [[[NSAlert alloc] init] autorelease]; + [alert setMessageText:base::SysUTF16ToNSString(message)]; + [alert setAlertStyle:NSWarningAlertStyle]; + if (type == MESSAGE_BOX_TYPE_QUESTION) { + [alert addButtonWithTitle:l10n_util::GetNSString( + IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL)]; + [alert addButtonWithTitle:l10n_util::GetNSString( + IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL)]; + } else { + [alert addButtonWithTitle:l10n_util::GetNSString(IDS_OK)]; + } + + base::scoped_nsobject<NSButton> checkbox; + if (!checkbox_text.empty()) { + checkbox.reset([[NSButton alloc] initWithFrame:NSZeroRect]); + [checkbox setButtonType:NSSwitchButton]; + [checkbox setTitle:base::SysUTF16ToNSString(checkbox_text)]; + [checkbox sizeToFit]; + [alert setAccessoryView:checkbox]; + } + + NSInteger result = [alert runModal]; + if (result == NSAlertSecondButtonReturn) + return MESSAGE_BOX_RESULT_NO; + + if (!checkbox || ([checkbox state] == NSOnState)) + return MESSAGE_BOX_RESULT_YES; + + return MESSAGE_BOX_RESULT_NO; +} + +} // namespace chrome
diff --git a/chrome/browser/ui/cocoa/simple_message_box_mac.mm b/chrome/browser/ui/cocoa/simple_message_box_mac.mm deleted file mode 100644 index 62507b53..0000000 --- a/chrome/browser/ui/cocoa/simple_message_box_mac.mm +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/simple_message_box.h" - -#import <Cocoa/Cocoa.h> - -#include <utility> - -#include "base/callback.h" -#include "base/mac/scoped_nsobject.h" -#include "base/strings/sys_string_conversions.h" -#include "chrome/browser/ui/simple_message_box_internal.h" -#include "chrome/grit/generated_resources.h" -#include "components/startup_metric_utils/browser/startup_metric_utils.h" -#include "components/strings/grit/components_strings.h" -#include "ui/base/l10n/l10n_util_mac.h" - -namespace chrome { - -namespace { - -MessageBoxResult ShowMessageBox(gfx::NativeWindow parent, - const base::string16& title, - const base::string16& message, - const base::string16& checkbox_text, - MessageBoxType type) { - startup_metric_utils::SetNonBrowserUIDisplayed(); - if (internal::g_should_skip_message_box_for_test) - return MESSAGE_BOX_RESULT_YES; - - // Ignore the title; it's the window title on other platforms and ignorable. - NSAlert* alert = [[[NSAlert alloc] init] autorelease]; - [alert setMessageText:base::SysUTF16ToNSString(message)]; - [alert setAlertStyle:NSWarningAlertStyle]; - if (type == MESSAGE_BOX_TYPE_QUESTION) { - [alert addButtonWithTitle: - l10n_util::GetNSString(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL)]; - [alert addButtonWithTitle: - l10n_util::GetNSString(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL)]; - } else { - [alert addButtonWithTitle:l10n_util::GetNSString(IDS_OK)]; - } - - base::scoped_nsobject<NSButton> checkbox; - if (!checkbox_text.empty()) { - checkbox.reset([[NSButton alloc] initWithFrame:NSZeroRect]); - [checkbox setButtonType:NSSwitchButton]; - [checkbox setTitle:base::SysUTF16ToNSString(checkbox_text)]; - [checkbox sizeToFit]; - [alert setAccessoryView:checkbox]; - } - - NSInteger result = [alert runModal]; - if (result == NSAlertSecondButtonReturn) - return MESSAGE_BOX_RESULT_NO; - - if (!checkbox || ([checkbox state] == NSOnState)) - return MESSAGE_BOX_RESULT_YES; - - return MESSAGE_BOX_RESULT_NO; -} - -} // namespace - -void ShowWarningMessageBox(gfx::NativeWindow parent, - const base::string16& title, - const base::string16& message) { - ShowMessageBox(parent, title, message, base::string16(), - MESSAGE_BOX_TYPE_WARNING); -} - -void ShowWarningMessageBoxWithCheckbox( - gfx::NativeWindow parent, - const base::string16& title, - const base::string16& message, - const base::string16& checkbox_text, - base::OnceCallback<void(bool checked)> callback) { - ShowMessageBox(parent, title, message, checkbox_text, - MESSAGE_BOX_TYPE_WARNING); - std::move(callback).Run(false); -} - -MessageBoxResult ShowQuestionMessageBox(gfx::NativeWindow parent, - const base::string16& title, - const base::string16& message) { - return ShowMessageBox(parent, title, message, base::string16(), - MESSAGE_BOX_TYPE_QUESTION); -} - -bool CloseMessageBoxForTest(bool accept) { - NOTIMPLEMENTED(); - return false; -} - -} // namespace chrome
diff --git a/chrome/browser/ui/simple_message_box.h b/chrome/browser/ui/simple_message_box.h index 1dd0ce1..ef8a75b 100644 --- a/chrome/browser/ui/simple_message_box.h +++ b/chrome/browser/ui/simple_message_box.h
@@ -19,6 +19,10 @@ // User chose YES or OK. If there's a checkbox, then the checkbox was checked. MESSAGE_BOX_RESULT_YES = 1, + + // Message box was displayed asynchronously and is pending a real result, + // which will be delivered via callback. + MESSAGE_BOX_RESULT_DEFERRED = 2, }; enum MessageBoxType {
diff --git a/chrome/browser/ui/views/simple_message_box_views.cc b/chrome/browser/ui/views/simple_message_box_views.cc index 8f6194e..6940d06 100644 --- a/chrome/browser/ui/views/simple_message_box_views.cc +++ b/chrome/browser/ui/views/simple_message_box_views.cc
@@ -14,12 +14,14 @@ #include "build/build_config.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/simple_message_box_internal.h" +#include "chrome/browser/ui/views/simple_message_box_views.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "components/startup_metric_utils/browser/startup_metric_utils.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_features.h" #include "ui/gfx/native_widget_types.h" #include "ui/views/controls/message_box_view.h" #include "ui/views/widget/widget.h" @@ -30,102 +32,131 @@ #include "ui/views/win/hwnd_util.h" #endif -namespace chrome { - -namespace { - -class SimpleMessageBoxViews : public views::DialogDelegate { - public: - using MessageBoxResultCallback = - base::OnceCallback<void(MessageBoxResult result)>; - - SimpleMessageBoxViews(const base::string16& title, - const base::string16& message, - MessageBoxType type, - const base::string16& yes_text, - const base::string16& no_text, - const base::string16& checkbox_text, - bool is_system_modal); - ~SimpleMessageBoxViews() override; - - void Run(MessageBoxResultCallback result_callback); - - // Overridden from views::DialogDelegate: - int GetDialogButtons() const override; - base::string16 GetDialogButtonLabel(ui::DialogButton button) const override; - bool Cancel() override; - bool Accept() override; - - // Overridden from views::WidgetDelegate: - base::string16 GetWindowTitle() const override; - void DeleteDelegate() override; - ui::ModalType GetModalType() const override; - views::View* GetContentsView() override; - views::Widget* GetWidget() override; - const views::Widget* GetWidget() const override; - - private: - void Done(); - - const base::string16 window_title_; - const MessageBoxType type_; - base::string16 yes_text_; - base::string16 no_text_; - MessageBoxResult result_; - views::MessageBoxView* message_box_view_; - MessageBoxResultCallback result_callback_; - bool is_system_modal_; - - DISALLOW_COPY_AND_ASSIGN(SimpleMessageBoxViews); -}; - // The currently showing message box, if there is one. Used for tests. SimpleMessageBoxViews* g_current_message_box = nullptr; +namespace { +#if defined(OS_WIN) +UINT GetMessageBoxFlagsFromType(chrome::MessageBoxType type) { + UINT flags = MB_SETFOREGROUND; + switch (type) { + case chrome::MESSAGE_BOX_TYPE_WARNING: + return flags | MB_OK | MB_ICONWARNING; + case chrome::MESSAGE_BOX_TYPE_QUESTION: + return flags | MB_YESNO | MB_ICONQUESTION; + } + NOTREACHED(); + return flags | MB_OK | MB_ICONWARNING; +} +#endif + +// static +chrome::MessageBoxResult ShowSync(gfx::NativeWindow parent, + const base::string16& title, + const base::string16& message, + chrome::MessageBoxType type, + const base::string16& yes_text, + const base::string16& no_text, + const base::string16& checkbox_text) { + chrome::MessageBoxResult result = chrome::MESSAGE_BOX_RESULT_NO; + + // TODO(pkotwicz): Exit message loop when the dialog is closed by some other + // means than |Cancel| or |Accept|. crbug.com/404385 + base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); + base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); + base::RunLoop run_loop; + + SimpleMessageBoxViews::Show( + parent, title, message, type, yes_text, no_text, checkbox_text, + base::Bind( + [](base::RunLoop* run_loop, chrome::MessageBoxResult* out_result, + chrome::MessageBoxResult messagebox_result) { + *out_result = messagebox_result; + run_loop->Quit(); + }, + &run_loop, &result)); + + run_loop.Run(); + return result; +} +} // namespace + //////////////////////////////////////////////////////////////////////////////// // SimpleMessageBoxViews, public: -SimpleMessageBoxViews::SimpleMessageBoxViews( +// static +chrome::MessageBoxResult SimpleMessageBoxViews::Show( + gfx::NativeWindow parent, const base::string16& title, const base::string16& message, - MessageBoxType type, + chrome::MessageBoxType type, const base::string16& yes_text, const base::string16& no_text, const base::string16& checkbox_text, - bool is_system_modal) - : window_title_(title), - type_(type), - yes_text_(yes_text), - no_text_(no_text), - result_(MESSAGE_BOX_RESULT_NO), - message_box_view_(new views::MessageBoxView( - views::MessageBoxView::InitParams(message))), - is_system_modal_(is_system_modal) { - if (yes_text_.empty()) { - yes_text_ = - type_ == MESSAGE_BOX_TYPE_QUESTION - ? l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL) - : l10n_util::GetStringUTF16(IDS_OK); + SimpleMessageBoxViews::MessageBoxResultCallback callback) { + if (!callback) + return ShowSync(parent, title, message, type, yes_text, no_text, + checkbox_text); + + startup_metric_utils::SetNonBrowserUIDisplayed(); + if (chrome::internal::g_should_skip_message_box_for_test) { + std::move(callback).Run(chrome::MESSAGE_BOX_RESULT_YES); + return chrome::MESSAGE_BOX_RESULT_DEFERRED; } - if (no_text_.empty() && type_ == MESSAGE_BOX_TYPE_QUESTION) - no_text_ = l10n_util::GetStringUTF16(IDS_CANCEL); +// Views dialogs cannot be shown outside the UI thread message loop or if the +// ResourceBundle is not initialized yet. +// Fallback to logging with a default response or a Windows MessageBox. +#if defined(OS_WIN) + if (!base::MessageLoopForUI::IsCurrent() || + !base::RunLoop::IsRunningOnCurrentThread() || + !ResourceBundle::HasSharedInstance()) { + LOG_IF(ERROR, !checkbox_text.empty()) << "Dialog checkbox won't be shown"; + int result = ui::MessageBox(views::HWNDForNativeWindow(parent), message, + title, GetMessageBoxFlagsFromType(type)); + std::move(callback).Run((result == IDYES || result == IDOK) + ? chrome::MESSAGE_BOX_RESULT_YES + : chrome::MESSAGE_BOX_RESULT_NO); + return chrome::MESSAGE_BOX_RESULT_DEFERRED; + } +#else + if (!base::MessageLoopForUI::IsCurrent() || + !ResourceBundle::HasSharedInstance()) { + LOG(ERROR) << "Unable to show a dialog outside the UI thread message loop: " + << title << " - " << message; + std::move(callback).Run(chrome::MESSAGE_BOX_RESULT_NO); + return chrome::MESSAGE_BOX_RESULT_DEFERRED; + } +#endif - if (!checkbox_text.empty()) - message_box_view_->SetCheckBoxLabel(checkbox_text); - chrome::RecordDialogCreation(chrome::DialogIdentifier::SIMPLE_MESSAGE_BOX); -} + bool is_system_modal = !parent; -SimpleMessageBoxViews::~SimpleMessageBoxViews() { -} +#if defined(OS_MACOSX) + // Mac does not support system modals, so never ask SimpleMessageBoxViews to + // be system modal. + is_system_modal = false; +#endif -void SimpleMessageBoxViews::Run(MessageBoxResultCallback result_callback) { - g_current_message_box = this; - result_callback_ = std::move(result_callback); + SimpleMessageBoxViews* dialog = new SimpleMessageBoxViews( + title, message, type, yes_text, no_text, checkbox_text, is_system_modal); + views::Widget* widget = + constrained_window::CreateBrowserModalDialogViews(dialog, parent); + +#if defined(OS_MACOSX) + // Mac does not support system modal dialogs. If there is no parent window to + // attach to, move the dialog's widget on top so other windows do not obscure + // it. + if (!parent) + widget->SetAlwaysOnTop(true); +#endif + + widget->Show(); + dialog->Run(std::move(callback)); + return chrome::MESSAGE_BOX_RESULT_DEFERRED; } int SimpleMessageBoxViews::GetDialogButtons() const { - if (type_ == MESSAGE_BOX_TYPE_QUESTION) + if (type_ == chrome::MESSAGE_BOX_TYPE_QUESTION) return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; return ui::DIALOG_BUTTON_OK; @@ -139,7 +170,7 @@ } bool SimpleMessageBoxViews::Cancel() { - result_ = MESSAGE_BOX_RESULT_NO; + result_ = chrome::MESSAGE_BOX_RESULT_NO; Done(); return true; } @@ -147,9 +178,9 @@ bool SimpleMessageBoxViews::Accept() { if (!message_box_view_->HasCheckBox() || message_box_view_->IsCheckBoxSelected()) { - result_ = MESSAGE_BOX_RESULT_YES; + result_ = chrome::MESSAGE_BOX_RESULT_YES; } else { - result_ = MESSAGE_BOX_RESULT_NO; + result_ = chrome::MESSAGE_BOX_RESULT_NO; } Done(); @@ -183,105 +214,53 @@ //////////////////////////////////////////////////////////////////////////////// // SimpleMessageBoxViews, private: +SimpleMessageBoxViews::SimpleMessageBoxViews( + const base::string16& title, + const base::string16& message, + chrome::MessageBoxType type, + const base::string16& yes_text, + const base::string16& no_text, + const base::string16& checkbox_text, + bool is_system_modal) + : window_title_(title), + type_(type), + yes_text_(yes_text), + no_text_(no_text), + result_(chrome::MESSAGE_BOX_RESULT_NO), + message_box_view_(new views::MessageBoxView( + views::MessageBoxView::InitParams(message))), + is_system_modal_(is_system_modal) { + if (yes_text_.empty()) { + yes_text_ = + type_ == chrome::MESSAGE_BOX_TYPE_QUESTION + ? l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL) + : l10n_util::GetStringUTF16(IDS_OK); + } + + if (no_text_.empty() && type_ == chrome::MESSAGE_BOX_TYPE_QUESTION) + no_text_ = l10n_util::GetStringUTF16(IDS_CANCEL); + + if (!checkbox_text.empty()) + message_box_view_->SetCheckBoxLabel(checkbox_text); + chrome::RecordDialogCreation(chrome::DialogIdentifier::SIMPLE_MESSAGE_BOX); +} + +SimpleMessageBoxViews::~SimpleMessageBoxViews() {} + +void SimpleMessageBoxViews::Run(MessageBoxResultCallback result_callback) { + g_current_message_box = this; + result_callback_ = std::move(result_callback); +} + void SimpleMessageBoxViews::Done() { CHECK(!result_callback_.is_null()); std::move(result_callback_).Run(result_); g_current_message_box = nullptr; } -#if defined(OS_WIN) -UINT GetMessageBoxFlagsFromType(MessageBoxType type) { - UINT flags = MB_SETFOREGROUND; - switch (type) { - case MESSAGE_BOX_TYPE_WARNING: - return flags | MB_OK | MB_ICONWARNING; - case MESSAGE_BOX_TYPE_QUESTION: - return flags | MB_YESNO | MB_ICONQUESTION; - } - NOTREACHED(); - return flags | MB_OK | MB_ICONWARNING; -} -#endif +namespace chrome { -void ShowMessageBoxAsyncImpl( - gfx::NativeWindow parent, - const base::string16& title, - const base::string16& message, - MessageBoxType type, - const base::string16& yes_text, - const base::string16& no_text, - const base::string16& checkbox_text, - SimpleMessageBoxViews::MessageBoxResultCallback callback) { - startup_metric_utils::SetNonBrowserUIDisplayed(); - if (internal::g_should_skip_message_box_for_test) { - std::move(callback).Run(MESSAGE_BOX_RESULT_YES); - return; - } - - // Views dialogs cannot be shown outside the UI thread message loop or if the - // ResourceBundle is not initialized yet. - // Fallback to logging with a default response or a Windows MessageBox. -#if defined(OS_WIN) - if (!base::MessageLoopForUI::IsCurrent() || - !base::RunLoop::IsRunningOnCurrentThread() || - !ResourceBundle::HasSharedInstance()) { - LOG_IF(ERROR, !checkbox_text.empty()) << "Dialog checkbox won't be shown"; - int result = ui::MessageBox(views::HWNDForNativeWindow(parent), message, - title, GetMessageBoxFlagsFromType(type)); - std::move(callback).Run((result == IDYES || result == IDOK) - ? MESSAGE_BOX_RESULT_YES - : MESSAGE_BOX_RESULT_NO); - return; - } -#else - if (!base::MessageLoopForUI::IsCurrent() || - !ResourceBundle::HasSharedInstance()) { - LOG(ERROR) << "Unable to show a dialog outside the UI thread message loop: " - << title << " - " << message; - std::move(callback).Run(MESSAGE_BOX_RESULT_NO); - return; - } -#endif - - SimpleMessageBoxViews* dialog = - new SimpleMessageBoxViews(title, message, type, yes_text, no_text, - checkbox_text, !parent /* is_system_modal */); - constrained_window::CreateBrowserModalDialogViews(dialog, parent)->Show(); - - dialog->Run(std::move(callback)); -} - -MessageBoxResult ShowMessageBoxImpl(gfx::NativeWindow parent, - const base::string16& title, - const base::string16& message, - MessageBoxType type, - const base::string16& yes_text, - const base::string16& no_text, - const base::string16& checkbox_text) { - MessageBoxResult result = MESSAGE_BOX_RESULT_NO; - - // TODO(pkotwicz): Exit message loop when the dialog is closed by some other - // means than |Cancel| or |Accept|. crbug.com/404385 - base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); - base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); - base::RunLoop run_loop; - - ShowMessageBoxAsyncImpl( - parent, title, message, type, yes_text, no_text, checkbox_text, - base::Bind( - [](base::RunLoop* run_loop, MessageBoxResult* out_result, - MessageBoxResult messagebox_result) { - *out_result = messagebox_result; - run_loop->Quit(); - }, - &run_loop, &result)); - - run_loop.Run(); - return result; -} - -} // namespace - +#if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER) bool CloseMessageBoxForTest(bool accept) { if (!g_current_message_box) return false; @@ -296,8 +275,9 @@ void ShowWarningMessageBox(gfx::NativeWindow parent, const base::string16& title, const base::string16& message) { - ShowMessageBoxImpl(parent, title, message, MESSAGE_BOX_TYPE_WARNING, - base::string16(), base::string16(), base::string16()); + SimpleMessageBoxViews::Show( + parent, title, message, chrome::MESSAGE_BOX_TYPE_WARNING, + base::string16(), base::string16(), base::string16()); } void ShowWarningMessageBoxWithCheckbox( @@ -306,9 +286,9 @@ const base::string16& message, const base::string16& checkbox_text, base::OnceCallback<void(bool checked)> callback) { - ShowMessageBoxAsyncImpl( - parent, title, message, MESSAGE_BOX_TYPE_WARNING, base::string16(), - base::string16(), checkbox_text, + SimpleMessageBoxViews::Show( + parent, title, message, chrome::MESSAGE_BOX_TYPE_WARNING, + base::string16(), base::string16(), checkbox_text, base::Bind( [](base::OnceCallback<void(bool checked)> callback, MessageBoxResult message_box_result) { @@ -321,9 +301,9 @@ MessageBoxResult ShowQuestionMessageBox(gfx::NativeWindow parent, const base::string16& title, const base::string16& message) { - return ShowMessageBoxImpl(parent, title, message, MESSAGE_BOX_TYPE_QUESTION, - base::string16(), base::string16(), - base::string16()); + return SimpleMessageBoxViews::Show( + parent, title, message, chrome::MESSAGE_BOX_TYPE_QUESTION, + base::string16(), base::string16(), base::string16()); } MessageBoxResult ShowMessageBoxWithButtonText(gfx::NativeWindow parent, @@ -331,8 +311,11 @@ const base::string16& message, const base::string16& yes_text, const base::string16& no_text) { - return ShowMessageBoxImpl(parent, title, message, MESSAGE_BOX_TYPE_QUESTION, - yes_text, no_text, base::string16()); + return SimpleMessageBoxViews::Show(parent, title, message, + chrome::MESSAGE_BOX_TYPE_QUESTION, + yes_text, no_text, base::string16()); } +#endif // !OS_MACOSX || BUILDFLAG(MAC_VIEWS_BROWSER) + } // namespace chrome
diff --git a/chrome/browser/ui/views/simple_message_box_views.h b/chrome/browser/ui/views/simple_message_box_views.h new file mode 100644 index 0000000..c71b6eff --- /dev/null +++ b/chrome/browser/ui/views/simple_message_box_views.h
@@ -0,0 +1,65 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_SIMPLE_MESSAGE_BOX_VIEWS_H_ +#define CHROME_BROWSER_UI_VIEWS_SIMPLE_MESSAGE_BOX_VIEWS_H_ + +#include "chrome/browser/ui/simple_message_box.h" + +#include "ui/views/controls/message_box_view.h" +#include "ui/views/window/dialog_delegate.h" + +class SimpleMessageBoxViews : public views::DialogDelegate { + public: + using MessageBoxResultCallback = + base::OnceCallback<void(chrome::MessageBoxResult result)>; + + static chrome::MessageBoxResult Show( + gfx::NativeWindow parent, + const base::string16& title, + const base::string16& message, + chrome::MessageBoxType type, + const base::string16& yes_text, + const base::string16& no_text, + const base::string16& checkbox_text, + MessageBoxResultCallback callback = MessageBoxResultCallback()); + + // views::DialogDelegate: + int GetDialogButtons() const override; + base::string16 GetDialogButtonLabel(ui::DialogButton button) const override; + bool Cancel() override; + bool Accept() override; + base::string16 GetWindowTitle() const override; + void DeleteDelegate() override; + ui::ModalType GetModalType() const override; + views::View* GetContentsView() override; + views::Widget* GetWidget() override; + const views::Widget* GetWidget() const override; + + private: + SimpleMessageBoxViews(const base::string16& title, + const base::string16& message, + chrome::MessageBoxType type, + const base::string16& yes_text, + const base::string16& no_text, + const base::string16& checkbox_text, + bool is_system_modal); + ~SimpleMessageBoxViews() override; + + void Run(MessageBoxResultCallback result_callback); + void Done(); + + const base::string16 window_title_; + const chrome::MessageBoxType type_; + base::string16 yes_text_; + base::string16 no_text_; + chrome::MessageBoxResult result_; + views::MessageBoxView* message_box_view_; + MessageBoxResultCallback result_callback_; + bool is_system_modal_; + + DISALLOW_COPY_AND_ASSIGN(SimpleMessageBoxViews); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_SIMPLE_MESSAGE_BOX_VIEWS_H_
diff --git a/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc b/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc index 0c53db9..d16575a 100644 --- a/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc +++ b/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc
@@ -6,6 +6,8 @@ #include <algorithm> #include <string> +#include <unordered_set> +#include <utility> #include "base/strings/string16.h" #include "chrome/browser/profiles/profile.h" @@ -118,6 +120,10 @@ IDR_MD_BOOKMARKS_COMMAND_MANAGER_JS); source->AddResourcePath("constants.html", IDR_MD_BOOKMARKS_CONSTANTS_HTML); source->AddResourcePath("constants.js", IDR_MD_BOOKMARKS_CONSTANTS_JS); + source->AddResourcePath("dialog_focus_manager.html", + IDR_MD_BOOKMARKS_DIALOG_FOCUS_MANAGER_HTML); + source->AddResourcePath("dialog_focus_manager.js", + IDR_MD_BOOKMARKS_DIALOG_FOCUS_MANAGER_JS); source->AddResourcePath("dnd_manager.html", IDR_MD_BOOKMARKS_DND_MANAGER_HTML); source->AddResourcePath("dnd_manager.js", IDR_MD_BOOKMARKS_DND_MANAGER_JS);
diff --git a/chrome/browser/usb/usb_chooser_controller.cc b/chrome/browser/usb/usb_chooser_controller.cc index 662d292..1ed6096 100644 --- a/chrome/browser/usb/usb_chooser_controller.cc +++ b/chrome/browser/usb/usb_chooser_controller.cc
@@ -40,7 +40,7 @@ Browser* GetBrowser() { chrome::ScopedTabbedBrowserDisplayer browser_displayer( - ProfileManager::GetActiveUserProfile()); + ProfileManager::GetLastUsedProfileAllowedByPolicy()); DCHECK(browser_displayer.browser()); return browser_displayer.browser(); }
diff --git a/chrome/browser/win/jumplist.cc b/chrome/browser/win/jumplist.cc index bbca0370..db47277 100644 --- a/chrome/browser/win/jumplist.cc +++ b/chrome/browser/win/jumplist.cc
@@ -194,9 +194,9 @@ } // namespace -JumpList::UpdateResults::UpdateResults() {} +JumpList::UpdateTransaction::UpdateTransaction() {} -JumpList::UpdateResults::~UpdateResults() {} +JumpList::UpdateTransaction::~UpdateTransaction() {} // static bool JumpList::Enabled() { @@ -306,6 +306,8 @@ } void JumpList::InitializeTimerForUpdate() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (timer_.IsRunning()) { timer_.Reset(); } else { @@ -317,6 +319,7 @@ void JumpList::OnDelayTimer() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!update_in_progress_); if (updates_to_skip_ > 0) { --updates_to_skip_; @@ -340,6 +343,7 @@ void JumpList::ProcessTopSitesNotification() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!update_in_progress_); // Opening the first tab in one session triggers a TopSite history sync. // Delay this sync till the first tab is closed to allow the "recently closed" @@ -362,6 +366,7 @@ void JumpList::ProcessTabRestoreServiceNotification() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!update_in_progress_); // Create a list of ShellLinkItems from the "Recently Closed" pages. // As noted above, we create a ShellLinkItem objects with the following @@ -549,51 +554,53 @@ IncognitoModePrefs::Availability incognito_availability = IncognitoModePrefs::GetAvailability(profile_->GetPrefs()); - // Make local copies of JumpList member variables and use them for an update. - ShellLinkItemList local_most_visited_pages = most_visited_pages_; - ShellLinkItemList local_recently_closed_pages = recently_closed_pages_; + auto update_transaction = base::MakeUnique<UpdateTransaction>(); + if (most_visited_should_update_) + update_transaction->most_visited_icons = std::move(most_visited_icons_); + if (recently_closed_should_update_) { + update_transaction->recently_closed_icons = + std::move(recently_closed_icons_); + } - bool most_visited_should_update = most_visited_should_update_; - bool recently_closed_should_update = recently_closed_should_update_; - - auto update_results = base::MakeUnique<UpdateResults>(); - update_results->most_visited_icons_in_update = most_visited_icons_; - update_results->recently_closed_icons_in_update = recently_closed_icons_; - - // Parameter evaluation order is unspecified in C++. Ensure the pointer value - // is obtained before base::Passed() is called. - auto* update_results_raw = update_results.get(); + // Parameter evaluation order is unspecified in C++. Do the first bind and + // then move it into PostTaskAndReply to ensure the pointer value is obtained + // before base::Passed() is called. + auto run_update = + base::Bind(&JumpList::RunUpdateJumpList, app_id_, profile_dir, + most_visited_pages_, recently_closed_pages_, + most_visited_should_update_, recently_closed_should_update_, + incognito_availability, update_transaction.get()); // Post a task to update the JumpList, which consists of 1) create new icons, - // 2) delete old icons, 3) notify the OS. + // 2) notify the OS, 3) delete old icons. if (!update_jumplist_task_runner_->PostTaskAndReply( - FROM_HERE, - base::Bind(&JumpList::RunUpdateJumpList, app_id_, profile_dir, - local_most_visited_pages, local_recently_closed_pages, - most_visited_should_update, recently_closed_should_update, - incognito_availability, update_results_raw), + FROM_HERE, std::move(run_update), base::Bind(&JumpList::OnRunUpdateCompletion, weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(update_results))))) { - OnRunUpdateCompletion(base::MakeUnique<UpdateResults>()); + base::Passed(std::move(update_transaction))))) { + OnRunUpdateCompletion(base::MakeUnique<UpdateTransaction>()); } } void JumpList::OnRunUpdateCompletion( - std::unique_ptr<UpdateResults> update_results) { + std::unique_ptr<UpdateTransaction> update_transaction) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Update JumpList member variables based on the results from the update run // just finished. - if (update_results->update_timeout) + if (update_transaction->update_timeout) updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; - if (update_results->update_success) { - most_visited_icons_.swap(update_results->most_visited_icons_in_update); - recently_closed_icons_.swap( - update_results->recently_closed_icons_in_update); - most_visited_should_update_ = false; - recently_closed_should_update_ = false; + if (update_transaction->update_success) { + if (most_visited_should_update_) { + most_visited_icons_ = std::move(update_transaction->most_visited_icons); + most_visited_should_update_ = false; + } + if (recently_closed_should_update_) { + recently_closed_icons_ = + std::move(update_transaction->recently_closed_icons); + recently_closed_should_update_ = false; + } } update_in_progress_ = false; @@ -663,11 +670,46 @@ bool most_visited_should_update, bool recently_closed_should_update, IncognitoModePrefs::Availability incognito_availability, - UpdateResults* update_results) { + UpdateTransaction* update_transaction) { if (!JumpListUpdater::IsEnabled()) return; - DCHECK(update_results); + DCHECK(update_transaction); + + base::FilePath most_visited_icon_dir = GenerateJumplistIconDirName( + profile_dir, FILE_PATH_LITERAL("MostVisited")); + base::FilePath recently_closed_icon_dir = GenerateJumplistIconDirName( + profile_dir, FILE_PATH_LITERAL("RecentClosed")); + + CreateNewJumpListAndNotifyOS( + app_id, most_visited_icon_dir, recently_closed_icon_dir, + most_visited_pages, recently_closed_pages, most_visited_should_update, + recently_closed_should_update, incognito_availability, + update_transaction); + + // Delete any obsolete icon files. + if (most_visited_should_update) { + DeleteIconFiles(most_visited_icon_dir, + update_transaction->most_visited_icons); + } + if (recently_closed_should_update) { + DeleteIconFiles(recently_closed_icon_dir, + update_transaction->recently_closed_icons); + } +} + +// static +void JumpList::CreateNewJumpListAndNotifyOS( + const base::string16& app_id, + const base::FilePath& most_visited_icon_dir, + const base::FilePath& recently_closed_icon_dir, + const ShellLinkItemList& most_visited_pages, + const ShellLinkItemList& recently_closed_pages, + bool most_visited_should_update, + bool recently_closed_should_update, + IncognitoModePrefs::Availability incognito_availability, + UpdateTransaction* update_transaction) { + DCHECK(update_transaction); JumpListUpdater jumplist_updater(app_id); @@ -678,34 +720,31 @@ // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer // than the maximum allowed time, as it's very likely the following update - // steps will also take a long time. As we've not updated the icons on the - // disk, discarding this update wont't affect the current JumpList used by OS. + // steps will also take a long time. if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) { - update_results->update_timeout = true; + update_transaction->update_timeout = true; return; } // Record the desired number of icons created in this JumpList update. int icons_created = 0; + URLIconCache most_visited_icons_next; + URLIconCache recently_closed_icons_next; + // Update the icons for "Most Visisted" category of the JumpList if needed. if (most_visited_should_update) { - base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName( - profile_dir, FILE_PATH_LITERAL("MostVisited")); - icons_created += UpdateIconFiles( - icon_dir_most_visited, most_visited_pages, kMostVisitedItems, - &update_results->most_visited_icons_in_update); + most_visited_icon_dir, most_visited_pages, kMostVisitedItems, + &update_transaction->most_visited_icons, &most_visited_icons_next); } // Update the icons for "Recently Closed" category of the JumpList if needed. if (recently_closed_should_update) { - base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName( - profile_dir, FILE_PATH_LITERAL("RecentClosed")); - icons_created += UpdateIconFiles( - icon_dir_recent_closed, recently_closed_pages, kRecentlyClosedItems, - &update_results->recently_closed_icons_in_update); + recently_closed_icon_dir, recently_closed_pages, kRecentlyClosedItems, + &update_transaction->recently_closed_icons, + &recently_closed_icons_next); } // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. @@ -732,16 +771,12 @@ return; } - // If JumpListUpdater::AddCustomCategory or JumpListUpdater::CommitUpdate - // takes longer than the maximum allowed time, skip the next - // |kUpdatesToSkipUnderHeavyLoad| updates. This update should be finished - // because we've already updated the icons on the disk. If discarding this - // update from here, some items in the current JumpList may not have icons - // as they've been delete from the disk. In this case, the background color of - // the JumpList panel is used instead, which doesn't look nice. - - if (add_custom_category_timer.Elapsed() >= kTimeOutForAddCustomCategory) - update_results->update_timeout = true; + // If AddCustomCategory takes longer than the maximum allowed time, abort the + // current update and skip the next |kUpdatesToSkipUnderHeavyLoad| updates. + if (add_custom_category_timer.Elapsed() >= kTimeOutForAddCustomCategory) { + update_transaction->update_timeout = true; + return; + } // Update the "Tasks" category of the JumpList. if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) @@ -750,81 +785,98 @@ base::ElapsedTimer commit_update_timer; // Commit this transaction and send the updated JumpList to Windows. - if (jumplist_updater.CommitUpdate()) - update_results->update_success = true; + bool commit_success = jumplist_updater.CommitUpdate(); + // If CommitUpdate call takes longer than the maximum allowed time, skip the + // next |kUpdatesToSkipUnderHeavyLoad| updates. if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate) - update_results->update_timeout = true; + update_transaction->update_timeout = true; + + if (commit_success) { + update_transaction->update_success = true; + + // The move assignments below ensure update_transaction always has the icons + // to keep. + if (most_visited_should_update) { + update_transaction->most_visited_icons = + std::move(most_visited_icons_next); + } + if (recently_closed_should_update) { + update_transaction->recently_closed_icons = + std::move(recently_closed_icons_next); + } + } } // static int JumpList::UpdateIconFiles(const base::FilePath& icon_dir, - const ShellLinkItemList& page_list, - size_t slot_limit, - URLIconCache* icon_cache) { - int icons_created = 0; + const ShellLinkItemList& item_list, + size_t max_items, + URLIconCache* icon_cur, + URLIconCache* icon_next) { + DCHECK(icon_cur); + DCHECK(icon_next); - // Clear the JumpList icon folder at |icon_dir| and the cache when - // 1) |icon_cache| is empty. This happens when "Most visited" or "Recently + // Clear the JumpList icon folder at |icon_dir| and the caches when + // 1) |icon_cur| is empty. This happens when "Most visited" or "Recently // closed" category updates for the 1st time after Chrome is launched. // 2) The number of icons in |icon_dir| has exceeded the limit. - if (icon_cache->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) { + if (icon_cur->empty() || FilesExceedLimitInDir(icon_dir, max_items * 2)) { DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit); - icon_cache->clear(); + icon_cur->clear(); + icon_next->clear(); // Create new icons only when the directory exists and is empty. - if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) - icons_created += - CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); - } else if (base::CreateDirectory(icon_dir)) { - icons_created += - CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); - DeleteIconFiles(icon_dir, icon_cache); + if (!base::CreateDirectory(icon_dir) || !base::IsDirectoryEmpty(icon_dir)) + return 0; + } else if (!base::CreateDirectory(icon_dir)) { + return 0; } - return icons_created; + return CreateIconFiles(icon_dir, item_list, max_items, *icon_cur, icon_next); } // static int JumpList::CreateIconFiles(const base::FilePath& icon_dir, const ShellLinkItemList& item_list, size_t max_items, - URLIconCache* icon_cache) { + const URLIconCache& icon_cur, + URLIconCache* icon_next) { + DCHECK(icon_next); + // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration"); int icons_created = 0; // Reuse icons for urls that already present in the current JumpList. - URLIconCache updated_map; for (ShellLinkItemList::const_iterator iter = item_list.begin(); iter != item_list.end() && max_items > 0; ++iter, --max_items) { ShellLinkItem* item = iter->get(); - auto cache_iter = icon_cache->find(item->url()); - if (cache_iter != icon_cache->end()) { + auto cache_iter = icon_cur.find(item->url()); + if (cache_iter != icon_cur.end()) { item->set_icon(cache_iter->second.value(), 0); - updated_map[item->url()] = cache_iter->second; + (*icon_next)[item->url()] = cache_iter->second; } else { base::FilePath icon_path; if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) { ++icons_created; item->set_icon(icon_path.value(), 0); - updated_map[item->url()] = icon_path; + (*icon_next)[item->url()] = icon_path; } } } - icon_cache->swap(updated_map); return icons_created; } // static void JumpList::DeleteIconFiles(const base::FilePath& icon_dir, - URLIconCache* icon_cache) { + const URLIconCache& icons_cache) { // Put all cached icon file paths into a set. base::flat_set<base::FilePath> cached_files; - cached_files.reserve(icon_cache->size()); + cached_files.reserve(icons_cache.size()); - for (const auto& url_path_pair : *icon_cache) + for (const auto& url_path_pair : icons_cache) cached_files.insert(url_path_pair.second); DeleteNonCachedFiles(icon_dir, cached_files);
diff --git a/chrome/browser/win/jumplist.h b/chrome/browser/win/jumplist.h index da68edb..30df9199 100644 --- a/chrome/browser/win/jumplist.h +++ b/chrome/browser/win/jumplist.h
@@ -71,22 +71,26 @@ using UrlAndLinkItem = std::pair<std::string, scoped_refptr<ShellLinkItem>>; using URLIconCache = base::flat_map<std::string, base::FilePath>; - // Holds results of the RunUpdateJumpList run. - struct UpdateResults { - UpdateResults(); - ~UpdateResults(); + // Holds results of a RunUpdateJumpList run. + // In-out params: + // |most_visited_icons|, |recently_closed_icons| + // Out params: + // |update_success|, |update_timeout| + struct UpdateTransaction { + UpdateTransaction(); + ~UpdateTransaction(); // Icon file paths of the most visited links, indexed by tab url. // Holding a copy of most_visited_icons_ initially, it's updated by the // JumpList update run. If the update run succeeds, it overwrites // most_visited_icons_. - URLIconCache most_visited_icons_in_update; + URLIconCache most_visited_icons; - // icon file paths of the recently closed links, indexed by tab url. + // Icon file paths of the recently closed links, indexed by tab url. // Holding a copy of recently_closed_icons_ initially, it's updated by the // JumpList update run. If the update run succeeds, it overwrites // recently_closed_icons_. - URLIconCache recently_closed_icons_in_update; + URLIconCache recently_closed_icons; // A flag indicating if a JumpList update run is successful. bool update_success = false; @@ -161,10 +165,12 @@ // folders. void PostRunUpdate(); - // Callback for RunUpdateJumpList that notifies when it finishes running. - // Updates certain JumpList member variables and/or triggers a new JumpList - // update based on |update_results|. - void OnRunUpdateCompletion(std::unique_ptr<UpdateResults> update_results); + // Handles the completion of an update by incorporating its results in + // |update_transaction| back into this instance. Additionally, a new update is + // triggered as needed to process notifications that arrived while the + // now-completed update was running. + void OnRunUpdateCompletion( + std::unique_ptr<UpdateTransaction> update_transaction); // Cancels a pending JumpList update. void CancelPendingUpdate(); @@ -174,42 +180,58 @@ // the |profile_| is destroyed. void Terminate(); - // Updates the application JumpList, which consists of 1) create new icon - // files; 2) delete obsolete icon files; 3) notify the OS. - // Note that any timeout error along the way results in the old JumpList being - // left as-is, while any non-timeout error results in the old JumpList being - // left as-is, but without icon files. + // Updates the application JumpList, which consists of 1) create a new + // JumpList along with any icons that are not in the cache; 2) notify the OS; + // 3) delete obsolete icon files. Any error along the way results in the old + // JumpList being left as-is. static void RunUpdateJumpList( const base::string16& app_id, const base::FilePath& profile_dir, const ShellLinkItemList& most_visited_pages, const ShellLinkItemList& recently_closed_pages, - bool most_visited_pages_have_updates, - bool recently_closed_pages_have_updates, + bool most_visited_should_update, + bool recently_closed_should_update, IncognitoModePrefs::Availability incognito_availability, - UpdateResults* update_results); + UpdateTransaction* update_transaction); - // Updates icon files for |page_list| in |icon_dir|, which consists of - // 1) creating at most |slot_limit| new icons which are not in |icon_cache|; - // 2) deleting old icons which are not in |icon_cache|. - // Returns the number of new icon files created. + // Creates a new JumpList along with any icons that are not in the cache, + // and notifies the OS. + static void CreateNewJumpListAndNotifyOS( + const base::string16& app_id, + const base::FilePath& most_visited_icon_dir, + const base::FilePath& recently_closed_icon_dir, + const ShellLinkItemList& most_visited_pages, + const ShellLinkItemList& recently_closed_pages, + bool most_visited_should_update, + bool recently_closed_should_update, + IncognitoModePrefs::Availability incognito_availability, + UpdateTransaction* update_transaction); + + // Updates icon files for |item_list| in |icon_dir|, which consists of + // 1) If certain safe conditions are not met, clean the folder at |icon_dir|. + // If folder cleaning fails, skip step 2. Besides, clear |icon_cur| and + // |icon_next|. + // 2) Create at most |max_items| icon files which are not in |icon_cur| for + // the asynchrounously loaded icons stored in |item_list|. static int UpdateIconFiles(const base::FilePath& icon_dir, - const ShellLinkItemList& page_list, - size_t slot_limit, - URLIconCache* icon_cache); + const ShellLinkItemList& item_list, + size_t max_items, + URLIconCache* icon_cur, + URLIconCache* icon_next); // In |icon_dir|, creates at most |max_items| icon files which are not in - // |icon_cache| for the asynchrounously loaded icons stored in |item_list|. - // |icon_cache| is also updated for newly created icons. - // Returns the number of new icon files created. + // |icon_cur| for the asynchrounously loaded icons stored in |item_list|. + // |icon_next| is updated based on the reusable icons and the newly created + // icons. Returns the number of new icon files created. static int CreateIconFiles(const base::FilePath& icon_dir, const ShellLinkItemList& item_list, size_t max_items, - URLIconCache* icon_cache); + const URLIconCache& icon_cur, + URLIconCache* icon_next); - // Deletes icon files in |icon_dir| which are not in |icon_cache| anymore. + // Deletes icon files in |icon_dir| which are not in |icon_cache|. static void DeleteIconFiles(const base::FilePath& icon_dir, - URLIconCache* icon_cache); + const URLIconCache& icons_cache); // Tracks FaviconService tasks. base::CancelableTaskTracker cancelable_task_tracker_;
diff --git a/chrome/browser/win/settings_app_monitor.cc b/chrome/browser/win/settings_app_monitor.cc index 1f67ad4..57407cc 100644 --- a/chrome/browser/win/settings_app_monitor.cc +++ b/chrome/browser/win/settings_app_monitor.cc
@@ -800,7 +800,7 @@ } SettingsAppMonitor::~SettingsAppMonitor() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // context_ is still valid when the caller destroys the instance before the // callback(s) have fired. In this case, delete the context on the automation @@ -813,32 +813,32 @@ } void SettingsAppMonitor::OnInitialized(HRESULT result) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); delegate_->OnInitialized(result); } void SettingsAppMonitor::OnAppFocused() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); delegate_->OnAppFocused(); } void SettingsAppMonitor::OnChooserInvoked() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); delegate_->OnChooserInvoked(); } void SettingsAppMonitor::OnBrowserChosen(const base::string16& browser_name) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); delegate_->OnBrowserChosen(browser_name); } void SettingsAppMonitor::OnPromoFocused() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); delegate_->OnPromoFocused(); } void SettingsAppMonitor::OnPromoChoiceMade(bool accept_promo) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); delegate_->OnPromoChoiceMade(accept_promo); }
diff --git a/chrome/browser/win/settings_app_monitor.h b/chrome/browser/win/settings_app_monitor.h index 9e6ee68..90677283 100644 --- a/chrome/browser/win/settings_app_monitor.h +++ b/chrome/browser/win/settings_app_monitor.h
@@ -10,10 +10,10 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" #include "base/strings/string16.h" #include "base/strings/string_piece.h" #include "base/threading/thread.h" -#include "base/threading/thread_checker.h" namespace shell_integration { namespace win { @@ -65,7 +65,7 @@ void OnPromoFocused(); void OnPromoChoiceMade(bool accept_promo); - base::ThreadChecker thread_checker_; + SEQUENCE_CHECKER(sequence_checker_); Delegate* delegate_; // A thread in the COM MTA in which automation calls are made.
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 28d3183..99098ff 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -121,6 +121,9 @@ const base::Feature kCheckInstallabilityForBannerOnLoad{ "CheckInstallabilityForBannerOnLoad", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kClickToOpenPDFPlaceholder{ + "ClickToOpenPDFPlaceholder", base::FEATURE_DISABLED_BY_DEFAULT}; + #if defined(OS_ANDROID) // Experiment to make Geolocation permissions in the omnibox and the default // search engine's search page consistent.
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 014f3fd..51579cd6 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -66,6 +66,8 @@ extern const base::Feature kCheckInstallabilityForBannerOnLoad; +extern const base::Feature kClickToOpenPDFPlaceholder; + #if defined(OS_ANDROID) extern const base::Feature kConsistentOmniboxGeolocation; #endif
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.h b/chrome/renderer/extensions/automation_internal_custom_bindings.h index 78fb66e..f33db545 100644 --- a/chrome/renderer/extensions/automation_internal_custom_bindings.h +++ b/chrome/renderer/extensions/automation_internal_custom_bindings.h
@@ -5,6 +5,9 @@ #ifndef CHROME_RENDERER_EXTENSIONS_AUTOMATION_INTERNAL_CUSTOM_BINDINGS_H_ #define CHROME_RENDERER_EXTENSIONS_AUTOMATION_INTERNAL_CUSTOM_BINDINGS_H_ +#include <map> +#include <vector> + #include "base/compiler_specific.h" #include "base/macros.h" #include "chrome/common/extensions/api/automation.h" @@ -178,8 +181,8 @@ void SendChildTreeIDEvent(ui::AXTree* tree, ui::AXNode* node); void SendNodesRemovedEvent(ui::AXTree* tree, const std::vector<int>& ids); - base::hash_map<int, TreeCache*> tree_id_to_tree_cache_map_; - base::hash_map<ui::AXTree*, TreeCache*> axtree_to_tree_cache_map_; + std::map<int, TreeCache*> tree_id_to_tree_cache_map_; + std::map<ui::AXTree*, TreeCache*> axtree_to_tree_cache_map_; scoped_refptr<AutomationMessageFilter> message_filter_; bool is_active_profile_; std::vector<TreeChangeObserver> tree_change_observers_;
diff --git a/chrome/renderer/safe_browsing/features.h b/chrome/renderer/safe_browsing/features.h index 29fa40ca..e6f21df 100644 --- a/chrome/renderer/safe_browsing/features.h +++ b/chrome/renderer/safe_browsing/features.h
@@ -27,8 +27,8 @@ #include <stddef.h> #include <string> +#include <unordered_map> -#include "base/containers/hash_tables.h" #include "base/macros.h" namespace safe_browsing { @@ -52,7 +52,7 @@ bool AddRealFeature(const std::string& name, double value); // Provides read-only access to the current set of features. - const base::hash_map<std::string, double>& features() const { + const std::unordered_map<std::string, double>& features() const { return features_; } @@ -65,7 +65,7 @@ static const size_t kMaxFeatureMapSize; private: - base::hash_map<std::string, double> features_; + std::unordered_map<std::string, double> features_; DISALLOW_COPY_AND_ASSIGN(FeatureMap); };
diff --git a/chrome/renderer/safe_browsing/phishing_classifier.cc b/chrome/renderer/safe_browsing/phishing_classifier.cc index 03a2caf..13902df4 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier.cc +++ b/chrome/renderer/safe_browsing/phishing_classifier.cc
@@ -194,20 +194,17 @@ ClientPhishingRequest verdict; verdict.set_model_version(scorer_->model_version()); verdict.set_url(main_frame->GetDocument().Url().GetString().Utf8()); - for (base::hash_map<std::string, double>::const_iterator it = - features_->features().begin(); - it != features_->features().end(); ++it) { - DVLOG(2) << "Feature: " << it->first << " = " << it->second; + for (const auto& it : features_->features()) { + DVLOG(2) << "Feature: " << it.first << " = " << it.second; bool result = hashed_features.AddRealFeature( - crypto::SHA256HashString(it->first), it->second); + crypto::SHA256HashString(it.first), it.second); DCHECK(result); ClientPhishingRequest::Feature* feature = verdict.add_feature_map(); - feature->set_name(it->first); - feature->set_value(it->second); + feature->set_name(it.first); + feature->set_value(it.second); } - for (std::set<uint32_t>::const_iterator it = shingle_hashes_->begin(); - it != shingle_hashes_->end(); ++it) { - verdict.add_shingle_hashes(*it); + for (const auto& it : *shingle_hashes_) { + verdict.add_shingle_hashes(it); } float score = static_cast<float>(scorer_->ComputeScore(hashed_features)); verdict.set_client_score(score);
diff --git a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc index 7ba5f04f..b412eed0 100644 --- a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc +++ b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
@@ -5,6 +5,7 @@ #include "chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h" #include <memory> +#include <unordered_map> #include "base/bind.h" #include "base/callback.h" @@ -50,7 +51,7 @@ void SetDocumentDomain(std::string domain) { base_domain_ = domain; } void SetURLToFrameDomainCheckingMap( - const base::hash_map<std::string, std::string>& checking_map) { + const std::unordered_map<std::string, std::string>& checking_map) { url_to_frame_domain_map_ = checking_map; } @@ -122,7 +123,7 @@ // If html contains multiple frame/iframe, we track domain of each frame by // using this map, where keys are the urls mentioned in the html content, // values are the domains of the corresponding frames. - base::hash_map<std::string, std::string> url_to_frame_domain_map_; + std::unordered_map<std::string, std::string> url_to_frame_domain_map_; }; class TestChromeContentRendererClient : public ChromeContentRendererClient { @@ -154,7 +155,8 @@ void ExtractFeaturesAcrossFrames( const std::string& html_content, FeatureMap* features, - const base::hash_map<std::string, std::string>& url_frame_domain_map) { + const std::unordered_map<std::string, std::string>& + url_frame_domain_map) { extractor_->SetURLToFrameDomainCheckingMap(url_frame_domain_map); LoadHTML(html_content.c_str()); @@ -376,7 +378,7 @@ EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now())); const char urlprefix[] = "data:text/html;charset=utf-8,"; - base::hash_map<std::string, std::string> url_iframe_map; + std::unordered_map<std::string, std::string> url_iframe_map; std::string iframe1_nested_html( "<html><body><input type=password>" "<a href=\"https://host3.com/submit\">link</a>"
diff --git a/chrome/renderer/safe_browsing/scorer.cc b/chrome/renderer/safe_browsing/scorer.cc index fc03bad..7c25f3b 100644 --- a/chrome/renderer/safe_browsing/scorer.cc +++ b/chrome/renderer/safe_browsing/scorer.cc
@@ -7,6 +7,7 @@ #include <math.h> #include <memory> +#include <unordered_map> #include "base/logging.h" #include "base/metrics/histogram_macros.h" @@ -114,11 +115,11 @@ double Scorer::ComputeRuleScore(const ClientSideModel::Rule& rule, const FeatureMap& features) const { - const base::hash_map<std::string, double>& feature_map = features.features(); + const std::unordered_map<std::string, double>& feature_map = + features.features(); double rule_score = 1.0; for (int i = 0; i < rule.feature_size(); ++i) { - base::hash_map<std::string, double>::const_iterator it = feature_map.find( - model_.hashes(rule.feature(i))); + const auto it = feature_map.find(model_.hashes(rule.feature(i))); if (it == feature_map.end() || it->second == 0.0) { // If the feature of the rule does not exist in the given feature map the // feature weight is considered to be zero. If the feature weight is zero
diff --git a/chrome/renderer/tts_dispatcher.cc b/chrome/renderer/tts_dispatcher.cc index 4a01190a..4457253 100644 --- a/chrome/renderer/tts_dispatcher.cc +++ b/chrome/renderer/tts_dispatcher.cc
@@ -86,8 +86,7 @@ } WebSpeechSynthesisUtterance TtsDispatcher::FindUtterance(int utterance_id) { - base::hash_map<int, WebSpeechSynthesisUtterance>::const_iterator iter = - utterance_id_map_.find(utterance_id); + const auto iter = utterance_id_map_.find(utterance_id); if (iter == utterance_id_map_.end()) return WebSpeechSynthesisUtterance(); return iter->second;
diff --git a/chrome/renderer/tts_dispatcher.h b/chrome/renderer/tts_dispatcher.h index 96e289d7..fa03b2c 100644 --- a/chrome/renderer/tts_dispatcher.h +++ b/chrome/renderer/tts_dispatcher.h
@@ -5,10 +5,10 @@ #ifndef CHROME_RENDERER_TTS_DISPATCHER_H_ #define CHROME_RENDERER_TTS_DISPATCHER_H_ +#include <map> #include <vector> #include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" #include "base/macros.h" #include "content/public/renderer/render_thread_observer.h" #include "third_party/WebKit/public/platform/WebSpeechSynthesizer.h" @@ -68,7 +68,7 @@ static int next_utterance_id_; // Map from id to utterance objects. - base::hash_map<int, blink::WebSpeechSynthesisUtterance> utterance_id_map_; + std::map<int, blink::WebSpeechSynthesisUtterance> utterance_id_map_; DISALLOW_COPY_AND_ASSIGN(TtsDispatcher); };
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java index 3aa174c..40bffcdb 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
@@ -7,7 +7,6 @@ import android.annotation.TargetApi; import android.os.Build; -import org.chromium.chrome.browser.ntp.ChromeHomeNewTabPage; import org.chromium.chrome.browser.ntp.IncognitoNewTabPage; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.tab.Tab; @@ -31,9 +30,7 @@ public boolean isSatisfied() { if (!tab.isIncognito()) { // TODO(tedchoc): Make MostVisitedPage also have a isLoaded() concept. - if (tab.getNativePage() instanceof ChromeHomeNewTabPage) { - return true; - } else if (tab.getNativePage() instanceof NewTabPage) { + if (tab.getNativePage() instanceof NewTabPage) { return ((NewTabPage) tab.getNativePage()).isLoadedForTests(); } else { return false;
diff --git a/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js b/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js index ba79c7de..db7ddc0 100644 --- a/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js +++ b/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js
@@ -396,5 +396,125 @@ }); }); + suite('DialogFocusManager', function() { + var list; + var store; + var items; + var commandManager; + var dialogFocusManager; + + function waitForClose(el) { + return new Promise(function(resolve) { + listenOnce(el, 'close', function(e) { + resolve(); + }) + }); + } + + function keydown(el, key) { + MockInteractions.keyDownOn(el, '', '', key); + } + + setup(function() { + store = new bookmarks.TestStore({ + nodes: testTree(createFolder( + '1', + [ + createItem('2'), + createItem('3'), + createItem('4'), + createItem('5'), + createItem('6'), + createFolder('7', []), + ])), + selectedFolder: '1', + }); + store.setReducersEnabled(true); + store.replaceSingleton(); + + list = document.createElement('bookmarks-list'); + list.style.height = '100%'; + list.style.width = '100%'; + list.style.position = 'absolute'; + replaceBody(list); + Polymer.dom.flush(); + items = list.root.querySelectorAll('bookmarks-item'); + + commandManager = new TestCommandManager(); + document.body.appendChild(commandManager); + + dialogFocusManager = new bookmarks.DialogFocusManager(); + bookmarks.DialogFocusManager.instance_ = dialogFocusManager; + }); + + test('restores focus on dialog dismissal', function() { + var focusedItem = items[0]; + focusedItem.focus(); + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + + commandManager.openCommandMenuAtPosition(0, 0); + var dropdown = commandManager.$.dropdown.getIfExists(); + + assertTrue(dropdown.open); + assertNotEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + + keydown(dropdown, 'Escape'); + assertFalse(dropdown.open); + + return waitForClose(dropdown).then(() => { + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + }); + }); + + test('restores focus after stacked dialogs', function() { + var focusedItem = items[0]; + focusedItem.focus(); + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + + commandManager.openCommandMenuAtPosition(0, 0); + var dropdown = commandManager.$.dropdown.getIfExists(); + dropdown.close(); + assertNotEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + + var editDialog = commandManager.$.editDialog.get(); + editDialog.showEditDialog(store.data.nodes['2']); + + return waitForClose(dropdown).then(() => { + editDialog.onCancelButtonTap_(); + assertNotEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + + return waitForClose(editDialog); + }).then(() => { + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + }); + }); + + test('restores focus after multiple shows of same dialog', function() { + var focusedItem = items[0]; + focusedItem.focus(); + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + + commandManager.openCommandMenuAtPosition(0, 0); + assertNotEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + var dropdown = commandManager.$.dropdown.getIfExists(); + dropdown.close(); + + focusedItem = items[3]; + focusedItem.focus(); + commandManager.openCommandMenuAtPosition(0, 0); + + return waitForClose(dropdown).then(() => { + assertTrue(dropdown.open); + dropdown.close(); + assertNotEquals( + focusedItem, dialogFocusManager.getFocusedElement_()); + + return waitForClose(dropdown); + }).then(() => { + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); + }); + }); + }); + mocha.run(); });
diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg index 58d5771..1dc822a 100644 --- a/chrome/tools/build/win/FILES.cfg +++ b/chrome/tools/build/win/FILES.cfg
@@ -82,7 +82,7 @@ { 'filename': '*.manifest', 'buildtype': ['dev', 'official'], - 'filegroup': ['default', 'symsrc'], + 'filegroup': ['default'], }, { 'filename': 'chrome_100_percent.pak',
diff --git a/chromecast/media/cma/backend/alsa/volume_control.cc b/chromecast/media/cma/backend/alsa/volume_control.cc index f030c54..7ab9875 100644 --- a/chromecast/media/cma/backend/alsa/volume_control.cc +++ b/chromecast/media/cma/backend/alsa/volume_control.cc
@@ -50,6 +50,7 @@ constexpr char kKeyVolumeMap[] = "volume_map"; constexpr char kKeyLevel[] = "level"; constexpr char kKeyDb[] = "db"; +constexpr char kKeyDefaultVolume[] = "default_volume"; struct LevelToDb { float level; @@ -206,6 +207,26 @@ stored_values_.SetDouble(ContentTypeToDbFSKey(type), volume); } } + } else { + // If saved_volumes does not exist, use per device default if it exists. + auto cast_audio_config = DeserializeJsonFromFile( + base::FilePath(PostProcessingPipelineParser::GetFilePath())); + const base::DictionaryValue* cast_audio_dict; + if (cast_audio_config && + cast_audio_config->GetAsDictionary(&cast_audio_dict)) { + const base::DictionaryValue* default_volume_dict; + if (cast_audio_dict && cast_audio_dict->GetDictionary( + kKeyDefaultVolume, &default_volume_dict)) { + for (auto type : types) { + if (default_volume_dict->GetDouble(ContentTypeToDbFSKey(type), + &volume)) { + stored_values_.SetDouble(ContentTypeToDbFSKey(type), volume); + LOG(INFO) << "Setting default volume for " + << ContentTypeToDbFSKey(type) << " to " << volume; + } + } + } + } } base::Thread::Options options;
diff --git a/components/cronet/ios/BUILD.gn b/components/cronet/ios/BUILD.gn index e0b57e86..dfe018b5 100644 --- a/components/cronet/ios/BUILD.gn +++ b/components/cronet/ios/BUILD.gn
@@ -294,20 +294,20 @@ action("generate_license") { _license_path = "$_package_dir/LICENSE" - script = "//components/cronet/tools/cronet_licenses.py" + script = "//tools/licenses.py" inputs = [ "//build/util/LASTCHANGE", - "//buildtools/$host_os/gn", ] outputs = [ _license_path, ] args = [ - "license", + "license_file", rebase_path(_license_path, root_build_dir), - "--gn", - "--gn-path", - rebase_path("//buildtools/$host_os/gn", root_build_dir), + "--gn-target", + "//components/cronet/ios:cronet_framework", + "--gn-out-dir", + ".", ] }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index a9154966..626d794 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -1077,6 +1077,10 @@ return false; } + // AlwaysOn skips blacklist or disabled checks. + if (params::IsLoFiAlwaysOnViaFlags()) + return true; + if (IsBlackListedOrDisabled(request, previews_decider, previews::PreviewsType::LITE_PAGE)) { return false; @@ -1107,14 +1111,15 @@ return false; } + // AlwaysOn skips blacklist or disabled checks. + if (params::IsLoFiAlwaysOnViaFlags()) + return true; + if (IsBlackListedOrDisabled(request, previews_decider, previews::PreviewsType::LOFI)) { return false; } - if (params::IsLoFiAlwaysOnViaFlags()) - return true; - if (params::IsLoFiCellularOnlyViaFlags()) { return net::NetworkChangeNotifier::IsConnectionCellular(connection_type_); } @@ -1140,14 +1145,15 @@ DCHECK(!base::FeatureList::IsEnabled( features::kDataReductionProxyDecidesTransform)); + // AlwaysOn skips blacklist or disabled checks. + if (params::IsLoFiAlwaysOnViaFlags() && params::AreLitePagesEnabledViaFlags()) + return true; + if (IsBlackListedOrDisabled(request, previews_decider, previews::PreviewsType::LITE_PAGE)) { return false; } - if (params::IsLoFiAlwaysOnViaFlags() && params::AreLitePagesEnabledViaFlags()) - return true; - if (params::IsLoFiCellularOnlyViaFlags() && params::AreLitePagesEnabledViaFlags()) { return net::NetworkChangeNotifier::IsConnectionCellular(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index 3d9e073..32ac3582 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -853,8 +853,8 @@ }, { // Lo-Fi is enabled through command line switch, but opted out. LoFi - // should not be used. - true, false, std::string(), false, false, 0, + // should be used. + true, false, std::string(), false, true, 0, 0, // not in enabled field trial, UMA is not recorded true, }, @@ -942,8 +942,8 @@ }, { // Lo-Fi is enabled through command line switch, but opted out. LoFi - // should not be used. - true, true, std::string(), false, false, 0, + // should be used. + true, true, std::string(), false, true, 0, 0, // not in enabled field trial, UMA is not recorded true, }, @@ -1574,6 +1574,12 @@ EXPECT_TRUE(config()->ShouldAcceptServerPreview(*request.get(), *previews_decider.get())); + // Verify PreviewsDecider check. + previews_decider = base::MakeUnique<TestPreviewsDecider>(true); + EXPECT_TRUE(config()->ShouldAcceptServerPreview(*request.get(), + *previews_decider.get())); + previews_decider = base::MakeUnique<TestPreviewsDecider>(false); + // Verify false for Cellular Only flag and WIFI connection. base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL); base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( @@ -1590,8 +1596,8 @@ EXPECT_TRUE(config()->ShouldAcceptServerPreview(*request.get(), *previews_decider.get())); - // Verify PreviewsDecider check. { + // Verfiy true for always on. base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL); base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( switches::kDataReductionProxyLoFi, @@ -1599,9 +1605,6 @@ base::FieldTrialList field_trial_list(nullptr); base::FieldTrialList::CreateFieldTrial( "DataReductionProxyPreviewsBlackListTransition", "Enabled"); - EXPECT_FALSE(config()->ShouldAcceptServerPreview(*request.get(), - *previews_decider.get())); - previews_decider = base::MakeUnique<TestPreviewsDecider>(true); EXPECT_TRUE(config()->ShouldAcceptServerPreview(*request.get(), *previews_decider.get())); }
diff --git a/components/data_use_measurement/core/data_use_recorder.cc b/components/data_use_measurement/core/data_use_recorder.cc index c4230c24..6d7282b 100644 --- a/components/data_use_measurement/core/data_use_recorder.cc +++ b/components/data_use_measurement/core/data_use_recorder.cc
@@ -17,6 +17,16 @@ return pending_url_requests_.empty(); } +void DataUseRecorder::GetPendingURLRequests( + std::vector<net::URLRequest*>* requests) const { + // Reference to |pending_url_requests_| could be returned instead of copying + // to a vector. But that leads to issues when the caller calls other member + // functions that modify/erase the same map, while iterating. + requests->reserve(pending_url_requests_.size()); + for (const auto& request : pending_url_requests_) + requests->push_back(request.first); +} + void DataUseRecorder::AddPendingURLRequest(net::URLRequest* request) { pending_url_requests_.emplace(std::piecewise_construct, std::forward_as_tuple(request), @@ -27,8 +37,8 @@ pending_url_requests_.erase(request); } -void DataUseRecorder::MovePendingURLRequest(DataUseRecorder* other, - net::URLRequest* request) { +void DataUseRecorder::MovePendingURLRequestTo(DataUseRecorder* other, + net::URLRequest* request) { auto request_it = pending_url_requests_.find(request); DCHECK(request_it != pending_url_requests_.end()); DCHECK(other->pending_url_requests_.find(request) ==
diff --git a/components/data_use_measurement/core/data_use_recorder.h b/components/data_use_measurement/core/data_use_recorder.h index c04f7abf..e66b8fb6 100644 --- a/components/data_use_measurement/core/data_use_recorder.h +++ b/components/data_use_measurement/core/data_use_recorder.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <vector> #include "base/macros.h" #include "base/supports_user_data.h" @@ -42,10 +43,7 @@ // Returns the actual data used by the entity being tracked. DataUse& data_use() { return data_use_; } - const std::map<net::URLRequest*, URLRequestDataUse>& pending_url_requests() - const { - return pending_url_requests_; - } + const net::URLRequest* main_url_request() const { return main_url_request_; } void set_main_url_request(const net::URLRequest* request) { @@ -66,13 +64,19 @@ // by the entity tracked by this recorder. For example, bool IsDataUseComplete(); + // Populate the pending requests to |requests|. + // Reference to the map is not returned since other member functions that + // modify/erase could be called while iterating. + void GetPendingURLRequests(std::vector<net::URLRequest*>* requests) const; + // Adds |request| to the list of pending URLRequests that ascribe data use to // this recorder. void AddPendingURLRequest(net::URLRequest* request); // Moves pending |request| from |this| recorder to |other| recorder, and // updates the data use for the recorders. - void MovePendingURLRequest(DataUseRecorder* other, net::URLRequest* request); + void MovePendingURLRequestTo(DataUseRecorder* other, + net::URLRequest* request); // Clears the list of pending URLRequests that ascribe data use to this // recorder.
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc index d8760fc7..3327ebf 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc
@@ -202,6 +202,177 @@ std::vector<std::string> category_json_; }; +class RemoteSuggestionBuilder { + public: + RemoteSuggestionBuilder() = default; + + RemoteSuggestionBuilder& AddId(const std::string& id) { + if (!ids_) { + ids_ = std::vector<std::string>(); + } + ids_->push_back(id); + return *this; + } + RemoteSuggestionBuilder& SetTitle(const std::string& title) { + title_ = title; + return *this; + } + RemoteSuggestionBuilder& SetSnippet(const std::string& snippet) { + snippet_ = snippet; + return *this; + } + RemoteSuggestionBuilder& SetImageUrl(const std::string& image_url) { + salient_image_url_ = image_url; + return *this; + } + RemoteSuggestionBuilder& SetPublishDate(const base::Time& publish_date) { + publish_date_ = publish_date; + return *this; + } + RemoteSuggestionBuilder& SetExpiryDate(const base::Time& expiry_date) { + expiry_date_ = expiry_date; + return *this; + } + RemoteSuggestionBuilder& SetScore(double score) { + score_ = score; + return *this; + } + RemoteSuggestionBuilder& SetIsDismissed(bool is_dismissed) { + is_dismissed_ = is_dismissed; + return *this; + } + RemoteSuggestionBuilder& SetRemoteCategoryId(int remote_category_id) { + remote_category_id_ = remote_category_id; + return *this; + } + RemoteSuggestionBuilder& SetUrl(const std::string& url) { + url_ = url; + return *this; + } + RemoteSuggestionBuilder& SetPublisher(const std::string& publisher) { + publisher_name_ = publisher; + return *this; + } + RemoteSuggestionBuilder& SetAmpUrl(const std::string& amp_url) { + amp_url_ = amp_url; + return *this; + } + RemoteSuggestionBuilder& SetFetchDate(const base::Time& fetch_date) { + fetch_date_ = fetch_date; + return *this; + } + + std::unique_ptr<RemoteSuggestion> Build() const { + SnippetProto proto; + proto.set_title(title_.value_or("Title")); + proto.set_snippet(snippet_.value_or("Snippet")); + proto.set_salient_image_url( + salient_image_url_.value_or("http://image_url.com/")); + proto.set_publish_date( + publish_date_.value_or(GetDefaultCreationTime()).ToInternalValue()); + proto.set_expiry_date( + expiry_date_.value_or(GetDefaultExpirationTime()).ToInternalValue()); + proto.set_score(score_.value_or(1)); + proto.set_dismissed(is_dismissed_.value_or(false)); + proto.set_remote_category_id(remote_category_id_.value_or(1)); + auto* source = proto.add_sources(); + source->set_url(url_.value_or("http://url.com/")); + source->set_publisher_name(publisher_name_.value_or("Publisher")); + source->set_amp_url(amp_url_.value_or("http://amp_url.com/")); + proto.set_fetch_date( + fetch_date_.value_or(base::Time::Now()).ToInternalValue()); + for (const auto& id : + ids_.value_or(std::vector<std::string>{source->url()})) { + proto.add_ids(id); + } + return RemoteSuggestion::CreateFromProto(proto); + } + + private: + base::Optional<std::vector<std::string>> ids_; + base::Optional<std::string> title_; + base::Optional<std::string> snippet_; + base::Optional<std::string> salient_image_url_; + base::Optional<base::Time> publish_date_; + base::Optional<base::Time> expiry_date_; + base::Optional<double> score_; + base::Optional<bool> is_dismissed_; + base::Optional<int> remote_category_id_; + base::Optional<std::string> url_; + base::Optional<std::string> publisher_name_; + base::Optional<std::string> amp_url_; + base::Optional<base::Time> fetch_date_; +}; + +class FetchedCategoryBuilder { + public: + FetchedCategoryBuilder() = default; + + FetchedCategoryBuilder& SetCategory(Category category) { + category_ = category; + return *this; + } + FetchedCategoryBuilder& SetTitle(const std::string& title) { + title_ = base::UTF8ToUTF16(title); + return *this; + } + FetchedCategoryBuilder& SetCardLayout( + ContentSuggestionsCardLayout card_layout) { + card_layout_ = card_layout; + return *this; + } + FetchedCategoryBuilder& SetAdditionalAction( + ContentSuggestionsAdditionalAction additional_action) { + additional_action_ = additional_action; + return *this; + } + FetchedCategoryBuilder& SetShowIfEmpty(bool show_if_empty) { + show_if_empty_ = show_if_empty; + return *this; + } + FetchedCategoryBuilder& SetNoSuggestionsMessage( + const std::string& no_suggestions_message) { + no_suggestions_message_ = base::UTF8ToUTF16(no_suggestions_message); + return *this; + } + FetchedCategoryBuilder& AddSuggestionViaBuilder( + const RemoteSuggestionBuilder& builder) { + if (!suggestion_builders_) { + suggestion_builders_ = std::vector<RemoteSuggestionBuilder>(); + } + suggestion_builders_->push_back(builder); + return *this; + } + + FetchedCategory Build() const { + FetchedCategory result = FetchedCategory( + category_.value_or(Category::FromRemoteCategory(1)), + CategoryInfo( + title_.value_or(base::UTF8ToUTF16("Category title")), + card_layout_.value_or(ContentSuggestionsCardLayout::FULL_CARD), + additional_action_.value_or( + ContentSuggestionsAdditionalAction::FETCH), + show_if_empty_.value_or(false), + no_suggestions_message_.value_or( + base::UTF8ToUTF16("No suggestions message")))); + + if (suggestion_builders_) { + for (const auto& suggestion_builder : *suggestion_builders_) + result.suggestions.push_back(suggestion_builder.Build()); + } + return result; + } + + private: + base::Optional<Category> category_; + base::Optional<base::string16> title_; + base::Optional<ContentSuggestionsCardLayout> card_layout_; + base::Optional<ContentSuggestionsAdditionalAction> additional_action_; + base::Optional<bool> show_if_empty_; + base::Optional<base::string16> no_suggestions_message_; + base::Optional<std::vector<RemoteSuggestionBuilder>> suggestion_builders_; +}; + // TODO(vitaliii): Remove these convenience functions as they do not provide // that much value and add additional redirections obscuring the code. std::string GetTestJson(const std::vector<std::string>& suggestions, @@ -639,11 +810,44 @@ net::URLRequestStatus::SUCCESS); } - void FetchSuggestions( + void FetchTheseSuggestions( RemoteSuggestionsProviderImpl* provider, bool interactive_request, - const RemoteSuggestionsProvider::FetchStatusCallback& callback) { - provider->FetchSuggestions(interactive_request, callback); + Status status, + base::Optional<std::vector<FetchedCategory>> fetched_categories) { + auto* mock_fetcher = static_cast<StrictMock<MockRemoteSuggestionsFetcher>*>( + suggestions_fetcher()); + RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; + EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) + .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) + .RetiresOnSaturation(); + provider->FetchSuggestions( + interactive_request, RemoteSuggestionsProvider::FetchStatusCallback()); + std::move(snippets_callback) + .Run(Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); + } + + void FetchMoreTheseSuggestions( + RemoteSuggestionsProviderImpl* provider, + const Category& category, + const std::set<std::string>& known_suggestion_ids, + FetchDoneCallback fetch_done_callback, + Status status, + base::Optional<std::vector<FetchedCategory>> fetched_categories) { + auto* mock_fetcher = static_cast<StrictMock<MockRemoteSuggestionsFetcher>*>( + suggestions_fetcher()); + RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; + EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) + .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) + .RetiresOnSaturation(); + EXPECT_CALL(*scheduler(), AcquireQuotaForInteractiveFetch()) + .WillOnce(Return(true)) + .RetiresOnSaturation(); + provider->Fetch(category, known_suggestion_ids, fetch_done_callback); + std::move(snippets_callback) + .Run(Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); } void LoadFromJSONString(RemoteSuggestionsProviderImpl* provider, @@ -719,12 +923,23 @@ }; TEST_F(RemoteSuggestionsProviderImplTest, Full) { - std::string json_str(GetTestJson({GetSuggestion()})); - auto provider = MakeSuggestionsProvider( - /*use_mock_suggestions_fetcher=*/false, /*set_empty_response=*/true); + /*use_mock_suggestions_fetcher=*/true, /*set_empty_response=*/true); - LoadFromJSONString(provider.get(), json_str); + std::vector<FetchedCategory> fetched_categories; + fetched_categories.push_back( + FetchedCategoryBuilder() + .SetCategory(articles_category()) + .AddSuggestionViaBuilder(RemoteSuggestionBuilder() + .AddId(kSuggestionUrl) + .SetTitle(kSuggestionTitle) + .SetSnippet(kSuggestionText) + .SetPublishDate(GetDefaultCreationTime()) + .SetPublisher(kSuggestionPublisherName)) + .Build()); + FetchTheseSuggestions(provider.get(), /*interactive_request=*/true, + Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), SizeIs(1)); @@ -1189,8 +1404,6 @@ /*set_empty_response=*/true); // Fetch a suggestion. - auto* mock_fetcher = static_cast<StrictMock<MockRemoteSuggestionsFetcher>*>( - suggestions_fetcher()); std::vector<FetchedCategory> fetched_categories; fetched_categories.push_back(FetchedCategory( articles_category(), @@ -1198,16 +1411,9 @@ /*allow_fetching_more_results=*/true))); fetched_categories[0].suggestions.push_back( CreateTestRemoteSuggestion("http://old.com/")); - - RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) - .RetiresOnSaturation(); - FetchSuggestions(provider.get(), /*interactive_request=*/true, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::SUCCESS, "message"), - std::move(fetched_categories)); + FetchTheseSuggestions(provider.get(), /*interactive_request=*/true, + Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); ASSERT_THAT( observer().SuggestionsForCategory(articles_category()), @@ -1230,18 +1436,12 @@ ASSERT_THAT(suggestions[0].id().id_within_category(), Eq("http://fetched-more.com/")); }); - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) - .RetiresOnSaturation(); - EXPECT_CALL(*scheduler(), AcquireQuotaForInteractiveFetch()) - .WillOnce(Return(true)) - .RetiresOnSaturation(); - provider->Fetch(articles_category(), - /*known_suggestion_ids=*/{"http://old.com/"}, - assert_receiving_one_new_suggestion); - std::move(snippets_callback) - .Run(Status(StatusCode::SUCCESS, "message"), - std::move(fetched_categories)); + FetchMoreTheseSuggestions( + provider.get(), articles_category(), + /*known_suggestion_ids=*/{"http://old.com/"}, + /*fetch_done_callback=*/assert_receiving_one_new_suggestion, + Status(StatusCode::SUCCESS, "message"), std::move(fetched_categories)); + // Other surfaces should remain the same. EXPECT_THAT( observer().SuggestionsForCategory(articles_category()), @@ -1422,18 +1622,11 @@ ShouldNotAddNewSuggestionsAfterFetchError) { auto provider = MakeSuggestionsProvider( /*use_mock_suggestions_fetcher=*/true, /*set_empty_response=*/true); - auto* mock_fetcher = static_cast<StrictMock<MockRemoteSuggestionsFetcher>*>( - suggestions_fetcher()); - RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; - MockFunction<void(Status, const std::vector<ContentSuggestion>&)> loaded; - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)); - FetchSuggestions(provider.get(), /*interactive_request=*/false, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::TEMPORARY_ERROR, "Received invalid JSON"), - base::nullopt); + FetchTheseSuggestions( + provider.get(), /*interactive_request=*/false, + Status(StatusCode::TEMPORARY_ERROR, "Received invalid JSON"), + base::nullopt); EXPECT_THAT(provider->GetSuggestionsForTesting(articles_category()), IsEmpty()); } @@ -1442,8 +1635,6 @@ ShouldNotClearOldSuggestionsAfterFetchError) { auto provider = MakeSuggestionsProvider( /*use_mock_suggestions_fetcher=*/true, /*set_empty_response=*/true); - auto* mock_fetcher = static_cast<StrictMock<MockRemoteSuggestionsFetcher>*>( - suggestions_fetcher()); std::vector<FetchedCategory> fetched_categories; fetched_categories.push_back(FetchedCategory( @@ -1452,26 +1643,18 @@ /*allow_fetching_more_results=*/true))); fetched_categories[0].suggestions.push_back( CreateTestRemoteSuggestion(base::StringPrintf("http://abc.com/"))); - RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)); - FetchSuggestions(provider.get(), /*interactive_request=*/false, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::SUCCESS, "success message"), - std::move(fetched_categories)); + FetchTheseSuggestions(provider.get(), /*interactive_request=*/false, + Status(StatusCode::SUCCESS, "success message"), + std::move(fetched_categories)); ASSERT_THAT( provider->GetSuggestionsForTesting(articles_category()), ElementsAre(Pointee(Property(&RemoteSuggestion::id, "http://abc.com/")))); - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)); - FetchSuggestions(provider.get(), /*interactive_request=*/false, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::TEMPORARY_ERROR, "Received invalid JSON"), - base::nullopt); + FetchTheseSuggestions( + provider.get(), /*interactive_request=*/false, + Status(StatusCode::TEMPORARY_ERROR, "Received invalid JSON"), + base::nullopt); // This should not have changed the existing suggestions. EXPECT_THAT( provider->GetSuggestionsForTesting(articles_category()), @@ -2095,17 +2278,9 @@ CreateTestRemoteSuggestion("http://abc.com/")); ASSERT_TRUE(fetched_categories[0].suggestions[0]->is_complete()); - // Fetch the suggestion. - RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) - .RetiresOnSaturation(); - FetchSuggestions(provider.get(), /*interactive_request=*/true, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::SUCCESS, "message"), - std::move(fetched_categories)); - + FetchTheseSuggestions(provider.get(), /*interactive_request=*/true, + Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); provider->DismissSuggestion(MakeArticleID("http://abc.com/")); std::set<std::string> expected_excluded_ids({"http://abc.com/"}); @@ -2145,17 +2320,9 @@ base::StringPrintf("http://abc.com/%d/", i))); } - // Fetch the suggestions. - RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) - .RetiresOnSaturation(); - FetchSuggestions(provider.get(), /*interactive_request=*/true, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::SUCCESS, "message"), - std::move(fetched_categories)); - + FetchTheseSuggestions(provider.get(), /*interactive_request=*/true, + Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); // Dismiss them. for (int i = 0; i < kSuggestionsCount; ++i) { provider->DismissSuggestion( @@ -2199,16 +2366,9 @@ base::StringPrintf("http://abc.com/%d/", i))); } - // Fetch the suggestions. - RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) - .RetiresOnSaturation(); - FetchSuggestions(provider.get(), /*interactive_request=*/true, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::SUCCESS, "message"), - std::move(fetched_categories)); + FetchTheseSuggestions(provider.get(), /*interactive_request=*/true, + Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); // Dismiss them in reverse order. std::string first_dismissed_suggestion_id; @@ -2269,16 +2429,9 @@ base::StringPrintf("http://other.com/%d/", i))); } - // Fetch the suggestions. - RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) - .RetiresOnSaturation(); - FetchSuggestions(provider.get(), /*interactive_request=*/true, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::SUCCESS, "message"), - std::move(fetched_categories)); + FetchTheseSuggestions(provider.get(), /*interactive_request=*/true, + Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); // Dismiss all suggestions. std::set<std::string> expected_excluded_ids; @@ -2336,16 +2489,9 @@ fetched_categories[1].suggestions.push_back( CreateTestRemoteSuggestion("http://other.com/")); - // Fetch the suggestions. - RemoteSuggestionsFetcher::SnippetsAvailableCallback snippets_callback; - EXPECT_CALL(*mock_fetcher, FetchSnippets(_, _)) - .WillOnce(MoveSecondArgumentPointeeTo(&snippets_callback)) - .RetiresOnSaturation(); - FetchSuggestions(provider.get(), /*interactive_request=*/true, - RemoteSuggestionsProvider::FetchStatusCallback()); - std::move(snippets_callback) - .Run(Status(StatusCode::SUCCESS, "message"), - std::move(fetched_categories)); + FetchTheseSuggestions(provider.get(), /*interactive_request=*/true, + Status(StatusCode::SUCCESS, "message"), + std::move(fetched_categories)); // Dismiss article suggestions first. for (int i = 0; i < kMaxExcludedDismissedIds; ++i) {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 233cd9b..452bfb5 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -8178,9 +8178,8 @@ { 'name': 'ForceBrowserSignin', 'type': 'main', - 'future': True, 'schema': { 'type': 'boolean' }, - 'supported_on': ['chrome.*:55-', 'android:57-'], + 'supported_on': ['chrome.win:61-', 'chrome.linux:61-', 'android:63-'], 'features': { 'dynamic_refresh': False, 'per_profile': False,
diff --git a/components/proximity_auth/webui/proximity_auth_webui_handler.cc b/components/proximity_auth/webui/proximity_auth_webui_handler.cc index a2fccec..ec4fcc1 100644 --- a/components/proximity_auth/webui/proximity_auth_webui_handler.cc +++ b/components/proximity_auth/webui/proximity_auth_webui_handler.cc
@@ -539,14 +539,15 @@ // the corresponding local device data (e.g. connection status and remote // status updates). std::string public_key = device_info.public_key(); + std::vector<cryptauth::ExternalDeviceInfo> unlock_keys = + device_manager->GetUnlockKeys(); auto iterator = std::find_if( - device_manager->GetUnlockKeys().begin(), - device_manager->GetUnlockKeys().end(), + unlock_keys.begin(), unlock_keys.end(), [&public_key](const cryptauth::ExternalDeviceInfo& unlock_key) { return unlock_key.public_key() == public_key; }); - if (iterator == device_manager->GetUnlockKeys().end() || + if (iterator == unlock_keys.end() || selected_remote_device_.public_key != device_info.public_key()) return dictionary;
diff --git a/components/search_engines/prepopulated_engines.json b/components/search_engines/prepopulated_engines.json index da820086..02999b5 100644 --- a/components/search_engines/prepopulated_engines.json +++ b/components/search_engines/prepopulated_engines.json
@@ -592,6 +592,7 @@ "name": "\u042f\u043d\u0434\u0435\u043a\u0441", "keyword": "yandex.by", "favicon_url": "https://yastatic.net/lego/_/pDu9OWAQKB0s2J9IojKpiS_Eho.ico", + "logo_url": "https://storage.ape.yandex.net/get/browser/Doodles/yandex/drawable-xxhdpi/yandex.png", "search_url": "https://yandex.by/{yandex:searchPath}?text={searchTerms}", "suggest_url": "https://suggest.yandex.by/suggest-ff.cgi?part={searchTerms}", "image_url": "https://yandex.by/images/search/?rpt=imageview", @@ -605,6 +606,7 @@ "name": "\u042f\u043d\u0434\u0435\u043a\u0441", "keyword": "yandex.kz", "favicon_url": "https://yastatic.net/lego/_/pDu9OWAQKB0s2J9IojKpiS_Eho.ico", + "logo_url": "https://storage.ape.yandex.net/get/browser/Doodles/yandex/drawable-xxhdpi/yandex.png", "search_url": "https://yandex.kz/{yandex:searchPath}?text={searchTerms}", "suggest_url": "https://suggest.yandex.kz/suggest-ff.cgi?part={searchTerms}", "image_url": "https://yandex.kz/images/search/?rpt=imageview", @@ -618,6 +620,7 @@ "name": "\u042f\u043d\u0434\u0435\u043a\u0441", "keyword": "yandex.ru", "favicon_url": "https://yastatic.net/lego/_/pDu9OWAQKB0s2J9IojKpiS_Eho.ico", + "logo_url": "https://storage.ape.yandex.net/get/browser/Doodles/yandex/drawable-xxhdpi/yandex.png", "search_url": "https://yandex.ru/{yandex:searchPath}?text={searchTerms}&{yandex:referralID}", "suggest_url": "https://suggest.yandex.ru/suggest-ff.cgi?part={searchTerms}", "image_url": "https://yandex.ru/images/search/?rpt=imageview", @@ -644,6 +647,7 @@ "name": "\u042f\u043d\u0434\u0435\u043a\u0441", "keyword": "yandex.ua", "favicon_url": "https://yastatic.net/lego/_/pDu9OWAQKB0s2J9IojKpiS_Eho.ico", + "logo_url": "https://storage.ape.yandex.net/get/browser/Doodles/yandex/drawable-xxhdpi/yandex.png", "search_url": "https://yandex.ua/{yandex:searchPath}?text={searchTerms}", "suggest_url": "https://suggest.yandex.ua/suggest-ff.cgi?part={searchTerms}", "image_url": "https://yandex.ua/images/search/?rpt=imageview",
diff --git a/components/toolbar/BUILD.gn b/components/toolbar/BUILD.gn index 0f1cc9f0..d10a79f 100644 --- a/components/toolbar/BUILD.gn +++ b/components/toolbar/BUILD.gn
@@ -59,7 +59,7 @@ "//ui/gfx", ] - if (!is_android && !is_ios) { + if (!is_ios) { deps += [ ":vector_icons" ] } }
diff --git a/components/toolbar/toolbar_model_impl.cc b/components/toolbar/toolbar_model_impl.cc index fee722b..3f20e14 100644 --- a/components/toolbar/toolbar_model_impl.cc +++ b/components/toolbar/toolbar_model_impl.cc
@@ -21,7 +21,7 @@ #include "ui/gfx/text_elider.h" #include "ui/gfx/vector_icon_types.h" -#if !defined(OS_ANDROID) && !defined(OS_IOS) +#if !defined(OS_IOS) #include "components/toolbar/vector_icons.h" // nogncheck #include "ui/vector_icons/vector_icons.h" // nogncheck #endif @@ -73,7 +73,7 @@ } const gfx::VectorIcon& ToolbarModelImpl::GetVectorIcon() const { -#if !defined(OS_ANDROID) && !defined(OS_IOS) +#if !defined(OS_IOS) auto* const icon_override = delegate_->GetVectorIconOverride(); if (icon_override) return *icon_override;
diff --git a/content/browser/compositor/surface_utils.cc b/content/browser/compositor/surface_utils.cc index 67347b8..04184659 100644 --- a/content/browser/compositor/surface_utils.cc +++ b/content/browser/compositor/surface_utils.cc
@@ -169,7 +169,7 @@ return CompositorImpl::GetSurfaceManager(); #else ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); - if (!factory) + if (factory == NULL) return nullptr; return factory->GetContextFactoryPrivate()->GetSurfaceManager(); #endif @@ -179,10 +179,7 @@ #if defined(OS_ANDROID) return CompositorImpl::GetHostFrameSinkManager(); #else - ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); - if (!factory) - return nullptr; - return factory->GetContextFactoryPrivate()->GetHostFrameSinkManager(); + return BrowserMainLoop::GetInstance()->host_frame_sink_manager(); #endif }
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.cc b/content/browser/devtools/devtools_url_interceptor_request_job.cc index ef62d008..8db9c692 100644 --- a/content/browser/devtools/devtools_url_interceptor_request_job.cc +++ b/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -9,6 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "content/browser/devtools/protocol/network_handler.h" #include "content/browser/devtools/protocol/page.h" +#include "content/browser/loader/resource_request_info_impl.h" #include "net/base/elements_upload_data_stream.h" #include "net/base/io_buffer.h" #include "net/base/upload_bytes_element_reader.h" @@ -674,6 +675,38 @@ request_->set_method(request_details.method); request_->SetExtraRequestHeaders(request_details.extra_request_headers); + // Mimic the ResourceRequestInfoImpl of the original request. + const ResourceRequestInfoImpl* resource_request_info = + static_cast<const ResourceRequestInfoImpl*>( + ResourceRequestInfo::ForRequest( + devtools_interceptor_request_job->request())); + ResourceRequestInfoImpl* extra_data = new ResourceRequestInfoImpl( + resource_request_info->requester_info(), + resource_request_info->GetRouteID(), + resource_request_info->GetFrameTreeNodeId(), + resource_request_info->GetOriginPID(), + resource_request_info->GetRequestID(), + resource_request_info->GetRenderFrameID(), + resource_request_info->IsMainFrame(), + resource_request_info->ParentIsMainFrame(), + resource_request_info->GetResourceType(), + resource_request_info->GetPageTransition(), + resource_request_info->should_replace_current_entry(), + resource_request_info->IsDownload(), resource_request_info->is_stream(), + resource_request_info->allow_download(), + resource_request_info->HasUserGesture(), + resource_request_info->is_load_timing_enabled(), + resource_request_info->is_upload_progress_enabled(), + resource_request_info->do_not_prompt_for_login(), + resource_request_info->GetReferrerPolicy(), + resource_request_info->GetVisibilityState(), + resource_request_info->GetContext(), + resource_request_info->ShouldReportRawHeaders(), + resource_request_info->IsAsync(), + resource_request_info->GetPreviewsState(), resource_request_info->body(), + resource_request_info->initiated_in_secure_context()); + extra_data->AssociateWithRequest(request_.get()); + if (request_details.post_data) request_->set_upload(std::move(request_details.post_data));
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 0e0e30a2..4d7dc4d 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -18,7 +18,6 @@ #include "cc/surfaces/compositor_frame_sink_support.h" #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_manager.h" -#include "components/viz/host/host_frame_sink_manager.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/browser_plugin/browser_plugin_guest.h" #include "content/browser/compositor/surface_utils.h" @@ -107,8 +106,8 @@ if (frame_connector_) { if (parent_frame_sink_id_.is_valid() && !service_manager::ServiceManagerIsRemote()) { - GetHostFrameSinkManager()->UnregisterFrameSinkHierarchy( - parent_frame_sink_id_, frame_sink_id_); + GetSurfaceManager()->UnregisterFrameSinkHierarchy(parent_frame_sink_id_, + frame_sink_id_); } parent_frame_sink_id_ = cc::FrameSinkId(); local_surface_id_ = cc::LocalSurfaceId(); @@ -125,8 +124,8 @@ parent_frame_sink_id_ = parent_view->GetFrameSinkId(); DCHECK(parent_frame_sink_id_.is_valid()); if (!service_manager::ServiceManagerIsRemote()) { - GetHostFrameSinkManager()->RegisterFrameSinkHierarchy( - parent_frame_sink_id_, frame_sink_id_); + GetSurfaceManager()->RegisterFrameSinkHierarchy(parent_frame_sink_id_, + frame_sink_id_); } } @@ -806,7 +805,7 @@ cc::SurfaceId RenderWidgetHostViewChildFrame::SurfaceIdForTesting() const { return cc::SurfaceId(frame_sink_id_, local_surface_id_); -} +}; void RenderWidgetHostViewChildFrame::CreateCompositorFrameSinkSupport() { if (service_manager::ServiceManagerIsRemote()) @@ -820,8 +819,8 @@ this, GetSurfaceManager(), frame_sink_id_, is_root, handles_frame_sink_id_invalidation, needs_sync_points); if (parent_frame_sink_id_.is_valid()) { - GetHostFrameSinkManager()->RegisterFrameSinkHierarchy(parent_frame_sink_id_, - frame_sink_id_); + GetSurfaceManager()->RegisterFrameSinkHierarchy(parent_frame_sink_id_, + frame_sink_id_); } if (host_->needs_begin_frames()) support_->SetNeedsBeginFrame(true); @@ -831,8 +830,8 @@ if (!support_) return; if (parent_frame_sink_id_.is_valid()) { - GetHostFrameSinkManager()->UnregisterFrameSinkHierarchy( - parent_frame_sink_id_, frame_sink_id_); + GetSurfaceManager()->UnregisterFrameSinkHierarchy(parent_frame_sink_id_, + frame_sink_id_); } support_.reset(); }
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h index 5aabe8bc..525ccb9e 100644 --- a/content/browser/loader/resource_request_info_impl.h +++ b/content/browser/loader/resource_request_info_impl.h
@@ -115,7 +115,9 @@ // request). int frame_tree_node_id() const { return frame_tree_node_id_; } - ResourceRequesterInfo* requester_info() { return requester_info_.get(); } + ResourceRequesterInfo* requester_info() const { + return requester_info_.get(); + } // Updates the data associated with this request after it is is transferred // to a new renderer process. Not all data will change during a transfer.
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc index 6fb5641c..c6ed491 100644 --- a/content/browser/presentation/presentation_service_impl.cc +++ b/content/browser/presentation/presentation_service_impl.cc
@@ -59,8 +59,10 @@ render_process_id_ = render_frame_host->GetProcess()->GetID(); render_frame_id_ = render_frame_host->GetRoutingID(); - DVLOG(2) << "PresentationServiceImpl: " - << render_process_id_ << ", " << render_frame_id_; + is_main_frame_ = !render_frame_host->GetParent(); + + DVLOG(2) << "PresentationServiceImpl: " << render_process_id_ << ", " + << render_frame_id_ << " is main frame: " << is_main_frame_; if (auto* delegate = GetPresentationServiceDelegate()) delegate->AddObserver(render_process_id_, render_frame_id_, this); @@ -114,7 +116,7 @@ // TODO(imcheng): Set ErrorHandler to listen for errors. client_ = std::move(client); - if (receiver_delegate_) { + if (receiver_delegate_ && is_main_frame_) { receiver_delegate_->RegisterReceiverConnectionAvailableCallback( base::Bind(&PresentationServiceImpl::OnReceiverConnectionAvailable, weak_factory_.GetWeakPtr())); @@ -428,8 +430,11 @@ void PresentationServiceImpl::Reset() { DVLOG(2) << "PresentationServiceImpl::Reset"; - if (auto* delegate = GetPresentationServiceDelegate()) - delegate->Reset(render_process_id_, render_frame_id_); + if (controller_delegate_) + controller_delegate_->Reset(render_process_id_, render_frame_id_); + + if (receiver_delegate_ && is_main_frame_) + receiver_delegate_->Reset(render_process_id_, render_frame_id_); default_presentation_urls_.clear();
diff --git a/content/browser/presentation/presentation_service_impl.h b/content/browser/presentation/presentation_service_impl.h index c097ad9..4c6393d 100644 --- a/content/browser/presentation/presentation_service_impl.h +++ b/content/browser/presentation/presentation_service_impl.h
@@ -103,6 +103,8 @@ MaxPendingReconnectPresentationRequests); FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest, ReceiverPresentationServiceDelegate); + FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest, + ReceiverDelegateOnSubFrame); // Maximum number of pending ReconnectPresentation requests at any given time. static const int kMaxQueuedRequests = 10; @@ -278,6 +280,9 @@ int render_process_id_; int render_frame_id_; + // If current frame is top level frame. + bool is_main_frame_; + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<PresentationServiceImpl> weak_factory_;
diff --git a/content/browser/presentation/presentation_service_impl_unittest.cc b/content/browser/presentation/presentation_service_impl_unittest.cc index d582207..beb33bb4 100644 --- a/content/browser/presentation/presentation_service_impl_unittest.cc +++ b/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -644,14 +644,13 @@ } TEST_F(PresentationServiceImplTest, ReceiverPresentationServiceDelegate) { - MockReceiverPresentationServiceDelegate mock_receiver_delegate; - EXPECT_CALL(mock_receiver_delegate, AddObserver(_, _, _)).Times(1); + EXPECT_CALL(mock_receiver_delegate_, AddObserver(_, _, _)).Times(1); PresentationServiceImpl service_impl(main_rfh(), contents(), nullptr, - &mock_receiver_delegate); + &mock_receiver_delegate_); ReceiverConnectionAvailableCallback callback; - EXPECT_CALL(mock_receiver_delegate, + EXPECT_CALL(mock_receiver_delegate_, RegisterReceiverConnectionAvailableCallback(_)) .WillOnce(SaveArg<0>(&callback)); @@ -677,7 +676,32 @@ mojo::MakeRequest(&receiver_connection)); base::RunLoop().RunUntilIdle(); - EXPECT_CALL(mock_receiver_delegate, RemoveObserver(_, _)).Times(1); + EXPECT_CALL(mock_receiver_delegate_, RemoveObserver(_, _)).Times(1); +} + +TEST_F(PresentationServiceImplTest, ReceiverDelegateOnSubFrame) { + EXPECT_CALL(mock_receiver_delegate_, AddObserver(_, _, _)).Times(1); + + PresentationServiceImpl service_impl(main_rfh(), contents(), nullptr, + &mock_receiver_delegate_); + service_impl.is_main_frame_ = false; + + ReceiverConnectionAvailableCallback callback; + EXPECT_CALL(mock_receiver_delegate_, + RegisterReceiverConnectionAvailableCallback(_)) + .Times(0); + + blink::mojom::PresentationServiceClientPtr client_ptr; + client_binding_.reset( + new mojo::Binding<blink::mojom::PresentationServiceClient>( + &mock_client_, mojo::MakeRequest(&client_ptr))); + service_impl.controller_delegate_ = nullptr; + service_impl.SetClient(std::move(client_ptr)); + + EXPECT_CALL(mock_receiver_delegate_, Reset(_, _)).Times(0); + service_impl.Reset(); + + EXPECT_CALL(mock_receiver_delegate_, RemoveObserver(_, _)).Times(1); } } // namespace content
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index ce101b0..e0b8c93 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -890,8 +890,8 @@ void CompositorImpl::AddChildFrameSink(const cc::FrameSinkId& frame_sink_id) { if (has_layer_tree_frame_sink_) { - GetHostFrameSinkManager()->RegisterFrameSinkHierarchy(frame_sink_id_, - frame_sink_id); + GetSurfaceManager()->RegisterFrameSinkHierarchy(frame_sink_id_, + frame_sink_id); } else { pending_child_frame_sink_ids_.insert(frame_sink_id); } @@ -904,8 +904,8 @@ pending_child_frame_sink_ids_.erase(it); return; } - GetHostFrameSinkManager()->UnregisterFrameSinkHierarchy(frame_sink_id_, - frame_sink_id); + GetSurfaceManager()->UnregisterFrameSinkHierarchy(frame_sink_id_, + frame_sink_id); } bool CompositorImpl::HavePendingReadbacks() {
diff --git a/content/renderer/media_recorder/video_track_recorder.cc b/content/renderer/media_recorder/video_track_recorder.cc index 6c7a21f4..d128bd7c 100644 --- a/content/renderer/media_recorder/video_track_recorder.cc +++ b/content/renderer/media_recorder/video_track_recorder.cc
@@ -75,6 +75,14 @@ static_cast<int>(CodecId::LAST), "|kPreferredCodecIdAndVEAProfiles| should consider all CodecIds"); +// The maximum number of frames that we keep the reference alive for encode. +// This guarantees that there is limit on the number of frames in a FIFO queue +// that are being encoded and frames coming after this limit is reached are +// dropped. +// TODO(emircan): Make this a LIFO queue that has different sizes for each +// encoder implementation. +const int kMaxNumberOfFramesInEncode = 10; + // Class to encapsulate the enumeration of CodecIds/VideoCodecProfiles supported // by the VEA underlying platform. Provides methods to query the preferred // CodecId and to check if a given CodecId is supported. @@ -168,7 +176,8 @@ encoding_task_runner_(encoding_task_runner), paused_(false), on_encoded_video_callback_(on_encoded_video_callback), - bits_per_second_(bits_per_second) { + bits_per_second_(bits_per_second), + num_frames_in_encode_(0) { DCHECK(!on_encoded_video_callback_.is_null()); if (encoding_task_runner_) return; @@ -200,6 +209,11 @@ return; } + if (num_frames_in_encode_ > kMaxNumberOfFramesInEncode) { + DLOG(WARNING) << "Too many frames are queued up. Dropping this one."; + return; + } + if (video_frame->HasTextures()) { main_task_runner_->PostTask( FROM_HERE, base::Bind(&Encoder::RetrieveFrameOnMainThread, this, @@ -207,14 +221,23 @@ return; } - scoped_refptr<media::VideoFrame> frame = video_frame; + scoped_refptr<media::VideoFrame> wrapped_frame; // Drop alpha channel if the encoder does not support it yet. - if (!CanEncodeAlphaChannel() && frame->format() == media::PIXEL_FORMAT_YV12A) - frame = media::WrapAsI420VideoFrame(video_frame); + if (!CanEncodeAlphaChannel() && + video_frame->format() == media::PIXEL_FORMAT_YV12A) { + wrapped_frame = media::WrapAsI420VideoFrame(video_frame); + } else { + wrapped_frame = media::VideoFrame::WrapVideoFrame( + video_frame, video_frame->format(), video_frame->visible_rect(), + video_frame->natural_size()); + } + wrapped_frame->AddDestructionObserver(media::BindToCurrentLoop(base::Bind( + &VideoTrackRecorder::Encoder::FrameReleased, this, video_frame))); + ++num_frames_in_encode_; encoding_task_runner_->PostTask( - FROM_HERE, base::Bind(&Encoder::EncodeOnEncodingTaskRunner, this, frame, - capture_timestamp)); + FROM_HERE, base::Bind(&Encoder::EncodeOnEncodingTaskRunner, this, + wrapped_frame, capture_timestamp)); } void VideoTrackRecorder::Encoder::RetrieveFrameOnMainThread( @@ -330,6 +353,12 @@ return false; } +void VideoTrackRecorder::Encoder::FrameReleased( + const scoped_refptr<VideoFrame>& frame) { + DCHECK(origin_task_runner_->BelongsToCurrentThread()); + --num_frames_in_encode_; +} + // static VideoTrackRecorder::CodecId VideoTrackRecorder::GetPreferredCodecId() { return GetCodecEnumerator()->GetPreferredCodecId();
diff --git a/content/renderer/media_recorder/video_track_recorder.h b/content/renderer/media_recorder/video_track_recorder.h index 282c6df7..9efa4e61 100644 --- a/content/renderer/media_recorder/video_track_recorder.h +++ b/content/renderer/media_recorder/video_track_recorder.h
@@ -116,12 +116,17 @@ protected: friend class base::RefCountedThreadSafe<Encoder>; + friend class VideoTrackRecorderTest; + virtual ~Encoder(); virtual void EncodeOnEncodingTaskRunner( scoped_refptr<media::VideoFrame> frame, base::TimeTicks capture_timestamp) = 0; + // Called when the frame reference is released after encode. + void FrameReleased(const scoped_refptr<media::VideoFrame>& frame); + // Used to shutdown properly on the same thread we were created. const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; @@ -144,6 +149,9 @@ // Target bitrate for video encoding. If 0, a standard bitrate is used. const int32_t bits_per_second_; + // Number of frames that we keep the reference alive for encode. + uint32_t num_frames_in_encode_; + // Used to retrieve incoming opaque VideoFrames (i.e. VideoFrames backed by // textures). Created on-demand on |main_task_runner_|. std::unique_ptr<media::SkCanvasVideoRenderer> video_renderer_;
diff --git a/content/renderer/media_recorder/video_track_recorder_unittest.cc b/content/renderer/media_recorder/video_track_recorder_unittest.cc index ee70c84..287127c 100644 --- a/content/renderer/media_recorder/video_track_recorder_unittest.cc +++ b/content/renderer/media_recorder/video_track_recorder_unittest.cc
@@ -129,6 +129,10 @@ return video_track_recorder_->encoder_.get() != nullptr; } + uint32_t NumFramesInEncode() { + return video_track_recorder_->encoder_->num_frames_in_encode_; + } + // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks // and Sources below into believing they are on the right threads. const base::MessageLoopForUI message_loop_; @@ -325,6 +329,26 @@ Mock::VerifyAndClearExpectations(this); } +// Inserts a frame for encode and makes sure that it is released properly and +// NumFramesInEncode() is updated. +TEST_F(VideoTrackRecorderTest, ReleasesFrame) { + InitializeRecorder(VideoTrackRecorder::CodecId::VP8); + + const gfx::Size& frame_size = kTrackRecorderTestSize[0]; + scoped_refptr<VideoFrame> video_frame = + VideoFrame::CreateBlackFrame(frame_size); + + base::RunLoop run_loop; + video_frame->AddDestructionObserver(run_loop.QuitClosure()); + EXPECT_CALL(*this, DoOnEncodedVideo(_, _, _, _, true)).Times(1); + Encode(video_frame, base::TimeTicks::Now()); + video_frame = nullptr; + run_loop.Run(); + EXPECT_EQ(0u, NumFramesInEncode()); + + Mock::VerifyAndClearExpectations(this); +} + INSTANTIATE_TEST_CASE_P(, VideoTrackRecorderTest, ::testing::Combine(ValuesIn(kTrackRecorderTestCodec),
diff --git a/content/renderer/media_recorder/vpx_encoder.cc b/content/renderer/media_recorder/vpx_encoder.cc index 65cb740..7c9484e 100644 --- a/content/renderer/media_recorder/vpx_encoder.cc +++ b/content/renderer/media_recorder/vpx_encoder.cc
@@ -70,7 +70,7 @@ DCHECK(encoding_task_runner_->BelongsToCurrentThread()); const gfx::Size frame_size = frame->visible_rect().size(); - const base::TimeDelta duration = EstimateFrameDuration(frame); + base::TimeDelta duration = EstimateFrameDuration(frame); const media::WebmMuxer::VideoParameters video_params(frame); if (!IsInitialized(codec_config_) || @@ -79,6 +79,8 @@ } const bool frame_has_alpha = frame->format() == media::PIXEL_FORMAT_YV12A; + // Split the duration between two encoder instances if alpha is encoded. + duration = frame_has_alpha ? duration / 2 : duration; if (frame_has_alpha && (!IsInitialized(alpha_codec_config_) || gfx::Size(alpha_codec_config_.g_w, alpha_codec_config_.g_h) != frame_size)) {
diff --git a/docs/speed/perf_bot_sheriffing.md b/docs/speed/perf_bot_sheriffing.md index ab28765..f5b3573 100644 --- a/docs/speed/perf_bot_sheriffing.md +++ b/docs/speed/perf_bot_sheriffing.md
@@ -11,6 +11,9 @@ * [Handle Test Failures](#Handle-Test-Failures) * [Follow up on failures](#Follow-up-on-failures) +## Table of Contents +[TOC] + ## Understanding the Waterfall State **[Sheriff-O-Matic](https://sheriff-o-matic.appspot.com/chromium.perf)** is (as of @@ -62,16 +65,72 @@ **[perf-sheriffs@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/perf-sheriffs)** postings for important announcements about bot turndowns and other known issues. +## Swarming +As of Q2 2017 all desktop and android bots have been moved to the swarming. +There is now one machine on the chromium.perf waterfall for each desktop +configuration that is triggering test tasks on 5 corresponding swarming bots. +All of our swarming bots exist in the [chrome-perf swarming pool](https://chromium-swarm.appspot.com/botlist?c=id&c=os&c=task&c=status&f=pool%3AChrome-perf&l=100&s=id%3Aasc) + +Some things have probably changed about sheriffing since we migrated from +buildbot. Here's a partial list: +1. Buildbot status pages + * Every test that is run now has 2-3 recipe steps on the buildbot status + page associated with it + 1. '[trigger] <test_name>' step (you can mostly ignore this) + 2. '<test_name>' This is the test that was run on the swarming bot, + 'shard #0' link on the step takes you to the swarming task page + 3. '<test_name> Dashboard Upload' This is the upload of the perf tests + results to the perf dashboard. This will not be present if the test + was disabled. + * We now run most benchmark tests even if they are disabled, but disabled + tests will always return success and you can ignore them. You can + identify these by the 'DISABLED_BENCHMARK' link under the step and the + fact that they don’t have an upload step after them. + * Some tests aren't run, if it's possible for us to tell that it would + just be disabled. Right now, we don't trigger "mobile" benchmarks for + desktop bots. +2. Debugging Expiring Jobs on the waterfall + * You can tell a job is expiring in one of two ways: + 1. Click on the 'shard #0' link of the failed test and you will see + EXPIRED on the swarming task page + 2. If there is a 'no_results_exc' and an 'invalid_results_exc' link on + the buildbot failing test step with the dashboard upload step + failing (Note: this could be an EXPIRED job or a TIMEOUT. An + Expired job means the task never got scheduled within the 5 hour + swarming timeout and TIMEOUT means it started running but couldn’t + finish before the 5 hour swarming timeout) + * You can quickly see what bots the jobs are expiring/timing out on with + the ‘Bot id’ annotation on the failing test step + * Troubleshooting why they are expiring + 1. Bot might be down, check the chrome-perf pool for that bot-id and + file a ticket with go/bugatrooper if the bot is down. [Example bot + page](https://chromium-swarm.appspot.com/bot?id=build73-b1--device1&sort_stats=total%3Adesc) + * Can also identify a down bot through [viceroy](https://viceroy.corp.google.com/chrome_infra/Machines/per_machine) + Search for a bot id and if the graph stops it tells you the bot + is down + 2. Otherwise check the bots swarming page task list for each bot that + has failing jobs and examine what might be going on (good [video](https://youtu.be/gRa0LvICthk) + from maruel@ on the swarming ui and how to filter and search bot + task lists. For example you can filter on bot-id and name to + examine the last n runs of a test). + * A test might be timing out on a bot that is causing subsequent + tests to expire even though they would pass normally but never + get scheduled due to that timing out test. Debug the timing out + test. + * A test might be taking a longer time than normal but still + passing, but the extra execution time causes other unrelated + tests to fail. Examine the last passing run to the first + failing run and see if you can see a test that is taking a + significantly longer time and debug that issue. If you need help + with this, martiniss@ can get some useful data. + + ## Handle Device and Bot Failures ### Offline Buildslaves -Some build configurations, in particular the perf builders and trybots, have -multiple machines attached. If one or more of the machines go down, there are -still other machines running, so the console or waterfall view will still show -green, but those configs will run at reduced throughput. At least once during -your shift, you should check the lists of buildslaves and ensure they're all -running. +At least once during your shift, you should check the lists of buildslaves and +ensure they're all running. * [chromium.perf buildslaves](https://build.chromium.org/p/chromium.perf/buildslaves) * [tryserver.chromium.perf buildslaves](https://build.chromium.org/p/tryserver.chromium.perf/buildslaves) @@ -107,26 +166,19 @@ ### Android Device failures -There are three types of device failures: +Android device failures will mainly manifest by turning a bunch of steps on a +builder purple. Failures of this type are expected to be purple. This will +manifest itself as a string of tests failing, all with the same device id. +Sheriff-o-matic will try to do this grouping for you, and it will make an entry +in sheriff-o-matic with a title like `bot affinity build123-b1 is broken on +chromium.perf/Linux Perf, affecting 10 tests`. -1. A device is blacklisted in the `device_status` step. Device failures of this - type are expected to be purple. You can look at the buildbot status page to - see how many devices were listed as online during this step. You should - always see 7 devices online. If you see fewer than 7 devices online, there - is a problem in the lab. -2. A device is passing `device_status` but still in poor health. The - symptom of this is that all the tests are failing on it. You can see that on - the buildbot status page by looking at the `Device Affinity`. If all tests - with the same device affinity number are failing, it's probably a device - failure. -3. A device has completely disappeared from `device_status` step. You should - always see 7 total devices on a bot in one of three statuses: online, - misisng, or blacklisted. If you see fewer than 7 devices it means there is - a problem with the known devices persistent file and the device is - unreachable via adb. This usually means the known devices file was cleared - while a device was unreachable. A bug should be filed saying that there is a - missing device. Going through previous logs will usually yield a device ID - for the missing device. +These issues are usually automatically handled by the labs team. +If you are a Googler, you can see a list of tickets [here](https://gutsv3.corp.google.com/#adhoc/core.requester%3A%22chrome-infra-prod-borg%22%20AND%20Android%20Devices/0) +which have been auto-filed by Chrome Infra. These are filed twice a day, and +usually get attention from people in the lab, who can fix these bugs quickly. +Check this list to see if a device is on there. If it isn't, then follow the +instructions below to file a ticket with the labs team. For these types of failures, please file a bug with [this template](https://bugs.chromium.org/p/chromium/issues/entry?components=Infra%3ELabs&labels=Pri-1,Performance-Sheriff-BotHealth,OS-Android&comment=Link+to+buildbot+status+page:&summary=Device+offline+on+chromium.perf) @@ -140,7 +192,6 @@ priority issues, like a build breakage. Please add a comment explaining what you want the trooper to do. - Here are the common components you should also use: * **Infra>Labs** adds the bug to the labs queue. If there is a hardware @@ -278,124 +329,6 @@ Click link under _"stack tool with logcat dump"_ to see symbolized Android crashes. -## Swarming Bots -As of Q4 2016 all desktop bots have been moved to the swarming pool with a goal -of moving all android bots to swarming in early 2017. There is now one machine -on the chromium.perf waterfall for each desktop configuration that is triggering -test tasks on 5 corresponding swarming bots. All of our swarming bots exists in -the [chrome-perf swarming pool](https://chromium-swarm.appspot.com/botlist?c=id&c=os&c=task&c=status&f=pool%3AChrome-perf&l=100&s=id%3Aasc) - -1. Buildbot status page FYIs - * Every test that is run now has 2-3 recipe steps on the buildbot status - page associated with it - 1. '[trigger] <test_name>' step (you can mostly ignore this) - 2. '<test_name>' This is the test that was run on the swarming bot, - 'shard #0' link on the step takes you to the swarming task page - 3. '<test_name> Dashboard Upload' This is the upload of the perf tests - results to the perf dashboard. This will not be present if the test - was disabled. - * We now run all benchmark tests even if they are disabled, but disabled - tests will always return success and you can ignore them. You can - identify these by the 'DISABLED_BENCHMARK' link under the step and the - fact that they don’t have an upload step after them -2. Debugging Expiring Jobs on the waterfall - * You can tell a job is expiring in one of two ways: - 1. Click on the 'shard #0' link of the failed test and you will see - EXPIRED on the swarming task page - 2. If there is a 'no_results_exc' and an 'invalid_results_exc' link on - the buildbot failing test step with the dashboard upload step - failing (Note: this could be an EXPIRED job or a TIMEOUT. An - Expired job means the task never got scheduled within the 5 hour - swarming timeout and TIMEOUT means it started running but couldn’t - finish before the 5 hour swarming timeout) - * You can quickly see what bots the jobs are expiring/timing out on with - the ‘Bot id’ annotation on the failing test step - * Troubleshooting why they are expiring - 1. Bot might be down, check the chrome-perf pool for that bot-id and - file a ticket with go/bugatrooper if the bot is down. - * Can also identify a down bot through [viceroy](https://viceroy.corp.google.com/chrome_infra/Machines/per_machine) - Search for a bot id and if the graph stops it tells you the bot - is down - 2. Otherwise check the bots swarming page task list for each bot that - has failing jobs and examine what might be going on (good [video](https://youtu.be/gRa0LvICthk) - from maruel@ on the swarming ui and how to filter and search bot - task lists. For example you can filter on bot-id and name to - examine the last n runs of a test). - * A test might be timing out on a bot that is causing subsequent - tests to expire even though they would pass normally but never - get scheduled due to that timing out test. Debug the timing out - test. - * A test might be taking a longer time than normal but still - passing, but the extra execution time causes other unrelated - tests to fail. Examine the last passing run to the first - failing run and see if you can see a test that is taking a - significantly longer time and debug that issue. -3. Reproducing swarming task runs - * Reproduce on local machine using same inputs as bot - 1. Note that the local machines spec must roughly match that of the - swarming bot - 2. See 'Reproducing the task locally' on swarming task page - 3. First run the command under - 'Download input files into directory foo' - 4. cd into foo/out/Release if those downloaded inputs - 5. Execute test from this directory. Command you are looking for - should be at the top of the logs, you just need to update the - `--isolated-script-test-output=/b/s/w/ioFB73Qz/output.json` and - `--isolated-script-test-chartjson-output=/b/s/w/ioFB73Qz/chartjson-output.json` - flags to be a local path - 6. Example with tmp as locally created dir: - `/usr/bin/python ../../testing/scripts/run_telemetry_benchmark_as_googletest.py ../../tools/perf/run_benchmark speedometer -v --upload-results --output-format=chartjson --browser=release --isolated-script-test-output=tmp/output.json --isolated-script-test-chartjson-output=tmp/chartjson-output.json` - * ssh into swarming bot and run test on that machine - 1. NOTE: this should be a last resort since it will cause a fifth of - the benchmarks to continuously fail on the waterfall - 2 First you need to decommission the swarming bot so other jobs don’t - interfere, file a ticket with go/bugatrooper - 3. See [remote access to bots](https://sites.google.com/a/google.com/chrome-infrastructure/golo/remote-access?pli=1) - on how to ssh into the bot and then run the test. - Rough overview for build161-m1 - * prodaccess --chromegolo_ssh - * Ssh build161-m1.golo - * Password is in valentine - "Chrome Golo, Perf, GPU bots - chrome-bot" - * File a bug to reboot the machine to get it online in the - swarming pool again -4. Running local changes on swarming bot - * Using sunspider as example benchmark since it is a quick one - * First, run test locally to make sure there is no issue with the binary - or the script running the test on the swarming bot. Make sure dir foo - exists: - `python testing/scripts/run_telemetry_benchmark_as_googletest.py tools/perf/run_benchmark sunspider -v --output-format=chartjson --upload-results --browser=reference --output-trace-tag=_ref --isolated-script-test-output=foo/output.json --isolated-script-test-chartjson-output=foo/chart-output.json` - * Build any dependencies needed in isolate: - 1. ninja -C out/Release chrome/test:telemetry_perf_tests - 2. This target should be enough if you are running a benchmark, - otherwise build any targets that they say are missing when building - the isolate in step #2. - 3. Make sure [compiler proxy is running](https://sites.google.com/a/google.com/goma/how-to-use-goma/how-to-use-goma-for-chrome-team?pli=1) - * ./goma_ctl.py ensure_start from goma directory - * Build the isolate - 1. `python tools/mb/mb.py isolate //out/Release -m chromium.perf -b "Linux Builder" telemetry_perf_tests` - * -m is the master - * -b is the builder name from mb_config.pyl that corresponds to - the platform you are running this command on - * telemetry_perf_tests is the isolate name - * Might run into internal source deps when building the isolate, - depending on the isolate. Might need to update the entry in - mb_config.pyl for this builder to not be an official built so - src/internal isn’t required - * Archive and create the isolate hash - 1. `python tools/swarming_client/isolate.py archive -I isolateserver.appspot.com -i out/Release/telemetry_perf_tests.isolate -s out/Release/telemetry_perf_tests.isolated` - * Run the test with the has from step #3 - 1. Run hash locally - * Note output paths are local - * `./tools/swarming_client/run_isolated.py -I https://isolateserver.appspot.com -s <insert_hash_here> -- sunspider -v --upload-results --output-format=chartjson --browser=reference --output-trace-tag=_ref --isolated-script-test-output=/usr/local/google/home/eyaich/projects/chromium/src/tmp/output.json` - 2. Trigger on swarming bot - * Note paths are using swarming output dir environment variable - ISOLATED_OUTDIR and dimensions are based on the bot and os you - are triggering the job on - * `python tools/swarming_client/swarming.py trigger -v --isolate-server isolateserver.appspot.com -S chromium-swarm.appspot.com -d id build150-m1 -d pool Chrome-perf -d os Linux -s <insert_hash_here> -- sunspider -v --upload-results --output-format=chartjson --browser=reference --output-trace-tag=_ref -isolated-script-test-output='${ISOLATED_OUTDIR}/output.json' --isolated-script-test-chartjson-output='${ISOLATED_OUTDIR}/chart-output.json'` - * All args after the '--' are for the swarming task and not for - the trigger command. The output dirs must be in quotes when - triggering on swarming bot ### Disabling Telemetry Tests @@ -479,6 +412,77 @@ any highlights or lowlights from your sheriffing shift as well as any other feedback you may have that could improve future sheriffing shifts. + +## Miscellaneous + +### Reproducing swarming task runs +* Reproduce on local machine using same inputs as bot + 1. Note that the local machines spec must roughly match that of the + swarming bot + 2. See 'Reproducing the task locally' on swarming task page + 3. First run the command under + 'Download input files into directory foo' + 4. cd into foo/out/Release of those downloaded inputs + 5. Execute test from this directory. Command you are looking for + should be at the top of the logs, you just need to update the + `--isolated-script-test-output=/b/s/w/ioFB73Qz/output.json` and + `--isolated-script-test-chartjson-output=/b/s/w/ioFB73Qz/chartjson-output.json` + flags to be a local path + 6. Example with tmp as locally created dir: + `/usr/bin/python ../../testing/scripts/run_telemetry_benchmark_as_googletest.py ../../tools/perf/run_benchmark speedometer -v --upload-results --output-format=chartjson --browser=release --isolated-script-test-output=tmp/output.json --isolated-script-test-chartjson-output=tmp/chartjson-output.json` +* ssh into swarming bot and run test on that machine + 1. NOTE: this should be a last resort since it will cause a fifth of + the benchmarks to continuously fail on the waterfall. Notify to + nednguyen@ or sullivan@ if you are going to do this. + 2 First you need to decommission the swarming bot so other jobs don’t + interfere, file a ticket with go/bugatrooper + 3. See [remote access to bots](https://sites.google.com/a/google.com/chrome-infrastructure/golo/remote-access?pli=1) + on how to ssh into the bot and then run the test. + Rough overview for build161-m1 + * prodaccess --chromegolo_ssh + * Ssh build161-m1.golo + * Password is in valentine + "Chrome Golo, Perf, GPU bots - chrome-bot" + * File a bug to reboot the machine to get it online in the + swarming pool again +* Running local changes on swarming bot + * Using sunspider as example benchmark since it is a quick one + * First, run test locally to make sure there is no issue with the binary + or the script running the test on the swarming bot. Make sure dir foo + exists: + `python testing/scripts/run_telemetry_benchmark_as_googletest.py tools/perf/run_benchmark sunspider -v --output-format=chartjson --upload-results --browser=reference --output-trace-tag=_ref --isolated-script-test-output=foo/output.json --isolated-script-test-chartjson-output=foo/chart-output.json` + * Build any dependencies needed in isolate: + 1. ninja -C out/Release chrome/test:telemetry_perf_tests + 2. This target should be enough if you are running a benchmark, + otherwise build any targets that they say are missing when building + the isolate in step #2. + 3. Make sure [compiler proxy is running](https://sites.google.com/a/google.com/goma/how-to-use-goma/how-to-use-goma-for-chrome-team?pli=1) + * ./goma_ctl.py ensure_start from goma directory + * Build the isolate + 1. `python tools/mb/mb.py isolate //out/Release -m chromium.perf -b "Linux Builder" telemetry_perf_tests` + * -m is the master + * -b is the builder name from mb_config.pyl that corresponds to + the platform you are running this command on + * telemetry_perf_tests is the isolate name + * Might run into internal source deps when building the isolate, + depending on the isolate. Might need to update the entry in + mb_config.pyl for this builder to not be an official built so + src/internal isn’t required + * Archive and create the isolate hash + 1. `python tools/swarming_client/isolate.py archive -I isolateserver.appspot.com -i out/Release/telemetry_perf_tests.isolate -s out/Release/telemetry_perf_tests.isolated` + * Run the test with the has from step #3 + 1. Run hash locally + * Note output paths are local + * `./tools/swarming_client/run_isolated.py -I https://isolateserver.appspot.com -s <insert_hash_here> -- sunspider -v --upload-results --output-format=chartjson --browser=reference --output-trace-tag=_ref --isolated-script-test-output=/usr/local/google/home/eyaich/projects/chromium/src/tmp/output.json` + 2. Trigger on swarming bot + * Note paths are using swarming output dir environment variable + ISOLATED_OUTDIR and dimensions are based on the bot and os you + are triggering the job on + * `python tools/swarming_client/swarming.py trigger -v --isolate-server isolateserver.appspot.com -S chromium-swarm.appspot.com -d id build150-m1 -d pool Chrome-perf -d os Linux -s <insert_hash_here> -- sunspider -v --upload-results --output-format=chartjson --browser=reference --output-trace-tag=_ref -isolated-script-test-output='${ISOLATED_OUTDIR}/output.json' --isolated-script-test-chartjson-output='${ISOLATED_OUTDIR}/chart-output.json'` + * All args after the '--' are for the swarming task and not for + the trigger command. The output dirs must be in quotes when + triggering on swarming bot + <!-- Unresolved issues: 1. Do perf sheriffs watch the bisect waterfall? 2. Do perf sheriffs watch the internal clank waterfall?
diff --git a/extensions/renderer/resources/binding.js b/extensions/renderer/resources/binding.js index d25353b5..d0b7e61b 100644 --- a/extensions/renderer/resources/binding.js +++ b/extensions/renderer/resources/binding.js
@@ -70,36 +70,6 @@ }); }; -APIFunctions.prototype.setHandleRequestWithPromise = - function(apiName, customizedFunction) { - var prefix = this.namespace; - return this.setHook_(apiName, 'handleRequest', function() { - var name = prefix + '.' + apiName; - logActivity.LogAPICall(extensionId, name, $Array.slice(arguments)); - var stack = exceptionHandler.getExtensionStackTrace(); - var callback = arguments[arguments.length - 1]; - var args = $Array.slice(arguments, 0, arguments.length - 1); - var keepAlivePromise = requireAsync('keep_alive').then(function(module) { - return module.createKeepAlive(); - }); - $Function.apply(customizedFunction, this, args).then(function(result) { - if (callback) { - exceptionHandler.safeCallbackApply(name, {'stack': stack}, callback, - [result]); - } - }).catch(function(error) { - if (callback) { - var message = exceptionHandler.safeErrorToString(error, true); - lastError.run(name, message, stack, callback); - } - }).then(function() { - keepAlivePromise.then(function(keepAlive) { - keepAlive.close(); - }); - }); - }); -}; - APIFunctions.prototype.setUpdateArgumentsPostValidate = function(apiName, customizedFunction) { return this.setHook_(
diff --git a/extensions/renderer/resources/mime_handler_private_custom_bindings.js b/extensions/renderer/resources/mime_handler_private_custom_bindings.js index 1fa03663..bb04683e 100644 --- a/extensions/renderer/resources/mime_handler_private_custom_bindings.js +++ b/extensions/renderer/resources/mime_handler_private_custom_bindings.js
@@ -6,7 +6,9 @@ * Custom bindings for the mime handler API. */ -var binding = require('binding').Binding.create('mimeHandlerPrivate'); +var binding = + apiBridge || require('binding').Binding.create('mimeHandlerPrivate'); +var utils = require('utils'); var NO_STREAM_ERROR = 'Streams are only available from a mime handler view guest.'; @@ -57,17 +59,22 @@ binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; - apiFunctions.setHandleRequestWithPromise('getStreamInfo', function() { + utils.handleRequestWithPromiseDoNotUse( + apiFunctions, 'mimeHandlerPrivate', 'getStreamInfo', + function() { if (!streamInfoPromise) streamInfoPromise = createStreamInfoPromise(); return streamInfoPromise.then(constructStreamInfoDict); }); - apiFunctions.setHandleRequestWithPromise('abortStream', function() { + utils.handleRequestWithPromiseDoNotUse( + apiFunctions, 'mimeHandlerPrivate', 'abortStream', + function() { return servicePromise.then(function(service) { return service.abortStream().then(function() {}); }).catch(throwNoStreamError); }); }); -exports.$set('binding', binding.generate()); +if (!apiBridge) + exports.$set('binding', binding.generate());
diff --git a/extensions/renderer/resources/utils.js b/extensions/renderer/resources/utils.js index 3b5a68d6..0ec387b 100644 --- a/extensions/renderer/resources/utils.js +++ b/extensions/renderer/resources/utils.js
@@ -4,6 +4,22 @@ var nativeDeepCopy = requireNative('utils').deepCopy; var DCHECK = requireNative('logging').DCHECK; +var WARNING = requireNative('logging').WARNING; +var logActivity = requireNative('activityLogger'); +var exceptionHandler = require('uncaught_exception_handler'); + +var runCallbackWithLastError; +if (bindingUtil) { + runCallbackWithLastError = function(name, message, stack, callback, args) { + bindingUtil.runCallbackWithLastError(message, function() { + $Function.apply(callback, null, args); + }); + } +} else { + var lastError = require('lastError'); + if (lastError) // lastError can be undefined in unittests. + runCallbackWithLastError = lastError.run; +} /** * An object forEach. Calls |f| with each (key, value) pair of |obj|, using @@ -206,9 +222,43 @@ }); } +// DO NOT USE. This causes problems with safe builtins, and makes migration to +// native bindings more difficult. +function handleRequestWithPromiseDoNotUse( + binding, apiName, methodName, customizedFunction) { + var fullName = apiName + '.' + methodName; + var extensionId = requireNative('process').GetExtensionId(); + binding.setHandleRequest(methodName, function() { + logActivity.LogAPICall(extensionId, fullName, $Array.slice(arguments)); + var stack = exceptionHandler.getExtensionStackTrace(); + var callback = arguments[arguments.length - 1]; + var args = $Array.slice(arguments, 0, arguments.length - 1); + var keepAlivePromise = requireAsync('keep_alive').then(function(module) { + return module.createKeepAlive(); + }); + $Function.apply(customizedFunction, this, args).then(function(result) { + if (callback) { + exceptionHandler.safeCallbackApply( + fullName, {__proto__: null, stack: stack}, callback, [result]); + } + }).catch(function(error) { + if (callback) { + var message = exceptionHandler.safeErrorToString(error, true); + runCallbackWithLastError(fullName, message, stack, callback); + } + }).then(function() { + keepAlivePromise.then(function(keepAlive) { + keepAlive.close(); + }); + }); + }); +}; + exports.$set('forEach', forEach); exports.$set('lookup', lookup); exports.$set('defineProperty', defineProperty); exports.$set('expose', expose); exports.$set('deepCopy', deepCopy); exports.$set('promise', promise); +exports.$set('handleRequestWithPromiseDoNotUse', + handleRequestWithPromiseDoNotUse);
diff --git a/extensions/test/data/keep_alive_client_unittest.js b/extensions/test/data/keep_alive_client_unittest.js index 7b88fb0..97ddba54 100644 --- a/extensions/test/data/keep_alive_client_unittest.js +++ b/extensions/test/data/keep_alive_client_unittest.js
@@ -18,8 +18,8 @@ // simple signature. var binding = require('binding').Binding.create('serial'); binding.registerCustomHook(function(bindingsAPI) { - bindingsAPI.apiFunctions.setHandleRequestWithPromise('getDevices', - function() { + utils.handleRequestWithPromiseDoNotUse(bindingsAPI.apiFunctions, + 'serial', 'getDevices', function() { if (shouldSucceed) return Promise.resolve([]); else
diff --git a/headless/lib/frame_id_browsertest.cc b/headless/lib/frame_id_browsertest.cc index a5651a28..6a383333 100644 --- a/headless/lib/frame_id_browsertest.cc +++ b/headless/lib/frame_id_browsertest.cc
@@ -103,7 +103,7 @@ const Request* request = pending_request->GetRequest(); std::string url = request->GetURLRequest()->url().spec(); int frame_tree_node_id = request->GetFrameTreeNodeId(); - DCHECK_NE(frame_tree_node_id, -1); + DCHECK_NE(frame_tree_node_id, -1) << " For url " << url; protocol_handler_->url_to_frame_tree_node_id_[url] = frame_tree_node_id; pending_request->AllowRequest(); } @@ -190,15 +190,25 @@ } // namespace class FrameIdTest : public HeadlessAsyncDevTooledBrowserTest, - public network::Observer, + public network::ExperimentalObserver, public page::Observer { public: void RunDevTooledTest() override { http_handler_->SetHeadlessBrowserContext(browser_context_); EXPECT_TRUE(embedded_test_server()->Start()); - devtools_client_->GetNetwork()->AddObserver(this); + devtools_client_->GetNetwork()->GetExperimental()->AddObserver(this); devtools_client_->GetNetwork()->Enable(); + + if (EnableInterception()) { + devtools_client_->GetNetwork() + ->GetExperimental() + ->EnableRequestInterception( + network::EnableRequestInterceptionParams::Builder() + .SetEnabled(true) + .Build()); + } + devtools_client_->GetPage()->AddObserver(this); base::RunLoop run_loop; @@ -253,6 +263,8 @@ FinishAsynchronousTest(); } + virtual bool EnableInterception() const { return false; } + private: std::map<std::string, std::string> url_to_frame_id_; TestProtocolHandler* http_handler_; // NOT OWNED @@ -260,4 +272,23 @@ HEADLESS_ASYNC_DEVTOOLED_TEST_F(FrameIdTest); +// Frame IDs should still be available with network request interception enabled +class FrameIdWithDevtoolsRequestInterceptionTest : public FrameIdTest { + public: + void OnRequestIntercepted( + const network::RequestInterceptedParams& params) override { + // Allow the request to continue. + devtools_client_->GetNetwork() + ->GetExperimental() + ->ContinueInterceptedRequest( + network::ContinueInterceptedRequestParams::Builder() + .SetInterceptionId(params.GetInterceptionId()) + .Build()); + } + + bool EnableInterception() const override { return true; } +}; + +HEADLESS_ASYNC_DEVTOOLED_TEST_F(FrameIdWithDevtoolsRequestInterceptionTest); + } // namespace headless
diff --git a/ios/build/tools/convert_gn_xcodeproj.py b/ios/build/tools/convert_gn_xcodeproj.py index 0e1af63..50161b1 100755 --- a/ios/build/tools/convert_gn_xcodeproj.py +++ b/ios/build/tools/convert_gn_xcodeproj.py
@@ -129,7 +129,7 @@ build_config_template = project.objects[value['buildConfigurations'][0]] build_config_template['buildSettings']['CONFIGURATION_BUILD_DIR'] = \ - '../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)' + '$(PROJECT_DIR)/../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)' value['buildConfigurations'] = [] for configuration in configurations:
diff --git a/ios/chrome/browser/content_suggestions/BUILD.gn b/ios/chrome/browser/content_suggestions/BUILD.gn index 7aebf2d1..06a438a 100644 --- a/ios/chrome/browser/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/content_suggestions/BUILD.gn
@@ -5,9 +5,6 @@ source_set("content_suggestions") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "content_suggestions_alert_commands.h", - "content_suggestions_alert_factory.h", - "content_suggestions_alert_factory.mm", "content_suggestions_category_wrapper.h", "content_suggestions_category_wrapper.mm", "content_suggestions_coordinator.h", @@ -76,27 +73,3 @@ ] configs += [ "//build/config/compiler:enable_arc" ] } - -source_set("eg_tests") { - configs += [ "//build/config/compiler:enable_arc" ] - testonly = true - sources = [ - "content_suggestions_alert_egtest.mm", - ] - deps = [ - ":content_suggestions", - "//base", - "//base/test:test_support", - "//ios/chrome/app/strings", - "//ios/chrome/browser/ui/alert_coordinator", - "//ios/chrome/browser/ui/alert_coordinator", - "//ios/chrome/browser/ui/collection_view/cells", - "//ios/chrome/browser/ui/util", - "//ios/chrome/test/earl_grey:test_support", - "//ui/strings", - ] - libs = [ - "UIKit.framework", - "XCTest.framework", - ] -}
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_alert_commands.h b/ios/chrome/browser/content_suggestions/content_suggestions_alert_commands.h deleted file mode 100644 index d734e65..0000000 --- a/ios/chrome/browser/content_suggestions/content_suggestions_alert_commands.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ALERT_COMMANDS_H_ -#define IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ALERT_COMMANDS_H_ - -#import <UIKit/UIKit.h> - -@class CollectionViewItem; - -// Command protocol for the ContentSuggestionsAlertFactory, handling the -// callbacks from the alerts. -@protocol ContentSuggestionsAlertCommands - -// Opens the URL corresponding to the |item| in a new tab, |incognito| or not. -// The item has to be a suggestion item. -- (void)openNewTabWithSuggestionsItem:(nonnull CollectionViewItem*)item - incognito:(BOOL)incognito; - -// Adds the |item| to the reading list. The item has to be a suggestion item. -- (void)addItemToReadingList:(nonnull CollectionViewItem*)item; - -// Dismiss the |item| at |indexPath|. The item has to be a suggestion item. -- (void)dismissSuggestion:(nonnull CollectionViewItem*)item - atIndexPath:(nonnull NSIndexPath*)indexPath; - -// Open the URL corresponding to the |item| in a new tab, |incognito| or not. -// The item has to be a Most Visited item. -- (void)openNewTabWithMostVisitedItem:(nonnull CollectionViewItem*)item - incognito:(BOOL)incognito - atIndex:(NSInteger)mostVisitedIndex; - -// Removes the most visited |item|. -- (void)removeMostVisited:(nonnull CollectionViewItem*)item; - -@end - -#endif // IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ALERT_COMMANDS_H_
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_alert_egtest.mm b/ios/chrome/browser/content_suggestions/content_suggestions_alert_egtest.mm deleted file mode 100644 index 05399ae1..0000000 --- a/ios/chrome/browser/content_suggestions/content_suggestions_alert_egtest.mm +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.h" - -#import <EarlGrey/EarlGrey.h> -#import <XCTest/XCTest.h> - -#import "ios/chrome/browser/content_suggestions/content_suggestions_alert_commands.h" -#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" -#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" -#import "ios/chrome/browser/ui/util/top_view_controller.h" -#include "ios/chrome/grit/ios_strings.h" -#import "ios/chrome/test/earl_grey/chrome_matchers.h" -#import "ios/chrome/test/earl_grey/chrome_test_case.h" -#include "ui/strings/grit/ui_strings.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface ContentSuggestionsAlertFactoryTestCase : XCTestCase - -@end - -@implementation ContentSuggestionsAlertFactoryTestCase - -- (void)testSuggestionsAlert { - UIViewController* viewController = - top_view_controller::TopPresentedViewController(); - AlertCoordinator* coordinator = [ContentSuggestionsAlertFactory - alertCoordinatorForSuggestionItem:nil - onViewController:viewController - atPoint:CGPointMake(50, 50) - atIndexPath:nil - commandHandler:nil]; - [coordinator start]; - - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)] - assertWithMatcher:grey_interactable()]; - [[EarlGrey selectElementWithMatcher: - chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB)] - assertWithMatcher:grey_interactable()]; - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_SUGGESTIONS_REMOVE)] - assertWithMatcher:grey_interactable()]; - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST)] - assertWithMatcher:grey_interactable()]; - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_APP_CANCEL)] - assertWithMatcher:grey_interactable()]; - - [coordinator stop]; -} - -- (void)testMostVisitedAlert { - UIViewController* viewController = - top_view_controller::TopPresentedViewController(); - AlertCoordinator* coordinator = [ContentSuggestionsAlertFactory - alertCoordinatorForSuggestionItem:nil - onViewController:viewController - atPoint:CGPointMake(50, 50) - atIndexPath:nil - commandHandler:nil]; - [coordinator start]; - - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)] - assertWithMatcher:grey_interactable()]; - [[EarlGrey selectElementWithMatcher: - chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB)] - assertWithMatcher:grey_interactable()]; - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_CONTENT_SUGGESTIONS_REMOVE)] - assertWithMatcher:grey_interactable()]; - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_APP_CANCEL)] - assertWithMatcher:grey_interactable()]; - - [coordinator stop]; -} - -@end
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.h b/ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.h deleted file mode 100644 index accca13..0000000 --- a/ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ALERT_FACTORY_H_ -#define IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ALERT_FACTORY_H_ - -#import <UIKit/UIKit.h> - -@class AlertCoordinator; -@class CollectionViewItem; -@protocol ContentSuggestionsAlertCommands; - -// Factory for AlertCoordinators for ContentSuggestions. -@interface ContentSuggestionsAlertFactory : NSObject - -// Returns an AlertCoordinator for a suggestions |item| with the indexPath -// |indexPath|. The alert will be presented on the |viewController| at the -// |touchLocation|, in the coordinates of the |viewController|'s view. The -// |commandHandler| will receive callbacks when the user chooses one of the -// options displayed by the alert. -+ (AlertCoordinator*) -alertCoordinatorForSuggestionItem:(CollectionViewItem*)item - onViewController:(UIViewController*)viewController - atPoint:(CGPoint)touchLocation - atIndexPath:(NSIndexPath*)indexPath - commandHandler: - (id<ContentSuggestionsAlertCommands>)commandHandler; - -// Same as above but for a MostVisited item. -+ (AlertCoordinator*) -alertCoordinatorForMostVisitedItem:(CollectionViewItem*)item - onViewController:(UIViewController*)viewController - atPoint:(CGPoint)touchLocation - atIndexPath:(NSIndexPath*)indexPath - commandHandler: - (id<ContentSuggestionsAlertCommands>)commandHandler; - -@end - -#endif // IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ALERT_FACTORY_H_
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.mm b/ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.mm deleted file mode 100644 index 1deedfb5..0000000 --- a/ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.mm +++ /dev/null
@@ -1,167 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.h" - -#import "ios/chrome/browser/content_suggestions/content_suggestions_alert_commands.h" -#import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" -#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" -#include "ios/chrome/grit/ios_strings.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/strings/grit/ui_strings.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation ContentSuggestionsAlertFactory - -+ (AlertCoordinator*) -alertCoordinatorForSuggestionItem:(CollectionViewItem*)item - onViewController:(UIViewController*)viewController - atPoint:(CGPoint)touchLocation - atIndexPath:(NSIndexPath*)indexPath - commandHandler: - (id<ContentSuggestionsAlertCommands>)commandHandler { - AlertCoordinator* alertCoordinator = [[ActionSheetCoordinator alloc] - initWithBaseViewController:viewController - title:nil - message:nil - rect:CGRectMake(touchLocation.x, touchLocation.y, 0, - 0) - view:[viewController view]]; - - __weak CollectionViewItem* weakItem = item; - __weak id<ContentSuggestionsAlertCommands> weakCommandHandler = - commandHandler; - - NSString* openInNewTabTitle = - l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB); - [alertCoordinator addItemWithTitle:openInNewTabTitle - action:^{ - CollectionViewItem* strongItem = weakItem; - if (strongItem) { - // TODO(crbug.com/691979): Add metrics. - [weakCommandHandler - openNewTabWithSuggestionsItem:strongItem - incognito:NO]; - } - } - style:UIAlertActionStyleDefault]; - - NSString* openInNewTabIncognitoTitle = - l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB); - [alertCoordinator addItemWithTitle:openInNewTabIncognitoTitle - action:^{ - CollectionViewItem* strongItem = weakItem; - if (strongItem) { - // TODO(crbug.com/691979): Add metrics. - [weakCommandHandler - openNewTabWithSuggestionsItem:strongItem - incognito:YES]; - } - } - style:UIAlertActionStyleDefault]; - - NSString* readLaterTitle = - l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST); - [alertCoordinator - addItemWithTitle:readLaterTitle - action:^{ - CollectionViewItem* strongItem = weakItem; - if (strongItem) { - // TODO(crbug.com/691979): Add metrics. - [weakCommandHandler addItemToReadingList:strongItem]; - } - } - style:UIAlertActionStyleDefault]; - - NSString* deleteTitle = - l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_REMOVE); - [alertCoordinator addItemWithTitle:deleteTitle - action:^{ - CollectionViewItem* strongItem = weakItem; - if (strongItem) { - // TODO(crbug.com/691979): Add metrics. - [weakCommandHandler - dismissSuggestion:strongItem - atIndexPath:indexPath]; - } - } - style:UIAlertActionStyleDestructive]; - - [alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_APP_CANCEL) - action:^{ - // TODO(crbug.com/691979): Add metrics. - } - style:UIAlertActionStyleCancel]; - return alertCoordinator; -} - -+ (AlertCoordinator*) -alertCoordinatorForMostVisitedItem:(CollectionViewItem*)item - onViewController:(UIViewController*)viewController - atPoint:(CGPoint)touchLocation - atIndexPath:(NSIndexPath*)indexPath - commandHandler: - (id<ContentSuggestionsAlertCommands>)commandHandler { - AlertCoordinator* alertCoordinator = [[ActionSheetCoordinator alloc] - initWithBaseViewController:viewController - title:nil - message:nil - rect:CGRectMake(touchLocation.x, touchLocation.y, 0, - 0) - view:[viewController view]]; - - __weak CollectionViewItem* weakItem = item; - __weak id<ContentSuggestionsAlertCommands> weakCommandHandler = - commandHandler; - - [alertCoordinator - addItemWithTitle:l10n_util::GetNSStringWithFixup( - IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB) - action:^{ - CollectionViewItem* strongItem = weakItem; - if (strongItem) { - [weakCommandHandler - openNewTabWithMostVisitedItem:strongItem - incognito:NO - atIndex:indexPath.item]; - } - } - style:UIAlertActionStyleDefault]; - - [alertCoordinator - addItemWithTitle:l10n_util::GetNSStringWithFixup( - IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB) - action:^{ - CollectionViewItem* strongItem = weakItem; - if (strongItem) { - [weakCommandHandler - openNewTabWithMostVisitedItem:strongItem - incognito:YES - atIndex:indexPath.item]; - } - } - style:UIAlertActionStyleDefault]; - - [alertCoordinator - addItemWithTitle:l10n_util::GetNSStringWithFixup( - IDS_IOS_CONTENT_SUGGESTIONS_REMOVE) - action:^{ - CollectionViewItem* strongItem = weakItem; - if (strongItem) { - [weakCommandHandler removeMostVisited:strongItem]; - } - } - style:UIAlertActionStyleDestructive]; - - [alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_APP_CANCEL) - action:nil - style:UIAlertActionStyleCancel]; - - return alertCoordinator; -} - -@end
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm index c42c369..2d3ee36 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
@@ -16,8 +16,6 @@ #include "components/reading_list/core/reading_list_model.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#import "ios/chrome/browser/content_suggestions/content_suggestions_alert_commands.h" -#import "ios/chrome/browser/content_suggestions/content_suggestions_alert_factory.h" #import "ios/chrome/browser/content_suggestions/content_suggestions_header_controller.h" #import "ios/chrome/browser/content_suggestions/content_suggestions_mediator.h" #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" @@ -25,7 +23,7 @@ #include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h" #include "ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.h" #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" -#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" +#import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" #include "ios/chrome/browser/ui/commands/ios_command_ids.h" @@ -54,7 +52,6 @@ #endif @interface ContentSuggestionsCoordinator ()< - ContentSuggestionsAlertCommands, ContentSuggestionsCommands, ContentSuggestionsHeaderCommands, ContentSuggestionsViewControllerDelegate, @@ -74,6 +71,13 @@ // |YES| if the fakebox header should be animated on scroll. @property(nonatomic, assign) BOOL animateHeader; +// Opens the |URL| in a new tab |incognito| or not. +- (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito; +// Dismisses the |article|, removing it from the content service, and dismisses +// the item at |indexPath| in the view controller. +- (void)dismissArticle:(ContentSuggestionsItem*)article + atIndexPath:(NSIndexPath*)indexPath; + @end @implementation ContentSuggestionsCoordinator @@ -165,6 +169,8 @@ referrer:web::Referrer() transition:ui::PAGE_TRANSITION_AUTO_BOOKMARK rendererInitiated:NO]; + + [self stop]; } - (void)openMostVisitedItem:(CollectionViewItem*)item @@ -178,17 +184,85 @@ referrer:web::Referrer() transition:ui::PAGE_TRANSITION_AUTO_BOOKMARK rendererInitiated:NO]; + + [self stop]; } - (void)displayContextMenuForArticle:(CollectionViewItem*)item atPoint:(CGPoint)touchLocation atIndexPath:(NSIndexPath*)indexPath { - self.alertCoordinator = [ContentSuggestionsAlertFactory - alertCoordinatorForSuggestionItem:item - onViewController:self.suggestionsViewController - atPoint:touchLocation - atIndexPath:indexPath - commandHandler:self]; + ContentSuggestionsItem* articleItem = + base::mac::ObjCCastStrict<ContentSuggestionsItem>(item); + self.alertCoordinator = [[ActionSheetCoordinator alloc] + initWithBaseViewController:self.suggestionsViewController + title:nil + message:nil + rect:CGRectMake(touchLocation.x, touchLocation.y, 0, + 0) + view:self.suggestionsViewController.collectionView]; + + __weak ContentSuggestionsCoordinator* weakSelf = self; + GURL articleURL = articleItem.URL; + NSString* articleTitle = articleItem.title; + __weak ContentSuggestionsItem* weakArticle = articleItem; + + NSString* openInNewTabTitle = + l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB); + [self.alertCoordinator + addItemWithTitle:openInNewTabTitle + action:^{ + // TODO(crbug.com/691979): Add metrics. + [weakSelf openNewTabWithURL:articleURL incognito:NO]; + } + style:UIAlertActionStyleDefault]; + + NSString* openInNewTabIncognitoTitle = + l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB); + [self.alertCoordinator + addItemWithTitle:openInNewTabIncognitoTitle + action:^{ + // TODO(crbug.com/691979): Add metrics. + [weakSelf openNewTabWithURL:articleURL incognito:YES]; + } + style:UIAlertActionStyleDefault]; + + NSString* readLaterTitle = + l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST); + [self.alertCoordinator + addItemWithTitle:readLaterTitle + action:^{ + ContentSuggestionsCoordinator* strongSelf = weakSelf; + if (!strongSelf) + return; + + base::RecordAction( + base::UserMetricsAction("MobileReadingListAdd")); + // TODO(crbug.com/691979): Add metrics. + + ReadingListModel* readingModel = + ReadingListModelFactory::GetForBrowserState( + strongSelf.browserState); + readingModel->AddEntry(articleURL, + base::SysNSStringToUTF8(articleTitle), + reading_list::ADDED_VIA_CURRENT_APP); + } + style:UIAlertActionStyleDefault]; + + NSString* deleteTitle = + l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_REMOVE); + [self.alertCoordinator addItemWithTitle:deleteTitle + action:^{ + // TODO(crbug.com/691979): Add metrics. + [weakSelf dismissArticle:weakArticle + atIndexPath:indexPath]; + } + style:UIAlertActionStyleDestructive]; + + [self.alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_APP_CANCEL) + action:^{ + // TODO(crbug.com/691979): Add metrics. + } + style:UIAlertActionStyleCancel]; [self.alertCoordinator start]; } @@ -196,12 +270,68 @@ - (void)displayContextMenuForMostVisitedItem:(CollectionViewItem*)item atPoint:(CGPoint)touchLocation atIndexPath:(NSIndexPath*)indexPath { - self.alertCoordinator = [ContentSuggestionsAlertFactory - alertCoordinatorForMostVisitedItem:item - onViewController:self.suggestionsViewController - atPoint:touchLocation - atIndexPath:indexPath - commandHandler:self]; + ContentSuggestionsMostVisitedItem* mostVisitedItem = + base::mac::ObjCCastStrict<ContentSuggestionsMostVisitedItem>(item); + self.alertCoordinator = [[ActionSheetCoordinator alloc] + initWithBaseViewController:self.suggestionsViewController + title:nil + message:nil + rect:CGRectMake(touchLocation.x, touchLocation.y, 0, + 0) + view:self.suggestionsViewController.collectionView]; + + __weak ContentSuggestionsCoordinator* weakSelf = self; + __weak ContentSuggestionsMostVisitedItem* weakItem = mostVisitedItem; + + [self.alertCoordinator + addItemWithTitle:l10n_util::GetNSStringWithFixup( + IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB) + action:^{ + ContentSuggestionsCoordinator* strongSelf = weakSelf; + ContentSuggestionsMostVisitedItem* strongItem = weakItem; + if (!strongSelf || !strongItem) + return; + [strongSelf logMostVisitedOpening:strongItem + atIndex:indexPath.item]; + [strongSelf openNewTabWithURL:strongItem.URL incognito:NO]; + } + style:UIAlertActionStyleDefault]; + + if (!self.browserState->IsOffTheRecord()) { + [self.alertCoordinator + addItemWithTitle:l10n_util::GetNSStringWithFixup( + IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB) + action:^{ + ContentSuggestionsCoordinator* strongSelf = weakSelf; + ContentSuggestionsMostVisitedItem* strongItem = weakItem; + if (!strongSelf || !strongItem) + return; + [strongSelf logMostVisitedOpening:strongItem + atIndex:indexPath.item]; + [strongSelf openNewTabWithURL:strongItem.URL incognito:YES]; + } + style:UIAlertActionStyleDefault]; + } + + [self.alertCoordinator + addItemWithTitle:l10n_util::GetNSStringWithFixup( + IDS_IOS_CONTENT_SUGGESTIONS_REMOVE) + action:^{ + ContentSuggestionsCoordinator* strongSelf = weakSelf; + ContentSuggestionsMostVisitedItem* strongItem = weakItem; + if (!strongSelf || !strongItem) + return; + base::RecordAction( + base::UserMetricsAction("MostVisited_UrlBlacklisted")); + [strongSelf.contentSuggestionsMediator + blacklistMostVisitedURL:strongItem.URL]; + [strongSelf showMostVisitedUndoForURL:strongItem.URL]; + } + style:UIAlertActionStyleDestructive]; + + [self.alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_APP_CANCEL) + action:nil + style:UIAlertActionStyleCancel]; [self.alertCoordinator start]; } @@ -234,54 +364,6 @@ NOTREACHED(); } -#pragma mark - ContentSuggestionsAlertCommands - -- (void)openNewTabWithSuggestionsItem:(CollectionViewItem*)item - incognito:(BOOL)incognito { - ContentSuggestionsItem* suggestionsItem = - base::mac::ObjCCastStrict<ContentSuggestionsItem>(item); - [self openNewTabWithURL:suggestionsItem.URL incognito:incognito]; -} - -- (void)addItemToReadingList:(CollectionViewItem*)item { - ContentSuggestionsItem* suggestionsItem = - base::mac::ObjCCastStrict<ContentSuggestionsItem>(item); - base::RecordAction(base::UserMetricsAction("MobileReadingListAdd")); - ReadingListModel* readingModel = - ReadingListModelFactory::GetForBrowserState(self.browserState); - readingModel->AddEntry(suggestionsItem.URL, - base::SysNSStringToUTF8(suggestionsItem.title), - reading_list::ADDED_VIA_CURRENT_APP); -} - -- (void)dismissSuggestion:(CollectionViewItem*)item - atIndexPath:(NSIndexPath*)indexPath { - ContentSuggestionsItem* suggestionsItem = - base::mac::ObjCCastStrict<ContentSuggestionsItem>(item); - - // TODO(crbug.com/691979): Add metrics. - [self.contentSuggestionsMediator - dismissSuggestion:suggestionsItem.suggestionIdentifier]; - [self.suggestionsViewController dismissEntryAtIndexPath:indexPath]; -} - -- (void)openNewTabWithMostVisitedItem:(CollectionViewItem*)item - incognito:(BOOL)incognito - atIndex:(NSInteger)index { - ContentSuggestionsMostVisitedItem* mostVisitedItem = - base::mac::ObjCCastStrict<ContentSuggestionsMostVisitedItem>(item); - [self logMostVisitedOpening:mostVisitedItem atIndex:index]; - [self openNewTabWithURL:mostVisitedItem.URL incognito:incognito]; -} - -- (void)removeMostVisited:(CollectionViewItem*)item { - ContentSuggestionsMostVisitedItem* mostVisitedItem = - base::mac::ObjCCastStrict<ContentSuggestionsMostVisitedItem>(item); - base::RecordAction(base::UserMetricsAction("MostVisited_UrlBlacklisted")); - [self.contentSuggestionsMediator blacklistMostVisitedURL:mostVisitedItem.URL]; - [self showMostVisitedUndoForURL:mostVisitedItem.URL]; -} - #pragma mark - ContentSuggestionsHeaderCommands - (void)updateFakeOmniboxForScrollView:(UIScrollView*)scrollView { @@ -405,7 +487,6 @@ #pragma mark - Private -// Opens the |URL| in a new tab |incognito| or not. - (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito { // TODO(crbug.com/691979): Add metrics. @@ -414,6 +495,19 @@ inIncognito:incognito inBackground:NO appendTo:kCurrentTab]; + + [self stop]; +} + +- (void)dismissArticle:(ContentSuggestionsItem*)article + atIndexPath:(NSIndexPath*)indexPath { + if (!article) + return; + + // TODO(crbug.com/691979): Add metrics. + [self.contentSuggestionsMediator + dismissSuggestion:article.suggestionIdentifier]; + [self.suggestionsViewController dismissEntryAtIndexPath:indexPath]; } // Logs a histogram due to a Most Visited item being opened.
diff --git a/ios/chrome/browser/ui/ntp/google_landing_mediator.mm b/ios/chrome/browser/ui/ntp/google_landing_mediator.mm index ef06b35d..693d450 100644 --- a/ios/chrome/browser/ui/ntp/google_landing_mediator.mm +++ b/ios/chrome/browser/ui/ntp/google_landing_mediator.mm
@@ -116,45 +116,51 @@ // Most visited data from the MostVisitedSites service currently in use. ntp_tiles::NTPTilesVector _mostVisitedData; + // Most visited data from the MostVisitedSites service (copied upon receiving + // the callback), not yet used by the collection. It will be used after a user + // interaction. + ntp_tiles::NTPTilesVector _freshMostVisitedData; + + // Most visited data used for logging the tiles impression. The data are + // copied when receiving the first non-empty data. This copy is used to make + // sure only the data received the first time are logged, and only once. + ntp_tiles::NTPTilesVector _mostVisitedDataForLogging; + // Observes the WebStateList so that this mediator can update the UI when the // active WebState changes. std::unique_ptr<WebStateListObserverBridge> _webStateListObserver; // What's new promo. - std::unique_ptr<NotificationPromoWhatsNew> _notification_promo; + std::unique_ptr<NotificationPromoWhatsNew> _notificationPromo; // Used to cancel tasks for the LargeIconService. base::CancelableTaskTracker _cancelable_task_tracker; + + // Consumer to handle google landing update notifications. + base::WeakNSProtocol<id<GoogleLandingConsumer>> _consumer; + + // Dispatcher for this mediator. + base::WeakNSProtocol<id<ChromeExecuteCommand, UrlLoader>> _dispatcher; } // Consumer to handle google landing update notifications. -@property(nonatomic) id<GoogleLandingConsumer> consumer; +@property(nonatomic, assign, readonly) id<GoogleLandingConsumer> consumer; // The WebStateList that is being observed by this mediator. -@property(nonatomic, assign) WebStateList* webStateList; +@property(nonatomic, assign, readonly) WebStateList* webStateList; // The dispatcher for this mediator. -@property(nonatomic, assign) id<ChromeExecuteCommand, UrlLoader> dispatcher; - -// Most visited data from the MostVisitedSites service (copied upon receiving -// the callback), not yet used. -@property(nonatomic, assign) ntp_tiles::NTPTilesVector freshMostVisitedData; +@property(nonatomic, assign, readonly) id<ChromeExecuteCommand, UrlLoader> + dispatcher; // Perform initial setup. - (void)setUp; -// If there is some fresh most visited tiles, they become the current tiles and -// the consumer gets notified. -- (void)useFreshData; - @end @implementation GoogleLandingMediator -@synthesize consumer = _consumer; -@synthesize dispatcher = _dispatcher; @synthesize webStateList = _webStateList; -@synthesize freshMostVisitedData = _freshMostVisitedData; - (instancetype)initWithConsumer:(id<GoogleLandingConsumer>)consumer browserState:(ios::ChromeBrowserState*)browserState @@ -162,9 +168,9 @@ webStateList:(WebStateList*)webStateList { self = [super init]; if (self) { - _consumer = consumer; + _consumer.reset(consumer); _browserState = browserState; - _dispatcher = dispatcher; + _dispatcher.reset(dispatcher); _webStateList = webStateList; _webStateListObserver = base::MakeUnique<WebStateListObserverBridge>(self); @@ -178,20 +184,21 @@ - (void)shutdown { _webStateList->RemoveObserver(_webStateListObserver.get()); [[NSNotificationCenter defaultCenter] removeObserver:self.consumer]; + _observer.reset(); } - (void)setUp { - [_consumer setVoiceSearchIsEnabled:ios::GetChromeBrowserProvider() - ->GetVoiceSearchProvider() - ->IsVoiceSearchEnabled()]; - [_consumer + [self.consumer setVoiceSearchIsEnabled:ios::GetChromeBrowserProvider() + ->GetVoiceSearchProvider() + ->IsVoiceSearchEnabled()]; + [self.consumer setMaximumMostVisitedSitesShown:[GoogleLandingMediator maxSitesShown]]; - [_consumer setTabCount:self.webStateList->count()]; + [self.consumer setTabCount:self.webStateList->count()]; web::WebState* webState = _webStateList->GetActiveWebState(); if (webState) { web::NavigationManager* nav = webState->GetNavigationManager(); - [_consumer setCanGoForward:nav->CanGoForward()]; - [_consumer setCanGoBack:nav->CanGoBack()]; + [self.consumer setCanGoForward:nav->CanGoForward()]; + [self.consumer setCanGoBack:nav->CanGoBack()]; } // Set up template URL service to listen for default search engine changes. @@ -202,7 +209,7 @@ _templateURLService->Load(); _doodleController.reset(ios::GetChromeBrowserProvider()->CreateLogoVendor( _browserState, self.dispatcher)); - [_consumer setLogoVendor:_doodleController]; + [self.consumer setLogoVendor:_doodleController]; [self updateShowLogo]; // Set up most visited sites. This call may have the side effect of @@ -218,24 +225,24 @@ // Set up notifications; NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; [defaultCenter - addObserver:_consumer + addObserver:self.consumer selector:@selector(locationBarBecomesFirstResponder) name:ios_internal::kLocationBarBecomesFirstResponderNotification object:nil]; [defaultCenter - addObserver:_consumer + addObserver:self.consumer selector:@selector(locationBarResignsFirstResponder) name:ios_internal::kLocationBarResignsFirstResponderNotification object:nil]; // Set up what's new. - _notification_promo.reset( + _notificationPromo.reset( new NotificationPromoWhatsNew(GetApplicationContext()->GetLocalState())); - _notification_promo->Init(); - [_consumer setPromoText:[base::SysUTF8ToNSString( - _notification_promo->promo_text()) copy]]; - [_consumer setPromoIcon:_notification_promo->icon()]; - [_consumer setPromoCanShow:_notification_promo->CanShow()]; + _notificationPromo->Init(); + [self.consumer setPromoText:[base::SysUTF8ToNSString( + _notificationPromo->promo_text()) copy]]; + [self.consumer setPromoIcon:_notificationPromo->icon()]; + [self.consumer setPromoCanShow:_notificationPromo->CanShow()]; } - (void)updateShowLogo { @@ -260,7 +267,7 @@ if (_mostVisitedData.size() > 0) { // If some content is already displayed to the user, do not update it to // prevent updating the all the tiles without any action from the user. - self.freshMostVisitedData = data; + _freshMostVisitedData = data; return; } @@ -269,12 +276,7 @@ if (data.size() && !_recordedPageImpression) { _recordedPageImpression = YES; - int index = 0; - for (const ntp_tiles::NTPTile& ntpTile : data) { - ntp_tiles::metrics::RecordTileImpression( - index++, ntpTile.source, ntp_tiles::UNKNOWN_TILE_TYPE, ntpTile.url, - GetApplicationContext()->GetRapporServiceImpl()); - } + _mostVisitedDataForLogging = data; ntp_tiles::metrics::RecordPageImpression(data.size()); } } @@ -300,6 +302,8 @@ void (^faviconBlock)(const favicon_base::LargeIconResult&) = ^( const favicon_base::LargeIconResult& result) { + ntp_tiles::TileVisualType tileType; + if (result.bitmap.is_valid()) { scoped_refptr<base::RefCountedMemory> data = result.bitmap.bitmap_data.get(); @@ -307,6 +311,7 @@ imageWithData:[NSData dataWithBytes:data->front() length:data->size()] scale:[UIScreen mainScreen].scale]; imageCallback(favicon); + tileType = ntp_tiles::TileVisualType::ICON_REAL; } else if (result.fallback_icon_style) { UIColor* backgroundColor = skia::UIColorFromSkColor( result.fallback_icon_style->background_color); @@ -315,12 +320,16 @@ BOOL isDefaultColor = result.fallback_icon_style->is_default_background_color; fallbackCallback(textColor, backgroundColor, isDefaultColor); + fallbackCallback(backgroundColor, textColor, isDefaultColor); + tileType = isDefaultColor ? ntp_tiles::TileVisualType::ICON_DEFAULT + : ntp_tiles::TileVisualType::ICON_COLOR; } base::scoped_nsobject<GoogleLandingMediator> strongSelf([weakSelf retain]); - if (strongSelf && - (result.bitmap.is_valid() || result.fallback_icon_style)) { - [strongSelf largeIconCache]->SetCachedResult(URL, result); + if (strongSelf) { + if ((result.bitmap.is_valid() || result.fallback_icon_style)) + [strongSelf largeIconCache]->SetCachedResult(URL, result); + [strongSelf faviconOfType:tileType fetchedForURL:URL]; } }; @@ -411,28 +420,28 @@ } - (void)promoViewed { - DCHECK(_notification_promo); - _notification_promo->HandleViewed(); - [self.consumer setPromoCanShow:_notification_promo->CanShow()]; + DCHECK(_notificationPromo); + _notificationPromo->HandleViewed(); + [self.consumer setPromoCanShow:_notificationPromo->CanShow()]; } - (void)promoTapped { - DCHECK(_notification_promo); - _notification_promo->HandleClosed(); - [self.consumer setPromoCanShow:_notification_promo->CanShow()]; + DCHECK(_notificationPromo); + _notificationPromo->HandleClosed(); + [self.consumer setPromoCanShow:_notificationPromo->CanShow()]; - if (_notification_promo->IsURLPromo()) { - [self.dispatcher webPageOrderedOpen:_notification_promo->url() + if (_notificationPromo->IsURLPromo()) { + [self.dispatcher webPageOrderedOpen:_notificationPromo->url() referrer:web::Referrer() inBackground:NO appendTo:kCurrentTab]; return; } - if (_notification_promo->IsChromeCommand()) { + if (_notificationPromo->IsChromeCommand()) { base::scoped_nsobject<GenericChromeCommand> command( [[GenericChromeCommand alloc] - initWithTag:_notification_promo->command_id()]); + initWithTag:_notificationPromo->command_id()]); [self.dispatcher chromeExecuteCommand:command]; return; } @@ -441,9 +450,38 @@ #pragma mark - Private +// If there is some fresh most visited tiles, they become the current tiles and +// the consumer gets notified. - (void)useFreshData { - _mostVisitedData = self.freshMostVisitedData; + _mostVisitedData = _freshMostVisitedData; [self.consumer mostVisitedDataUpdated]; } +// If it is the first time we see the favicon corresponding to |URL|, we log the +// |tileType| impression. +- (void)faviconOfType:(ntp_tiles::TileVisualType)tileType + fetchedForURL:(const GURL&)URL { + for (size_t i = 0; i < _mostVisitedDataForLogging.size(); ++i) { + ntp_tiles::NTPTile& ntpTile = _mostVisitedDataForLogging[i]; + if (ntpTile.url == URL) { + ntp_tiles::metrics::RecordTileImpression( + i, ntpTile.source, tileType, URL, + GetApplicationContext()->GetRapporServiceImpl()); + // Reset the URL to be sure to log the impression only once. + ntpTile.url = GURL(); + break; + } + } +} + +#pragma mark - Properties + +- (id<GoogleLandingConsumer>)consumer { + return _consumer.get(); +} + +- (id<ChromeExecuteCommand, UrlLoader>)dispatcher { + return _dispatcher.get(); +} + @end
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller_egtest.mm b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller_egtest.mm index a1b4787..ef08816 100644 --- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller_egtest.mm
@@ -12,6 +12,7 @@ #include "components/version_info/version_info.h" #import "ios/chrome/app/main_controller.h" #include "ios/chrome/browser/chrome_switches.h" +#include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/ui/browser_view_controller.h" #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" #include "ios/chrome/browser/ui/commands/ios_command_ids.h" @@ -111,12 +112,31 @@ grey_accessibilityTrait(UIAccessibilityTraitStaticText), nil); } -// Opens the QR Scanner view using a command. -// TODO(crbug.com/629776): Replace the command call with a UI action. -void ShowQRScannerWithCommand() { - GenericChromeCommand* command = - [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_QR_SCANNER]; - chrome_test_util::RunCommandWithActiveViewController(command); +// Opens the QR Scanner view. +void ShowQRScanner() { + // TODO(crbug.com/738106): only show the QR Scanner via the Keyboard Accessory + // View. + if (experimental_flags::IsKeyboardAccessoryViewWithCameraSearchEnabled()) { + // Tap the omnibox to get the keyboard accessory view to show up. + id<GREYMatcher> locationbarButton = grey_allOf( + grey_accessibilityLabel(l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)), + grey_minimumVisiblePercent(0.2), nil); + [[EarlGrey selectElementWithMatcher:locationbarButton] + assertWithMatcher:grey_text(@"Search or type URL")]; + [[EarlGrey selectElementWithMatcher:locationbarButton] + performAction:grey_tap()]; + + // Tap the QR Code scanner button in the keyboard accessory view. + id<GREYMatcher> matcher = + grey_allOf(grey_accessibilityLabel(@"QR code Search"), + grey_kindOfClass([UIButton class]), nil); + + [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; + } else { + GenericChromeCommand* command = + [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_QR_SCANNER]; + chrome_test_util::RunCommandWithActiveViewController(command); + } } // Taps the |button|. @@ -251,7 +271,7 @@ [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; [self addCameraControllerInitializationExpectations:mock]; - ShowQRScannerWithCommand(); + ShowQRScanner(); [self waitForModalOfClass:[QRScannerViewController class] toAppearAbove:bvc]; [self assertQRScannerUIIsVisibleWithTorch:NO]; [self assertModalOfClass:[UIAlertController class] @@ -632,7 +652,7 @@ AVAuthorizationStatusDenied]; [self swizzleCameraController:cameraControllerMock]; - ShowQRScannerWithCommand(); + ShowQRScanner(); [self assertModalOfClass:[QRScannerViewController class] isNotPresentedBy:bvc]; [self waitForModalOfClass:[UIAlertController class] toAppearAbove:bvc];
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm index 96f6bd9..9322f86 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
@@ -471,4 +471,40 @@ SelectNewTabPagePanel(NewTabPage::kMostVisitedPanel); } + +// Tests typing in the omnibox using the keyboard accessory view. +- (void)testToolbarOmniboxKeyboardAccessoryView { + // Select the omnibox to get the keyboard up. + id<GREYMatcher> locationbarButton = grey_allOf( + grey_accessibilityLabel(l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)), + grey_minimumVisiblePercent(0.2), nil); + [[EarlGrey selectElementWithMatcher:locationbarButton] + assertWithMatcher:grey_text(@"Search or type URL")]; + [[EarlGrey selectElementWithMatcher:locationbarButton] + performAction:grey_tap()]; + + // Tap the "/" keyboard accessory button. + id<GREYMatcher> slashButtonMatcher = grey_allOf( + grey_accessibilityLabel(@"/"), grey_kindOfClass([UIButton class]), nil); + + [[EarlGrey selectElementWithMatcher:slashButtonMatcher] + performAction:grey_tap()]; + + // Tap the ".com" keyboard accessory button. + id<GREYMatcher> dotComButtonMatcher = + grey_allOf(grey_accessibilityLabel(@".com"), + grey_kindOfClass([UIButton class]), nil); + + [[EarlGrey selectElementWithMatcher:dotComButtonMatcher] + performAction:grey_tap()]; + + // Verify that the omnibox contains "/.com" + [[EarlGrey + selectElementWithMatcher:grey_allOf(grey_accessibilityLabel(@"/.com"), + grey_kindOfClass( + [OmniboxPopupMaterialRow class]), + nil)] + assertWithMatcher:grey_sufficientlyVisible()]; +} + @end
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 07a9fd3..d497f3cd 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -46,7 +46,6 @@ chrome_ios_eg_test("ios_chrome_ui_egtests") { deps = [ "//ios/chrome/app/safe_mode:eg_tests", - "//ios/chrome/browser/content_suggestions:eg_tests", "//ios/chrome/browser/ui:eg_tests", "//ios/chrome/browser/ui/activity_services:eg_tests", "//ios/chrome/browser/ui/alert_coordinator:eg_tests",
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index af12d1a2..d74c8a4 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -216,8 +216,8 @@ #define SK_SUPPORT_LEGACY_TILED_BITMAPS #endif -#ifndef SK_SUPPORT_LEGACY_SWIZZLE_SHADER -#define SK_SUPPORT_LEGACY_SWIZZLE_SHADER +#ifndef SK_SUPPORT_LEGACY_2PTCONICAL_GRADIENT +#define SK_SUPPORT_LEGACY_2PTCONICAL_GRADIENT #endif ///////////////////////// Imported from BUILD.gn and skia_common.gypi
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index e82c4052..036dfc51 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1137,7 +1137,7 @@ "type": "console_test_launcher", }, "zucchini_unittests": { - "label": "//zucchini:zucchini_unittests", + "label": "//chrome/installer/zucchini:zucchini_unittests", "type": "console_test_launcher", }, }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index b8c9ede2..06316992 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1797,6 +1797,32 @@ ] } ], + "NewTabInProductHelp": [ + { + "platforms": [ + "linux", + "mac", + "win" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_new_tab_opened": "name:new_tab_opened;comparator:==0;window:3650;storage:3650", + "event_omnibox_used": "name:omnibox_used;comparator:>=1;window:3650;storage:3650", + "event_session_time": "name:session_time;comparator:>=1;window:3650;storage:3650", + "event_trigger": "name:new_tab_trigger;comparator:any;window:3650;storage:3650", + "event_used": "name:new_tab_clicked;comparator:any;window:3650;storage:3650", + "session_rate": "<=3" + }, + "enable_features": [ + "IPH_NewTab" + ] + } + ] + } + ], "NoCreditCardAbort": [ { "platforms": [ @@ -2711,7 +2737,7 @@ ], "experiments": [ { - "name": "Enabled", + "name": "AdIdentifiers", "params": { "tag_attribute_csv": "div,id,iframe,id" }, @@ -3144,6 +3170,24 @@ "enable_features": [ "TranslateCompactUI" ] + }, + { + "name": "CompactUIAndRanker", + "enable_features": [ + "TranslateCompactUI", + "TranslateRankerEnforcement", + "TranslateRankerQuery" + ] + }, + { + "name": "RankerOnly", + "enable_features": [ + "TranslateRankerEnforcement", + "TranslateRankerQuery" + ], + "disable_features": [ + "TranslateCompactUI" + ] } ] } @@ -3151,7 +3195,6 @@ "TranslateRankerModel": [ { "platforms": [ - "android", "chromeos", "ios", "linux", @@ -3292,6 +3335,25 @@ ] } ], + "V8AsmJSToWasm": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "win" + ], + "experiments": [ + { + "name": "AsmJsToWebAssembly", + "enable_features": [ + "AsmJsToWebAssembly" + ] + } + ] + } + ], "V8CacheStrategiesForCacheStorage": [ { "platforms": [ @@ -3397,6 +3459,9 @@ "experiments": [ { "name": "Enabled", + "params": { + "play_install": "true" + }, "enable_features": [ "ImprovedA2HS" ]
diff --git a/third_party/.gitignore b/third_party/.gitignore index 5bf71dee..b9b092a 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -117,6 +117,7 @@ /llvm-bootstrap /llvm-build /lss +/material_design_icons/src /mesa/src /mingw-w64 /minigbm/src
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 2b3d1b4..c222cc4 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -13490,7 +13490,7 @@ crbug.com/591099 fast/text-autosizing/list-marker-with-images-and-forms-autosizing.html [ Crash Failure ] crbug.com/591099 fast/text-autosizing/list-marker-with-links-autosizing.html [ Crash Failure ] crbug.com/591099 fast/text-autosizing/narrow-child.html [ Failure ] -crbug.com/591099 fast/text-autosizing/narrow-iframe.html [ Failure ] +crbug.com/591099 http/tests/text-autosizing/narrow-iframe.html [ Failure ] crbug.com/591099 fast/text-autosizing/nested-child.html [ Failure ] crbug.com/591099 fast/text-autosizing/nested-em-line-height.html [ Failure ] crbug.com/591099 fast/text-autosizing/oscillation-javascript-fontsize-change.html [ Failure ] @@ -13523,7 +13523,7 @@ crbug.com/591099 fast/text-autosizing/vertical-writing-mode.html [ Failure ] crbug.com/591099 fast/text-autosizing/wide-block.html [ Failure ] crbug.com/591099 fast/text-autosizing/wide-child.html [ Failure ] -crbug.com/591099 fast/text-autosizing/wide-iframe.html [ Failure ] +crbug.com/591099 http/tests/text-autosizing/wide-iframe.html [ Failure ] crbug.com/591099 fast/text-autosizing/wide-in-narrow-overflow-scroll.html [ Failure ] crbug.com/591099 fast/text/apply-start-width-after-skipped-text.html [ Failure ] crbug.com/591099 fast/text/atsui-kerning-and-ligatures.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service b/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service index 82103d8..ade9c10 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service
@@ -409,6 +409,7 @@ Bug(none) external/wpt/html/semantics/forms/form-submission-0/submit-entity-body.html [ Failure Timeout ] Bug(none) external/wpt/html/semantics/forms/the-legend-element/legend-form.html [ Failure Timeout ] Bug(none) external/wpt/html/semantics/scripting-1/the-script-element/async_003.htm [ Failure Timeout ] +Bug(none) external/wpt/html/semantics/scripting-1/the-script-element/module/credentials.sub.html [ Failure Timeout ] Bug(none) external/wpt/html/semantics/scripting-1/the-script-element/script-crossorigin-network.html [ Failure Timeout ] Bug(none) external/wpt/html/webappapis/idle-callbacks/callback-suspended.html [ Failure Timeout ] Bug(none) external/wpt/html/webappapis/scripting/events/messageevent-constructor.https.html [ Failure Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process index 86bf9739..c0c3b9f 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process +++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -1,6 +1,12 @@ # These tests currently fail when they run with --site-per-process. # See https://crbug.com/477150. +# https://crbug.com/393285: Text-autosizing doesn't support OOPIFs. +# https://crbug.com/667551: Pixel dumps don't support OOPIFs. +# Both of the bugs above need to be fixed, before enabling the tests below. +crbug.com/393285 http/tests/text-autosizing/narrow-iframe.html [ Failure ] +crbug.com/393285 http/tests/text-autosizing/wide-iframe.html [ Failure ] + # https://crbug.com/710098: Tests failing because of r462933. crbug.com/710098 http/tests/security/document-all.html [ Failure ] crbug.com/710098 http/tests/security/window-named-proto.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-display-contents-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-display-contents-crash-expected.txt new file mode 100644 index 0000000..88e5335 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-display-contents-crash-expected.txt
@@ -0,0 +1 @@ +Shouldn't crash.
diff --git a/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-display-contents-crash.html b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-display-contents-crash.html new file mode 100644 index 0000000..0623be38 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-display-contents-crash.html
@@ -0,0 +1,13 @@ +<div style="display: contents"><a href="#"></a></div> +Shouldn't crash. +<script> +testRunner.dumpAsText(); +testRunner.overridePreference("WebKitTabToLinksPreferenceKey", 1); +testRunner.overridePreference("WebKitSpatialNavigationEnabled", 1); + +function runTest() { + eventSender.keyDown("ArrowLeft"); +} + +window.onload = runTest; +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/sub-pixel/input-caret-on-subpixel-bound-expected.html b/third_party/WebKit/LayoutTests/fast/sub-pixel/input-caret-on-subpixel-bound-expected.html index 93a2148c..4c24240 100644 --- a/third_party/WebKit/LayoutTests/fast/sub-pixel/input-caret-on-subpixel-bound-expected.html +++ b/third_party/WebKit/LayoutTests/fast/sub-pixel/input-caret-on-subpixel-bound-expected.html
@@ -7,10 +7,10 @@ font-family: sans-serif; } table { - padding: 2px 3px 3px 2px; + padding: 2px 2px 2px 2px; } input { - padding: 6px 6px 5px 5px; + padding: 5px 6px 6px 5px; } </style> </head>
diff --git a/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-expected.png b/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-expected.png index 78ba1ba..04272d5 100644 --- a/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-expected.png +++ b/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-quirks-mode-expected.png b/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-quirks-mode-expected.png index 78ba1ba..04272d5 100644 --- a/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-quirks-mode-expected.png +++ b/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-quirks-mode-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/sendbeacon/beacon-cross-origin-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/sendbeacon/beacon-cross-origin-redirect-expected.txt index 6579136bb..369c773 100644 --- a/third_party/WebKit/LayoutTests/http/tests/sendbeacon/beacon-cross-origin-redirect-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/sendbeacon/beacon-cross-origin-redirect-expected.txt
@@ -1,4 +1,5 @@ PingLoader dispatched to 'http://127.0.0.1:8080/resources/redirection-response.php?status=302&target=/non-existent.php'. +CONSOLE ERROR: Redirect from 'http://127.0.0.1:8080/resources/redirection-response.php?status=302&target=/non-existent.php' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. Verifying that navigator.sendBeacon() to non-CORS cross-origin redirect fails. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/http/tests/sendbeacon/resources/save-beacon.php b/third_party/WebKit/LayoutTests/http/tests/sendbeacon/resources/save-beacon.php index 1888c93..bf71ba4a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/sendbeacon/resources/save-beacon.php +++ b/third_party/WebKit/LayoutTests/http/tests/sendbeacon/resources/save-beacon.php
@@ -37,4 +37,6 @@ foreach ($_COOKIE as $name => $value) setcookie($name, "deleted", time() - 60, "/"); } +header('Access-Control-Allow-Origin: http://127.0.0.1:8000'); +header('Access-Control-Allow-Credentials: true'); ?>
diff --git a/third_party/WebKit/LayoutTests/fast/text-autosizing/narrow-iframe-expected.html b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/narrow-iframe-expected.html similarity index 100% rename from third_party/WebKit/LayoutTests/fast/text-autosizing/narrow-iframe-expected.html rename to third_party/WebKit/LayoutTests/http/tests/text-autosizing/narrow-iframe-expected.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/text-autosizing/narrow-iframe.html b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/narrow-iframe.html new file mode 100644 index 0000000..5f4009f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/narrow-iframe.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta name="viewport" content="width=800"> +<style> +body { width: 800px; margin: 0; } +</style> +<script src="resources/autosizingTest.js"></script> +</head> +<body> + <iframe + style="width: 100%; height: 300px; border: 0" + src="http://localhost:8000/text-autosizing/resources/narrow-iframe.html"> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/autosizingTest.js b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/autosizingTest.js new file mode 100644 index 0000000..f0e30d18 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/autosizingTest.js
@@ -0,0 +1,24 @@ +function setWindowSizeOverride(width, height) { + if (window.internals) + window.internals.settings.setTextAutosizingWindowSizeOverride(width, height); +} + +function setFontScaleFactor(scale) { + if (window.internals) + window.internals.settings.setAccessibilityFontScaleFactor(scale); +} + +function initAutosizingTest() { + if (window.internals) { + window.internals.settings.setTextAutosizingEnabled(true); + setWindowSizeOverride(320, 480); + } else if (window.console && console.warn) { + console.warn("This test depends on Text Autosizing being enabled. Run with content shell " + + "and --run-layout-test or manually enable Text Autosizing and either use a " + + "mobile device with 320px device-width (like Nexus S or iPhone), or define " + + "DEBUG_TEXT_AUTOSIZING_ON_DESKTOP."); + } +} + +// Automatically call init. Users who want a different window size can use setWindowSizeOverride. +initAutosizingTest();
diff --git a/third_party/WebKit/LayoutTests/fast/text-autosizing/narrow-iframe.html b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/narrow-iframe.html similarity index 72% rename from third_party/WebKit/LayoutTests/fast/text-autosizing/narrow-iframe.html rename to third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/narrow-iframe.html index 2dfeacd..d821e82 100644 --- a/third_party/WebKit/LayoutTests/fast/text-autosizing/narrow-iframe.html +++ b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/narrow-iframe.html
@@ -1,17 +1,5 @@ <!DOCTYPE html> -<html> -<head> -<meta name="viewport" content="width=800"> -<style> -body { width: 800px; margin: 0; } -</style> -<script src="resources/autosizingTest.js"></script> -</head> -<body> -<iframe style="width: 100%; height: 300px; border: 0" src='data:text/html, <html style="font-size: 16px"><body style="margin: 0; overflow-y: hidden"><div style="width: 400px"> This text should be autosized to just 20px computed font size, i.e. scaled up by 1.25x, since although this block is in an 800px wide iframe, it is in a 400px block and 400 / 320 = 1.25.<br> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -</div></body></html>'> -</body> -</html> +</div></body></html>
diff --git a/third_party/WebKit/LayoutTests/fast/text-autosizing/wide-iframe.html b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/wide-iframe.html similarity index 80% rename from third_party/WebKit/LayoutTests/fast/text-autosizing/wide-iframe.html rename to third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/wide-iframe.html index b966107c..189f317 100644 --- a/third_party/WebKit/LayoutTests/fast/text-autosizing/wide-iframe.html +++ b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/resources/wide-iframe.html
@@ -1,22 +1,5 @@ <!DOCTYPE html> -<html> -<head> - -<meta name="viewport" content="width=800"> -<style> -body { width: 800px; margin: 0; } -</style> - -<script src="resources/autosizingTest.js"></script> - -</head> -<body> - -<iframe style="width: 3200px; height: 50%; border: 0" src='data:text/html, <html style="font-size: 16px"><body style="margin: 0; overflow-y: hidden"><div style="width: 1600px"> This text should be autosized to just 40px computed font size, i.e. scaled up by 2.5x, since although this block is 1600px wide and is in a 3200px wide iframe, the top level frame is only 800px wide, and min(1600, 3200, 800) / 320 = 2.5.<br> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -</div></body></html>'> - -</body> -</html> +</div></body></html>
diff --git a/third_party/WebKit/LayoutTests/fast/text-autosizing/wide-iframe-expected.html b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/wide-iframe-expected.html similarity index 100% rename from third_party/WebKit/LayoutTests/fast/text-autosizing/wide-iframe-expected.html rename to third_party/WebKit/LayoutTests/http/tests/text-autosizing/wide-iframe-expected.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/text-autosizing/wide-iframe.html b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/wide-iframe.html new file mode 100644 index 0000000..b9c71eddc6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/text-autosizing/wide-iframe.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> + +<meta name="viewport" content="width=800"> +<style> +body { width: 800px; margin: 0; } +</style> + +<script src="resources/autosizingTest.js"></script> + +</head> +<body> + + <iframe + style="width: 3200px; height: 50%; border: 0" + src="http://localhost:8000/text-autosizing/resources/wide-iframe.html"> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png index 59f61c5..b7a8662c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt index 772f112e..71d96ef 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt
@@ -3,103 +3,103 @@ layer at (0,0) size 800x339 LayoutBlockFlow {HTML} at (0,0) size 800x339.09 LayoutBlockFlow {BODY} at (5.55,5.55) size 788.91x328 - LayoutTable {TABLE} at (0,0) size 460x328 - LayoutTableSection {TBODY} at (0,0) size 460x328 - LayoutTableRow {TR} at (0,1) size 460x14 - LayoutTableCell {TH} at (1,1) size 64x14 [bgcolor=#DDDD99] [r=0 c=0 rs=1 cs=1] - LayoutText {#text} at (6,0) size 52x14 - text run at (6,0) width 52: "viewBox?" - LayoutTableCell {TH} at (66,1) size 111x14 [bgcolor=#DDDD99] [r=0 c=1 rs=1 cs=1] - LayoutText {#text} at (0,0) size 111x14 - text run at (0,0) width 111: "preserve\x{AD}Aspect\x{AD}Ratio" - LayoutTableCell {TH} at (178,1) size 140x14 [bgcolor=#DDDD99] [r=0 c=2 rs=1 cs=1] - LayoutText {#text} at (54,0) size 32x14 - text run at (54,0) width 32: "<img>" - LayoutTableCell {TH} at (319,1) size 140x14 [bgcolor=#DDDD99] [r=0 c=3 rs=1 cs=1] - LayoutText {#text} at (47,0) size 46x14 - text run at (47,0) width 46: "<object>" - LayoutTableRow {TR} at (0,16) size 460x38 - LayoutTableCell {TH} at (1,86) size 64x14 [bgcolor=#DDDD99] [r=1 c=0 rs=4 cs=1] - LayoutText {#text} at (0,0) size 64x14 - text run at (0,0) width 64: "No viewBox" - LayoutTableCell {TH} at (66,35) size 111x0 [bgcolor=#DDDD99] [r=1 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (178,16) size 140x38 [r=1 c=2 rs=1 cs=1] + LayoutTable {TABLE} at (0,0) size 456x328 + LayoutTableSection {TBODY} at (0,0) size 456x328 + LayoutTableRow {TR} at (0,1) size 456x14 + LayoutTableCell {TH} at (1,1) size 63x14 [bgcolor=#DDDD99] [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (5,0) size 53x14 + text run at (5,0) width 53: "viewBox?" + LayoutTableCell {TH} at (65,1) size 110x14 [bgcolor=#DDDD99] [r=0 c=1 rs=1 cs=1] + LayoutText {#text} at (0,0) size 110x14 + text run at (0,0) width 110: "preserve\x{AD}Aspect\x{AD}Ratio" + LayoutTableCell {TH} at (176,1) size 139x14 [bgcolor=#DDDD99] [r=0 c=2 rs=1 cs=1] + LayoutText {#text} at (53,0) size 33x14 + text run at (53,0) width 33: "<img>" + LayoutTableCell {TH} at (316,1) size 139x14 [bgcolor=#DDDD99] [r=0 c=3 rs=1 cs=1] + LayoutText {#text} at (47,0) size 45x14 + text run at (47,0) width 45: "<object>" + LayoutTableRow {TR} at (0,16) size 456x38 + LayoutTableCell {TH} at (1,86) size 63x14 [bgcolor=#DDDD99] [r=1 c=0 rs=4 cs=1] + LayoutText {#text} at (0,0) size 63x14 + text run at (0,0) width 63: "No viewBox" + LayoutTableCell {TH} at (65,35) size 110x0 [bgcolor=#DDDD99] [r=1 c=1 rs=1 cs=1] + LayoutTableCell {TD} at (176,16) size 139x38 [r=1 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (319,16) size 140x38 [r=1 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (316,16) size 139x38 [r=1 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,55) size 460x38 - LayoutTableCell {TH} at (66,67) size 111x14 [bgcolor=#DDDD99] [r=2 c=1 rs=1 cs=1] - LayoutText {#text} at (42,0) size 27x14 - text run at (42,0) width 27: "none" - LayoutTableCell {TD} at (178,55) size 140x38 [r=2 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,55) size 456x38 + LayoutTableCell {TH} at (65,67) size 110x14 [bgcolor=#DDDD99] [r=2 c=1 rs=1 cs=1] + LayoutText {#text} at (41,0) size 28x14 + text run at (41,0) width 28: "none" + LayoutTableCell {TD} at (176,55) size 139x38 [r=2 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (319,55) size 140x38 [r=2 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (316,55) size 139x38 [r=2 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,94) size 460x38 - LayoutTableCell {TH} at (66,106) size 111x14 [bgcolor=#DDDD99] [r=3 c=1 rs=1 cs=1] - LayoutText {#text} at (42,0) size 27x14 - text run at (42,0) width 27: "meet" - LayoutTableCell {TD} at (178,94) size 140x38 [r=3 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,94) size 456x38 + LayoutTableCell {TH} at (65,106) size 110x14 [bgcolor=#DDDD99] [r=3 c=1 rs=1 cs=1] + LayoutText {#text} at (42,0) size 26x14 + text run at (42,0) width 26: "meet" + LayoutTableCell {TD} at (176,94) size 139x38 [r=3 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (319,94) size 140x38 [r=3 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (316,94) size 139x38 [r=3 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,133) size 460x38 - LayoutTableCell {TH} at (66,145) size 111x14 [bgcolor=#DDDD99] [r=4 c=1 rs=1 cs=1] - LayoutText {#text} at (43,0) size 25x14 - text run at (43,0) width 25: "slice" - LayoutTableCell {TD} at (178,133) size 140x38 [r=4 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,133) size 456x38 + LayoutTableCell {TH} at (65,145) size 110x14 [bgcolor=#DDDD99] [r=4 c=1 rs=1 cs=1] + LayoutText {#text} at (43,0) size 24x14 + text run at (43,0) width 24: "slice" + LayoutTableCell {TD} at (176,133) size 139x38 [r=4 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (319,133) size 140x38 [r=4 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (316,133) size 139x38 [r=4 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,172) size 460x38 - LayoutTableCell {TH} at (1,242) size 64x14 [bgcolor=#DDDD99] [r=5 c=0 rs=4 cs=1] - LayoutText {#text} at (9,0) size 46x14 - text run at (9,0) width 46: "viewBox" - LayoutTableCell {TH} at (66,191) size 111x0 [bgcolor=#DDDD99] [r=5 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (178,172) size 140x38 [r=5 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,172) size 456x38 + LayoutTableCell {TH} at (1,242) size 63x14 [bgcolor=#DDDD99] [r=5 c=0 rs=4 cs=1] + LayoutText {#text} at (9,0) size 45x14 + text run at (9,0) width 45: "viewBox" + LayoutTableCell {TH} at (65,191) size 110x0 [bgcolor=#DDDD99] [r=5 c=1 rs=1 cs=1] + LayoutTableCell {TD} at (176,172) size 139x38 [r=5 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (319,172) size 140x38 [r=5 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (316,172) size 139x38 [r=5 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,211) size 460x38 - LayoutTableCell {TH} at (66,223) size 111x14 [bgcolor=#DDDD99] [r=6 c=1 rs=1 cs=1] - LayoutText {#text} at (42,0) size 27x14 - text run at (42,0) width 27: "none" - LayoutTableCell {TD} at (178,211) size 140x38 [r=6 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,211) size 456x38 + LayoutTableCell {TH} at (65,223) size 110x14 [bgcolor=#DDDD99] [r=6 c=1 rs=1 cs=1] + LayoutText {#text} at (41,0) size 28x14 + text run at (41,0) width 28: "none" + LayoutTableCell {TD} at (176,211) size 139x38 [r=6 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (319,211) size 140x38 [r=6 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (316,211) size 139x38 [r=6 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,250) size 460x38 - LayoutTableCell {TH} at (66,262) size 111x14 [bgcolor=#DDDD99] [r=7 c=1 rs=1 cs=1] - LayoutText {#text} at (42,0) size 27x14 - text run at (42,0) width 27: "meet" - LayoutTableCell {TD} at (178,250) size 140x38 [r=7 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,250) size 456x38 + LayoutTableCell {TH} at (65,262) size 110x14 [bgcolor=#DDDD99] [r=7 c=1 rs=1 cs=1] + LayoutText {#text} at (42,0) size 26x14 + text run at (42,0) width 26: "meet" + LayoutTableCell {TD} at (176,250) size 139x38 [r=7 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (319,250) size 140x38 [r=7 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (316,250) size 139x38 [r=7 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,289) size 460x38 - LayoutTableCell {TH} at (66,301) size 111x14 [bgcolor=#DDDD99] [r=8 c=1 rs=1 cs=1] - LayoutText {#text} at (43,0) size 25x14 - text run at (43,0) width 25: "slice" - LayoutTableCell {TD} at (178,289) size 140x38 [r=8 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,289) size 456x38 + LayoutTableCell {TH} at (65,301) size 110x14 [bgcolor=#DDDD99] [r=8 c=1 rs=1 cs=1] + LayoutText {#text} at (43,0) size 24x14 + text run at (43,0) width 24: "slice" + LayoutTableCell {TD} at (176,289) size 139x38 [r=8 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (319,289) size 140x38 [r=8 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (316,289) size 139x38 [r=8 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 -layer at (325,22) size 139x35 +layer at (322,22) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 layer at (0,0) size 133x29 LayoutSVGRoot {svg} at (0,0) size 133x29 LayoutSVGEllipse {circle} at (0,0) size 220x220 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [cx=110.00] [cy=110.00] [r=110.00] -layer at (325,61) size 139x35 +layer at (322,61) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -108,7 +108,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (325,100) size 139x35 +layer at (322,100) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -117,7 +117,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (325,139) size 139x35 +layer at (322,139) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -126,7 +126,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (325,178) size 139x35 +layer at (322,178) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -135,7 +135,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (325,217) size 139x35 +layer at (322,217) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -144,7 +144,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (325,256) size 139x35 +layer at (322,256) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -153,7 +153,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (325,295) size 139x35 +layer at (322,295) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png index f1843ef..79edb450 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt index 7aae683..a6523bb 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x199 LayoutBlockFlow {html} at (0,0) size 800x199.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x188 - LayoutTable {table} at (142.45,0) size 504x188 - LayoutTableSection (anonymous) at (0,0) size 504x188 - LayoutTableRow {tr} at (0,0) size 504x188 - LayoutTableCell {td} at (0,0) size 504x188 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 491x176 - LayoutTableSection (anonymous) at (0,0) size 491x176 - LayoutTableRow {tr} at (0,1) size 491x66 - LayoutTableCell {td} at (1,1) size 489x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 479x26 - LayoutText {#text} at (0,0) size 479x25 - text run at (0,0) width 479: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 491x24 - LayoutTableCell {td} at (1,68) size 244x24 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (95,5) size 54x14 - text run at (95,5) width 54: "SVG Image" - LayoutTableCell {td} at (246,68) size 244x24 [r=1 c=1 rs=1 cs=1] + LayoutTable {table} at (143.45,0) size 502x188 + LayoutTableSection (anonymous) at (0,0) size 502x188 + LayoutTableRow {tr} at (0,0) size 502x188 + LayoutTableCell {td} at (0,0) size 502x188 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 490x176 + LayoutTableSection (anonymous) at (0,0) size 490x176 + LayoutTableRow {tr} at (0,1) size 490x66 + LayoutTableCell {td} at (1,1) size 488x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 478x26 + LayoutText {#text} at (0,0) size 478x25 + text run at (0,0) width 478: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 490x24 + LayoutTableCell {td} at (1,68) size 243x24 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (94,5) size 55x14 + text run at (94,5) width 55: "SVG Image" + LayoutTableCell {td} at (245,68) size 244x24 [r=1 c=1 rs=1 cs=1] LayoutText {#text} at (95,5) size 54x14 text run at (95,5) width 54: "PNG Image" - LayoutTableRow {tr} at (0,93) size 491x82 - LayoutTableCell {td} at (1,93) size 244x82 [r=2 c=0 rs=1 cs=1] + LayoutTableRow {tr} at (0,93) size 490x82 + LayoutTableCell {td} at (1,93) size 243x82 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (246,93) size 244x82 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (245,93) size 244x82 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 138.88x69.44 LayoutText {#text} at (0,0) size 0x0 -layer at (257,110) size 139x69 - LayoutEmbeddedObject {object} at (100.13,5) size 138.88x69.44 +layer at (255,110) size 139x69 + LayoutEmbeddedObject {object} at (99.13,5) size 138.88x69.44 layer at (0,0) size 139x69 LayoutView at (0,0) size 139x69 layer at (0,0) size 139x69
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png index f1843ef..79edb450 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt index 7aae683..a6523bb 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x199 LayoutBlockFlow {html} at (0,0) size 800x199.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x188 - LayoutTable {table} at (142.45,0) size 504x188 - LayoutTableSection (anonymous) at (0,0) size 504x188 - LayoutTableRow {tr} at (0,0) size 504x188 - LayoutTableCell {td} at (0,0) size 504x188 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 491x176 - LayoutTableSection (anonymous) at (0,0) size 491x176 - LayoutTableRow {tr} at (0,1) size 491x66 - LayoutTableCell {td} at (1,1) size 489x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 479x26 - LayoutText {#text} at (0,0) size 479x25 - text run at (0,0) width 479: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 491x24 - LayoutTableCell {td} at (1,68) size 244x24 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (95,5) size 54x14 - text run at (95,5) width 54: "SVG Image" - LayoutTableCell {td} at (246,68) size 244x24 [r=1 c=1 rs=1 cs=1] + LayoutTable {table} at (143.45,0) size 502x188 + LayoutTableSection (anonymous) at (0,0) size 502x188 + LayoutTableRow {tr} at (0,0) size 502x188 + LayoutTableCell {td} at (0,0) size 502x188 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 490x176 + LayoutTableSection (anonymous) at (0,0) size 490x176 + LayoutTableRow {tr} at (0,1) size 490x66 + LayoutTableCell {td} at (1,1) size 488x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 478x26 + LayoutText {#text} at (0,0) size 478x25 + text run at (0,0) width 478: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 490x24 + LayoutTableCell {td} at (1,68) size 243x24 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (94,5) size 55x14 + text run at (94,5) width 55: "SVG Image" + LayoutTableCell {td} at (245,68) size 244x24 [r=1 c=1 rs=1 cs=1] LayoutText {#text} at (95,5) size 54x14 text run at (95,5) width 54: "PNG Image" - LayoutTableRow {tr} at (0,93) size 491x82 - LayoutTableCell {td} at (1,93) size 244x82 [r=2 c=0 rs=1 cs=1] + LayoutTableRow {tr} at (0,93) size 490x82 + LayoutTableCell {td} at (1,93) size 243x82 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (246,93) size 244x82 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (245,93) size 244x82 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 138.88x69.44 LayoutText {#text} at (0,0) size 0x0 -layer at (257,110) size 139x69 - LayoutEmbeddedObject {object} at (100.13,5) size 138.88x69.44 +layer at (255,110) size 139x69 + LayoutEmbeddedObject {object} at (99.13,5) size 138.88x69.44 layer at (0,0) size 139x69 LayoutView at (0,0) size 139x69 layer at (0,0) size 139x69
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png index c457613..e392a14 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt index 3db7cd7..1c465e5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x380 LayoutBlockFlow {html} at (0,0) size 800x380.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x369 - LayoutTable {table} at (41.45,0) size 706x369 - LayoutTableSection (anonymous) at (0,0) size 706x369 - LayoutTableRow {tr} at (0,0) size 706x369 - LayoutTableCell {td} at (0,0) size 706x369 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 693x357 - LayoutTableSection (anonymous) at (0,0) size 693x357 - LayoutTableRow {tr} at (0,1) size 693x66 - LayoutTableCell {td} at (1,1) size 691x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 681x26 - LayoutText {#text} at (101,0) size 479x25 - text run at (101,0) width 479: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 693x24 - LayoutTableCell {td} at (1,68) size 345x24 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (145,5) size 55x14 - text run at (145,5) width 55: "SVG Image" - LayoutTableCell {td} at (347,68) size 345x24 [r=1 c=1 rs=1 cs=1] - LayoutText {#text} at (145,5) size 55x14 - text run at (145,5) width 55: "PNG Image" - LayoutTableRow {tr} at (0,93) size 693x263 - LayoutTableCell {td} at (1,93) size 345x263 [r=2 c=0 rs=1 cs=1] + LayoutTable {table} at (42.95,0) size 703x369 + LayoutTableSection (anonymous) at (0,0) size 703x369 + LayoutTableRow {tr} at (0,0) size 703x369 + LayoutTableCell {td} at (0,0) size 703x369 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 691x357 + LayoutTableSection (anonymous) at (0,0) size 691x357 + LayoutTableRow {tr} at (0,1) size 691x66 + LayoutTableCell {td} at (1,1) size 689x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 679x26 + LayoutText {#text} at (100,0) size 479x25 + text run at (100,0) width 479: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 691x24 + LayoutTableCell {td} at (1,68) size 344x24 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (145,5) size 54x14 + text run at (145,5) width 54: "SVG Image" + LayoutTableCell {td} at (346,68) size 344x24 [r=1 c=1 rs=1 cs=1] + LayoutText {#text} at (145,5) size 54x14 + text run at (145,5) width 54: "PNG Image" + LayoutTableRow {tr} at (0,93) size 691x263 + LayoutTableCell {td} at (1,93) size 344x263 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (347,93) size 345x263 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (346,93) size 344x263 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 333.33x249.97 LayoutText {#text} at (0,0) size 0x0 -layer at (62,110) size 333x250 - LayoutEmbeddedObject {object} at (6.67,5) size 333.33x249.98 +layer at (61,110) size 333x250 + LayoutEmbeddedObject {object} at (5.67,5) size 333.33x249.98 layer at (0,0) size 333x250 LayoutView at (0,0) size 333x250 layer at (0,0) size 333x250
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/bugs/bug89315-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/bugs/bug89315-expected.png index 271c3887..a5b7ca3 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/bugs/bug89315-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/bugs/bug89315-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/bugs/bug89315-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/bugs/bug89315-expected.png index df6d6a4..ab10411 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/bugs/bug89315-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/bugs/bug89315-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png index d02e5887..ae6728a7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt index 078d1e9..643b704 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt
@@ -3,103 +3,103 @@ layer at (0,0) size 800x339 LayoutBlockFlow {HTML} at (0,0) size 800x339.09 LayoutBlockFlow {BODY} at (5.55,5.55) size 788.91x328 - LayoutTable {TABLE} at (0,0) size 462x328 - LayoutTableSection {TBODY} at (0,0) size 462x328 - LayoutTableRow {TR} at (0,1) size 462x14 - LayoutTableCell {TH} at (1,1) size 64x14 [bgcolor=#DDDD99] [r=0 c=0 rs=1 cs=1] - LayoutText {#text} at (6,0) size 52x14 - text run at (6,0) width 52: "viewBox?" - LayoutTableCell {TH} at (66,1) size 113x14 [bgcolor=#DDDD99] [r=0 c=1 rs=1 cs=1] - LayoutText {#text} at (0,0) size 113x14 - text run at (0,0) width 113: "preserve\x{AD}Aspect\x{AD}Ratio" - LayoutTableCell {TH} at (180,1) size 140x14 [bgcolor=#DDDD99] [r=0 c=2 rs=1 cs=1] - LayoutText {#text} at (53,0) size 34x14 - text run at (53,0) width 34: "<img>" - LayoutTableCell {TH} at (321,1) size 140x14 [bgcolor=#DDDD99] [r=0 c=3 rs=1 cs=1] - LayoutText {#text} at (47,0) size 46x14 - text run at (47,0) width 46: "<object>" - LayoutTableRow {TR} at (0,16) size 462x38 - LayoutTableCell {TH} at (1,86) size 64x14 [bgcolor=#DDDD99] [r=1 c=0 rs=4 cs=1] - LayoutText {#text} at (0,0) size 64x14 - text run at (0,0) width 64: "No viewBox" - LayoutTableCell {TH} at (66,35) size 113x0 [bgcolor=#DDDD99] [r=1 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (180,16) size 140x38 [r=1 c=2 rs=1 cs=1] + LayoutTable {TABLE} at (0,0) size 458x328 + LayoutTableSection {TBODY} at (0,0) size 458x328 + LayoutTableRow {TR} at (0,1) size 458x14 + LayoutTableCell {TH} at (1,1) size 63x14 [bgcolor=#DDDD99] [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (5,0) size 53x14 + text run at (5,0) width 53: "viewBox?" + LayoutTableCell {TH} at (65,1) size 112x14 [bgcolor=#DDDD99] [r=0 c=1 rs=1 cs=1] + LayoutText {#text} at (0,0) size 112x14 + text run at (0,0) width 112: "preserve\x{AD}Aspect\x{AD}Ratio" + LayoutTableCell {TH} at (178,1) size 139x14 [bgcolor=#DDDD99] [r=0 c=2 rs=1 cs=1] + LayoutText {#text} at (53,0) size 33x14 + text run at (53,0) width 33: "<img>" + LayoutTableCell {TH} at (318,1) size 139x14 [bgcolor=#DDDD99] [r=0 c=3 rs=1 cs=1] + LayoutText {#text} at (46,0) size 47x14 + text run at (46,0) width 47: "<object>" + LayoutTableRow {TR} at (0,16) size 458x38 + LayoutTableCell {TH} at (1,86) size 63x14 [bgcolor=#DDDD99] [r=1 c=0 rs=4 cs=1] + LayoutText {#text} at (0,0) size 63x14 + text run at (0,0) width 63: "No viewBox" + LayoutTableCell {TH} at (65,35) size 112x0 [bgcolor=#DDDD99] [r=1 c=1 rs=1 cs=1] + LayoutTableCell {TD} at (178,16) size 139x38 [r=1 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (321,16) size 140x38 [r=1 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (318,16) size 139x38 [r=1 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,55) size 462x38 - LayoutTableCell {TH} at (66,67) size 113x14 [bgcolor=#DDDD99] [r=2 c=1 rs=1 cs=1] - LayoutText {#text} at (43,0) size 27x14 - text run at (43,0) width 27: "none" - LayoutTableCell {TD} at (180,55) size 140x38 [r=2 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,55) size 458x38 + LayoutTableCell {TH} at (65,67) size 112x14 [bgcolor=#DDDD99] [r=2 c=1 rs=1 cs=1] + LayoutText {#text} at (42,0) size 28x14 + text run at (42,0) width 28: "none" + LayoutTableCell {TD} at (178,55) size 139x38 [r=2 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (321,55) size 140x38 [r=2 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (318,55) size 139x38 [r=2 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,94) size 462x38 - LayoutTableCell {TH} at (66,106) size 113x14 [bgcolor=#DDDD99] [r=3 c=1 rs=1 cs=1] - LayoutText {#text} at (43,0) size 27x14 - text run at (43,0) width 27: "meet" - LayoutTableCell {TD} at (180,94) size 140x38 [r=3 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,94) size 458x38 + LayoutTableCell {TH} at (65,106) size 112x14 [bgcolor=#DDDD99] [r=3 c=1 rs=1 cs=1] + LayoutText {#text} at (43,0) size 26x14 + text run at (43,0) width 26: "meet" + LayoutTableCell {TD} at (178,94) size 139x38 [r=3 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (321,94) size 140x38 [r=3 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (318,94) size 139x38 [r=3 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,133) size 462x38 - LayoutTableCell {TH} at (66,145) size 113x14 [bgcolor=#DDDD99] [r=4 c=1 rs=1 cs=1] - LayoutText {#text} at (44,0) size 25x14 - text run at (44,0) width 25: "slice" - LayoutTableCell {TD} at (180,133) size 140x38 [r=4 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,133) size 458x38 + LayoutTableCell {TH} at (65,145) size 112x14 [bgcolor=#DDDD99] [r=4 c=1 rs=1 cs=1] + LayoutText {#text} at (43,0) size 26x14 + text run at (43,0) width 26: "slice" + LayoutTableCell {TD} at (178,133) size 139x38 [r=4 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (321,133) size 140x38 [r=4 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (318,133) size 139x38 [r=4 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,172) size 462x38 - LayoutTableCell {TH} at (1,242) size 64x14 [bgcolor=#DDDD99] [r=5 c=0 rs=4 cs=1] - LayoutText {#text} at (9,0) size 46x14 - text run at (9,0) width 46: "viewBox" - LayoutTableCell {TH} at (66,191) size 113x0 [bgcolor=#DDDD99] [r=5 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (180,172) size 140x38 [r=5 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,172) size 458x38 + LayoutTableCell {TH} at (1,242) size 63x14 [bgcolor=#DDDD99] [r=5 c=0 rs=4 cs=1] + LayoutText {#text} at (8,0) size 47x14 + text run at (8,0) width 47: "viewBox" + LayoutTableCell {TH} at (65,191) size 112x0 [bgcolor=#DDDD99] [r=5 c=1 rs=1 cs=1] + LayoutTableCell {TD} at (178,172) size 139x38 [r=5 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (321,172) size 140x38 [r=5 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (318,172) size 139x38 [r=5 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,211) size 462x38 - LayoutTableCell {TH} at (66,223) size 113x14 [bgcolor=#DDDD99] [r=6 c=1 rs=1 cs=1] - LayoutText {#text} at (43,0) size 27x14 - text run at (43,0) width 27: "none" - LayoutTableCell {TD} at (180,211) size 140x38 [r=6 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,211) size 458x38 + LayoutTableCell {TH} at (65,223) size 112x14 [bgcolor=#DDDD99] [r=6 c=1 rs=1 cs=1] + LayoutText {#text} at (42,0) size 28x14 + text run at (42,0) width 28: "none" + LayoutTableCell {TD} at (178,211) size 139x38 [r=6 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (321,211) size 140x38 [r=6 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (318,211) size 139x38 [r=6 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,250) size 462x38 - LayoutTableCell {TH} at (66,262) size 113x14 [bgcolor=#DDDD99] [r=7 c=1 rs=1 cs=1] - LayoutText {#text} at (43,0) size 27x14 - text run at (43,0) width 27: "meet" - LayoutTableCell {TD} at (180,250) size 140x38 [r=7 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,250) size 458x38 + LayoutTableCell {TH} at (65,262) size 112x14 [bgcolor=#DDDD99] [r=7 c=1 rs=1 cs=1] + LayoutText {#text} at (43,0) size 26x14 + text run at (43,0) width 26: "meet" + LayoutTableCell {TD} at (178,250) size 139x38 [r=7 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (321,250) size 140x38 [r=7 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (318,250) size 139x38 [r=7 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,289) size 462x38 - LayoutTableCell {TH} at (66,301) size 113x14 [bgcolor=#DDDD99] [r=8 c=1 rs=1 cs=1] - LayoutText {#text} at (44,0) size 25x14 - text run at (44,0) width 25: "slice" - LayoutTableCell {TD} at (180,289) size 140x38 [r=8 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,289) size 458x38 + LayoutTableCell {TH} at (65,301) size 112x14 [bgcolor=#DDDD99] [r=8 c=1 rs=1 cs=1] + LayoutText {#text} at (43,0) size 26x14 + text run at (43,0) width 26: "slice" + LayoutTableCell {TD} at (178,289) size 139x38 [r=8 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (321,289) size 140x38 [r=8 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (318,289) size 139x38 [r=8 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 -layer at (327,22) size 139x35 +layer at (324,22) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 layer at (0,0) size 133x29 LayoutSVGRoot {svg} at (0,0) size 133x29 LayoutSVGEllipse {circle} at (0,0) size 220x220 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [cx=110.00] [cy=110.00] [r=110.00] -layer at (327,61) size 139x35 +layer at (324,61) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -108,7 +108,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,375.72) size 362.86x390.92 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,375.72) size 362.86x390.92 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (327,100) size 139x35 +layer at (324,100) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -117,7 +117,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,375.72) size 362.86x390.92 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,375.72) size 362.86x390.92 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (327,139) size 139x35 +layer at (324,139) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -126,7 +126,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,375.72) size 362.86x390.92 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,375.72) size 362.86x390.92 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (327,178) size 139x35 +layer at (324,178) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -135,7 +135,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,375.72) size 362.86x390.92 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,375.72) size 362.86x390.92 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (327,217) size 139x35 +layer at (324,217) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -144,7 +144,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,375.72) size 362.86x390.92 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,375.72) size 362.86x390.92 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (327,256) size 139x35 +layer at (324,256) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -153,7 +153,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,375.72) size 362.86x390.92 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,375.72) size 362.86x390.92 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (327,295) size 139x35 +layer at (324,295) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png index 517875e4..3edf887 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt index 69630f41..0a0a440 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x198 LayoutBlockFlow {html} at (0,0) size 800x198.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x187 - LayoutTable {table} at (141.45,0) size 506x187 - LayoutTableSection (anonymous) at (0,0) size 506x187 - LayoutTableRow {tr} at (0,0) size 506x187 - LayoutTableCell {td} at (0,0) size 506x187 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 493x175 - LayoutTableSection (anonymous) at (0,0) size 493x175 - LayoutTableRow {tr} at (0,1) size 493x66 - LayoutTableCell {td} at (1,1) size 491x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 481x26 - LayoutText {#text} at (0,0) size 481x26 - text run at (0,0) width 481: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 493x23 - LayoutTableCell {td} at (1,68) size 245x23 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (96,5) size 53x13 - text run at (96,5) width 53: "SVG Image" - LayoutTableCell {td} at (247,68) size 245x23 [r=1 c=1 rs=1 cs=1] + LayoutTable {table} at (142.45,0) size 504x187 + LayoutTableSection (anonymous) at (0,0) size 504x187 + LayoutTableRow {tr} at (0,0) size 504x187 + LayoutTableCell {td} at (0,0) size 504x187 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 492x175 + LayoutTableSection (anonymous) at (0,0) size 492x175 + LayoutTableRow {tr} at (0,1) size 492x66 + LayoutTableCell {td} at (1,1) size 490x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 480x26 + LayoutText {#text} at (0,0) size 480x26 + text run at (0,0) width 480: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 492x23 + LayoutTableCell {td} at (1,68) size 244x23 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (95,5) size 54x13 + text run at (95,5) width 54: "SVG Image" + LayoutTableCell {td} at (246,68) size 245x23 [r=1 c=1 rs=1 cs=1] LayoutText {#text} at (96,5) size 53x13 text run at (96,5) width 53: "PNG Image" - LayoutTableRow {tr} at (0,92) size 493x82 - LayoutTableCell {td} at (1,92) size 245x82 [r=2 c=0 rs=1 cs=1] + LayoutTableRow {tr} at (0,92) size 492x82 + LayoutTableCell {td} at (1,92) size 244x82 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (247,92) size 245x82 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (246,92) size 245x82 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 138.88x69.44 LayoutText {#text} at (0,0) size 0x0 -layer at (257,109) size 139x69 - LayoutEmbeddedObject {object} at (101.13,5) size 138.88x69.44 +layer at (255,109) size 139x69 + LayoutEmbeddedObject {object} at (100.13,5) size 138.88x69.44 layer at (0,0) size 139x69 LayoutView at (0,0) size 139x69 layer at (0,0) size 139x69
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png index 517875e4..3edf887 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt index 69630f41..0a0a440 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x198 LayoutBlockFlow {html} at (0,0) size 800x198.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x187 - LayoutTable {table} at (141.45,0) size 506x187 - LayoutTableSection (anonymous) at (0,0) size 506x187 - LayoutTableRow {tr} at (0,0) size 506x187 - LayoutTableCell {td} at (0,0) size 506x187 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 493x175 - LayoutTableSection (anonymous) at (0,0) size 493x175 - LayoutTableRow {tr} at (0,1) size 493x66 - LayoutTableCell {td} at (1,1) size 491x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 481x26 - LayoutText {#text} at (0,0) size 481x26 - text run at (0,0) width 481: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 493x23 - LayoutTableCell {td} at (1,68) size 245x23 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (96,5) size 53x13 - text run at (96,5) width 53: "SVG Image" - LayoutTableCell {td} at (247,68) size 245x23 [r=1 c=1 rs=1 cs=1] + LayoutTable {table} at (142.45,0) size 504x187 + LayoutTableSection (anonymous) at (0,0) size 504x187 + LayoutTableRow {tr} at (0,0) size 504x187 + LayoutTableCell {td} at (0,0) size 504x187 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 492x175 + LayoutTableSection (anonymous) at (0,0) size 492x175 + LayoutTableRow {tr} at (0,1) size 492x66 + LayoutTableCell {td} at (1,1) size 490x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 480x26 + LayoutText {#text} at (0,0) size 480x26 + text run at (0,0) width 480: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 492x23 + LayoutTableCell {td} at (1,68) size 244x23 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (95,5) size 54x13 + text run at (95,5) width 54: "SVG Image" + LayoutTableCell {td} at (246,68) size 245x23 [r=1 c=1 rs=1 cs=1] LayoutText {#text} at (96,5) size 53x13 text run at (96,5) width 53: "PNG Image" - LayoutTableRow {tr} at (0,92) size 493x82 - LayoutTableCell {td} at (1,92) size 245x82 [r=2 c=0 rs=1 cs=1] + LayoutTableRow {tr} at (0,92) size 492x82 + LayoutTableCell {td} at (1,92) size 244x82 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (247,92) size 245x82 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (246,92) size 245x82 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 138.88x69.44 LayoutText {#text} at (0,0) size 0x0 -layer at (257,109) size 139x69 - LayoutEmbeddedObject {object} at (101.13,5) size 138.88x69.44 +layer at (255,109) size 139x69 + LayoutEmbeddedObject {object} at (100.13,5) size 138.88x69.44 layer at (0,0) size 139x69 LayoutView at (0,0) size 139x69 layer at (0,0) size 139x69
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png index 3dcc236..9f1a7f4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt index 410b49f..62c9787 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x379 LayoutBlockFlow {html} at (0,0) size 800x379.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x368 - LayoutTable {table} at (41.45,0) size 706x368 - LayoutTableSection (anonymous) at (0,0) size 706x368 - LayoutTableRow {tr} at (0,0) size 706x368 - LayoutTableCell {td} at (0,0) size 706x368 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 693x356 - LayoutTableSection (anonymous) at (0,0) size 693x356 - LayoutTableRow {tr} at (0,1) size 693x66 - LayoutTableCell {td} at (1,1) size 691x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 681x26 - LayoutText {#text} at (100,0) size 481x26 - text run at (100,0) width 481: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 693x23 - LayoutTableCell {td} at (1,68) size 345x23 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (146,5) size 53x13 - text run at (146,5) width 53: "SVG Image" - LayoutTableCell {td} at (347,68) size 345x23 [r=1 c=1 rs=1 cs=1] - LayoutText {#text} at (146,5) size 53x13 - text run at (146,5) width 53: "PNG Image" - LayoutTableRow {tr} at (0,92) size 693x263 - LayoutTableCell {td} at (1,92) size 345x263 [r=2 c=0 rs=1 cs=1] + LayoutTable {table} at (42.95,0) size 703x368 + LayoutTableSection (anonymous) at (0,0) size 703x368 + LayoutTableRow {tr} at (0,0) size 703x368 + LayoutTableCell {td} at (0,0) size 703x368 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 691x356 + LayoutTableSection (anonymous) at (0,0) size 691x356 + LayoutTableRow {tr} at (0,1) size 691x66 + LayoutTableCell {td} at (1,1) size 689x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 679x26 + LayoutText {#text} at (99,0) size 481x26 + text run at (99,0) width 481: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 691x23 + LayoutTableCell {td} at (1,68) size 344x23 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (145,5) size 54x13 + text run at (145,5) width 54: "SVG Image" + LayoutTableCell {td} at (346,68) size 344x23 [r=1 c=1 rs=1 cs=1] + LayoutText {#text} at (145,5) size 54x13 + text run at (145,5) width 54: "PNG Image" + LayoutTableRow {tr} at (0,92) size 691x263 + LayoutTableCell {td} at (1,92) size 344x263 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (347,92) size 345x263 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (346,92) size 344x263 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 333.33x249.97 LayoutText {#text} at (0,0) size 0x0 -layer at (62,109) size 333x250 - LayoutEmbeddedObject {object} at (6.67,5) size 333.33x249.98 +layer at (61,109) size 333x250 + LayoutEmbeddedObject {object} at (5.67,5) size 333.33x249.98 layer at (0,0) size 333x250 LayoutView at (0,0) size 333x250 layer at (0,0) size 333x250
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug89315-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug89315-expected.png index e4bd464..25ce0999 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug89315-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug89315-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png index 8498b7f..66066ae 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt index b03fc463..46f326b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.txt
@@ -3,103 +3,103 @@ layer at (0,0) size 800x339 LayoutBlockFlow {HTML} at (0,0) size 800x339.09 LayoutBlockFlow {BODY} at (5.55,5.55) size 788.91x328 - LayoutTable {TABLE} at (0,0) size 467x328 - LayoutTableSection {TBODY} at (0,0) size 467x328 - LayoutTableRow {TR} at (0,1) size 467x14 - LayoutTableCell {TH} at (1,1) size 64x14 [bgcolor=#DDDD99] [r=0 c=0 rs=1 cs=1] - LayoutText {#text} at (5,0) size 54x14 - text run at (5,0) width 54: "viewBox?" - LayoutTableCell {TH} at (66,1) size 118x14 [bgcolor=#DDDD99] [r=0 c=1 rs=1 cs=1] - LayoutText {#text} at (0,0) size 118x14 - text run at (0,0) width 118: "preserve\x{AD}Aspect\x{AD}Ratio" - LayoutTableCell {TH} at (185,1) size 140x14 [bgcolor=#DDDD99] [r=0 c=2 rs=1 cs=1] - LayoutText {#text} at (53,0) size 34x14 - text run at (53,0) width 34: "<img>" - LayoutTableCell {TH} at (326,1) size 140x14 [bgcolor=#DDDD99] [r=0 c=3 rs=1 cs=1] - LayoutText {#text} at (47,0) size 46x14 - text run at (47,0) width 46: "<object>" - LayoutTableRow {TR} at (0,16) size 467x38 - LayoutTableCell {TH} at (1,86) size 64x14 [bgcolor=#DDDD99] [r=1 c=0 rs=4 cs=1] - LayoutText {#text} at (0,0) size 64x14 - text run at (0,0) width 64: "No viewBox" - LayoutTableCell {TH} at (66,35) size 118x0 [bgcolor=#DDDD99] [r=1 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (185,16) size 140x38 [r=1 c=2 rs=1 cs=1] + LayoutTable {TABLE} at (0,0) size 463x328 + LayoutTableSection {TBODY} at (0,0) size 463x328 + LayoutTableRow {TR} at (0,1) size 463x14 + LayoutTableCell {TH} at (1,1) size 63x14 [bgcolor=#DDDD99] [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (5,0) size 53x14 + text run at (5,0) width 53: "viewBox?" + LayoutTableCell {TH} at (65,1) size 117x14 [bgcolor=#DDDD99] [r=0 c=1 rs=1 cs=1] + LayoutText {#text} at (0,0) size 117x14 + text run at (0,0) width 117: "preserve\x{AD}Aspect\x{AD}Ratio" + LayoutTableCell {TH} at (183,1) size 139x14 [bgcolor=#DDDD99] [r=0 c=2 rs=1 cs=1] + LayoutText {#text} at (53,0) size 33x14 + text run at (53,0) width 33: "<img>" + LayoutTableCell {TH} at (323,1) size 139x14 [bgcolor=#DDDD99] [r=0 c=3 rs=1 cs=1] + LayoutText {#text} at (46,0) size 47x14 + text run at (46,0) width 47: "<object>" + LayoutTableRow {TR} at (0,16) size 463x38 + LayoutTableCell {TH} at (1,86) size 63x14 [bgcolor=#DDDD99] [r=1 c=0 rs=4 cs=1] + LayoutText {#text} at (0,0) size 63x14 + text run at (0,0) width 63: "No viewBox" + LayoutTableCell {TH} at (65,35) size 117x0 [bgcolor=#DDDD99] [r=1 c=1 rs=1 cs=1] + LayoutTableCell {TD} at (183,16) size 139x38 [r=1 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (326,16) size 140x38 [r=1 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (323,16) size 139x38 [r=1 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,55) size 467x38 - LayoutTableCell {TH} at (66,67) size 118x14 [bgcolor=#DDDD99] [r=2 c=1 rs=1 cs=1] - LayoutText {#text} at (45,0) size 28x14 - text run at (45,0) width 28: "none" - LayoutTableCell {TD} at (185,55) size 140x38 [r=2 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,55) size 463x38 + LayoutTableCell {TH} at (65,67) size 117x14 [bgcolor=#DDDD99] [r=2 c=1 rs=1 cs=1] + LayoutText {#text} at (44,0) size 29x14 + text run at (44,0) width 29: "none" + LayoutTableCell {TD} at (183,55) size 139x38 [r=2 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (326,55) size 140x38 [r=2 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (323,55) size 139x38 [r=2 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,94) size 467x38 - LayoutTableCell {TH} at (66,106) size 118x14 [bgcolor=#DDDD99] [r=3 c=1 rs=1 cs=1] - LayoutText {#text} at (44,0) size 30x14 - text run at (44,0) width 30: "meet" - LayoutTableCell {TD} at (185,94) size 140x38 [r=3 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,94) size 463x38 + LayoutTableCell {TH} at (65,106) size 117x14 [bgcolor=#DDDD99] [r=3 c=1 rs=1 cs=1] + LayoutText {#text} at (44,0) size 29x14 + text run at (44,0) width 29: "meet" + LayoutTableCell {TD} at (183,94) size 139x38 [r=3 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (326,94) size 140x38 [r=3 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (323,94) size 139x38 [r=3 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,133) size 467x38 - LayoutTableCell {TH} at (66,145) size 118x14 [bgcolor=#DDDD99] [r=4 c=1 rs=1 cs=1] - LayoutText {#text} at (46,0) size 26x14 - text run at (46,0) width 26: "slice" - LayoutTableCell {TD} at (185,133) size 140x38 [r=4 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,133) size 463x38 + LayoutTableCell {TH} at (65,145) size 117x14 [bgcolor=#DDDD99] [r=4 c=1 rs=1 cs=1] + LayoutText {#text} at (45,0) size 27x14 + text run at (45,0) width 27: "slice" + LayoutTableCell {TD} at (183,133) size 139x38 [r=4 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (326,133) size 140x38 [r=4 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (323,133) size 139x38 [r=4 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,172) size 467x38 - LayoutTableCell {TH} at (1,242) size 64x14 [bgcolor=#DDDD99] [r=5 c=0 rs=4 cs=1] - LayoutText {#text} at (9,0) size 46x14 - text run at (9,0) width 46: "viewBox" - LayoutTableCell {TH} at (66,191) size 118x0 [bgcolor=#DDDD99] [r=5 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (185,172) size 140x38 [r=5 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,172) size 463x38 + LayoutTableCell {TH} at (1,242) size 63x14 [bgcolor=#DDDD99] [r=5 c=0 rs=4 cs=1] + LayoutText {#text} at (8,0) size 47x14 + text run at (8,0) width 47: "viewBox" + LayoutTableCell {TH} at (65,191) size 117x0 [bgcolor=#DDDD99] [r=5 c=1 rs=1 cs=1] + LayoutTableCell {TD} at (183,172) size 139x38 [r=5 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (326,172) size 140x38 [r=5 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (323,172) size 139x38 [r=5 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,211) size 467x38 - LayoutTableCell {TH} at (66,223) size 118x14 [bgcolor=#DDDD99] [r=6 c=1 rs=1 cs=1] - LayoutText {#text} at (45,0) size 28x14 - text run at (45,0) width 28: "none" - LayoutTableCell {TD} at (185,211) size 140x38 [r=6 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,211) size 463x38 + LayoutTableCell {TH} at (65,223) size 117x14 [bgcolor=#DDDD99] [r=6 c=1 rs=1 cs=1] + LayoutText {#text} at (44,0) size 29x14 + text run at (44,0) width 29: "none" + LayoutTableCell {TD} at (183,211) size 139x38 [r=6 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (326,211) size 140x38 [r=6 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (323,211) size 139x38 [r=6 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,250) size 467x38 - LayoutTableCell {TH} at (66,262) size 118x14 [bgcolor=#DDDD99] [r=7 c=1 rs=1 cs=1] - LayoutText {#text} at (44,0) size 30x14 - text run at (44,0) width 30: "meet" - LayoutTableCell {TD} at (185,250) size 140x38 [r=7 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,250) size 463x38 + LayoutTableCell {TH} at (65,262) size 117x14 [bgcolor=#DDDD99] [r=7 c=1 rs=1 cs=1] + LayoutText {#text} at (44,0) size 29x14 + text run at (44,0) width 29: "meet" + LayoutTableCell {TD} at (183,250) size 139x38 [r=7 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (326,250) size 140x38 [r=7 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (323,250) size 139x38 [r=7 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableRow {TR} at (0,289) size 467x38 - LayoutTableCell {TH} at (66,301) size 118x14 [bgcolor=#DDDD99] [r=8 c=1 rs=1 cs=1] - LayoutText {#text} at (46,0) size 26x14 - text run at (46,0) width 26: "slice" - LayoutTableCell {TD} at (185,289) size 140x38 [r=8 c=2 rs=1 cs=1] + LayoutTableRow {TR} at (0,289) size 463x38 + LayoutTableCell {TH} at (65,301) size 117x14 [bgcolor=#DDDD99] [r=8 c=1 rs=1 cs=1] + LayoutText {#text} at (45,0) size 27x14 + text run at (45,0) width 27: "slice" + LayoutTableCell {TD} at (183,289) size 139x38 [r=8 c=2 rs=1 cs=1] LayoutImage {IMG} at (0,0) size 138.88x34.72 [border: (1.38px dashed #800000)] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {TD} at (326,289) size 140x38 [r=8 c=3 rs=1 cs=1] + LayoutTableCell {TD} at (323,289) size 139x38 [r=8 c=3 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 -layer at (332,22) size 139x35 +layer at (329,22) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 layer at (0,0) size 133x29 LayoutSVGRoot {svg} at (0,0) size 133x29 LayoutSVGEllipse {circle} at (0,0) size 220x220 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [cx=110.00] [cy=110.00] [r=110.00] -layer at (332,61) size 139x35 +layer at (329,61) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -108,7 +108,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (332,100) size 139x35 +layer at (329,100) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -117,7 +117,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (332,139) size 139x35 +layer at (329,139) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -126,7 +126,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (332,178) size 139x35 +layer at (329,178) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -135,7 +135,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (332,217) size 139x35 +layer at (329,217) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -144,7 +144,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (332,256) size 139x35 +layer at (329,256) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29 @@ -153,7 +153,7 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGContainer {g} at (162.86,403.79) size 362.86x362.86 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-162.36,-403.29)}] LayoutSVGPath {path} at (162.86,403.79) size 362.86x362.86 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#D9BB7A] [fill rule=EVEN-ODD]}] [data="M 525.714 585.219 A 181.429 181.429 0 1 1 162.857 585.219 A 181.429 181.429 0 1 1 525.714 585.219 Z"] -layer at (332,295) size 139x35 +layer at (329,295) size 139x35 LayoutEmbeddedObject {OBJECT} at (0,0) size 138.88x34.72 [border: (0.69px dashed #008000)] layer at (0,0) size 133x29 LayoutView at (0,0) size 133x29
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png index 809cddc..8c86f65 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt index 061d399..d2b6c58 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x199 LayoutBlockFlow {html} at (0,0) size 800x199.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x188 - LayoutTable {table} at (143.45,0) size 502x188 - LayoutTableSection (anonymous) at (0,0) size 502x188 - LayoutTableRow {tr} at (0,0) size 502x188 - LayoutTableCell {td} at (0,0) size 502x188 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 489x176 - LayoutTableSection (anonymous) at (0,0) size 489x176 - LayoutTableRow {tr} at (0,1) size 489x66 - LayoutTableCell {td} at (1,1) size 487x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 477x26 - LayoutText {#text} at (0,0) size 477x25 - text run at (0,0) width 477: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 489x24 - LayoutTableCell {td} at (1,68) size 243x24 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (96,5) size 51x14 - text run at (96,5) width 51: "SVG Image" - LayoutTableCell {td} at (245,68) size 243x24 [r=1 c=1 rs=1 cs=1] + LayoutTable {table} at (144.45,0) size 500x188 + LayoutTableSection (anonymous) at (0,0) size 500x188 + LayoutTableRow {tr} at (0,0) size 500x188 + LayoutTableCell {td} at (0,0) size 500x188 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 488x176 + LayoutTableSection (anonymous) at (0,0) size 488x176 + LayoutTableRow {tr} at (0,1) size 488x66 + LayoutTableCell {td} at (1,1) size 486x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 476x26 + LayoutText {#text} at (0,0) size 476x25 + text run at (0,0) width 476: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 488x24 + LayoutTableCell {td} at (1,68) size 242x24 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (96,5) size 50x14 + text run at (96,5) width 50: "SVG Image" + LayoutTableCell {td} at (244,68) size 243x24 [r=1 c=1 rs=1 cs=1] LayoutText {#text} at (95,5) size 53x14 text run at (95,5) width 53: "PNG Image" - LayoutTableRow {tr} at (0,93) size 489x82 - LayoutTableCell {td} at (1,93) size 243x82 [r=2 c=0 rs=1 cs=1] + LayoutTableRow {tr} at (0,93) size 488x82 + LayoutTableCell {td} at (1,93) size 242x82 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (245,93) size 243x82 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (244,93) size 243x82 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 138.88x69.44 LayoutText {#text} at (0,0) size 0x0 -layer at (257,110) size 139x69 - LayoutEmbeddedObject {object} at (99.13,5) size 138.88x69.44 +layer at (255,110) size 139x69 + LayoutEmbeddedObject {object} at (98.13,5) size 138.88x69.44 layer at (0,0) size 139x69 LayoutView at (0,0) size 139x69 layer at (0,0) size 139x69
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png index 809cddc..8c86f65 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt index 061d399..d2b6c58 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x199 LayoutBlockFlow {html} at (0,0) size 800x199.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x188 - LayoutTable {table} at (143.45,0) size 502x188 - LayoutTableSection (anonymous) at (0,0) size 502x188 - LayoutTableRow {tr} at (0,0) size 502x188 - LayoutTableCell {td} at (0,0) size 502x188 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 489x176 - LayoutTableSection (anonymous) at (0,0) size 489x176 - LayoutTableRow {tr} at (0,1) size 489x66 - LayoutTableCell {td} at (1,1) size 487x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 477x26 - LayoutText {#text} at (0,0) size 477x25 - text run at (0,0) width 477: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 489x24 - LayoutTableCell {td} at (1,68) size 243x24 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (96,5) size 51x14 - text run at (96,5) width 51: "SVG Image" - LayoutTableCell {td} at (245,68) size 243x24 [r=1 c=1 rs=1 cs=1] + LayoutTable {table} at (144.45,0) size 500x188 + LayoutTableSection (anonymous) at (0,0) size 500x188 + LayoutTableRow {tr} at (0,0) size 500x188 + LayoutTableCell {td} at (0,0) size 500x188 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 488x176 + LayoutTableSection (anonymous) at (0,0) size 488x176 + LayoutTableRow {tr} at (0,1) size 488x66 + LayoutTableCell {td} at (1,1) size 486x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 476x26 + LayoutText {#text} at (0,0) size 476x25 + text run at (0,0) width 476: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 488x24 + LayoutTableCell {td} at (1,68) size 242x24 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (96,5) size 50x14 + text run at (96,5) width 50: "SVG Image" + LayoutTableCell {td} at (244,68) size 243x24 [r=1 c=1 rs=1 cs=1] LayoutText {#text} at (95,5) size 53x14 text run at (95,5) width 53: "PNG Image" - LayoutTableRow {tr} at (0,93) size 489x82 - LayoutTableCell {td} at (1,93) size 243x82 [r=2 c=0 rs=1 cs=1] + LayoutTableRow {tr} at (0,93) size 488x82 + LayoutTableCell {td} at (1,93) size 242x82 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (245,93) size 243x82 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (244,93) size 243x82 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 138.88x69.44 LayoutText {#text} at (0,0) size 0x0 -layer at (257,110) size 139x69 - LayoutEmbeddedObject {object} at (99.13,5) size 138.88x69.44 +layer at (255,110) size 139x69 + LayoutEmbeddedObject {object} at (98.13,5) size 138.88x69.44 layer at (0,0) size 139x69 LayoutView at (0,0) size 139x69 layer at (0,0) size 139x69
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png index 8655d45..f31ff92b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt index 9ce1c95..c33d0b2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.txt
@@ -3,32 +3,32 @@ layer at (0,0) size 800x380 LayoutBlockFlow {html} at (0,0) size 800x380.09 LayoutBlockFlow {body} at (5.55,5.55) size 788.91x369 - LayoutTable {table} at (41.45,0) size 706x369 - LayoutTableSection (anonymous) at (0,0) size 706x369 - LayoutTableRow {tr} at (0,0) size 706x369 - LayoutTableCell {td} at (0,0) size 706x369 [r=0 c=0 rs=1 cs=3] - LayoutTable {table} at (7.44,6) size 693x357 - LayoutTableSection (anonymous) at (0,0) size 693x357 - LayoutTableRow {tr} at (0,1) size 693x66 - LayoutTableCell {td} at (1,1) size 691x65.75 [r=0 c=0 rs=1 cs=2] - LayoutBlockFlow {h1} at (5.55,19.88) size 681x26 - LayoutText {#text} at (102,0) size 477x25 - text run at (102,0) width 477: "Both sides should have identical size after zooming" - LayoutTableRow {tr} at (0,68) size 693x24 - LayoutTableCell {td} at (1,68) size 345x24 [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (147,5) size 51x14 - text run at (147,5) width 51: "SVG Image" - LayoutTableCell {td} at (347,68) size 345x24 [r=1 c=1 rs=1 cs=1] - LayoutText {#text} at (146,5) size 53x14 - text run at (146,5) width 53: "PNG Image" - LayoutTableRow {tr} at (0,93) size 693x263 - LayoutTableCell {td} at (1,93) size 345x263 [r=2 c=0 rs=1 cs=1] + LayoutTable {table} at (42.95,0) size 703x369 + LayoutTableSection (anonymous) at (0,0) size 703x369 + LayoutTableRow {tr} at (0,0) size 703x369 + LayoutTableCell {td} at (0,0) size 703x369 [r=0 c=0 rs=1 cs=3] + LayoutTable {table} at (6,6) size 691x357 + LayoutTableSection (anonymous) at (0,0) size 691x357 + LayoutTableRow {tr} at (0,1) size 691x66 + LayoutTableCell {td} at (1,1) size 689x65.75 [r=0 c=0 rs=1 cs=2] + LayoutBlockFlow {h1} at (5,19.88) size 679x26 + LayoutText {#text} at (101,0) size 477x25 + text run at (101,0) width 477: "Both sides should have identical size after zooming" + LayoutTableRow {tr} at (0,68) size 691x24 + LayoutTableCell {td} at (1,68) size 344x24 [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (147,5) size 50x14 + text run at (147,5) width 50: "SVG Image" + LayoutTableCell {td} at (346,68) size 344x24 [r=1 c=1 rs=1 cs=1] + LayoutText {#text} at (145,5) size 54x14 + text run at (145,5) width 54: "PNG Image" + LayoutTableRow {tr} at (0,93) size 691x263 + LayoutTableCell {td} at (1,93) size 344x263 [r=2 c=0 rs=1 cs=1] LayoutText {#text} at (0,0) size 0x0 - LayoutTableCell {td} at (347,93) size 345x263 [r=2 c=1 rs=1 cs=1] + LayoutTableCell {td} at (346,93) size 344x263 [r=2 c=1 rs=1 cs=1] LayoutImage {img} at (5,5) size 333.33x249.97 LayoutText {#text} at (0,0) size 0x0 -layer at (62,110) size 333x250 - LayoutEmbeddedObject {object} at (6.67,5) size 333.33x249.98 +layer at (61,110) size 333x250 + LayoutEmbeddedObject {object} at (5.67,5) size 333.33x249.98 layer at (0,0) size 333x250 LayoutView at (0,0) size 333x250 layer at (0,0) size 333x250
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug89315-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug89315-expected.png index cf2d15d9..68319184 100644 --- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug89315-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug89315-expected.png Binary files differ
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index 9450b3d..c8ed280 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1424,7 +1424,6 @@ "layout/ng/ng_min_max_content_size_test.cc", "layout/ng/ng_out_of_flow_layout_part_test.cc", "layout/ng/ng_relative_utils_test.cc", - "layout/ng/ng_space_utils_test.cc", "layout/shapes/BoxShapeTest.cpp", "layout/svg/LayoutSVGForeignObjectTest.cpp", "layout/svg/LayoutSVGRootTest.cpp",
diff --git a/third_party/WebKit/Source/core/html/HTMLElement.h b/third_party/WebKit/Source/core/html/HTMLElement.h index df14759..5f32c96 100644 --- a/third_party/WebKit/Source/core/html/HTMLElement.h +++ b/third_party/WebKit/Source/core/html/HTMLElement.h
@@ -25,6 +25,7 @@ #include "core/CoreExport.h" #include "core/dom/Element.h" +#include "platform/text/TextDirection.h" namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/BUILD.gn b/third_party/WebKit/Source/core/layout/BUILD.gn index 96034692..2ff5fdf2 100644 --- a/third_party/WebKit/Source/core/layout/BUILD.gn +++ b/third_party/WebKit/Source/core/layout/BUILD.gn
@@ -428,6 +428,7 @@ "ng/ng_min_max_content_size.h", "ng/ng_out_of_flow_layout_part.cc", "ng/ng_out_of_flow_layout_part.h", + "ng/ng_out_of_flow_positioned_descendant.h", "ng/ng_physical_box_fragment.cc", "ng/ng_physical_box_fragment.h", "ng/ng_physical_fragment.cc",
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp index bcd7d16..494e870 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -3885,7 +3885,7 @@ if (!prev->floating_objects_) return; - logical_left_offset += MarginLogicalLeft(); + logical_left_offset += MarginLineLeft(); const FloatingObjectSet& prev_set = prev->floating_objects_->Set(); FloatingObjectSetIterator prev_end = prev_set.end();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h index 7f2ed16..cfc70092 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.h +++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -595,9 +595,7 @@ bool make_visible_in_visual_viewport = true, ScrollBehavior = kScrollBehaviorAuto); - LayoutRectOutsets MarginBoxOutsets() const override { - return margin_box_outsets_; - } + LayoutRectOutsets MarginBoxOutsets() const { return margin_box_outsets_; } LayoutUnit MarginTop() const override { return margin_box_outsets_.Top(); } LayoutUnit MarginBottom() const override { return margin_box_outsets_.Bottom(); @@ -615,66 +613,21 @@ margin_box_outsets_.SetRight(margin); } - LayoutUnit MarginLogicalLeft() const { - return margin_box_outsets_.LogicalLeft(Style()->GetWritingMode()); - } - LayoutUnit MarginLogicalRight() const { - return margin_box_outsets_.LogicalRight(Style()->GetWritingMode()); - } - - LayoutUnit MarginBefore( - const ComputedStyle* override_style = nullptr) const final { - return margin_box_outsets_.Before( - (override_style ? override_style : Style())->GetWritingMode()); - } - LayoutUnit MarginAfter( - const ComputedStyle* override_style = nullptr) const final { - return margin_box_outsets_.After( - (override_style ? override_style : Style())->GetWritingMode()); - } - LayoutUnit MarginStart( - const ComputedStyle* override_style = nullptr) const final { - const ComputedStyle* style_to_use = - override_style ? override_style : Style(); - return margin_box_outsets_.Start(style_to_use->GetWritingMode(), - style_to_use->Direction()); - } - LayoutUnit MarginEnd( - const ComputedStyle* override_style = nullptr) const final { - const ComputedStyle* style_to_use = - override_style ? override_style : Style(); - return margin_box_outsets_.end(style_to_use->GetWritingMode(), - style_to_use->Direction()); - } - LayoutUnit MarginOver() const final { - return margin_box_outsets_.Over(Style()->GetWritingMode()); - } - LayoutUnit MarginUnder() const final { - return margin_box_outsets_.Under(Style()->GetWritingMode()); - } void SetMarginBefore(LayoutUnit value, const ComputedStyle* override_style = nullptr) { - margin_box_outsets_.SetBefore( - (override_style ? override_style : Style())->GetWritingMode(), value); + LogicalMarginToPhysicalSetter(override_style).SetBefore(value); } void SetMarginAfter(LayoutUnit value, const ComputedStyle* override_style = nullptr) { - margin_box_outsets_.SetAfter( - (override_style ? override_style : Style())->GetWritingMode(), value); + LogicalMarginToPhysicalSetter(override_style).SetAfter(value); } void SetMarginStart(LayoutUnit value, const ComputedStyle* override_style = nullptr) { - const ComputedStyle* style_to_use = - override_style ? override_style : Style(); - margin_box_outsets_.SetStart(style_to_use->GetWritingMode(), - style_to_use->Direction(), value); + LogicalMarginToPhysicalSetter(override_style).SetStart(value); } void SetMarginEnd(LayoutUnit value, const ComputedStyle* override_style = nullptr) { - const ComputedStyle* style_to_use = - override_style ? override_style : Style(); - margin_box_outsets_.SetEnd(style_to_use->GetWritingMode(), - style_to_use->Direction(), value); + LogicalMarginToPhysicalSetter(override_style).SetEnd(value); } // The following functions are used to implement collapsing margins. @@ -1679,6 +1632,15 @@ std::unique_ptr<BoxOverflowModel> overflow_; private: + LogicalToPhysicalSetter<LayoutUnit, LayoutBox> LogicalMarginToPhysicalSetter( + const ComputedStyle* override_style) { + const auto& style = override_style ? *override_style : StyleRef(); + return LogicalToPhysicalSetter<LayoutUnit, LayoutBox>( + style.GetWritingMode(), style.Direction(), *this, + &LayoutBox::SetMarginTop, &LayoutBox::SetMarginRight, + &LayoutBox::SetMarginBottom, &LayoutBox::SetMarginLeft); + } + // The inline box containing this LayoutBox, for atomic inline elements. InlineBox* inline_box_wrapper_;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h index d2c10a3..336fe78f 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
@@ -31,6 +31,7 @@ #include "core/layout/LayoutObject.h" #include "core/page/scrolling/StickyPositionScrollingConstraints.h" #include "platform/geometry/LayoutRect.h" +#include "platform/text/WritingModeUtils.h" #include "platform/wtf/PtrUtil.h" namespace blink { @@ -243,14 +244,15 @@ } virtual LayoutUnit PaddingLeft() const { return ComputedCSSPaddingLeft(); } virtual LayoutUnit PaddingRight() const { return ComputedCSSPaddingRight(); } - virtual LayoutUnit PaddingBefore() const { - return ComputedCSSPaddingBefore(); + + LayoutUnit PaddingBefore() const { + return PhysicalPaddingToLogical().Before(); } - virtual LayoutUnit PaddingAfter() const { return ComputedCSSPaddingAfter(); } - virtual LayoutUnit PaddingStart() const { return ComputedCSSPaddingStart(); } - virtual LayoutUnit PaddingEnd() const { return ComputedCSSPaddingEnd(); } - LayoutUnit PaddingOver() const { return ComputedCSSPaddingOver(); } - LayoutUnit PaddingUnder() const { return ComputedCSSPaddingUnder(); } + LayoutUnit PaddingAfter() const { return PhysicalPaddingToLogical().After(); } + LayoutUnit PaddingStart() const { return PhysicalPaddingToLogical().Start(); } + LayoutUnit PaddingEnd() const { return PhysicalPaddingToLogical().End(); } + LayoutUnit PaddingOver() const { return PhysicalPaddingToLogical().Over(); } + LayoutUnit PaddingUnder() const { return PhysicalPaddingToLogical().Under(); } virtual LayoutUnit BorderTop() const { return LayoutUnit(Style()->BorderTopWidth()); @@ -264,29 +266,18 @@ virtual LayoutUnit BorderRight() const { return LayoutUnit(Style()->BorderRightWidth()); } - virtual LayoutUnit BorderBefore() const { - return LayoutUnit(Style()->BorderBeforeWidth()); - } - virtual LayoutUnit BorderAfter() const { - return LayoutUnit(Style()->BorderAfterWidth()); - } - virtual LayoutUnit BorderStart() const { - return LayoutUnit(Style()->BorderStartWidth()); - } - virtual LayoutUnit BorderEnd() const { - return LayoutUnit(Style()->BorderEndWidth()); - } - LayoutUnit BorderOver() const { - return LayoutUnit(Style()->BorderOverWidth()); - } - LayoutUnit BorderUnder() const { - return LayoutUnit(Style()->BorderUnderWidth()); - } + + LayoutUnit BorderBefore() const { return PhysicalBorderToLogical().Before(); } + LayoutUnit BorderAfter() const { return PhysicalBorderToLogical().After(); } + LayoutUnit BorderStart() const { return PhysicalBorderToLogical().Start(); } + LayoutUnit BorderEnd() const { return PhysicalBorderToLogical().End(); } + LayoutUnit BorderOver() const { return PhysicalBorderToLogical().Over(); } + LayoutUnit BorderUnder() const { return PhysicalBorderToLogical().Under(); } LayoutUnit BorderWidth() const { return BorderLeft() + BorderRight(); } LayoutUnit BorderHeight() const { return BorderTop() + BorderBottom(); } - virtual LayoutRectOutsets BorderBoxOutsets() const { + LayoutRectOutsets BorderBoxOutsets() const { return LayoutRectOutsets(BorderTop(), BorderRight(), BorderBottom(), BorderLeft()); } @@ -367,21 +358,36 @@ BorderBefore() + BorderAfter(); } - virtual LayoutRectOutsets MarginBoxOutsets() const = 0; virtual LayoutUnit MarginTop() const = 0; virtual LayoutUnit MarginBottom() const = 0; virtual LayoutUnit MarginLeft() const = 0; virtual LayoutUnit MarginRight() const = 0; - virtual LayoutUnit MarginBefore( - const ComputedStyle* other_style = nullptr) const = 0; - virtual LayoutUnit MarginAfter( - const ComputedStyle* other_style = nullptr) const = 0; - virtual LayoutUnit MarginStart( - const ComputedStyle* other_style = nullptr) const = 0; - virtual LayoutUnit MarginEnd( - const ComputedStyle* other_style = nullptr) const = 0; - virtual LayoutUnit MarginOver() const = 0; - virtual LayoutUnit MarginUnder() const = 0; + + LayoutUnit MarginBefore(const ComputedStyle* other_style = nullptr) const { + return PhysicalMarginToLogical(other_style).Before(); + } + LayoutUnit MarginAfter(const ComputedStyle* other_style = nullptr) const { + return PhysicalMarginToLogical(other_style).After(); + } + LayoutUnit MarginStart(const ComputedStyle* other_style = nullptr) const { + return PhysicalMarginToLogical(other_style).Start(); + } + LayoutUnit MarginEnd(const ComputedStyle* other_style = nullptr) const { + return PhysicalMarginToLogical(other_style).End(); + } + LayoutUnit MarginLineLeft() const { + return PhysicalMarginToLogical(nullptr).LineLeft(); + } + LayoutUnit MarginLineRight() const { + return PhysicalMarginToLogical(nullptr).LineRight(); + } + LayoutUnit MarginOver() const { + return PhysicalMarginToLogical(nullptr).Over(); + } + LayoutUnit MarginUnder() const { + return PhysicalMarginToLogical(nullptr).Under(); + } + DISABLE_CFI_PERF LayoutUnit MarginHeight() const { return MarginTop() + MarginBottom(); } @@ -550,6 +556,32 @@ LayoutUnit ComputedCSSPadding(const Length&) const; bool IsBoxModelObject() const final { return true; } + PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject> + PhysicalPaddingToLogical() const { + return PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>( + StyleRef().GetWritingMode(), StyleRef().Direction(), *this, + &LayoutBoxModelObject::PaddingTop, &LayoutBoxModelObject::PaddingRight, + &LayoutBoxModelObject::PaddingBottom, + &LayoutBoxModelObject::PaddingLeft); + } + + PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject> + PhysicalMarginToLogical(const ComputedStyle* other_style) const { + const auto& style = other_style ? *other_style : StyleRef(); + return PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>( + style.GetWritingMode(), style.Direction(), *this, + &LayoutBoxModelObject::MarginTop, &LayoutBoxModelObject::MarginRight, + &LayoutBoxModelObject::MarginBottom, &LayoutBoxModelObject::MarginLeft); + } + + PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject> + PhysicalBorderToLogical() const { + return PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>( + StyleRef().GetWritingMode(), StyleRef().Direction(), *this, + &LayoutBoxModelObject::BorderTop, &LayoutBoxModelObject::BorderRight, + &LayoutBoxModelObject::BorderBottom, &LayoutBoxModelObject::BorderLeft); + } + LayoutBoxModelObjectRareData& EnsureRareData() { if (!rare_data_) rare_data_ = WTF::MakeUnique<LayoutBoxModelObjectRareData>();
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp index e053cf9..c034749 100644 --- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -822,11 +822,6 @@ return LayoutUnit(); } -LayoutRectOutsets LayoutInline::MarginBoxOutsets() const { - return LayoutRectOutsets(MarginTop(), MarginRight(), MarginBottom(), - MarginLeft()); -} - LayoutUnit LayoutInline::MarginLeft() const { return ComputeMargin(this, Style()->MarginLeft()); } @@ -843,34 +838,6 @@ return ComputeMargin(this, Style()->MarginBottom()); } -LayoutUnit LayoutInline::MarginStart(const ComputedStyle* other_style) const { - return ComputeMargin(this, StyleRef().MarginStartUsing( - other_style ? *other_style : StyleRef())); -} - -LayoutUnit LayoutInline::MarginEnd(const ComputedStyle* other_style) const { - return ComputeMargin( - this, StyleRef().MarginEndUsing(other_style ? *other_style : StyleRef())); -} - -LayoutUnit LayoutInline::MarginBefore(const ComputedStyle* other_style) const { - return ComputeMargin(this, StyleRef().MarginBeforeUsing( - other_style ? *other_style : StyleRef())); -} - -LayoutUnit LayoutInline::MarginAfter(const ComputedStyle* other_style) const { - return ComputeMargin(this, StyleRef().MarginAfterUsing( - other_style ? *other_style : StyleRef())); -} - -LayoutUnit LayoutInline::MarginOver() const { - return ComputeMargin(this, Style()->MarginOver()); -} - -LayoutUnit LayoutInline::MarginUnder() const { - return ComputeMargin(this, Style()->MarginUnder()); -} - bool LayoutInline::NodeAtPoint(HitTestResult& result, const HitTestLocation& location_in_container, const LayoutPoint& accumulated_offset,
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.h b/third_party/WebKit/Source/core/layout/LayoutInline.h index 3b3348b3..0ae88fee 100644 --- a/third_party/WebKit/Source/core/layout/LayoutInline.h +++ b/third_party/WebKit/Source/core/layout/LayoutInline.h
@@ -135,20 +135,10 @@ return ToElement(LayoutBoxModelObject::GetNode()); } - LayoutRectOutsets MarginBoxOutsets() const final; LayoutUnit MarginLeft() const final; LayoutUnit MarginRight() const final; LayoutUnit MarginTop() const final; LayoutUnit MarginBottom() const final; - LayoutUnit MarginBefore( - const ComputedStyle* other_style = nullptr) const final; - LayoutUnit MarginAfter( - const ComputedStyle* other_style = nullptr) const final; - LayoutUnit MarginStart( - const ComputedStyle* other_style = nullptr) const final; - LayoutUnit MarginEnd(const ComputedStyle* other_style = nullptr) const final; - LayoutUnit MarginOver() const final; - LayoutUnit MarginUnder() const final; void AbsoluteRects(Vector<IntRect>&, const LayoutPoint& accumulated_offset) const final;
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h index b654339..435e23c 100644 --- a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h +++ b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h
@@ -48,10 +48,6 @@ void UpdateLayout() override; // Scrollbar parts needs to be rendered at device pixel boundaries. - LayoutRectOutsets MarginBoxOutsets() const override { - DCHECK(IsIntegerValue(LayoutBlock::MarginBoxOutsets().Top())); - return LayoutBlock::MarginBoxOutsets(); - } LayoutUnit MarginTop() const override { DCHECK(IsIntegerValue(LayoutBlock::MarginTop())); return LayoutBlock::MarginTop(); @@ -102,10 +98,6 @@ LayoutUnit PaddingBottom() const override { return LayoutUnit(); } LayoutUnit PaddingLeft() const override { return LayoutUnit(); } LayoutUnit PaddingRight() const override { return LayoutUnit(); } - LayoutUnit PaddingBefore() const override { return LayoutUnit(); } - LayoutUnit PaddingAfter() const override { return LayoutUnit(); } - LayoutUnit PaddingStart() const override { return LayoutUnit(); } - LayoutUnit PaddingEnd() const override { return LayoutUnit(); } void LayoutHorizontalPart(); void LayoutVerticalPart();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp index 5e01302..7533848 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -1135,36 +1135,36 @@ needs_section_recalc_ = false; } -LayoutUnit LayoutTable::BorderBefore() const { +LayoutUnit LayoutTable::BorderLeft() const { if (ShouldCollapseBorders()) { UpdateCollapsedOuterBorders(); - return LayoutUnit(collapsed_outer_border_before_); + return LayoutUnit(LogicalCollapsedOuterBorderToPhysical().Left()); } - return LayoutUnit(LayoutBlock::BorderBefore().ToInt()); + return LayoutUnit(LayoutBlock::BorderLeft().ToInt()); } -LayoutUnit LayoutTable::BorderAfter() const { +LayoutUnit LayoutTable::BorderRight() const { if (ShouldCollapseBorders()) { UpdateCollapsedOuterBorders(); - return LayoutUnit(collapsed_outer_border_after_); + return LayoutUnit(LogicalCollapsedOuterBorderToPhysical().Right()); } - return LayoutUnit(LayoutBlock::BorderAfter().ToInt()); + return LayoutUnit(LayoutBlock::BorderRight().ToInt()); } -LayoutUnit LayoutTable::BorderStart() const { +LayoutUnit LayoutTable::BorderTop() const { if (ShouldCollapseBorders()) { UpdateCollapsedOuterBorders(); - return LayoutUnit(collapsed_outer_border_start_); + return LayoutUnit(LogicalCollapsedOuterBorderToPhysical().Top()); } - return LayoutUnit(LayoutBlock::BorderStart().ToInt()); + return LayoutUnit(LayoutBlock::BorderTop().ToInt()); } -LayoutUnit LayoutTable::BorderEnd() const { +LayoutUnit LayoutTable::BorderBottom() const { if (ShouldCollapseBorders()) { UpdateCollapsedOuterBorders(); - return LayoutUnit(collapsed_outer_border_end_); + return LayoutUnit(LogicalCollapsedOuterBorderToPhysical().Bottom()); } - return LayoutUnit(LayoutBlock::BorderEnd().ToInt()); + return LayoutUnit(LayoutBlock::BorderBottom().ToInt()); } LayoutTableSection* LayoutTable::SectionAbove( @@ -1512,28 +1512,36 @@ if (ShouldCollapseBorders()) return LayoutUnit(); - return LayoutBlock::PaddingTop(); + // TODO(crbug.com/377847): The ToInt call should be removed when Table is + // sub-pixel aware. + return LayoutUnit(LayoutBlock::PaddingTop().ToInt()); } LayoutUnit LayoutTable::PaddingBottom() const { if (ShouldCollapseBorders()) return LayoutUnit(); - return LayoutBlock::PaddingBottom(); + // TODO(crbug.com/377847): The ToInt call should be removed when Table is + // sub-pixel aware. + return LayoutUnit(LayoutBlock::PaddingBottom().ToInt()); } LayoutUnit LayoutTable::PaddingLeft() const { if (ShouldCollapseBorders()) return LayoutUnit(); - return LayoutBlock::PaddingLeft(); + // TODO(crbug.com/377847): The ToInt call should be removed when Table is + // sub-pixel aware. + return LayoutUnit(LayoutBlock::PaddingLeft().ToInt()); } LayoutUnit LayoutTable::PaddingRight() const { if (ShouldCollapseBorders()) return LayoutUnit(); - return LayoutBlock::PaddingRight(); + // TODO(crbug.com/377847): The ToInt call should be removed when Table is + // sub-pixel aware. + return LayoutUnit(LayoutBlock::PaddingRight().ToInt()); } unsigned LayoutTable::ComputeCollapsedOuterBorderBefore() const {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.h b/third_party/WebKit/Source/core/layout/LayoutTable.h index 9cf82f5..f7f0035 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTable.h +++ b/third_party/WebKit/Source/core/layout/LayoutTable.h
@@ -148,38 +148,10 @@ return Style()->BorderCollapse() == EBorderCollapse::kCollapse; } - LayoutUnit BorderStart() const override; - LayoutUnit BorderEnd() const override; - LayoutUnit BorderBefore() const override; - LayoutUnit BorderAfter() const override; - - LayoutUnit BorderLeft() const override { - if (Style()->IsHorizontalWritingMode()) - return Style()->IsLeftToRightDirection() ? BorderStart() : BorderEnd(); - return Style()->IsFlippedBlocksWritingMode() ? BorderAfter() - : BorderBefore(); - } - - LayoutUnit BorderRight() const override { - if (Style()->IsHorizontalWritingMode()) - return Style()->IsLeftToRightDirection() ? BorderEnd() : BorderStart(); - return Style()->IsFlippedBlocksWritingMode() ? BorderBefore() - : BorderAfter(); - } - - LayoutUnit BorderTop() const override { - if (Style()->IsHorizontalWritingMode()) - return Style()->IsFlippedBlocksWritingMode() ? BorderAfter() - : BorderBefore(); - return Style()->IsLeftToRightDirection() ? BorderStart() : BorderEnd(); - } - - LayoutUnit BorderBottom() const override { - if (Style()->IsHorizontalWritingMode()) - return Style()->IsFlippedBlocksWritingMode() ? BorderBefore() - : BorderAfter(); - return Style()->IsLeftToRightDirection() ? BorderEnd() : BorderStart(); - } + LayoutUnit BorderLeft() const override; + LayoutUnit BorderRight() const override; + LayoutUnit BorderTop() const override; + LayoutUnit BorderBottom() const override; void AddChild(LayoutObject* child, LayoutObject* before_child = nullptr) override; @@ -295,15 +267,6 @@ LayoutUnit PaddingLeft() const override; LayoutUnit PaddingRight() const override; - // Override paddingStart/End to return pixel values to match behavor of - // LayoutTableCell. - LayoutUnit PaddingEnd() const override { - return LayoutUnit(LayoutBlock::PaddingEnd().ToInt()); - } - LayoutUnit PaddingStart() const override { - return LayoutUnit(LayoutBlock::PaddingStart().ToInt()); - } - LayoutUnit BordersPaddingAndSpacingInRowDirection() const { // 'border-spacing' only applies to separate borders (see 17.6.1 The // separated borders model). @@ -590,6 +553,13 @@ return NumEffectiveColumns(); } + LogicalToPhysical<unsigned> LogicalCollapsedOuterBorderToPhysical() const { + return LogicalToPhysical<unsigned>( + StyleRef().GetWritingMode(), StyleRef().Direction(), + collapsed_outer_border_start_, collapsed_outer_border_end_, + collapsed_outer_border_before_, collapsed_outer_border_after_); + } + short h_spacing_; short v_spacing_;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp index a749b9a9..da78da84 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
@@ -322,56 +322,34 @@ LayoutUnit LayoutTableCell::PaddingTop() const { LayoutUnit result = ComputedCSSPaddingTop(); - if (IsHorizontalWritingMode()) - result += (blink::IsHorizontalWritingMode(Style()->GetWritingMode()) - ? IntrinsicPaddingBefore() - : IntrinsicPaddingAfter()); - // TODO(leviw): The floor call should be removed when Table is sub-pixel - // aware. crbug.com/377847 - return LayoutUnit(result.Floor()); + result += LogicalIntrinsicPaddingToPhysical().Top(); + // TODO(crbug.com/377847): The ToInt call should be removed when Table is + // sub-pixel aware. + return LayoutUnit(result.ToInt()); } LayoutUnit LayoutTableCell::PaddingBottom() const { LayoutUnit result = ComputedCSSPaddingBottom(); - if (IsHorizontalWritingMode()) - result += (blink::IsHorizontalWritingMode(Style()->GetWritingMode()) - ? IntrinsicPaddingAfter() - : IntrinsicPaddingBefore()); - // TODO(leviw): The floor call should be removed when Table is sub-pixel - // aware. crbug.com/377847 - return LayoutUnit(result.Floor()); + result += LogicalIntrinsicPaddingToPhysical().Bottom(); + // TODO(crbug.com/377847): The ToInt call should be removed when Table is + // sub-pixel aware. + return LayoutUnit(result.ToInt()); } LayoutUnit LayoutTableCell::PaddingLeft() const { LayoutUnit result = ComputedCSSPaddingLeft(); - if (!IsHorizontalWritingMode()) - result += (IsFlippedLinesWritingMode(Style()->GetWritingMode()) - ? IntrinsicPaddingBefore() - : IntrinsicPaddingAfter()); - // TODO(leviw): The floor call should be removed when Table is sub-pixel - // aware. crbug.com/377847 - return LayoutUnit(result.Floor()); + result += LogicalIntrinsicPaddingToPhysical().Left(); + // TODO(crbug.com/377847): The ToInt call should be removed when Table is + // sub-pixel aware. + return LayoutUnit(result.ToInt()); } LayoutUnit LayoutTableCell::PaddingRight() const { LayoutUnit result = ComputedCSSPaddingRight(); - if (!IsHorizontalWritingMode()) - result += (IsFlippedLinesWritingMode(Style()->GetWritingMode()) - ? IntrinsicPaddingAfter() - : IntrinsicPaddingBefore()); - // TODO(leviw): The floor call should be removed when Table is sub-pixel - // aware. crbug.com/377847 - return LayoutUnit(result.Floor()); -} - -LayoutUnit LayoutTableCell::PaddingBefore() const { - return LayoutUnit(ComputedCSSPaddingBefore().Floor() + - IntrinsicPaddingBefore()); -} - -LayoutUnit LayoutTableCell::PaddingAfter() const { - return LayoutUnit(ComputedCSSPaddingAfter().Floor() + - IntrinsicPaddingAfter()); + result += LogicalIntrinsicPaddingToPhysical().Right(); + // TODO(crbug.com/377847): The ToInt call should be removed when Table is + // sub-pixel aware. + return LayoutUnit(result.ToInt()); } void LayoutTableCell::SetOverrideLogicalContentHeightFromRowHeight( @@ -1056,33 +1034,6 @@ : LayoutBlockFlow::BorderBottom(); } -// FIXME: https://bugs.webkit.org/show_bug.cgi?id=46191, make the collapsed -// border drawing work with different block flow values instead of being -// hard-coded to top-to-bottom. -LayoutUnit LayoutTableCell::BorderStart() const { - return Table()->ShouldCollapseBorders() - ? LayoutUnit(CollapsedBorderHalfStart(false)) - : LayoutBlockFlow::BorderStart(); -} - -LayoutUnit LayoutTableCell::BorderEnd() const { - return Table()->ShouldCollapseBorders() - ? LayoutUnit(CollapsedBorderHalfEnd(false)) - : LayoutBlockFlow::BorderEnd(); -} - -LayoutUnit LayoutTableCell::BorderBefore() const { - return Table()->ShouldCollapseBorders() - ? LayoutUnit(CollapsedBorderHalfBefore(false)) - : LayoutBlockFlow::BorderBefore(); -} - -LayoutUnit LayoutTableCell::BorderAfter() const { - return Table()->ShouldCollapseBorders() - ? LayoutUnit(CollapsedBorderHalfAfter(false)) - : LayoutBlockFlow::BorderAfter(); -} - unsigned LayoutTableCell::CollapsedBorderHalfStart(bool outer) const { UpdateCollapsedBorderValues(); const auto* collapsed_border_values = this->GetCollapsedBorderValues();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.h b/third_party/WebKit/Source/core/layout/LayoutTableCell.h index 72a17e8..06c189f8 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableCell.h +++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.h
@@ -182,10 +182,6 @@ LayoutUnit BorderRight() const override; LayoutUnit BorderTop() const override; LayoutUnit BorderBottom() const override; - LayoutUnit BorderStart() const override; - LayoutUnit BorderEnd() const override; - LayoutUnit BorderBefore() const override; - LayoutUnit BorderAfter() const override; void UpdateLayout() override; @@ -217,13 +213,6 @@ LayoutUnit PaddingLeft() const override; LayoutUnit PaddingRight() const override; - // FIXME: For now we just assume the cell has the same block flow direction as - // the table. It's likely we'll create an extra anonymous LayoutBlock to - // handle mixing directionality anyway, in which case we can lock the block - // flow directionality of the cells to the table's directionality. - LayoutUnit PaddingBefore() const override; - LayoutUnit PaddingAfter() const override; - void SetOverrideLogicalContentHeightFromRowHeight(LayoutUnit); void ScrollbarsChanged(bool horizontal_scrollbar_changed, @@ -360,6 +349,8 @@ void ComputeOverflow(LayoutUnit old_client_after_edge, bool recompute_floats = false) override; + // Converts collapsed border half width from the table's logical orientation + // to physical orientation. LogicalToPhysical<unsigned> LogicalCollapsedBorderHalfToPhysical( bool outer) const { return LogicalToPhysical<unsigned>( @@ -388,6 +379,11 @@ unsigned CollapsedBorderHalfBefore(bool outer) const; unsigned CollapsedBorderHalfAfter(bool outer) const; + LogicalToPhysical<int> LogicalIntrinsicPaddingToPhysical() const { + return LogicalToPhysical<int>( + StyleRef().GetWritingMode(), StyleRef().Direction(), 0, 0, + intrinsic_padding_before_, intrinsic_padding_after_); + } void SetIntrinsicPaddingBefore(int p) { intrinsic_padding_before_ = p; } void SetIntrinsicPaddingAfter(int p) { intrinsic_padding_after_ = p; } void SetIntrinsicPadding(int before, int after) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp index 2781377..109d8eb6 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp
@@ -203,6 +203,25 @@ EXPECT_EQ(999999, table->OffsetWidth()); } +TEST_F(LayoutTableTest, PaddingWithCollapsedBorder) { + SetBodyInnerHTML( + "<table id='table' style='padding: 20px; border-collapse: collapse'>" + " <tr><td>TD</td</tr>" + "</table>"); + + auto* table = GetTableByElementId("table"); + EXPECT_EQ(0, table->PaddingLeft()); + EXPECT_EQ(0, table->PaddingRight()); + EXPECT_EQ(0, table->PaddingTop()); + EXPECT_EQ(0, table->PaddingBottom()); + EXPECT_EQ(0, table->PaddingStart()); + EXPECT_EQ(0, table->PaddingEnd()); + EXPECT_EQ(0, table->PaddingBefore()); + EXPECT_EQ(0, table->PaddingAfter()); + EXPECT_EQ(0, table->PaddingOver()); + EXPECT_EQ(0, table->PaddingUnder()); +} + } // anonymous namespace } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp index a06265e..90e423e6 100644 --- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp +++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -963,7 +963,7 @@ // actually the opposite shadow that applies, since the line is "upside down" // in terms of block coordinates. LayoutRectOutsets logical_outsets( - outsets.LogicalOutsetsWithFlippedLines(writing_mode)); + outsets.LineOrientationOutsetsWithFlippedLines(writing_mode)); LayoutRect shadow_bounds(LogicalFrameRect()); shadow_bounds.Expand(logical_outsets); @@ -987,7 +987,7 @@ // actually the opposite border that applies, since the line is "upside down" // in terms of block coordinates. vertical-rl is the flipped line mode. LayoutRectOutsets logical_outsets = - style.BorderImageOutsets().LogicalOutsetsWithFlippedLines( + style.BorderImageOutsets().LineOrientationOutsetsWithFlippedLines( style.GetWritingMode()); if (!IncludeLogicalLeftEdge()) @@ -1066,10 +1066,11 @@ std::min(0.0f, style.GetFont().GetFontDescription().LetterSpacing()); LayoutRectOutsets text_shadow_logical_outsets; - if (ShadowList* text_shadow = style.TextShadow()) + if (ShadowList* text_shadow = style.TextShadow()) { text_shadow_logical_outsets = LayoutRectOutsets(text_shadow->RectOutsetsIncludingOriginal()) - .LogicalOutsets(style.GetWritingMode()); + .LineOrientationOutsets(style.GetWritingMode()); + } // FIXME: This code currently uses negative values for expansion of the top // and left edges. This should be cleaned up.
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc index 7c62132..01b1c7f 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -201,10 +201,10 @@ container_builder_.AddOutOfFlowDescendant( // Absolute positioning blockifies the box's display type. // https://drafts.csswg.org/css-display/#transformations - NGBlockNode(ToLayoutBox(item.GetLayoutObject())), - NGStaticPosition::Create(ConstraintSpace().WritingMode(), - ConstraintSpace().Direction(), - NGPhysicalOffset())); + {NGBlockNode(ToLayoutBox(item.GetLayoutObject())), + NGStaticPosition::Create(ConstraintSpace().WritingMode(), + ConstraintSpace().Direction(), + NGPhysicalOffset())}); continue; } else { continue;
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc index efdb2e3..f50fa2c 100644 --- a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc +++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
@@ -41,9 +41,9 @@ SetLogicalTop(computed_values.position_); } - for (NGBlockNode descendant : result->OutOfFlowDescendants()) - descendant.UseOldOutOfFlowPositioning(); - + for (NGOutOfFlowPositionedDescendant descendant : + result->OutOfFlowPositionedDescendants()) + descendant.node.UseOldOutOfFlowPositioning(); } NGInlineNodeData& LayoutNGBlockFlow::GetNGInlineNodeData() const {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc index 45688101..846f71d 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -450,17 +450,19 @@ if (child.CreatesNewFormattingContext()) child_bfc_offset = PositionNewFc(child, previous_inflow_position, fragment, child_data, child_space); - else if (fragment.BfcOffset()) - child_bfc_offset = PositionWithBfcOffset(fragment); + else if (layout_result->BfcOffset()) + child_bfc_offset = + PositionWithBfcOffset(layout_result->BfcOffset().value()); else if (container_builder_.BfcOffset()) - child_bfc_offset = PositionWithParentBfc(child_space, child_data, fragment); + child_bfc_offset = + PositionWithParentBfc(child_space, child_data, *layout_result); else DCHECK(!fragment.BlockSize()); NGLogicalOffset logical_offset = CalculateLogicalOffset(child_data.margins, child_bfc_offset); - NGMarginStrut margin_strut = fragment.EndMarginStrut(); + NGMarginStrut margin_strut = layout_result->EndMarginStrut(); margin_strut.Append(child_data.margins.block_end); // Only modify content_size_ if the fragment's BlockSize is not empty. This is @@ -485,9 +487,9 @@ LayoutUnit logical_block_offset; if (child_bfc_offset) { - // TODO(crbug.com/716930): I think the fragment.BfcOffset() condition here - // can be removed once we've removed inline splitting. - if (fragment.BlockSize() || fragment.BfcOffset()) { + // TODO(crbug.com/716930): I think the layout_result->BfcOffset() condition + // here can be removed once we've removed inline splitting. + if (fragment.BlockSize() || layout_result->BfcOffset()) { child_end_bfc_block_offset = child_bfc_offset.value().block_offset + fragment.BlockSize(); logical_block_offset = logical_offset.block_offset + fragment.BlockSize(); @@ -568,23 +570,23 @@ } NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithBfcOffset( - const NGBoxFragment& fragment) { - DCHECK(fragment.BfcOffset()); - LayoutUnit bfc_block_offset = fragment.BfcOffset().value().block_offset; + const NGLogicalOffset& bfc_offset) { + LayoutUnit bfc_block_offset = bfc_offset.block_offset; MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_block_offset, &container_builder_); PositionPendingFloats(bfc_block_offset, &container_builder_, MutableConstraintSpace()); - return fragment.BfcOffset().value(); + return bfc_offset; } NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc( const NGConstraintSpace& space, const NGInflowChildData& child_data, - const NGBoxFragment& fragment) { + const NGLayoutResult& layout_result) { // The child must be an in-flow zero-block-size fragment, use its end margin // strut for positioning. - DCHECK(!fragment.BfcOffset()); + NGFragment fragment(ConstraintSpace().WritingMode(), + layout_result.PhysicalFragment().Get()); DCHECK_EQ(fragment.BlockSize(), LayoutUnit()); NGLogicalOffset child_bfc_offset = { @@ -592,7 +594,7 @@ border_scrollbar_padding_.inline_start + child_data.margins.inline_start, child_data.bfc_offset_estimate.block_offset + - fragment.EndMarginStrut().Sum()}; + layout_result.EndMarginStrut().Sum()}; AdjustToClearance(space.ClearanceOffset(), &child_bfc_offset); PositionPendingFloatsFromOffset(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h index 1e1a584..f93787e1 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -94,7 +94,7 @@ const NGConstraintSpace& child_space); // Positions the fragment that knows its BFC offset. - NGLogicalOffset PositionWithBfcOffset(const NGBoxFragment&); + NGLogicalOffset PositionWithBfcOffset(const NGLogicalOffset& bfc_offset); // Positions using the parent BFC offset. // Fragment doesn't know its offset but we can still calculate its BFC @@ -105,7 +105,7 @@ // <div id="empty-div" style="margins: 1px"></div> NGLogicalOffset PositionWithParentBfc(const NGConstraintSpace&, const NGInflowChildData& child_data, - const NGBoxFragment&); + const NGLayoutResult&); NGLogicalOffset PositionLegacy(const NGConstraintSpace& child_space, const NGInflowChildData& child_data);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc index ba2499a3..b2761b84 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -407,15 +407,12 @@ // Margins are collapsed with the result 200 = std::max(20, 200) // The fragment size 258 == body's margin 8 + child's height 50 + 200 EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(258)), fragment->Size()); - EXPECT_EQ(NGMarginStrut({LayoutUnit(200)}), - container_fragment->EndMarginStrut()); // height == fixed run_test(Length(50, kFixed)); // Margins are not collapsed, so fragment still has margins == 20. // The fragment size 78 == body's margin 8 + child's height 50 + 20 EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(78)), fragment->Size()); - EXPECT_EQ(NGMarginStrut(), container_fragment->EndMarginStrut()); } // Verifies that 2 adjoining margins are not collapsed if there is padding or
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.cc index 1d51f39..99db6d8 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.cc
@@ -15,19 +15,4 @@ return physical_fragment->OverflowSize().ConvertToLogical(WritingMode()); } -const WTF::Optional<NGLogicalOffset>& NGBoxFragment::BfcOffset() const { - WRITING_MODE_IGNORED( - "Accessing BFC offset is allowed here because writing" - "modes are irrelevant in this case."); - return ToNGPhysicalBoxFragment(physical_fragment_)->BfcOffset(); -} - -const NGMarginStrut& NGBoxFragment::EndMarginStrut() const { - WRITING_MODE_IGNORED( - "Accessing the margin strut is fine here. Changing the writing mode" - "establishes a new formatting context, for which a margin strut is" - "never set for a fragment."); - return ToNGPhysicalBoxFragment(physical_fragment_)->EndMarginStrut(); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.h index 4e2e4c57..60c14c8 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.h
@@ -22,10 +22,6 @@ // Returns the total size, including the contents outside of the border-box. NGLogicalSize OverflowSize() const; - - const WTF::Optional<NGLogicalOffset>& BfcOffset() const; - - const NGMarginStrut& EndMarginStrut() const; }; DEFINE_TYPE_CASTS(NGBoxFragment,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment.h index e1fdb9f7..fd44298f 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment.h
@@ -20,6 +20,10 @@ STACK_ALLOCATED(); public: + NGFragment(NGWritingMode writing_mode, + const NGPhysicalFragment* physical_fragment) + : physical_fragment_(physical_fragment), writing_mode_(writing_mode) {} + NGWritingMode WritingMode() const { return static_cast<NGWritingMode>(writing_mode_); } @@ -39,10 +43,6 @@ NGPhysicalFragment::NGFragmentType Type() const; protected: - NGFragment(NGWritingMode writing_mode, - const NGPhysicalFragment* physical_fragment) - : physical_fragment_(physical_fragment), writing_mode_(writing_mode) {} - const NGPhysicalFragment* physical_fragment_; unsigned writing_mode_ : 3;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc index 6967109..f8cc737 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -73,13 +73,10 @@ << "Only box fragments can have children"; // Collect child's out of flow descendants. - const Vector<NGStaticPosition>& oof_positions = child->OutOfFlowPositions(); - size_t oof_index = 0; - for (NGBlockNode oof_node : child->OutOfFlowDescendants()) { - NGStaticPosition oof_position = oof_positions[oof_index++]; - out_of_flow_descendant_candidates_.push_back(oof_node); - out_of_flow_candidate_placements_.push_back( - OutOfFlowPlacement{child_offset, oof_position}); + for (const NGOutOfFlowPositionedDescendant& descendant : + child->OutOfFlowPositionedDescendants()) { + oof_positioned_candidates_.push_back( + NGOutOfFlowPositionedCandidate{descendant, child_offset}); } return AddChild(child->PhysicalFragment(), child_offset); @@ -137,12 +134,15 @@ NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowChildCandidate( NGBlockNode child, - NGLogicalOffset child_offset) { - out_of_flow_descendant_candidates_.push_back(child); - NGStaticPosition child_position = - NGStaticPosition::Create(writing_mode_, direction_, NGPhysicalOffset()); - out_of_flow_candidate_placements_.push_back( - OutOfFlowPlacement{child_offset, child_position}); + const NGLogicalOffset& child_offset) { + DCHECK(child); + + oof_positioned_candidates_.push_back(NGOutOfFlowPositionedCandidate{ + NGOutOfFlowPositionedDescendant{ + child, NGStaticPosition::Create(writing_mode_, direction_, + NGPhysicalOffset())}, + child_offset}); + child.SaveStaticOffsetForLegacy(child_offset); return *this; } @@ -154,40 +154,41 @@ } void NGFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates( - Vector<NGBlockNode>* descendants, - Vector<NGStaticPosition>* descendant_positions) { - DCHECK(descendants->IsEmpty()); - DCHECK(descendant_positions->IsEmpty()); + Vector<NGOutOfFlowPositionedDescendant>* descendant_candidates) { + DCHECK(descendant_candidates->IsEmpty()); + + descendant_candidates->ReserveCapacity(oof_positioned_candidates_.size()); DCHECK_GE(size_.inline_size, LayoutUnit()); DCHECK_GE(size_.block_size, LayoutUnit()); NGPhysicalSize builder_physical_size{size_.ConvertToPhysical(writing_mode_)}; - size_t placement_index = 0; - for (NGBlockNode oof_node : out_of_flow_descendant_candidates_) { - OutOfFlowPlacement oof_placement = - out_of_flow_candidate_placements_[placement_index++]; - - NGPhysicalOffset child_offset = - oof_placement.child_offset.ConvertToPhysical( - writing_mode_, direction_, builder_physical_size, NGPhysicalSize()); + for (NGOutOfFlowPositionedCandidate& candidate : oof_positioned_candidates_) { + NGPhysicalOffset child_offset = candidate.child_offset.ConvertToPhysical( + writing_mode_, direction_, builder_physical_size, NGPhysicalSize()); NGStaticPosition builder_relative_position; - builder_relative_position.type = oof_placement.descendant_position.type; + builder_relative_position.type = candidate.descendant.static_position.type; builder_relative_position.offset = - child_offset + oof_placement.descendant_position.offset; - descendants->push_back(oof_node); - descendant_positions->push_back(builder_relative_position); + child_offset + candidate.descendant.static_position.offset; + + descendant_candidates->push_back(NGOutOfFlowPositionedDescendant{ + candidate.descendant.node, builder_relative_position}); } - out_of_flow_descendant_candidates_.clear(); - out_of_flow_candidate_placements_.clear(); + + // Clear our current canidate list. This may get modified again if the + // current fragment is a containing block, and AddChild is called with a + // descendant from this list. + // + // The descendant may be a "position: absolute" which contains a "position: + // fixed" for example. (This fragment isn't the containing block for the + // fixed descendant). + oof_positioned_candidates_.clear(); } NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowDescendant( - NGBlockNode descendant, - const NGStaticPosition& position) { - out_of_flow_descendants_.push_back(descendant); - out_of_flow_positions_.push_back(position); + NGOutOfFlowPositionedDescendant descendant) { + oof_positioned_descendants_.push_back(descendant); return *this; } @@ -228,12 +229,12 @@ RefPtr<NGPhysicalBoxFragment> fragment = AdoptRef(new NGPhysicalBoxFragment( layout_object_, physical_size, overflow_.ConvertToPhysical(writing_mode_), - children_, positioned_floats_, bfc_offset_, end_margin_strut_, - border_edges_.ToPhysical(writing_mode_), std::move(break_token))); + children_, positioned_floats_, border_edges_.ToPhysical(writing_mode_), + std::move(break_token))); return AdoptRef( - new NGLayoutResult(std::move(fragment), out_of_flow_descendants_, - out_of_flow_positions_, unpositioned_floats_)); + new NGLayoutResult(std::move(fragment), oof_positioned_descendants_, + unpositioned_floats_, bfc_offset_, end_margin_strut_)); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h index d54b264b..5ea8559 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -9,6 +9,7 @@ #include "core/layout/ng/inline/ng_physical_text_fragment.h" #include "core/layout/ng/ng_break_token.h" #include "core/layout/ng/ng_constraint_space.h" +#include "core/layout/ng/ng_out_of_flow_positioned_descendant.h" #include "core/layout/ng/ng_physical_fragment.h" #include "core/layout/ng/ng_positioned_float.h" #include "core/layout/ng/ng_unpositioned_float.h" @@ -76,13 +77,13 @@ // NGOutOfFlowLayoutPart(container_style, builder).Run(); // // See layout part for builder interaction. - NGFragmentBuilder& AddOutOfFlowChildCandidate(NGBlockNode, NGLogicalOffset); + NGFragmentBuilder& AddOutOfFlowChildCandidate(NGBlockNode, + const NGLogicalOffset&); - void GetAndClearOutOfFlowDescendantCandidates(Vector<NGBlockNode>*, - Vector<NGStaticPosition>*); + void GetAndClearOutOfFlowDescendantCandidates( + Vector<NGOutOfFlowPositionedDescendant>* descendant_candidates); - NGFragmentBuilder& AddOutOfFlowDescendant(NGBlockNode, - const NGStaticPosition&); + NGFragmentBuilder& AddOutOfFlowDescendant(NGOutOfFlowPositionedDescendant); // Sets how much of the block size we've used so far for this box. // @@ -135,22 +136,24 @@ } private: - // Out-of-flow descendant placement information. - // The generated fragment must compute NGStaticPosition for all - // out-of-flow descendants. - // The resulting NGStaticPosition gets derived from: - // 1. The offset of fragment's child. - // 2. The static position of descendant wrt child. + // An out-of-flow positioned-candidate is a temporary data structure used + // within the NGFragmentBuilder. // - // A child can be: - // 1. A descendant itself. In this case, descendant position is (0,0). - // 2. A fragment containing a descendant. + // A positioned-candidate can be: + // 1. A direct out-of-flow positioned child. The child_offset is (0,0). + // 2. A fragment containing an out-of-flow positioned-descendant. The + // child_offset in this case is the containing fragment's offset. // - // child_offset is stored as NGLogicalOffset because physical offset cannot - // be computed until we know fragment's size. - struct OutOfFlowPlacement { + // The child_offset is stored as a NGLogicalOffset as the physical offset + // cannot be computed until we know the current fragment's size. + // + // When returning the positioned-candidates (from + // GetAndClearOutOfFlowDescendantCandidates), the NGFragmentBuilder will + // convert the positioned-candidate to a positioned-descendant using the + // physical size the fragment builder. + struct NGOutOfFlowPositionedCandidate { + NGOutOfFlowPositionedDescendant descendant; NGLogicalOffset child_offset; - NGStaticPosition descendant_position; }; NGPhysicalFragment::NGFragmentType type_; @@ -172,11 +175,8 @@ Vector<RefPtr<NGBreakToken>> child_break_tokens_; RefPtr<NGBreakToken> last_inline_break_token_; - Vector<NGBlockNode> out_of_flow_descendant_candidates_; - Vector<OutOfFlowPlacement> out_of_flow_candidate_placements_; - - Vector<NGBlockNode> out_of_flow_descendants_; - Vector<NGStaticPosition> out_of_flow_positions_; + Vector<NGOutOfFlowPositionedCandidate> oof_positioned_candidates_; + Vector<NGOutOfFlowPositionedDescendant> oof_positioned_descendants_; // Floats that need to be positioned by the next in-flow fragment that can // determine its block position in space.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc index cc11684..35779bcf 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc
@@ -8,13 +8,15 @@ NGLayoutResult::NGLayoutResult( PassRefPtr<NGPhysicalFragment> physical_fragment, - Vector<NGBlockNode>& out_of_flow_descendants, - Vector<NGStaticPosition> out_of_flow_positions, - Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats) + Vector<NGOutOfFlowPositionedDescendant> oof_positioned_descendants, + Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats, + const WTF::Optional<NGLogicalOffset> bfc_offset, + const NGMarginStrut end_margin_strut) : physical_fragment_(std::move(physical_fragment)), - out_of_flow_descendants_(out_of_flow_descendants), - out_of_flow_positions_(out_of_flow_positions) { + bfc_offset_(bfc_offset), + end_margin_strut_(end_margin_strut) { unpositioned_floats_.swap(unpositioned_floats); + oof_positioned_descendants_.swap(oof_positioned_descendants); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h index 5604d22..017b94f 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h
@@ -8,6 +8,7 @@ #include "core/CoreExport.h" #include "core/layout/ng/geometry/ng_static_position.h" #include "core/layout/ng/ng_block_node.h" +#include "core/layout/ng/ng_out_of_flow_positioned_descendant.h" #include "core/layout/ng/ng_physical_fragment.h" #include "core/layout/ng/ng_unpositioned_float.h" #include "platform/LayoutUnit.h" @@ -32,12 +33,9 @@ return physical_fragment_; } - const Vector<NGBlockNode>& OutOfFlowDescendants() const { - return out_of_flow_descendants_; - } - - const Vector<NGStaticPosition>& OutOfFlowPositions() const { - return out_of_flow_positions_; + const Vector<NGOutOfFlowPositionedDescendant> OutOfFlowPositionedDescendants() + const { + return oof_positioned_descendants_; } // List of floats that need to be positioned by the next in-flow child that @@ -52,18 +50,28 @@ return unpositioned_floats_; } + const WTF::Optional<NGLogicalOffset>& BfcOffset() const { + return bfc_offset_; + } + + const NGMarginStrut EndMarginStrut() const { return end_margin_strut_; } + private: friend class NGFragmentBuilder; NGLayoutResult(PassRefPtr<NGPhysicalFragment> physical_fragment, - Vector<NGBlockNode>& out_of_flow_descendants, - Vector<NGStaticPosition> out_of_flow_positions, - Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats); + Vector<NGOutOfFlowPositionedDescendant> + out_of_flow_positioned_descendants, + Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats, + const WTF::Optional<NGLogicalOffset> bfc_offset, + const NGMarginStrut end_margin_strut); RefPtr<NGPhysicalFragment> physical_fragment_; - Vector<NGBlockNode> out_of_flow_descendants_; - Vector<NGStaticPosition> out_of_flow_positions_; Vector<RefPtr<NGUnpositionedFloat>> unpositioned_floats_; + + Vector<NGOutOfFlowPositionedDescendant> oof_positioned_descendants_; + const WTF::Optional<NGLogicalOffset> bfc_offset_; + const NGMarginStrut end_margin_strut_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc index 368e872..21e540fa 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -65,35 +65,28 @@ } void NGOutOfFlowLayoutPart::Run() { - Vector<NGBlockNode> out_of_flow_candidates; - Vector<NGStaticPosition> out_of_flow_candidate_positions; + Vector<NGOutOfFlowPositionedDescendant> descendant_candidates; container_builder_->GetAndClearOutOfFlowDescendantCandidates( - &out_of_flow_candidates, &out_of_flow_candidate_positions); + &descendant_candidates); - while (out_of_flow_candidates.size() > 0) { - size_t position_index = 0; - - for (auto& descendant : out_of_flow_candidates) { - NGStaticPosition static_position = - out_of_flow_candidate_positions[position_index++]; - + while (descendant_candidates.size() > 0) { + for (auto& candidate : descendant_candidates) { if (IsContainingBlockForAbsoluteDescendant(container_style_, - descendant.Style())) { + candidate.node.Style())) { NGLogicalOffset offset; - RefPtr<NGLayoutResult> result = - LayoutDescendant(descendant, static_position, &offset); + RefPtr<NGLayoutResult> result = LayoutDescendant( + candidate.node, candidate.static_position, &offset); // TODO(atotic) Need to adjust size of overflow rect per spec. container_builder_->AddChild(std::move(result), offset); } else { - container_builder_->AddOutOfFlowDescendant(descendant, static_position); + container_builder_->AddOutOfFlowDescendant(candidate); } } // Sweep any descendants that might have been added. // This happens when an absolute container has a fixed child. - out_of_flow_candidates.clear(); - out_of_flow_candidate_positions.clear(); + descendant_candidates.clear(); container_builder_->GetAndClearOutOfFlowDescendantCandidates( - &out_of_flow_candidates, &out_of_flow_candidate_positions); + &descendant_candidates); } } @@ -101,6 +94,8 @@ NGBlockNode descendant, NGStaticPosition static_position, NGLogicalOffset* offset) { + DCHECK(descendant); + // Adjust the static_position origin. The static_position coordinate origin is // relative to the container's border box, ng_absolute_utils expects it to be // relative to the container's padding box.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part_test.cc index 37bb93d..2aadabcaa2 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part_test.cc
@@ -69,7 +69,7 @@ NGConstraintSpace::CreateFromLayoutObject(*block_flow); NGBlockNode node(block_flow); RefPtr<NGLayoutResult> result = node.Layout(space.Get()); - EXPECT_EQ(result->OutOfFlowDescendants().size(), (size_t)2); + EXPECT_EQ(result->OutOfFlowPositionedDescendants().size(), (size_t)2); // Test the final result. Element* fixed_1 = GetDocument().getElementById("fixed1");
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_positioned_descendant.h b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_positioned_descendant.h new file mode 100644 index 0000000..ae1de47d --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_positioned_descendant.h
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NGOutOfFlowPositionedDescendant_h +#define NGOutOfFlowPositionedDescendant_h + +#include "core/CoreExport.h" + +#include "core/layout/ng/geometry/ng_static_position.h" +#include "core/layout/ng/ng_block_node.h" + +namespace blink { + +// An out-of-flow positioned-descendant is an element with the style "postion: +// absolute" or "position: fixed" which hasn't been bubbled up to its +// containing block yet, e.g. an element with "position: relative". As soon as +// a descendant reaches its containing block, it gets placed, and doesn't bubble +// up the tree. +// +// This needs its static position [1] to be placed correcting in its containing +// block. +// +// [1] https://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width +struct CORE_EXPORT NGOutOfFlowPositionedDescendant { + NGBlockNode node; + NGStaticPosition static_position; +}; + +} // namespace blink + +#endif // NGOutOfFlowPositionedDescendant_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc index d21294d4..6146b2f 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc
@@ -14,8 +14,6 @@ NGPhysicalSize overflow, Vector<RefPtr<NGPhysicalFragment>>& children, Vector<NGPositionedFloat>& positioned_floats, - const WTF::Optional<NGLogicalOffset>& bfc_offset, - const NGMarginStrut& end_margin_strut, unsigned border_edges, // NGBorderEdges::Physical RefPtr<NGBreakToken> break_token) : NGPhysicalFragment(layout_object, @@ -23,9 +21,7 @@ kFragmentBox, std::move(break_token)), overflow_(overflow), - positioned_floats_(positioned_floats), - bfc_offset_(bfc_offset), - end_margin_strut_(end_margin_strut) { + positioned_floats_(positioned_floats) { children_.swap(children); border_edge_ = border_edges; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h index 176c96d..7e1ec6a 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
@@ -22,8 +22,6 @@ NGPhysicalSize overflow, Vector<RefPtr<NGPhysicalFragment>>& children, Vector<NGPositionedFloat>& positioned_floats, - const WTF::Optional<NGLogicalOffset>& bfc_offset, - const NGMarginStrut& end_margin_strut, unsigned, // NGBorderEdges::Physical RefPtr<NGBreakToken> break_token = nullptr); @@ -41,18 +39,10 @@ return positioned_floats_; } - const WTF::Optional<NGLogicalOffset>& BfcOffset() const { - return bfc_offset_; - } - - const NGMarginStrut& EndMarginStrut() const { return end_margin_strut_; } - private: NGPhysicalSize overflow_; Vector<RefPtr<NGPhysicalFragment>> children_; Vector<NGPositionedFloat> positioned_floats_; - const WTF::Optional<NGLogicalOffset> bfc_offset_; - const NGMarginStrut end_margin_strut_; }; DEFINE_TYPE_CASTS(NGPhysicalBoxFragment,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_space_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_space_utils.cc index 7d11bc2..27ed337 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_space_utils.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_space_utils.cc
@@ -24,46 +24,8 @@ return value2; } -bool IsOutOfFlowPositioned(const EPosition& position) { - return position == EPosition::kAbsolute || position == EPosition::kFixed; -} - } // namespace -bool IsNewFormattingContextForBlockLevelChild(const ComputedStyle& parent_style, - const NGLayoutInputNode& node) { - // TODO(layout-dev): This doesn't capture a few cases which can't be computed - // directly from style yet: - // - The child is a <fieldset>. - // - "column-span: all" is set on the child (requires knowledge that we are - // in a multi-col formatting context). - // (https://drafts.csswg.org/css-multicol-1/#valdef-column-span-all) - - if (node.IsInline()) - return false; - - const ComputedStyle& style = node.Style(); - if (style.IsFloating() || IsOutOfFlowPositioned(style.GetPosition())) - return true; - - if (style.SpecifiesColumns() || style.ContainsPaint() || - style.ContainsLayout()) - return true; - - if (!style.IsOverflowVisible()) - return true; - - EDisplay display = style.Display(); - if (display == EDisplay::kGrid || display == EDisplay::kFlex || - display == EDisplay::kWebkitBox) - return true; - - if (parent_style.GetWritingMode() != style.GetWritingMode()) - return true; - - return false; -} - WTF::Optional<LayoutUnit> GetClearanceOffset( const std::shared_ptr<NGExclusions>& exclusions, EClear clear_type) {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_space_utils.h b/third_party/WebKit/Source/core/layout/ng/ng_space_utils.h index ee5cf74..579141cf 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_space_utils.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_space_utils.h
@@ -14,19 +14,8 @@ class ComputedStyle; struct NGExclusions; -class NGLayoutInputNode; struct NGLogicalOffset; -// Whether an in-flow child creates a new formatting context. -// -// This will *NOT* check the following cases: -// - The child is a inline-level, e.g. "display: inline-block". -// - The child establishes a new formatting context, but should be a child of -// another layout algorithm, e.g. "display: table-caption" or flex-item. -CORE_EXPORT bool IsNewFormattingContextForBlockLevelChild( - const ComputedStyle& parent_style, - const NGLayoutInputNode& node); - // Gets the clearance offset based on the provided {@code clear_type} and list // of exclusions that represent left/right float. CORE_EXPORT WTF::Optional<LayoutUnit> GetClearanceOffset(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_space_utils_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_space_utils_test.cc deleted file mode 100644 index db65ad436..0000000 --- a/third_party/WebKit/Source/core/layout/ng/ng_space_utils_test.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/layout/ng/ng_space_utils.h" - -#include "core/layout/ng/ng_base_layout_algorithm_test.h" -#include "core/layout/ng/ng_block_node.h" -#include "core/style/ComputedStyle.h" - -namespace blink { -namespace { - -class NGSpaceUtilsTest : public NGBaseLayoutAlgorithmTest {}; - -// Verifies that IsNewFormattingContextForInFlowBlockLevelChild returnes true -// if the child is out-of-flow, e.g. floating or abs-pos. -TEST_F(NGSpaceUtilsTest, NewFormattingContextForOutOfFlowChild) { - SetBodyInnerHTML(R"HTML( - <!DOCTYPE html> - <div id="parent"> - <div id="child"></div> - </div> - )HTML"); - - auto& parent_style = GetLayoutObjectByElementId("parent")->StyleRef(); - auto* child = GetLayoutObjectByElementId("child"); - NGBlockNode node(ToLayoutBox(child)); - - auto run_test = [&](RefPtr<ComputedStyle> style) { - child->SetStyle(style); - EXPECT_TRUE(IsNewFormattingContextForBlockLevelChild(parent_style, node)); - }; - - RefPtr<ComputedStyle> style = ComputedStyle::Create(); - style->SetFloating(EFloat::kLeft); - run_test(style); - - style = ComputedStyle::Create(); - style->SetPosition(EPosition::kAbsolute); - run_test(style); - - style = ComputedStyle::Create(); - style->SetPosition(EPosition::kFixed); - run_test(style); -} - -} // namespace -} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp b/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp index 2cf99987..914cc9cd 100644 --- a/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp +++ b/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp
@@ -116,11 +116,10 @@ static LayoutRect GetShapeImageMarginRect( const LayoutBox& layout_box, const LayoutSize& reference_box_logical_size) { - LayoutPoint margin_box_origin(-layout_box.MarginLogicalLeft() - - layout_box.BorderAndPaddingLogicalLeft(), - -layout_box.MarginBefore() - - layout_box.BorderBefore() - - layout_box.PaddingBefore()); + LayoutPoint margin_box_origin( + -layout_box.MarginLineLeft() - layout_box.BorderAndPaddingLogicalLeft(), + -layout_box.MarginBefore() - layout_box.BorderBefore() - + layout_box.PaddingBefore()); LayoutSize margin_box_size_delta( layout_box.MarginLogicalWidth() + layout_box.BorderAndPaddingLogicalWidth(),
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.cpp b/third_party/WebKit/Source/core/loader/PingLoader.cpp index c95e703..58d4552 100644 --- a/third_party/WebKit/Source/core/loader/PingLoader.cpp +++ b/third_party/WebKit/Source/core/loader/PingLoader.cpp
@@ -481,6 +481,9 @@ beacon.Serialize(request); FetchParameters params(request); params.MutableOptions().initiator_info.name = FetchInitiatorTypeNames::beacon; + params.SetCrossOriginAccessControl( + frame->GetDocument()->GetSecurityOrigin(), + WebURLRequest::kFetchCredentialsModeInclude); Resource* resource = RawResource::Fetch(params, frame->GetDocument()->Fetcher());
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h index 10a72ce4..04d2392 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.h +++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -39,6 +39,7 @@ #include "platform/graphics/TouchAction.h" #include "platform/heap/Handle.h" #include "platform/scroll/ScrollTypes.h" +#include "platform/text/TextDirection.h" #include "platform/wtf/Forward.h" #include "platform/wtf/Optional.h" #include "platform/wtf/Vector.h"
diff --git a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp index cd94dd90..b62702a 100644 --- a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp +++ b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
@@ -632,8 +632,15 @@ DCHECK(candidate.visible_node); DCHECK(candidate.is_offscreen); LayoutRect candidate_rect = candidate.rect; + // TODO(ecobos@igalia.com): Investigate interaction with Shadow DOM. for (Node& parent_node : NodeTraversal::AncestorsOf(*candidate.visible_node)) { + if (UNLIKELY(!parent_node.GetLayoutObject())) { + DCHECK(parent_node.IsElementNode() && + ToElement(parent_node).HasDisplayContentsStyle()); + continue; + } + LayoutRect parent_rect = NodeRectInAbsoluteCoordinates(&parent_node); if (!candidate_rect.Intersects(parent_rect)) { if (((type == kWebFocusTypeLeft || type == kWebFocusTypeRight) &&
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp index 5ca48a5..cd94eb74 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -21,6 +21,7 @@ #include "core/events/EventQueue.h" #include "core/frame/Deprecation.h" #include "core/frame/FrameOwner.h" +#include "core/frame/Settings.h" #include "core/html/HTMLIFrameElement.h" #include "core/inspector/ConsoleMessage.h" #include "core/inspector/ConsoleTypes.h" @@ -813,6 +814,14 @@ "Cannot show the payment request")); } + // VR mode uses popup suppression setting to disable html select element, + // date pickers, etc. + if (GetFrame()->GetDocument()->GetSettings()->GetPagePopupsSuppressed()) { + return ScriptPromise::RejectWithDOMException( + script_state, + DOMException::Create(kInvalidStateError, "Page popups are suppressed")); + } + payment_provider_->Show(); show_resolver_ = ScriptPromiseResolver::Create(script_state);
diff --git a/third_party/WebKit/Source/platform/geometry/LayoutRectOutsets.cpp b/third_party/WebKit/Source/platform/geometry/LayoutRectOutsets.cpp index d45cba62..c18fc42 100644 --- a/third_party/WebKit/Source/platform/geometry/LayoutRectOutsets.cpp +++ b/third_party/WebKit/Source/platform/geometry/LayoutRectOutsets.cpp
@@ -35,149 +35,19 @@ namespace blink { -LayoutUnit LayoutRectOutsets::LogicalTop(WritingMode writing_mode) const { - return IsHorizontalWritingMode(writing_mode) ? top_ : left_; -} - -LayoutUnit LayoutRectOutsets::LogicalBottom(WritingMode writing_mode) const { - return IsHorizontalWritingMode(writing_mode) ? bottom_ : right_; -} - -LayoutUnit LayoutRectOutsets::LogicalLeft(WritingMode writing_mode) const { - return IsHorizontalWritingMode(writing_mode) ? left_ : top_; -} - -LayoutUnit LayoutRectOutsets::LogicalRight(WritingMode writing_mode) const { - return IsHorizontalWritingMode(writing_mode) ? right_ : bottom_; -} - -LayoutRectOutsets LayoutRectOutsets::LogicalOutsets( +LayoutRectOutsets LayoutRectOutsets::LineOrientationOutsets( WritingMode writing_mode) const { if (!IsHorizontalWritingMode(writing_mode)) return LayoutRectOutsets(left_, bottom_, right_, top_); return *this; } -LayoutRectOutsets LayoutRectOutsets::LogicalOutsetsWithFlippedLines( +LayoutRectOutsets LayoutRectOutsets::LineOrientationOutsetsWithFlippedLines( WritingMode writing_mode) const { - LayoutRectOutsets outsets = LogicalOutsets(writing_mode); + LayoutRectOutsets outsets = LineOrientationOutsets(writing_mode); if (IsFlippedLinesWritingMode(writing_mode)) std::swap(outsets.top_, outsets.bottom_); return outsets; } -LayoutUnit LayoutRectOutsets::Before(WritingMode writing_mode) const { - switch (writing_mode) { - case WritingMode::kHorizontalTb: - return top_; - case WritingMode::kVerticalLr: - return left_; - case WritingMode::kVerticalRl: - return right_; - } - NOTREACHED(); - return top_; -} - -LayoutUnit LayoutRectOutsets::After(WritingMode writing_mode) const { - switch (writing_mode) { - case WritingMode::kHorizontalTb: - return bottom_; - case WritingMode::kVerticalLr: - return right_; - case WritingMode::kVerticalRl: - return left_; - } - NOTREACHED(); - return bottom_; -} - -LayoutUnit LayoutRectOutsets::Start(WritingMode writing_mode, - TextDirection direction) const { - if (IsHorizontalWritingMode(writing_mode)) - return IsLtr(direction) ? left_ : right_; - return IsLtr(direction) ? top_ : bottom_; -} - -LayoutUnit LayoutRectOutsets::end(WritingMode writing_mode, - TextDirection direction) const { - if (IsHorizontalWritingMode(writing_mode)) - return IsLtr(direction) ? right_ : left_; - return IsLtr(direction) ? bottom_ : top_; -} - -LayoutUnit LayoutRectOutsets::Over(WritingMode writing_mode) const { - return IsHorizontalWritingMode(writing_mode) ? top_ : right_; -} - -LayoutUnit LayoutRectOutsets::Under(WritingMode writing_mode) const { - return IsHorizontalWritingMode(writing_mode) ? bottom_ : left_; -} - -void LayoutRectOutsets::SetBefore(WritingMode writing_mode, LayoutUnit value) { - switch (writing_mode) { - case WritingMode::kHorizontalTb: - top_ = value; - break; - case WritingMode::kVerticalLr: - left_ = value; - break; - case WritingMode::kVerticalRl: - right_ = value; - break; - default: - NOTREACHED(); - top_ = value; - } -} - -void LayoutRectOutsets::SetAfter(WritingMode writing_mode, LayoutUnit value) { - switch (writing_mode) { - case WritingMode::kHorizontalTb: - bottom_ = value; - break; - case WritingMode::kVerticalLr: - right_ = value; - break; - case WritingMode::kVerticalRl: - left_ = value; - break; - default: - NOTREACHED(); - bottom_ = value; - } -} - -void LayoutRectOutsets::SetStart(WritingMode writing_mode, - TextDirection direction, - LayoutUnit value) { - if (IsHorizontalWritingMode(writing_mode)) { - if (IsLtr(direction)) - left_ = value; - else - right_ = value; - } else { - if (IsLtr(direction)) - top_ = value; - else - bottom_ = value; - } -} - -void LayoutRectOutsets::SetEnd(WritingMode writing_mode, - TextDirection direction, - LayoutUnit value) { - if (IsHorizontalWritingMode(writing_mode)) { - if (IsLtr(direction)) - right_ = value; - else - left_ = value; - } else { - if (IsLtr(direction)) - bottom_ = value; - else - top_ = value; - } -} - } // namespace blink
diff --git a/third_party/WebKit/Source/platform/geometry/LayoutRectOutsets.h b/third_party/WebKit/Source/platform/geometry/LayoutRectOutsets.h index cf9d1cd..15617ee 100644 --- a/third_party/WebKit/Source/platform/geometry/LayoutRectOutsets.h +++ b/third_party/WebKit/Source/platform/geometry/LayoutRectOutsets.h
@@ -35,7 +35,6 @@ #include "platform/PlatformExport.h" #include "platform/geometry/FloatRectOutsets.h" #include "platform/geometry/IntRectOutsets.h" -#include "platform/text/TextDirection.h" #include "platform/text/WritingMode.h" #include "platform/wtf/Allocator.h" @@ -84,29 +83,16 @@ void SetBottom(LayoutUnit value) { bottom_ = value; } void SetLeft(LayoutUnit value) { left_ = value; } - LayoutUnit LogicalTop(WritingMode) const; - LayoutUnit LogicalBottom(WritingMode) const; - LayoutUnit LogicalLeft(WritingMode) const; - LayoutUnit LogicalRight(WritingMode) const; - - // Produces a new LayoutRectOutsets whose |top| is the |logicalTop| of this - // one, and so on. - LayoutRectOutsets LogicalOutsets(WritingMode) const; + // Produces a new LayoutRectOutsets in line orientation + // (https://www.w3.org/TR/css-writing-modes-3/#line-orientation), whose + // - |top| is the logical 'over', + // - |right| is the logical 'line right', + // - |bottom| is the logical 'under', + // - |left| is the logical 'line left'. + LayoutRectOutsets LineOrientationOutsets(WritingMode) const; // The same as |logicalOutsets|, but also adjusting for flipped lines. - LayoutRectOutsets LogicalOutsetsWithFlippedLines(WritingMode) const; - - LayoutUnit Before(WritingMode) const; - LayoutUnit After(WritingMode) const; - LayoutUnit Start(WritingMode, TextDirection) const; - LayoutUnit end(WritingMode, TextDirection) const; - LayoutUnit Over(WritingMode) const; - LayoutUnit Under(WritingMode) const; - - void SetBefore(WritingMode, LayoutUnit); - void SetAfter(WritingMode, LayoutUnit); - void SetStart(WritingMode, TextDirection, LayoutUnit); - void SetEnd(WritingMode, TextDirection, LayoutUnit); + LayoutRectOutsets LineOrientationOutsetsWithFlippedLines(WritingMode) const; bool operator==(const LayoutRectOutsets other) const { return Top() == other.Top() && Right() == other.Right() &&
diff --git a/third_party/WebKit/Source/platform/geometry/LayoutRectOutsetsTest.cpp b/third_party/WebKit/Source/platform/geometry/LayoutRectOutsetsTest.cpp index d1a389a..d5da787 100644 --- a/third_party/WebKit/Source/platform/geometry/LayoutRectOutsetsTest.cpp +++ b/third_party/WebKit/Source/platform/geometry/LayoutRectOutsetsTest.cpp
@@ -9,28 +9,31 @@ namespace blink { namespace { -TEST(LayoutRectOutsetsTest, LogicalOutsets_Horizontal) { +TEST(LayoutRectOutsetsTest, LineOrientationOutsets_Horizontal) { LayoutRectOutsets outsets(1, 2, 3, 4); EXPECT_EQ(LayoutRectOutsets(1, 2, 3, 4), - outsets.LogicalOutsets(WritingMode::kHorizontalTb)); + outsets.LineOrientationOutsets(WritingMode::kHorizontalTb)); } -TEST(LayoutRectOutsetsTest, LogicalOutsets_Vertical) { +TEST(LayoutRectOutsetsTest, LineOrientationOutsets_Vertical) { LayoutRectOutsets outsets(1, 2, 3, 4); EXPECT_EQ(LayoutRectOutsets(4, 3, 2, 1), - outsets.LogicalOutsets(WritingMode::kVerticalLr)); + outsets.LineOrientationOutsets(WritingMode::kVerticalLr)); EXPECT_EQ(LayoutRectOutsets(4, 3, 2, 1), - outsets.LogicalOutsets(WritingMode::kVerticalRl)); + outsets.LineOrientationOutsets(WritingMode::kVerticalRl)); } -TEST(LayoutRectOutsetsTest, LogicalOutsetsWithFlippedLines) { +TEST(LayoutRectOutsetsTest, LineOrientationOutsetsWithFlippedLines) { LayoutRectOutsets outsets(1, 2, 3, 4); EXPECT_EQ(LayoutRectOutsets(1, 2, 3, 4), - outsets.LogicalOutsetsWithFlippedLines(WritingMode::kHorizontalTb)); - EXPECT_EQ(LayoutRectOutsets(2, 3, 4, 1), - outsets.LogicalOutsetsWithFlippedLines(WritingMode::kVerticalLr)); - EXPECT_EQ(LayoutRectOutsets(4, 3, 2, 1), - outsets.LogicalOutsetsWithFlippedLines(WritingMode::kVerticalRl)); + outsets.LineOrientationOutsetsWithFlippedLines( + WritingMode::kHorizontalTb)); + EXPECT_EQ( + LayoutRectOutsets(2, 3, 4, 1), + outsets.LineOrientationOutsetsWithFlippedLines(WritingMode::kVerticalLr)); + EXPECT_EQ( + LayoutRectOutsets(4, 3, 2, 1), + outsets.LineOrientationOutsetsWithFlippedLines(WritingMode::kVerticalRl)); } } // namespace
diff --git a/third_party/WebKit/Source/platform/text/WritingModeUtils.h b/third_party/WebKit/Source/platform/text/WritingModeUtils.h index f4d680e..03fcf20 100644 --- a/third_party/WebKit/Source/platform/text/WritingModeUtils.h +++ b/third_party/WebKit/Source/platform/text/WritingModeUtils.h
@@ -11,17 +11,43 @@ namespace blink { -template <typename T> +// Templates to map values between logical orientations and physical +// orientations. See https://www.w3.org/TR/css-writing-modes-3/ and +// https://www.w3.org/TR/css-logical-1/ for definitions of logical orientations. + +// This file provides two types of templates: +// +// - Simple value mappers (PhysicalToLogical and LogicalToPhysical): they take +// 4 input values in physical or logical orientations, and provide accessors +// to get values in logical or physical orientations. As the inputs may be +// evaluated even if not used (in case that the compiler is unable to remove +// unused evaluations, e.g. containing non-inlined function calls), for +// performance-senstive code, the evaluation of the inputs should be simple +// and/or be fully inlined. +// +// - Value mappers based on getter/setter methods (PhysicalToLogicalGetter, +// LogicalToPhysicalGetter, PhysicalToLogicalSetter and +// LogicalToPhysicalSetter): they take 4 method pointers as inputs pointing to +// methods accessing values in physical or logical orientations, and provide +// accessors to get or set values in logical or physical orientations. They +// are suitable for mapping of setters, or getters implemented with non- +// inlined functions. Evaluation of the input values are delayed when they are +// actually needed. +// +// See WritingModeUtilsTest.cpp, LayoutBoxModelObject.h and ComputedStyle.h for +// examples. + +template <typename Value> class PhysicalToLogical { STACK_ALLOCATED(); public: PhysicalToLogical(WritingMode writing_mode, TextDirection direction, - T top, - T right, - T bottom, - T left) + Value top, + Value right, + Value bottom, + Value left) : writing_mode_(writing_mode), direction_(direction), top_(top), @@ -29,72 +55,72 @@ bottom_(bottom), left_(left) {} - T InlineStart() const { + Value InlineStart() const { if (IsHorizontalWritingMode(writing_mode_)) return IsLtr(direction_) ? left_ : right_; return IsLtr(direction_) ? top_ : bottom_; } - T InlineEnd() const { + Value InlineEnd() const { if (IsHorizontalWritingMode(writing_mode_)) return IsLtr(direction_) ? right_ : left_; return IsLtr(direction_) ? bottom_ : top_; } - T BlockStart() const { + Value BlockStart() const { if (IsHorizontalWritingMode(writing_mode_)) return top_; return IsFlippedBlocksWritingMode(writing_mode_) ? right_ : left_; } - T BlockEnd() const { + Value BlockEnd() const { if (IsHorizontalWritingMode(writing_mode_)) return bottom_; return IsFlippedBlocksWritingMode(writing_mode_) ? left_ : right_; } - T Over() const { + Value Over() const { return IsHorizontalWritingMode(writing_mode_) ? top_ : right_; } - T Under() const { + Value Under() const { return IsHorizontalWritingMode(writing_mode_) ? bottom_ : left_; } - T LineLeft() const { + Value LineLeft() const { return IsHorizontalWritingMode(writing_mode_) ? left_ : top_; } - T LineRight() const { + Value LineRight() const { return IsHorizontalWritingMode(writing_mode_) ? right_ : bottom_; } // Legacy logical directions. - T Start() const { return InlineStart(); } - T End() const { return InlineEnd(); } - T Before() const { return BlockStart(); } - T After() const { return BlockEnd(); } + Value Start() const { return InlineStart(); } + Value End() const { return InlineEnd(); } + Value Before() const { return BlockStart(); } + Value After() const { return BlockEnd(); } private: WritingMode writing_mode_; TextDirection direction_; - T top_; - T right_; - T bottom_; - T left_; + Value top_; + Value right_; + Value bottom_; + Value left_; }; -template <typename T> +template <typename Value> class LogicalToPhysical { STACK_ALLOCATED(); public: LogicalToPhysical(WritingMode writing_mode, TextDirection direction, - T inline_start, - T inline_end, - T block_start, - T block_end) + Value inline_start, + Value inline_end, + Value block_start, + Value block_end) : writing_mode_(writing_mode), direction_(direction), inline_start_(inline_start), @@ -102,27 +128,27 @@ block_start_(block_start), block_end_(block_end) {} - T Left() const { + Value Left() const { if (IsHorizontalWritingMode(writing_mode_)) return IsLtr(direction_) ? inline_start_ : inline_end_; return IsFlippedBlocksWritingMode(writing_mode_) ? block_end_ : block_start_; } - T Right() const { + Value Right() const { if (IsHorizontalWritingMode(writing_mode_)) return IsLtr(direction_) ? inline_end_ : inline_start_; return IsFlippedBlocksWritingMode(writing_mode_) ? block_start_ : block_end_; } - T Top() const { + Value Top() const { if (IsHorizontalWritingMode(writing_mode_)) return block_start_; return IsLtr(direction_) ? inline_start_ : inline_end_; } - T Bottom() const { + Value Bottom() const { if (IsHorizontalWritingMode(writing_mode_)) return block_end_; return IsLtr(direction_) ? inline_end_ : inline_start_; @@ -131,10 +157,154 @@ private: WritingMode writing_mode_; TextDirection direction_; - T inline_start_; // a.k.a. start - T inline_end_; // a.k.a. end - T block_start_; // a.k.a. before - T block_end_; // a.k.a. after + Value inline_start_; // a.k.a. start + Value inline_end_; // a.k.a. end + Value block_start_; // a.k.a. before + Value block_end_; // a.k.a. after +}; + +template <typename Value, typename Object> +class LogicalToPhysicalGetter { + STACK_ALLOCATED(); + + public: + using Getter = Value (Object::*)() const; + LogicalToPhysicalGetter(WritingMode writing_mode, + TextDirection direction, + const Object& object, + Getter inline_start_getter, + Getter inline_end_getter, + Getter block_start_getter, + Getter block_end_getter) + : object_(object), + converter_(writing_mode, + direction, + inline_start_getter, + inline_end_getter, + block_start_getter, + block_end_getter) {} + + Value Left() const { return (object_.*converter_.Left())(); } + Value Right() const { return (object_.*converter_.Right())(); } + Value Top() const { return (object_.*converter_.Top())(); } + Value Bottom() const { return (object_.*converter_.Bottom())(); } + + private: + const Object& object_; + LogicalToPhysical<Getter> converter_; +}; + +template <typename Value, typename Object> +class PhysicalToLogicalGetter { + STACK_ALLOCATED(); + + public: + using Getter = Value (Object::*)() const; + PhysicalToLogicalGetter(WritingMode writing_mode, + TextDirection direction, + const Object& object, + Getter top_getter, + Getter right_getter, + Getter bottom_getter, + Getter left_getter) + : object_(object), + converter_(writing_mode, + direction, + top_getter, + right_getter, + bottom_getter, + left_getter) {} + + Value InlineStart() const { return (object_.*converter_.InlineStart())(); } + Value InlineEnd() const { return (object_.*converter_.InlineEnd())(); } + Value BlockStart() const { return (object_.*converter_.BlockStart())(); } + Value BlockEnd() const { return (object_.*converter_.BlockEnd())(); } + Value Over() const { return (object_.*converter_.Over())(); } + Value Under() const { return (object_.*converter_.Under())(); } + Value LineLeft() const { return (object_.*converter_.LineLeft())(); } + Value LineRight() const { return (object_.*converter_.LineRight())(); } + Value Start() const { return (object_.*converter_.Start())(); } + Value End() const { return (object_.*converter_.End())(); } + Value Before() const { return (object_.*converter_.Before())(); } + Value After() const { return (object_.*converter_.After())(); } + + private: + const Object& object_; + PhysicalToLogical<Getter> converter_; +}; + +template <typename Value, typename Object> +class PhysicalToLogicalSetter { + STACK_ALLOCATED(); + + public: + using Setter = void (Object::*)(Value); + PhysicalToLogicalSetter(WritingMode writing_mode, + TextDirection direction, + Object& object, + Setter inline_start_setter, + Setter inline_end_setter, + Setter block_start_setter, + Setter block_end_setter) + : object_(object), + converter_(writing_mode, + direction, + inline_start_setter, + inline_end_setter, + block_start_setter, + block_end_setter) {} + + void SetLeft(Value v) { (object_.*converter_.Left())(v); } + void SetRight(Value v) { (object_.*converter_.Right())(v); } + void SetTop(Value v) { (object_.*converter_.Top())(v); } + void SetBottom(Value v) { (object_.*converter_.Bottom())(v); } + + private: + Object& object_; + // This converter converts logical setters to physical setters which accept + // physical values and call the logical setters to set logical values. + LogicalToPhysical<Setter> converter_; +}; + +template <typename Value, typename Object> +class LogicalToPhysicalSetter { + STACK_ALLOCATED(); + + public: + using Setter = void (Object::*)(Value); + LogicalToPhysicalSetter(WritingMode writing_mode, + TextDirection direction, + Object& object, + Setter top_setter, + Setter right_setter, + Setter bottom_setter, + Setter left_setter) + : object_(object), + converter_(writing_mode, + direction, + top_setter, + right_setter, + bottom_setter, + left_setter) {} + + void SetInlineStart(Value v) { (object_.*converter_.InlineStart())(v); } + void SetInlineEnd(Value v) { (object_.*converter_.InlineEnd())(v); } + void SetBlockStart(Value v) { (object_.*converter_.BlockStart())(v); } + void SetBlockEnd(Value v) { (object_.*converter_.BlockEnd())(v); } + void SetOver(Value v) { (object_.*converter_.Over())(v); } + void SetUnder(Value v) { (object_.*converter_.Under())(v); } + void SetLineLeft(Value v) { (object_.*converter_.LineLeft())(v); } + void SetLineRight(Value v) { (object_.*converter_.LineRight())(v); } + void SetStart(Value v) { (object_.*converter_.Start())(v); } + void SetEnd(Value v) { (object_.*converter_.End())(v); } + void SetBefore(Value v) { (object_.*converter_.Before())(v); } + void SetAfter(Value v) { (object_.*converter_.After())(v); } + + private: + Object& object_; + // This converter converts physical setters to logical setters which accept + // logical values and call the physical setters to set physical values. + PhysicalToLogical<Setter> converter_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/text/WritingModeUtilsTest.cpp b/third_party/WebKit/Source/platform/text/WritingModeUtilsTest.cpp index 6683fefc..917a31c7 100644 --- a/third_party/WebKit/Source/platform/text/WritingModeUtilsTest.cpp +++ b/third_party/WebKit/Source/platform/text/WritingModeUtilsTest.cpp
@@ -12,7 +12,8 @@ enum { kTop, kRight, kBottom, kLeft }; -void CheckLegacyLogicalDirections(PhysicalToLogical<int> converter) { +template <typename PhysicalToLogicalConverter> +void CheckLegacyLogicalDirections(const PhysicalToLogicalConverter& converter) { EXPECT_EQ(converter.InlineStart(), converter.Start()); EXPECT_EQ(converter.InlineEnd(), converter.End()); EXPECT_EQ(converter.BlockStart(), converter.Before()); @@ -109,7 +110,7 @@ CheckLegacyLogicalDirections(converter); } -enum { kInlineStart, kInlineEnd, kBlockStart, kBlockEnd }; +enum { kInlineStart = 1000, kInlineEnd, kBlockStart, kBlockEnd }; TEST(WritingModeUtilsTest, LogicalToPhysicalHorizontalLtr) { LogicalToPhysical<int> converter(WritingMode::kHorizontalTb, @@ -171,6 +172,127 @@ EXPECT_EQ(kInlineStart, converter.Bottom()); } +class PhysicalValues { + public: + int Top() const { return top_; } + int Right() const { return right_; } + int Bottom() const { return bottom_; } + int Left() const { return left_; } + void SetTop(int top) { top_ = top; } + void SetRight(int right) { right_ = right; } + void SetBottom(int bottom) { bottom_ = bottom; } + void SetLeft(int left) { left_ = left; } + + private: + int top_ = kTop; + int right_ = kRight; + int bottom_ = kBottom; + int left_ = kLeft; +}; + +TEST(WritingModeUtilsTest, PhysicalToLogicalGetter) { + PhysicalValues physical_values; + PhysicalToLogicalGetter<int, PhysicalValues> getter( + WritingMode::kVerticalRl, TextDirection::kRtl, physical_values, + &PhysicalValues::Top, &PhysicalValues::Right, &PhysicalValues::Bottom, + &PhysicalValues::Left); + + EXPECT_EQ(kBottom, getter.InlineStart()); + EXPECT_EQ(kTop, getter.InlineEnd()); + EXPECT_EQ(kRight, getter.BlockStart()); + EXPECT_EQ(kLeft, getter.BlockEnd()); + EXPECT_EQ(kTop, getter.LineLeft()); + EXPECT_EQ(kBottom, getter.LineRight()); + EXPECT_EQ(kRight, getter.Over()); + EXPECT_EQ(kLeft, getter.Under()); + CheckLegacyLogicalDirections(getter); +} + +TEST(WritingModeUtilsTest, LogicalToPhysicalSetter) { + PhysicalValues physical_values; + LogicalToPhysicalSetter<int, PhysicalValues> setter( + WritingMode::kVerticalRl, TextDirection::kRtl, physical_values, + &PhysicalValues::SetTop, &PhysicalValues::SetRight, + &PhysicalValues::SetBottom, &PhysicalValues::SetLeft); + setter.SetInlineStart(kInlineStart); + setter.SetInlineEnd(kInlineEnd); + setter.SetBlockStart(kBlockStart); + setter.SetBlockEnd(kBlockEnd); + + EXPECT_EQ(kBlockEnd, physical_values.Left()); + EXPECT_EQ(kBlockStart, physical_values.Right()); + EXPECT_EQ(kInlineEnd, physical_values.Top()); + EXPECT_EQ(kInlineStart, physical_values.Bottom()); + + setter.SetStart(kInlineStart); + setter.SetEnd(kInlineEnd); + setter.SetBefore(kBlockStart); + setter.SetAfter(kBlockEnd); + + EXPECT_EQ(kBlockEnd, physical_values.Left()); + EXPECT_EQ(kBlockStart, physical_values.Right()); + EXPECT_EQ(kInlineEnd, physical_values.Top()); + EXPECT_EQ(kInlineStart, physical_values.Bottom()); + + setter.SetLineRight(kInlineStart); + setter.SetLineLeft(kInlineEnd); + setter.SetOver(kBlockStart); + setter.SetUnder(kBlockEnd); + + EXPECT_EQ(kBlockEnd, physical_values.Left()); + EXPECT_EQ(kBlockStart, physical_values.Right()); + EXPECT_EQ(kInlineEnd, physical_values.Top()); + EXPECT_EQ(kInlineStart, physical_values.Bottom()); +} + +class LogicalValues { + public: + int InlineStart() const { return inline_start_; } + int InlineEnd() const { return inline_end_; } + int BlockStart() const { return block_start_; } + int BlockEnd() const { return block_end_; } + void SetInlineStart(int inline_start) { inline_start_ = inline_start; } + void SetInlineEnd(int inline_end) { inline_end_ = inline_end; } + void SetBlockStart(int block_start) { block_start_ = block_start; } + void SetBlockEnd(int block_end) { block_end_ = block_end; } + + private: + int inline_start_ = kInlineStart; + int inline_end_ = kInlineEnd; + int block_start_ = kBlockStart; + int block_end_ = kBlockEnd; +}; + +TEST(WritingModeUtilsTest, LogicalToPhysicalGetter) { + LogicalValues logical_values; + LogicalToPhysicalGetter<int, LogicalValues> getter( + WritingMode::kVerticalRl, TextDirection::kRtl, logical_values, + &LogicalValues::InlineStart, &LogicalValues::InlineEnd, + &LogicalValues::BlockStart, &LogicalValues::BlockEnd); + + EXPECT_EQ(kBlockEnd, getter.Left()); + EXPECT_EQ(kBlockStart, getter.Right()); + EXPECT_EQ(kInlineEnd, getter.Top()); + EXPECT_EQ(kInlineStart, getter.Bottom()); +} + +TEST(WritingModeUtilsTest, PhysicalToLogicalSetter) { + LogicalValues logical_values; + PhysicalToLogicalSetter<int, LogicalValues> setter( + WritingMode::kVerticalRl, TextDirection::kRtl, logical_values, + &LogicalValues::SetInlineStart, &LogicalValues::SetInlineEnd, + &LogicalValues::SetBlockStart, &LogicalValues::SetBlockEnd); + setter.SetTop(kTop); + setter.SetRight(kRight); + setter.SetBottom(kBottom); + setter.SetLeft(kLeft); + + EXPECT_EQ(kBottom, logical_values.InlineStart()); + EXPECT_EQ(kTop, logical_values.InlineEnd()); + EXPECT_EQ(kRight, logical_values.BlockStart()); + EXPECT_EQ(kLeft, logical_values.BlockEnd()); +} + } // namespace } // namespace blink
diff --git a/third_party/material_design_icons/LICENSE b/third_party/material_design_icons/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/third_party/material_design_icons/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file
diff --git a/third_party/material_design_icons/OWNERS b/third_party/material_design_icons/OWNERS new file mode 100644 index 0000000..ccddf8d --- /dev/null +++ b/third_party/material_design_icons/OWNERS
@@ -0,0 +1,2 @@ +lpromero@chromium.org +sdefresne@chromium.org
diff --git a/third_party/material_design_icons/README.chromium b/third_party/material_design_icons/README.chromium new file mode 100644 index 0000000..e16b880 --- /dev/null +++ b/third_party/material_design_icons/README.chromium
@@ -0,0 +1,14 @@ +Name: Material Design Icons +URL: https://github.com/google/material-design-icons +Version: 0 +Revision: a6145e167b4a3a65640dd6279319cbc77a7e4e96 +License: Apache 2.0 +License File: LICENSE +Security Critical: yes + +Description: +Material design icons are the official icon set from Google that are designed +under the material design guidelines. + +Local Modifications: +None
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index 539939d..19089bf 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -81,61 +81,61 @@ # START chrome/browser section. "chrome/browser/browser_resources.grd": { "includes": [11000], - "structures": [11480], + "structures": [11510], }, "chrome/browser/resources/component_extension_resources.grd": { - "includes": [11580], - "structures": [11830], + "includes": [11610], + "structures": [11860], }, "chrome/browser/resources/invalidations_resources.grd": { - "includes": [11880], + "includes": [11910], }, "chrome/browser/resources/md_policy/policy_resources.grd": { - "structures": [11890], + "structures": [11920], }, "chrome/browser/resources/net_internals_resources.grd": { - "includes": [11930], + "includes": [11960], }, "chrome/browser/resources/options_resources.grd": { - "includes": [11940], - "structures": [11950], + "includes": [11970], + "structures": [11980], }, "chrome/browser/resources/password_manager_internals_resources.grd": { - "includes": [12010], - }, - "chrome/browser/resources/quota_internals_resources.grd": { - "includes": [12020], - }, - "chrome/browser/resources/settings/settings_resources_vulcanized.grd": { "includes": [12040], }, + "chrome/browser/resources/quota_internals_resources.grd": { + "includes": [12050], + }, + "chrome/browser/resources/settings/settings_resources_vulcanized.grd": { + "includes": [12070], + }, "chrome/browser/resources/settings/settings_resources.grd": { - "structures": [12050], + "structures": [12080], }, "chrome/browser/resources/sync_file_system_internals_resources.grd": { - "includes": [12550], - }, - "chrome/browser/resources/task_scheduler_internals/resources.grd": { "includes": [12580], }, + "chrome/browser/resources/task_scheduler_internals/resources.grd": { + "includes": [12610], + }, "chrome/browser/resources/translate_internals_resources.grd": { - "includes": [12590], + "includes": [12620], }, "chrome/browser/resources/webapks_ui_resources.grd": { - "includes": [12600], + "includes": [12630], }, # END chrome/browser section. # START chrome/ miscellaneous section. "chrome/common/common_resources.grd": { - "includes": [12720], + "includes": [12750], }, "chrome/renderer/resources/renderer_resources.grd": { - "includes": [12730], - "structures": [12810], + "includes": [12760], + "structures": [12840], }, "chrome/test/data/webui_test_resources.grd": { - "includes": [12820], + "includes": [12850], }, # END chrome/ miscellaneous section.
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index a6188e62..6d33b55 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -1122,7 +1122,18 @@ <description>User closed the Chrome Home bottom sheet.</description> </action> +<action name="Android.ChromeHome.ClosedByBackPress"> + <owner>mdjones@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <description> + User closed the Chrome Home bottom sheet by pressing the system back button. + </description> +</action> + <action name="Android.ChromeHome.ClosedByNTPCloseButton"> + <obsolete> + Deprecated 6/2017. There is no longer an NTP UI with a close button. + </obsolete> <owner>mdjones@chromium.org</owner> <owner>twellington@chromium.org</owner> <description> @@ -1170,6 +1181,16 @@ </description> </action> +<action name="Android.ChromeHome.NativeNTPShown"> + <owner>mdjones@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <description> + A user navigation instructed the NativePageFactory to create a native page + for the NTP. This may occur if the user has NTP URLs in a tab's navigation + history. + </description> +</action> + <action name="Android.ChromeHome.Opened"> <obsolete> Deprecated 5/2017. Replaced by the versions with a suffix, which are more
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b20478a..b80a3a8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -93041,6 +93041,7 @@ <affected-histogram name="OfflinePages.Background.FinalSavePageResult"/> <affected-histogram name="OfflinePages.Background.LoadingErrorStatusCode"/> <affected-histogram name="OfflinePages.Background.OfflinerRequestStatus"/> + <affected-histogram name="OfflinePages.Background.OffliningPreviewStatus"/> <affected-histogram name="OfflinePages.Background.TimeToCanceled"/> <affected-histogram name="OfflinePages.Background.TimeToSaved"/> <affected-histogram name="OfflinePages.Background.TimeToStart"/>
diff --git a/ui/base/ime/chromeos/input_method_util.cc b/ui/base/ime/chromeos/input_method_util.cc index c903ae5..f93231a 100644 --- a/ui/base/ime/chromeos/input_method_util.cc +++ b/ui/base/ime/chromeos/input_method_util.cc
@@ -378,13 +378,23 @@ ResetInputMethods(default_input_methods); // Initialize a map from English string to Chrome string resource ID as well. + // Since this array is write-once, initialize a flat map in one step with a + // given vector storage. + // + // TODO(brettw) this could be optimized further to binary search in the + // static data, avoiding this up-front cost. + std::vector<EnglishToIDMap::value_type> map_storage; + map_storage.reserve(kEnglishToResourceIdArraySize); for (size_t i = 0; i < kEnglishToResourceIdArraySize; ++i) { const EnglishToResouceId& map_entry = kEnglishToResourceIdArray[i]; - const bool result = english_to_resource_id_.insert(std::make_pair( - map_entry.english_string_from_ibus, map_entry.resource_id)).second; - DCHECK(result) << "Duplicated string is found: " - << map_entry.english_string_from_ibus; + map_storage.emplace_back(map_entry.english_string_from_ibus, + map_entry.resource_id); } + + english_to_resource_id_ = + EnglishToIDMap(std::move(map_storage), base::KEEP_FIRST_OF_DUPES); + DCHECK(english_to_resource_id_.size() == kEnglishToResourceIdArraySize) + << "Duplicate string is found"; } InputMethodUtil::~InputMethodUtil() {} @@ -413,7 +423,7 @@ // to get the translated string. std::string key_string = extension_ime_util::MaybeGetLegacyXkbId( english_string); - HashType::const_iterator iter = english_to_resource_id_.find(key_string); + auto iter = english_to_resource_id_.find(key_string); if (iter == english_to_resource_id_.end()) { // TODO(yusukes): Write Autotest which checks if all display names and all
diff --git a/ui/base/ime/chromeos/input_method_util.h b/ui/base/ime/chromeos/input_method_util.h index 06f886f..36565a7 100644 --- a/ui/base/ime/chromeos/input_method_util.h +++ b/ui/base/ime/chromeos/input_method_util.h
@@ -11,7 +11,7 @@ #include <string> #include <vector> -#include "base/containers/hash_tables.h" +#include "base/containers/flat_map.h" #include "base/macros.h" #include "base/strings/string16.h" #include "base/threading/thread_checker.h" @@ -206,8 +206,8 @@ LanguageCodeToIdsMap language_code_to_ids_; InputMethodIdToDescriptorMap id_to_descriptor_; - typedef base::hash_map<std::string, int> HashType; - HashType english_to_resource_id_; + using EnglishToIDMap = base::flat_map<std::string, int>; + EnglishToIDMap english_to_resource_id_; InputMethodDelegate* delegate_;
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index a29f0e3..01c52ef 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -34,7 +34,6 @@ #include "cc/surfaces/surface_manager.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" -#include "components/viz/host/host_frame_sink_manager.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/compositor/compositor_observer.h" #include "ui/compositor/compositor_switches.h" @@ -201,13 +200,12 @@ context_factory_->RemoveCompositor(this); if (context_factory_private_) { - auto* manager = context_factory_private_->GetHostFrameSinkManager(); + auto* manager = context_factory_private_->GetSurfaceManager(); for (auto& client : child_frame_sinks_) { DCHECK(client.is_valid()); manager->UnregisterFrameSinkHierarchy(frame_sink_id_, client); } - context_factory_private_->GetSurfaceManager()->InvalidateFrameSinkId( - frame_sink_id_); + manager->InvalidateFrameSinkId(frame_sink_id_); } } @@ -218,8 +216,8 @@ void Compositor::AddFrameSink(const cc::FrameSinkId& frame_sink_id) { if (!context_factory_private_) return; - context_factory_private_->GetHostFrameSinkManager() - ->RegisterFrameSinkHierarchy(frame_sink_id_, frame_sink_id); + context_factory_private_->GetSurfaceManager()->RegisterFrameSinkHierarchy( + frame_sink_id_, frame_sink_id); child_frame_sinks_.insert(frame_sink_id); } @@ -229,8 +227,8 @@ auto it = child_frame_sinks_.find(frame_sink_id); DCHECK(it != child_frame_sinks_.end()); DCHECK(it->is_valid()); - context_factory_private_->GetHostFrameSinkManager() - ->UnregisterFrameSinkHierarchy(frame_sink_id_, *it); + context_factory_private_->GetSurfaceManager()->UnregisterFrameSinkHierarchy( + frame_sink_id_, *it); child_frame_sinks_.erase(it); }
diff --git a/ui/gl/gl_context_egl.cc b/ui/gl/gl_context_egl.cc index 2fbfe08..63cdb22 100644 --- a/ui/gl/gl_context_egl.cc +++ b/ui/gl/gl_context_egl.cc
@@ -197,7 +197,8 @@ } bool GLContextEGL::MakeCurrent(GLSurface* surface) { - DCHECK(context_); + // TODO(sunnyps): Revert to DCHECK after crbug.com/724999 is fixed. + CHECK(context_); if (IsCurrent(surface)) return true; @@ -253,14 +254,16 @@ } bool GLContextEGL::IsCurrent(GLSurface* surface) { - DCHECK(context_); + // TODO(sunnyps): Revert to DCHECK after crbug.com/724999 is fixed. + CHECK(context_); bool native_context_is_current = context_ == eglGetCurrentContext(); // If our context is current then our notion of which GLContext is // current must be correct. On the other hand, third-party code // using OpenGL might change the current context. - DCHECK(!native_context_is_current || (GetRealCurrent() == this)); + // TODO(sunnyps): Revert to DCHECK after crbug.com/724999 is fixed. + CHECK(!native_context_is_current || (GetRealCurrent() == this)); if (!native_context_is_current) return false;
diff --git a/ui/message_center/views/notification_header_view.cc b/ui/message_center/views/notification_header_view.cc index 0911609..7a4fa5d 100644 --- a/ui/message_center/views/notification_header_view.cc +++ b/ui/message_center/views/notification_header_view.cc
@@ -14,6 +14,9 @@ #include "ui/message_center/vector_icons.h" #include "ui/message_center/views/padded_button.h" #include "ui/strings/grit/ui_strings.h" +#include "ui/views/animation/flood_fill_ink_drop_ripple.h" +#include "ui/views/animation/ink_drop_highlight.h" +#include "ui/views/animation/ink_drop_impl.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" @@ -33,10 +36,24 @@ // Bullet character. The divider symbol between different parts of the header. constexpr base::char16 kNotificationHeaderDividerSymbol = 0x2022; +// Base ink drop color of action buttons. +const SkColor kInkDropBaseColor = SkColorSetRGB(0x0, 0x0, 0x0); +// Ripple ink drop opacity of action buttons. +constexpr float kInkDropRippleVisibleOpacity = 0.08f; +// Highlight (hover) ink drop opacity of action buttons. +constexpr float kInkDropHighlightVisibleOpacity = 0.08f; + } // namespace NotificationHeaderView::NotificationHeaderView(views::ButtonListener* listener) : views::CustomButton(listener) { + SetInkDropMode(InkDropMode::ON); + set_has_ink_drop_action_on_click(true); + set_animate_on_state_change(true); + set_notify_enter_exit_on_child(true); + set_ink_drop_base_color(kInkDropBaseColor); + set_ink_drop_visible_opacity(kInkDropRippleVisibleOpacity); + views::BoxLayout* layout = new views::BoxLayout( views::BoxLayout::kHorizontal, kHeaderPadding, kHeaderHorizontalSpacing); layout->set_cross_axis_alignment( @@ -184,6 +201,30 @@ return close_button_enabled_; } +std::unique_ptr<views::InkDrop> NotificationHeaderView::CreateInkDrop() { + auto ink_drop = base::MakeUnique<views::InkDropImpl>(this, size()); + ink_drop->SetAutoHighlightMode( + views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE); + ink_drop->SetShowHighlightOnHover(false); + return ink_drop; +} + +std::unique_ptr<views::InkDropRipple> +NotificationHeaderView::CreateInkDropRipple() const { + return base::MakeUnique<views::FloodFillInkDropRipple>( + size(), GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(), + ink_drop_visible_opacity()); +} + +std::unique_ptr<views::InkDropHighlight> +NotificationHeaderView::CreateInkDropHighlight() const { + auto highlight = base::MakeUnique<views::InkDropHighlight>( + size(), kInkDropSmallCornerRadius, + gfx::RectF(GetLocalBounds()).CenterPoint(), GetInkDropBaseColor()); + highlight->set_visible_opacity(kInkDropHighlightVisibleOpacity); + return highlight; +} + void NotificationHeaderView::UpdateControlButtonsVisibility() { settings_button_->SetVisible(settings_button_enabled_ && is_control_buttons_visible_);
diff --git a/ui/message_center/views/notification_header_view.h b/ui/message_center/views/notification_header_view.h index 640f6be..addc8d19 100644 --- a/ui/message_center/views/notification_header_view.h +++ b/ui/message_center/views/notification_header_view.h
@@ -34,6 +34,12 @@ bool IsCloseButtonEnabled(); bool IsCloseButtonFocused(); + // CustomButton override: + std::unique_ptr<views::InkDrop> CreateInkDrop() override; + std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override; + std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() + const override; + views::ImageButton* expand_button() { return expand_button_; } views::ImageButton* settings_button() { return settings_button_; } views::ImageButton* close_button() { return close_button_; }