diff --git a/DEPS b/DEPS index 94476aa..1b90e811 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '9fd55f76d82496ca9233bd180f69152ff14b6613', + 'v8_revision': '170a71e43122d2f7aa8300433e33ca4782349fd7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other.
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index 650336b0..58b8e588 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -1124,15 +1124,9 @@ EXPECT_TRUE(test_api.is_animating_lock()); #endif - auto press_and_release_alt_tab = [&generator]() { - generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); - // Release the alt key to trigger the window activation. - generator.ReleaseKey(ui::VKEY_MENU, ui::EF_NONE); - }; - // A fullscreen window can consume ALT-TAB (preferred). ASSERT_EQ(w1, wm::GetActiveWindow()); - press_and_release_alt_tab(); + generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); ASSERT_EQ(w1, wm::GetActiveWindow()); ASSERT_NE(w2, wm::GetActiveWindow()); @@ -1147,7 +1141,7 @@ ASSERT_FALSE(w1_state->IsFullscreen()); EXPECT_EQ(w1, wm::GetActiveWindow()); - press_and_release_alt_tab(); + generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); ASSERT_NE(w1, wm::GetActiveWindow()); ASSERT_EQ(w2, wm::GetActiveWindow()); }
diff --git a/ash/common/ash_switches.cc b/ash/common/ash_switches.cc index ee32e4b3..1e45a7e 100644 --- a/ash/common/ash_switches.cc +++ b/ash/common/ash_switches.cc
@@ -78,6 +78,9 @@ // removed. const char kAshEnableTouchViewTesting[] = "ash-enable-touch-view-testing"; +// Enables the window cycling UI (more visual feedback for alt-tab). +const char kAshEnableWindowCycleUi[] = "ash-enable-window-cycle-ui"; + // Hides notifications that are irrelevant to Chrome OS device factory testing, // such as battery level updates. const char kAshHideNotificationsForFactory[] =
diff --git a/ash/common/ash_switches.h b/ash/common/ash_switches.h index 2d19523..21617aa 100644 --- a/ash/common/ash_switches.h +++ b/ash/common/ash_switches.h
@@ -38,6 +38,7 @@ ASH_EXPORT extern const char kAshEnableStableOverviewOrder[]; ASH_EXPORT extern const char kAshEnableSoftwareMirroring[]; ASH_EXPORT extern const char kAshEnableTouchViewTesting[]; +ASH_EXPORT extern const char kAshEnableWindowCycleUi[]; ASH_EXPORT extern const char kAshHideNotificationsForFactory[]; ASH_EXPORT extern const char kAshHostWindowBounds[]; ASH_EXPORT extern const char kAshMaterialDesign[];
diff --git a/ash/common/wm/window_cycle_controller.cc b/ash/common/wm/window_cycle_controller.cc index 4808148..6135f600 100644 --- a/ash/common/wm/window_cycle_controller.cc +++ b/ash/common/wm/window_cycle_controller.cc
@@ -6,12 +6,10 @@ #include "ash/common/metrics/task_switch_source.h" #include "ash/common/session/session_state_delegate.h" -#include "ash/common/shell_window_ids.h" #include "ash/common/wm/mru_window_tracker.h" #include "ash/common/wm/window_cycle_event_filter.h" #include "ash/common/wm/window_cycle_list.h" #include "ash/common/wm_shell.h" -#include "ash/common/wm_window.h" #include "base/metrics/histogram.h" namespace ash { @@ -54,19 +52,6 @@ void WindowCycleController::StartCycling() { MruWindowTracker::WindowList window_list = WmShell::Get()->mru_window_tracker()->BuildMruWindowList(); - // Exclude the AppList window, which will hide as soon as cycling starts - // anyway. It doesn't make sense to count it as a "switchable" window, yet - // a lot of code relies on the MRU list returning the app window. If we - // don't manually remove it, the window cycling UI won't crash or misbehave, - // but there will be a flicker as the target window changes. - window_list.erase(std::remove_if(window_list.begin(), window_list.end(), - [](WmWindow* window) { - return window->GetRootWindow() - ->GetChildByShellWindowId( - kShellWindowId_AppListContainer) - ->Contains(window); - }), - window_list.end()); active_window_before_window_cycle_ = GetActiveWindow(window_list);
diff --git a/ash/common/wm/window_cycle_list.cc b/ash/common/wm/window_cycle_list.cc index 845dcaa..2c0ec797 100644 --- a/ash/common/wm/window_cycle_list.cc +++ b/ash/common/wm/window_cycle_list.cc
@@ -30,10 +30,6 @@ namespace ash { -namespace { - -bool g_disable_initial_delay = false; - // Returns the window immediately below |window| in the current container. WmWindow* GetWindowBelow(WmWindow* window) { WmWindow* parent = window->GetParent(); @@ -65,8 +61,6 @@ DISALLOW_COPY_AND_ASSIGN(LayerFillBackgroundPainter); }; -} // namespace - // This class restores and moves a window to the front of the stacking order for // the duration of the class's scope. class ScopedShowWindow : public WmWindowObserver { @@ -308,28 +302,16 @@ target_window_ = target; if (GetWidget()) { Layout(); - if (target_window_) { - // In the window destruction case, we may have already removed the - // focused view and hence not be the focused window. We should still - // always be active, though. - DCHECK_EQ(ash::WmShell::Get()->GetActiveWindow()->GetInternalWidget(), - GetWidget()); - window_view_map_[target_window_]->RequestFocus(); - } + DCHECK(Contains(GetFocusManager()->GetFocusedView())); + window_view_map_[target_window_]->RequestFocus(); } } void HandleWindowDestruction(WmWindow* destroying_window, WmWindow* new_target) { auto view_iter = window_view_map_.find(destroying_window); - views::View* parent = view_iter->second->parent(); - DCHECK_EQ(mirror_container_, parent); - parent->RemoveChildView(view_iter->second); + view_iter->second->parent()->RemoveChildView(view_iter->second); window_view_map_.erase(view_iter); - // With one of its children now gone, we must re-layout |mirror_container_|. - // This must happen before SetTargetWindow() to make sure our own Layout() - // works correctly when it's calculating highlight bounds. - parent->Layout(); SetTargetWindow(new_target); } @@ -433,26 +415,19 @@ WindowCycleList::WindowCycleList(const WindowList& windows) : windows_(windows), current_index_(0), cycle_view_(nullptr) { - if (!ShouldShowUi()) - WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(true); + WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(true); for (WmWindow* window : windows_) window->AddObserver(this); if (ShouldShowUi()) { - if (g_disable_initial_delay) { - InitWindowCycleView(); - } else { - show_ui_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(150), - this, &WindowCycleList::InitWindowCycleView); - } + show_ui_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(150), + this, &WindowCycleList::InitWindowCycleView); } } WindowCycleList::~WindowCycleList() { - if (!ShouldShowUi()) - WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(false); - + WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(false); for (WmWindow* window : windows_) window->RemoveObserver(this); @@ -500,11 +475,6 @@ } } -// static -void WindowCycleList::DisableInitialDelayForTesting() { - g_disable_initial_delay = true; -} - void WindowCycleList::OnWindowDestroying(WmWindow* window) { window->RemoveObserver(this); @@ -531,7 +501,9 @@ } bool WindowCycleList::ShouldShowUi() { - return windows_.size() > 1; + return windows_.size() > 1 && + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAshEnableWindowCycleUi); } void WindowCycleList::InitWindowCycleView() {
diff --git a/ash/common/wm/window_cycle_list.h b/ash/common/wm/window_cycle_list.h index 6d073d16..34af309 100644 --- a/ash/common/wm/window_cycle_list.h +++ b/ash/common/wm/window_cycle_list.h
@@ -42,9 +42,6 @@ private: friend class WindowCycleControllerTest; - - static void DisableInitialDelayForTesting(); - const WindowList& windows() const { return windows_; } // WmWindowObserver overrides: @@ -70,8 +67,6 @@ int current_index_; // Wrapper for the window brought to the front. - // TODO(estade): remove ScopedShowWindow when we know we are happy launching - // the |cycle_view_| version. std::unique_ptr<ScopedShowWindow> showing_window_; // The top level View for the window cycle UI. May be null if the UI is not
diff --git a/ash/wm/window_cycle_controller_unittest.cc b/ash/wm/window_cycle_controller_unittest.cc index 48ab3b3..ad61331f 100644 --- a/ash/wm/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle_controller_unittest.cc
@@ -78,8 +78,6 @@ test::AshTestBase::SetUp(); ASSERT_TRUE(test::TestShelfDelegate::instance()); - WindowCycleList::DisableInitialDelayForTesting(); - shelf_view_test_.reset(new test::ShelfViewTestAPI( test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).shelf_view())); shelf_view_test_->SetAnimationDuration(1); @@ -175,12 +173,15 @@ // all the windows and wrap around. controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_TRUE(controller->IsCycling()); + EXPECT_TRUE(wm::IsActiveWindow(window1.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_TRUE(controller->IsCycling()); + EXPECT_TRUE(wm::IsActiveWindow(window2.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_TRUE(controller->IsCycling()); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); controller->StopCycling(); EXPECT_FALSE(controller->IsCycling()); @@ -191,29 +192,29 @@ wm::ActivateWindow(window1.get()); wm::ActivateWindow(window0.get()); - // Likewise we can cycle backwards through the windows. + // Likewise we can cycle backwards through all the windows. controller->HandleCycleWindow(WindowCycleController::BACKWARD); + EXPECT_TRUE(wm::IsActiveWindow(window2.get())); controller->HandleCycleWindow(WindowCycleController::BACKWARD); - controller->StopCycling(); EXPECT_TRUE(wm::IsActiveWindow(window1.get())); - - // Reset our stacking order. - wm::ActivateWindow(window2.get()); - wm::ActivateWindow(window1.get()); - wm::ActivateWindow(window0.get()); + controller->HandleCycleWindow(WindowCycleController::BACKWARD); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); + controller->StopCycling(); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); // When the screen is locked, cycling window does not take effect. WmShell::Get()->GetSessionStateDelegate()->LockScreen(); EXPECT_TRUE(wm::IsActiveWindow(window0.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_FALSE(controller->IsCycling()); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); + controller->HandleCycleWindow(WindowCycleController::BACKWARD); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); - // Unlock, it works again. WmShell::Get()->GetSessionStateDelegate()->UnlockScreen(); EXPECT_TRUE(wm::IsActiveWindow(window0.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window1.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); - controller->StopCycling(); EXPECT_TRUE(wm::IsActiveWindow(window2.get())); // When a modal window is active, cycling window does not take effect. @@ -226,13 +227,11 @@ EXPECT_TRUE(wm::IsActiveWindow(modal_window.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_TRUE(wm::IsActiveWindow(modal_window.get())); - EXPECT_FALSE(controller->IsCycling()); EXPECT_FALSE(wm::IsActiveWindow(window0.get())); EXPECT_FALSE(wm::IsActiveWindow(window1.get())); EXPECT_FALSE(wm::IsActiveWindow(window2.get())); controller->HandleCycleWindow(WindowCycleController::BACKWARD); EXPECT_TRUE(wm::IsActiveWindow(modal_window.get())); - EXPECT_FALSE(controller->IsCycling()); EXPECT_FALSE(wm::IsActiveWindow(window0.get())); EXPECT_FALSE(wm::IsActiveWindow(window1.get())); EXPECT_FALSE(wm::IsActiveWindow(window2.get())); @@ -251,13 +250,10 @@ // Rotate focus, this should move focus to window0. WindowCycleController* controller = WmShell::Get()->window_cycle_controller(); controller->HandleCycleWindow(WindowCycleController::FORWARD); - controller->StopCycling(); EXPECT_TRUE(wm::GetWindowState(window0.get())->IsActive()); - EXPECT_FALSE(window1_state->IsActive()); // One more time. controller->HandleCycleWindow(WindowCycleController::FORWARD); - controller->StopCycling(); EXPECT_TRUE(window1_state->IsActive()); } @@ -276,14 +272,11 @@ // Rotate focus, this should move focus to window1 and unminimize it. WindowCycleController* controller = WmShell::Get()->window_cycle_controller(); controller->HandleCycleWindow(WindowCycleController::FORWARD); - controller->StopCycling(); - EXPECT_FALSE(window0_state->IsActive()); EXPECT_FALSE(window1_state->IsMinimized()); EXPECT_TRUE(window1_state->IsActive()); // One more time back to w0. controller->HandleCycleWindow(WindowCycleController::FORWARD); - controller->StopCycling(); EXPECT_TRUE(window0_state->IsActive()); } @@ -309,6 +302,23 @@ EXPECT_EQ(window0.get(), GetWindows(controller)[0]); EXPECT_EQ(window2.get(), GetWindows(controller)[1]); EXPECT_EQ(window1.get(), GetWindows(controller)[2]); + + controller->StopCycling(); + EXPECT_TRUE(wm::IsActiveWindow(window2.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); + + controller->StopCycling(); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window2.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window1.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); } TEST_F(WindowCycleControllerTest, AlwaysOnTopMultiWindow) { @@ -335,6 +345,26 @@ EXPECT_EQ(window3.get(), GetWindows(controller)[1]); EXPECT_EQ(window2.get(), GetWindows(controller)[2]); EXPECT_EQ(window1.get(), GetWindows(controller)[3]); + + controller->StopCycling(); + EXPECT_TRUE(wm::IsActiveWindow(window3.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); + + controller->StopCycling(); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window3.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window2.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window1.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); } TEST_F(WindowCycleControllerTest, AlwaysOnTopMultipleRootWindows) { @@ -385,6 +415,26 @@ EXPECT_EQ(window3.get(), GetWindows(controller)[1]); EXPECT_EQ(window1.get(), GetWindows(controller)[2]); EXPECT_EQ(window0.get(), GetWindows(controller)[3]); + + controller->StopCycling(); + EXPECT_TRUE(wm::IsActiveWindow(window3.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window2.get())); + + controller->StopCycling(); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window3.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window1.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window2.get())); } TEST_F(WindowCycleControllerTest, MostRecentlyUsed) { @@ -408,19 +458,23 @@ EXPECT_EQ(window2.get(), GetWindows(controller)[1]); EXPECT_EQ(window1.get(), GetWindows(controller)[2]); - // Cycling through then stopping the cycling will activate a window. controller->HandleCycleWindow(WindowCycleController::FORWARD); controller->StopCycling(); EXPECT_TRUE(wm::IsActiveWindow(window1.get())); - // Cycling alone (without StopCycling()) doesn't activate. controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_FALSE(wm::IsActiveWindow(window0.get())); - - // Showing the Alt+Tab UI does however deactivate the erstwhile active window. - EXPECT_FALSE(wm::IsActiveWindow(window1.get())); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); controller->StopCycling(); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window1.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window2.get())); + + controller->HandleCycleWindow(WindowCycleController::FORWARD); + EXPECT_TRUE(wm::IsActiveWindow(window0.get())); } // Tests that beginning window selection hides the app list. @@ -433,14 +487,10 @@ EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); - - // Make sure that dismissing the app list this way doesn't pass activation - // to a different window. - EXPECT_FALSE(wm::IsActiveWindow(window0.get())); - EXPECT_FALSE(wm::IsActiveWindow(window1.get())); } -// Tests that cycling through windows doesn't change their minimized state. +// Tests that cycling through windows shows and minimizes windows as they +// are passed. TEST_F(WindowCycleControllerTest, CyclePreservesMinimization) { WindowCycleController* controller = WmShell::Get()->window_cycle_controller(); @@ -453,7 +503,7 @@ // On window 2. controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(IsWindowMinimized(window1.get())); + EXPECT_FALSE(IsWindowMinimized(window1.get())); // Back on window 1. controller->HandleCycleWindow(WindowCycleController::FORWARD);
diff --git a/ash/wm/window_mirror_view.cc b/ash/wm/window_mirror_view.cc index 374207c..58c89e1 100644 --- a/ash/wm/window_mirror_view.cc +++ b/ash/wm/window_mirror_view.cc
@@ -104,9 +104,6 @@ } gfx::Rect WindowMirrorView::GetClientAreaBounds() const { - // The target window may not have a widget in unit tests. - if (!target_->GetInternalWidget()) - return gfx::Rect(); views::View* client_view = target_->GetInternalWidget()->client_view(); return client_view->ConvertRectToWidget(client_view->GetLocalBounds()); }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 1173e9a..3f5251ce 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -6021,6 +6021,12 @@ <message name="IDS_FLAGS_ASH_ENABLE_UNIFIED_DESKTOP_DESCRIPTION" desc="Description for the flag to enable unified desktop mode."> Enable unified desktop mode which allows a window to span multiple displays. </message> + <message name="IDS_FLAGS_ASH_ENABLE_WINDOW_CYCLE_UI_NAME" desc="Name for the flag to enable the window cycle (Alt+Tab) UI."> + Enable window cycle UI. + </message> + <message name="IDS_FLAGS_ASH_ENABLE_WINDOW_CYCLE_UI_DESCRIPTION" desc="Description for the flag to enable the window cycle (Alt+Tab) UI."> + Enable window cycle UI (visual feedback for Alt+Tab). + </message> <message name="IDS_FLAGS_BOOT_ANIMATION" desc="Name for the flag for wallpaper boot animation (except for OOBE)."> Boot animation </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 5a01c86..509cdbf 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -911,6 +911,9 @@ {"ash-enable-unified-desktop", IDS_FLAGS_ASH_ENABLE_UNIFIED_DESKTOP_NAME, IDS_FLAGS_ASH_ENABLE_UNIFIED_DESKTOP_DESCRIPTION, kOsCrOS, SINGLE_VALUE_TYPE(ash::switches::kAshEnableUnifiedDesktop)}, + {"ash-enable-window-cycle-ui", IDS_FLAGS_ASH_ENABLE_WINDOW_CYCLE_UI_NAME, + IDS_FLAGS_ASH_ENABLE_WINDOW_CYCLE_UI_DESCRIPTION, kOsCrOS, + SINGLE_VALUE_TYPE(ash::switches::kAshEnableWindowCycleUi)}, {"enable-easy-unlock-proximity-detection", IDS_FLAGS_EASY_UNLOCK_PROXIMITY_DETECTION_NAME, IDS_FLAGS_EASY_UNLOCK_PROXIMITY_DETECTION_DESCRIPTION, kOsCrOS,
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 1672f19..8709696 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -892,7 +892,8 @@ scoped_refptr<update_client::Configurator> configurator = component_updater::MakeChromeComponentUpdaterConfigurator( base::CommandLine::ForCurrentProcess(), - io_thread()->system_url_request_context_getter()); + io_thread()->system_url_request_context_getter(), + g_browser_process->local_state()); // Creating the component updater does not do anything, components // need to be registered and Start() needs to be called. component_updater_.reset(component_updater::ComponentUpdateServiceFactory( @@ -952,8 +953,7 @@ Unpin(); } -void BrowserProcessImpl::OnKeepAliveRestartStateChanged(bool can_restart){ -} +void BrowserProcessImpl::OnKeepAliveRestartStateChanged(bool can_restart) {} void BrowserProcessImpl::CreateWatchdogThread() { DCHECK(!created_watchdog_thread_ && !watchdog_thread_);
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 4514bc6f..67f4273 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -196,6 +196,11 @@ TestParameter(NOT_IN_GUEST_MODE, "deleteOneItemFromToolbar"))); WRAPPED_INSTANTIATE_TEST_CASE_P( + QuickView, + FileManagerBrowserTest, + ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openQuickView"))); + +WRAPPED_INSTANTIATE_TEST_CASE_P( DetailsPanel, FileManagerDetailsPanelBrowserTest, ::testing::Values(
diff --git a/chrome/browser/component_updater/chrome_component_updater_configurator.cc b/chrome/browser/component_updater/chrome_component_updater_configurator.cc index fb5832cf..4e1b1ad 100644 --- a/chrome/browser/component_updater/chrome_component_updater_configurator.cc +++ b/chrome/browser/component_updater/chrome_component_updater_configurator.cc
@@ -32,7 +32,8 @@ class ChromeConfigurator : public update_client::Configurator { public: ChromeConfigurator(const base::CommandLine* cmdline, - net::URLRequestContextGetter* url_request_getter); + net::URLRequestContextGetter* url_request_getter, + PrefService* pref_service); // update_client::Configurator overrides. int InitialDelay() const override; @@ -65,6 +66,8 @@ ConfiguratorImpl configurator_impl_; + PrefService* pref_service_; // This member is not owned by this class. + ~ChromeConfigurator() override {} }; @@ -73,8 +76,12 @@ // a custom message signing protocol and it does not depend on using HTTPS. ChromeConfigurator::ChromeConfigurator( const base::CommandLine* cmdline, - net::URLRequestContextGetter* url_request_getter) - : configurator_impl_(cmdline, url_request_getter, false) {} + net::URLRequestContextGetter* url_request_getter, + PrefService* pref_service) + : configurator_impl_(cmdline, url_request_getter, false), + pref_service_(pref_service) { + DCHECK(pref_service_); +} int ChromeConfigurator::InitialDelay() const { return configurator_impl_.InitialDelay(); @@ -181,7 +188,8 @@ } PrefService* ChromeConfigurator::GetPrefService() const { - return g_browser_process->local_state(); + DCHECK(pref_service_); + return pref_service_; } } // namespace @@ -189,8 +197,9 @@ scoped_refptr<update_client::Configurator> MakeChromeComponentUpdaterConfigurator( const base::CommandLine* cmdline, - net::URLRequestContextGetter* context_getter) { - return new ChromeConfigurator(cmdline, context_getter); + net::URLRequestContextGetter* context_getter, + PrefService* pref_service) { + return new ChromeConfigurator(cmdline, context_getter, pref_service); } } // namespace component_updater
diff --git a/chrome/browser/component_updater/chrome_component_updater_configurator.h b/chrome/browser/component_updater/chrome_component_updater_configurator.h index 1e777b2..674059c 100644 --- a/chrome/browser/component_updater/chrome_component_updater_configurator.h +++ b/chrome/browser/component_updater/chrome_component_updater_configurator.h
@@ -8,6 +8,8 @@ #include "base/memory/ref_counted.h" #include "components/update_client/configurator.h" +class PrefService; + namespace base { class CommandLine; } @@ -21,7 +23,8 @@ scoped_refptr<update_client::Configurator> MakeChromeComponentUpdaterConfigurator( const base::CommandLine* cmdline, - net::URLRequestContextGetter* context_getter); + net::URLRequestContextGetter* context_getter, + PrefService* pref_service); } // namespace component_updater
diff --git a/chrome/browser/component_updater/chrome_component_updater_configurator_unittest.cc b/chrome/browser/component_updater/chrome_component_updater_configurator_unittest.cc index b464a779..49ffa83 100644 --- a/chrome/browser/component_updater/chrome_component_updater_configurator_unittest.cc +++ b/chrome/browser/component_updater/chrome_component_updater_configurator_unittest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> #include <string> #include <vector> @@ -11,27 +12,47 @@ #include "components/component_updater/component_updater_switches.h" #include "components/component_updater/component_updater_url_constants.h" #include "components/component_updater/configurator_impl.h" +#include "components/prefs/testing_pref_service.h" #include "components/update_client/configurator.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" namespace component_updater { -TEST(ChromeComponentUpdaterConfiguratorTest, TestDisablePings) { +class ChromeComponentUpdaterConfiguratorTest : public testing::Test { + public: + ChromeComponentUpdaterConfiguratorTest(); + ~ChromeComponentUpdaterConfiguratorTest() override{}; + + protected: + PrefService* pref_service() { return pref_service_.get(); } + + private: + std::unique_ptr<TestingPrefServiceSimple> pref_service_; + + DISALLOW_COPY_AND_ASSIGN(ChromeComponentUpdaterConfiguratorTest); +}; + +ChromeComponentUpdaterConfiguratorTest::ChromeComponentUpdaterConfiguratorTest() + : pref_service_(new TestingPrefServiceSimple()) {} + +TEST_F(ChromeComponentUpdaterConfiguratorTest, TestDisablePings) { base::CommandLine cmdline(*base::CommandLine::ForCurrentProcess()); cmdline.AppendSwitchASCII(switches::kComponentUpdater, "disable-pings"); - const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr)); + const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr, + pref_service())); const std::vector<GURL> pingUrls = config->PingUrl(); EXPECT_TRUE(pingUrls.empty()); } -TEST(ChromeComponentUpdaterConfiguratorTest, TestFastUpdate) { +TEST_F(ChromeComponentUpdaterConfiguratorTest, TestFastUpdate) { base::CommandLine cmdline(*base::CommandLine::ForCurrentProcess()); cmdline.AppendSwitchASCII(switches::kComponentUpdater, "fast-update"); - const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr)); + const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr, + pref_service())); CHECK_EQ(10, config->InitialDelay()); CHECK_EQ(6 * 60 * 60, config->NextCheckDelay()); @@ -40,7 +61,7 @@ CHECK_EQ(10, config->UpdateDelay()); } -TEST(ChromeComponentUpdaterConfiguratorTest, TestOverrideUrl) { +TEST_F(ChromeComponentUpdaterConfiguratorTest, TestOverrideUrl) { const char overrideUrl[] = "http://0.0.0.0/"; base::CommandLine cmdline(*base::CommandLine::ForCurrentProcess()); @@ -50,7 +71,8 @@ val.append(overrideUrl); cmdline.AppendSwitchASCII(switches::kComponentUpdater, val.c_str()); - const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr)); + const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr, + pref_service())); const std::vector<GURL> urls = config->UpdateUrl(); @@ -58,18 +80,20 @@ ASSERT_EQ(overrideUrl, urls.at(0).possibly_invalid_spec()); } -TEST(ChromeComponentUpdaterConfiguratorTest, TestSwitchRequestParam) { +TEST_F(ChromeComponentUpdaterConfiguratorTest, TestSwitchRequestParam) { base::CommandLine cmdline(*base::CommandLine::ForCurrentProcess()); cmdline.AppendSwitchASCII(switches::kComponentUpdater, "test-request"); - const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr)); + const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr, + pref_service())); EXPECT_FALSE(config->ExtraRequestParams().empty()); } -TEST(ChromeComponentUpdaterConfiguratorTest, TestUpdaterDefaultUrl) { +TEST_F(ChromeComponentUpdaterConfiguratorTest, TestUpdaterDefaultUrl) { base::CommandLine cmdline(*base::CommandLine::ForCurrentProcess()); - const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr)); + const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr, + pref_service())); const auto urls = config->UpdateUrl(); // Expect the default url to be cryptographically secure. @@ -77,16 +101,18 @@ EXPECT_TRUE(urls.front().SchemeIsCryptographic()); } -TEST(ChromeComponentUpdaterConfiguratorTest, TestEnabledCupSigning) { +TEST_F(ChromeComponentUpdaterConfiguratorTest, TestEnabledCupSigning) { base::CommandLine cmdline(*base::CommandLine::ForCurrentProcess()); - const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr)); + const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr, + pref_service())); EXPECT_TRUE(config->EnabledCupSigning()); } -TEST(ChromeComponentUpdaterConfiguratorTest, TestUseEncryption) { +TEST_F(ChromeComponentUpdaterConfiguratorTest, TestUseEncryption) { base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); - const auto config(MakeChromeComponentUpdaterConfigurator(cmdline, nullptr)); + const auto config( + MakeChromeComponentUpdaterConfigurator(cmdline, nullptr, pref_service())); const auto urls = config->UpdateUrl(); ASSERT_EQ(2u, urls.size()); @@ -115,9 +141,10 @@ } } -TEST(ChromeComponentUpdaterConfiguratorTest, TestEnabledComponentUpdates) { +TEST_F(ChromeComponentUpdaterConfiguratorTest, TestEnabledComponentUpdates) { base::CommandLine cmdline(*base::CommandLine::ForCurrentProcess()); - const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr)); + const auto config(MakeChromeComponentUpdaterConfigurator(&cmdline, nullptr, + pref_service())); EXPECT_TRUE(config->EnabledComponentUpdates()); }
diff --git a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc index ccee531..5a3976cb 100644 --- a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc
@@ -151,19 +151,19 @@ web_ui()->RegisterMessageCallback( "updateStorageInfo", base::Bind(&StorageManagerHandler::HandleUpdateStorageInfo, - base::Unretained(this))); + weak_ptr_factory_.GetWeakPtr())); web_ui()->RegisterMessageCallback( "openDownloads", base::Bind(&StorageManagerHandler::HandleOpenDownloads, - base::Unretained(this))); + weak_ptr_factory_.GetWeakPtr())); web_ui()->RegisterMessageCallback( "openArcStorage", base::Bind(&StorageManagerHandler::HandleOpenArcStorage, - base::Unretained(this))); + weak_ptr_factory_.GetWeakPtr())); web_ui()->RegisterMessageCallback( "clearDriveCache", base::Bind(&StorageManagerHandler::HandleClearDriveCache, - base::Unretained(this))); + weak_ptr_factory_.GetWeakPtr())); } void StorageManagerHandler::HandleUpdateStorageInfo( @@ -422,7 +422,7 @@ "options.StorageManager.showArcItem"); bool success = arc::ArcStorageManager::Get()->GetApplicationsSize( base::Bind(&StorageManagerHandler::OnGetArcSize, - base::Unretained(this))); + weak_ptr_factory_.GetWeakPtr())); if (!success) updating_arc_size_ = false; }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 7e9b339..c03a0f0 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -8703.0.0 \ No newline at end of file +8705.0.0 \ No newline at end of file
diff --git a/content/renderer/media/webrtc_audio_device_not_impl.cc b/content/renderer/media/webrtc_audio_device_not_impl.cc index a86fca0..016c32e 100644 --- a/content/renderer/media/webrtc_audio_device_not_impl.cc +++ b/content/renderer/media/webrtc_audio_device_not_impl.cc
@@ -270,4 +270,32 @@ return 0; } +bool WebRtcAudioDeviceNotImpl::BuiltInAGCIsAvailable() const { + return false; +} + +int32_t WebRtcAudioDeviceNotImpl::EnableBuiltInAGC(bool enable) { + return 0; +} + +bool WebRtcAudioDeviceNotImpl::BuiltInNSIsAvailable() const { + return false; +} + +int32_t WebRtcAudioDeviceNotImpl::EnableBuiltInNS(bool enable) { + return 0; +} + +#if defined(OS_IOS) +int WebRtcAudioDeviceNotImpl::GetPlayoutAudioParameters( + AudioParameters* params) const { + return 0; +} + +int WebRtcAudioDeviceNotImpl::GetRecordAudioParameters( + AudioParameters* params) const { + return 0; +} +#endif // OS_IOS + } // namespace content
diff --git a/content/renderer/media/webrtc_audio_device_not_impl.h b/content/renderer/media/webrtc_audio_device_not_impl.h index f0291ed9..e9a98f0 100644 --- a/content/renderer/media/webrtc_audio_device_not_impl.h +++ b/content/renderer/media/webrtc_audio_device_not_impl.h
@@ -103,7 +103,15 @@ int32_t SetAGC(bool enable) override; bool AGC() const override; bool BuiltInAECIsAvailable() const override; + bool BuiltInAGCIsAvailable() const override; + bool BuiltInNSIsAvailable() const override; int32_t EnableBuiltInAEC(bool enable) override; + int32_t EnableBuiltInAGC(bool enable) override; + int32_t EnableBuiltInNS(bool enable) override; +#if defined(OS_IOS) + int GetPlayoutAudioParameters(AudioParameters* params) const override; + int GetRecordAudioParameters(AudioParameters* params) const override; +#endif // OS_IOS protected: ~WebRtcAudioDeviceNotImpl() override{};
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 96c5f18..ede53df 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -135,7 +135,7 @@ crbug.com/636222 [ Mac10.10 ] fast/repaint/fixed-and-absolute-position-scrolled.html [ Failure ] -crbug.com/636271 [ Mac10.10 ] fast/repaint/resize-iframe-text.html [ Pass Failure ] +crbug.com/636271 [ Mac ] fast/repaint/resize-iframe-text.html [ Pass Failure ] crbug.com/636271 [ Linux ] fast/repaint/resize-iframe-text.html [ Pass Failure ] crbug.com/636271 [ Win ] fast/repaint/resize-iframe-text.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html b/third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html new file mode 100644 index 0000000..e6b38428 --- /dev/null +++ b/third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html
@@ -0,0 +1,285 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/custom-elements-helpers.js"></script> +<body> +<script> +'use strict'; + +// Looks up the preceeding element (which should be a template +// element) and creates a Promise test. The test name is taken from +// the template's data-test attribute. +// +// The content of the template is loaded into an iframe. On load, f +// is passed the frame's content window to run assertions. +function test_with_content(f) { + let t = document.currentScript.previousElementSibling; + test_with_window(f, t.dataset.test, t.innerHTML); +} + +// Searches the document for an iframe with the specified content window. +function findFrameWithWindow(w) { + return Array.prototype.find.call(document.querySelectorAll('iframe'), (f) => { + return f.contentWindow === w; + }); +} + +test_with_window((w) => { + assert_equals(findFrameWithWindow(w).contentWindow, w, + 'should find the frame with this window'); + assert_equals(findFrameWithWindow(window), undefined, + 'should return undefined if there is no such frame'); +}, 'sanity check the findFrameWithWindow function'); +</script> + +<template data-test="the parser synchronously creates elements"> + <script> + 'use strict'; + + window.invocations = []; + customElements.define('a-a', class extends HTMLElement { + constructor() { + super(); + invocations.push('constructor'); + } + static get observedAttributes() { return ['x']; } + attributeChangedCallback(name, oldValue, newValue, nsuri) { + invocations.push(`${name}="${newValue}"`); + } + connectedCallback() { + invocations.push('connected'); + } + }); + </script> + <a-a x="y"> + <script> + 'use strict'; + + invocations.push('script'); + </script> + </a-a> +</template> +<script> +'use strict'; + +test_with_content((w) => { + assert_array_equals(w.invocations, + ['constructor', 'x="y"', 'connected', 'script']); +}); +</script> + +<template data-test="element creation failure produces unknown element"> + <script> + 'use strict'; + + customElements.define('a-a', class extends HTMLElement { + constructor() { + super(); + + // Returning this different, in-use element causes element + // creation to fail in + // https://dom.spec.whatwg.org/#concept-create-element steps + // 6.4-9, eg: "If result has children then then throw a + // NotSupportedError." + return document.documentElement; + } + }); + </script> + <a-a> +</template> +<script> +'use strict'; + +test_with_content((w) => { + let e = w.document.querySelector('a-a'); + assert_true(e.matches(':not(:defined)')); + assert_equals(Object.getPrototypeOf(e), w.HTMLUnknownElement.prototype); +}); +</script> + +<template data-test="modify tree during creation"> + <script> + 'use strict'; + + customElements.define('a-a', class extends HTMLElement { + constructor() { + super(); + document.querySelector('b').remove(); + } + }); + </script> + <b> + <a-a> + </b> +</template> +<script> +'use strict'; + +test_with_content((w) => { + assert_equals(w.document.querySelectorAll('b').length, 0); +}); +</script> + +<template data-test="destructive writes are blocked during construction"> + <script> + // Custom element constructors do not set the insertion point, which + // makes document.write() "destructive." However they increment the + // ignore-destructive-writes counter, which blocks document.write. + // https://html.spec.whatwg.org/#create-an-element-for-the-token + // https://github.com/whatwg/html/issues/1630 + // https://html.spec.whatwg.org/#document.write() + 'use strict'; + + window.invocations = []; + customElements.define('a-a', class extends HTMLElement { + constructor() { + super(); + invocations.push('constructor'); + document.write( + `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`); + } + connectedCallback() { + invocations.push('connected'); + } + }); + </script> + <a-a> + <script> + 'use strict'; + invocations.push('parsed'); + </script> +</template> +<script> +'use strict'; + +test_with_content((w) => { + assert_array_equals( + w.invocations, + ['constructor', 'connected', 'parsed'], + 'the destructive document.write content should have been ignored'); +}); +</script> + +<template data-test="non-destructive writes are not blocked"> + <script> + // Script running sets the insertion point, which makes makes + // document.write() "non-destructive." Custom elements do not block + // non-destructive writes. + // https://html.spec.whatwg.org/#create-an-element-for-the-token + // https://html.spec.whatwg.org/#document.write() + 'use strict'; + + window.invocations = []; + customElements.define('a-a', class extends HTMLElement { + constructor() { + super(); + invocations.push('constructor'); + document.write( + `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`); + } + connectedCallback() { + invocations.push('connected'); + } + }); + document.write('<a-a>'); + invocations.push('post write'); + </script> + <script> + 'use strict'; + invocations.push('parsed'); + </script> +</template> +<script> +'use strict'; + +test_with_content((w) => { + assert_array_equals( + w.invocations, + ['constructor', 'connected', 'post write', 'written', 'parsed'], + 'the non-destructive document.write content should have been inserted'); +}); +</script> + +<template data-test="innerHTML is not blocked by custom element constructors"> + <script> + 'use strict'; + + window.invocations = []; + customElements.define('a-a', class extends HTMLElement { + constructor() { + super(); + invocations.push(`construct ${this.id}`); + if (!this.id) { + // If the ID attribute is not set, this was created + // synchronously by the parser. Adding children at this point + // would cause creation to fail, so embiggen the previous + // element instead. + document.querySelector('span').innerHTML = `<a-a id="r">`; + } + } + connectedCallback() { + invocations.push(`connected ${this.parentNode.localName}/${this.id}`); + } + }); + </script> + <span></span> + <a-a id="q"></a-a> + <script> + 'use strict'; + invocations.push('parsed'); + </script> +</template> +<script> +'use strict'; + +test_with_content((w) => { + assert_array_equals( + w.invocations, + ['construct ', 'construct r', 'connected span/r', 'connected body/q', + 'parsed'], + 'custom element constructors should not block innerHTML'); +}); +</script> + + +<template data-test="parsing without a browsing context should not create custom elements"> + <body> + <script> + 'use strict'; + + let f = parent.findFrameWithWindow(window); + f.invocations = []; + + customElements.define('a-a', class extends HTMLElement { + constructor() { + super(); + f.invocations.push(this); + } + }); + </script> + <a-a></a-a> + <script> + f.detached = document.implementation.createHTMLDocument(); + f.detached.documentElement.appendChild(document.body); + </script> + <a-a></a-a> +</template> +<script> +'use strict'; + +test_with_content((w) => { + let f = findFrameWithWindow(w); + assert_array_equals(f.invocations, + [f.detached.querySelector('a-a:first-of-type')], + 'one element should have been constructed'); + assert_true(f.invocations[0].matches(':defined'), + 'the element should have been created successfully'); + + let elements = f.detached.querySelectorAll('a-a'); + console.log(f.invocations[0].parentNode); + assert_equals(elements.length, 2, + 'two elements should have been created'); + assert_equals(Object.getPrototypeOf(elements[1]), w.HTMLElement.prototype, + 'the second element should be un-upgraded, not failed'); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/custom-elements/spec/resources/custom-elements-helpers.js b/third_party/WebKit/LayoutTests/custom-elements/spec/resources/custom-elements-helpers.js index 7a1c7196..114e1b00 100644 --- a/third_party/WebKit/LayoutTests/custom-elements/spec/resources/custom-elements-helpers.js +++ b/third_party/WebKit/LayoutTests/custom-elements/spec/resources/custom-elements-helpers.js
@@ -4,7 +4,7 @@ f.srcdoc = srcdoc ? srcdoc : ''; f.onload = (event) => { let w = f.contentWindow; - t.add_cleanup(() => f.remove()); + t.add_cleanup(() => f.parentNode && f.remove()); resolve(w); }; document.body.appendChild(f);
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/nth-pseudo.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/nth-pseudo.html index 9cffe1b..a5c4137 100644 --- a/third_party/WebKit/LayoutTests/fast/css/invalidation/nth-pseudo.html +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/nth-pseudo.html
@@ -56,6 +56,6 @@ t3.insertBefore(document.createElement("div"), t3.firstChild); assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 2); backgroundIsGreen(second); - }, "Prepending an element sibling should not affect :nth-last-child of succeeding siblings."); + }, "Prepending an element sibling causing :nth-child class invalidation."); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/alternate-stylesheets-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/shadow/alternate-stylesheets-expected.txt index fff2248d..7396617 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/alternate-stylesheets-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/alternate-stylesheets-expected.txt
@@ -5,6 +5,7 @@ PASS getComputedStyle(root.querySelector('div')).color is "rgb(0, 128, 0)" PASS getComputedStyle(alternate).color is "rgb(0, 128, 0)" +PASS host.shadowRoot.styleSheets[0].title is null PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/alternate-stylesheets.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/alternate-stylesheets.html index 1b97b2c..c18b603 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/alternate-stylesheets.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/alternate-stylesheets.html
@@ -14,4 +14,5 @@ shouldBeEqualToString("getComputedStyle(root.querySelector('div')).color", "rgb(0, 128, 0)"); shouldBeEqualToString("getComputedStyle(alternate).color", "rgb(0, 128, 0)"); + shouldBeNull("host.shadowRoot.styleSheets[0].title"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/parser/frameset-in-fragment.html b/third_party/WebKit/LayoutTests/fast/parser/frameset-in-fragment.html new file mode 100644 index 0000000..4b01c6e --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/parser/frameset-in-fragment.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +document.getElementsByTagName('html')[0].insertAdjacentHTML('afterbegin', '<p><frameset></frameset></p>'); +test(() => {}, "Forced body tag insertion in a fragment shouldn't crash on frameset"); +</script>
diff --git a/third_party/WebKit/LayoutTests/shadow-dom/link-title.html b/third_party/WebKit/LayoutTests/shadow-dom/link-title.html index 1e191c3..94566b4c 100644 --- a/third_party/WebKit/LayoutTests/shadow-dom/link-title.html +++ b/third_party/WebKit/LayoutTests/shadow-dom/link-title.html
@@ -41,4 +41,11 @@ assert_equals(colorFor(host.shadowRoot.querySelector('#shadowChild4')), 'rgb(0, 0, 0)'); }, '<link rel="alternate stylesheet" title="xxx"> shoule behave as <link rel="alternate stylesheet"> (never enabled because title is ignored) in a connected shadow tree.'); +test(() => { + assert_equals(host.shadowRoot.styleSheets.length, 4); + assert_equals(host.shadowRoot.styleSheets[0].title, null); + assert_equals(host.shadowRoot.styleSheets[1].title, null); + assert_equals(host.shadowRoot.styleSheets[2].title, null); + assert_equals(host.shadowRoot.styleSheets[3].title, null); +}, 'StyleSheet.title should always be null in shadow trees.'); </script>
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp index a4083d93..01172cd 100644 --- a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp +++ b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
@@ -432,15 +432,15 @@ std::unique_ptr<CompositorFilterOperations> ops = CompositorFilterOperations::create(); toCompositorFilterOperations(toAnimatableFilterOperations(value)->operations(), ops.get()); - CompositorFilterKeyframe filterKeyframe(keyframe->offset(), std::move(ops)); - curve.addKeyframe(filterKeyframe, keyframeTimingFunction); + CompositorFilterKeyframe filterKeyframe(keyframe->offset(), *ops, keyframeTimingFunction); + curve.addKeyframe(filterKeyframe); } void addKeyframeToCurve(CompositorFloatAnimationCurve& curve, Keyframe::PropertySpecificKeyframe* keyframe, const AnimatableValue* value, const TimingFunction& keyframeTimingFunction) { - CompositorFloatKeyframe floatKeyframe(keyframe->offset(), toAnimatableDouble(value)->toDouble()); - curve.addKeyframe(floatKeyframe, keyframeTimingFunction); + CompositorFloatKeyframe floatKeyframe(keyframe->offset(), toAnimatableDouble(value)->toDouble(), keyframeTimingFunction); + curve.addKeyframe(floatKeyframe); } void addKeyframeToCurve(CompositorTransformAnimationCurve& curve, Keyframe::PropertySpecificKeyframe* keyframe, @@ -449,8 +449,8 @@ std::unique_ptr<CompositorTransformOperations> ops = CompositorTransformOperations::create(); toCompositorTransformOperations(toAnimatableTransform(value)->transformOperations(), ops.get()); - CompositorTransformKeyframe transformKeyframe(keyframe->offset(), std::move(ops)); - curve.addKeyframe(transformKeyframe, keyframeTimingFunction); + CompositorTransformKeyframe transformKeyframe(keyframe->offset(), *ops, keyframeTimingFunction); + curve.addKeyframe(transformKeyframe); } template <typename PlatformAnimationCurveType>
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp index f4eb231..6f18f9e 100644 --- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp +++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
@@ -259,6 +259,14 @@ { return convertToCompositorAnimation(effect, 1.0); } + + void ExpectKeyframeTimingFunctionCubic(const CompositorFloatKeyframe& keyframe, const CubicBezierTimingFunction::EaseType easeType) + { + auto keyframeTimingFunction = keyframe.getTimingFunctionForTesting(); + DCHECK_EQ(keyframeTimingFunction->getType(), TimingFunction::Type::CUBIC_BEZIER); + const auto& cubicTimingFunction = toCubicBezierTimingFunction(*keyframeTimingFunction); + EXPECT_EQ(cubicTimingFunction.getEaseType(), easeType); + } }; class LayoutObjectProxy : public LayoutObject { @@ -649,16 +657,16 @@ std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(2UL, keyframes.size()); - EXPECT_EQ(0, keyframes[0].time); - EXPECT_EQ(2.0f, keyframes[0].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(0)); + EXPECT_EQ(0, keyframes[0]->time()); + EXPECT_EQ(2.0f, keyframes[0]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[0]->getTimingFunctionForTesting()->getType()); - EXPECT_EQ(1.0, keyframes[1].time); - EXPECT_EQ(5.0f, keyframes[1].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(1)); + EXPECT_EQ(1.0, keyframes[1]->time()); + EXPECT_EQ(5.0f, keyframes[1]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[1]->getTimingFunctionForTesting()->getType()); } TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationDuration) @@ -674,10 +682,10 @@ std::unique_ptr<CompositorAnimation> animation = convertToCompositorAnimation(*effect); std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(2UL, keyframes.size()); - EXPECT_EQ(duration, keyframes[1].time); + EXPECT_EQ(duration, keyframes[1]->time()); } TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimationLinear) @@ -702,24 +710,24 @@ std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(4UL, keyframes.size()); - EXPECT_EQ(0, keyframes[0].time); - EXPECT_EQ(2.0f, keyframes[0].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(0)); + EXPECT_EQ(0, keyframes[0]->time()); + EXPECT_EQ(2.0f, keyframes[0]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[0]->getTimingFunctionForTesting()->getType()); - EXPECT_EQ(0.25, keyframes[1].time); - EXPECT_EQ(-1.0f, keyframes[1].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(1)); + EXPECT_EQ(0.25, keyframes[1]->time()); + EXPECT_EQ(-1.0f, keyframes[1]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[1]->getTimingFunctionForTesting()->getType()); - EXPECT_EQ(0.5, keyframes[2].time); - EXPECT_EQ(20.0f, keyframes[2].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(2)); + EXPECT_EQ(0.5, keyframes[2]->time()); + EXPECT_EQ(20.0f, keyframes[2]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[2]->getTimingFunctionForTesting()->getType()); - EXPECT_EQ(1.0, keyframes[3].time); - EXPECT_EQ(5.0f, keyframes[3].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(3)); + EXPECT_EQ(1.0, keyframes[3]->time()); + EXPECT_EQ(5.0f, keyframes[3]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[3]->getTimingFunctionForTesting()->getType()); } TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationStartDelay) @@ -743,11 +751,11 @@ std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(2UL, keyframes.size()); - EXPECT_EQ(1.75, keyframes[1].time); - EXPECT_EQ(5.0f, keyframes[1].value); + EXPECT_EQ(1.75, keyframes[1]->time()); + EXPECT_EQ(5.0f, keyframes[1]->value()); } TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimationChained) @@ -777,24 +785,24 @@ std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(4UL, keyframes.size()); - EXPECT_EQ(0, keyframes[0].time); - EXPECT_EQ(2.0f, keyframes[0].value); - EXPECT_EQ(CubicBezierTimingFunction::EaseType::EASE, keyframedFloatCurve->getKeyframeEaseTypeForTesting(0)); + EXPECT_EQ(0, keyframes[0]->time()); + EXPECT_EQ(2.0f, keyframes[0]->value()); + ExpectKeyframeTimingFunctionCubic(*keyframes[0], CubicBezierTimingFunction::EaseType::EASE); - EXPECT_EQ(0.5, keyframes[1].time); - EXPECT_EQ(-1.0f, keyframes[1].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(1)); + EXPECT_EQ(0.5, keyframes[1]->time()); + EXPECT_EQ(-1.0f, keyframes[1]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[1]->getTimingFunctionForTesting()->getType()); - EXPECT_EQ(1.0, keyframes[2].time); - EXPECT_EQ(20.0f, keyframes[2].value); - EXPECT_EQ(CubicBezierTimingFunction::EaseType::CUSTOM, keyframedFloatCurve->getKeyframeEaseTypeForTesting(2)); + EXPECT_EQ(1.0, keyframes[2]->time()); + EXPECT_EQ(20.0f, keyframes[2]->value()); + ExpectKeyframeTimingFunctionCubic(*keyframes[2], CubicBezierTimingFunction::EaseType::CUSTOM); - EXPECT_EQ(2.0, keyframes[3].time); - EXPECT_EQ(5.0f, keyframes[3].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(3)); + EXPECT_EQ(2.0, keyframes[3]->time()); + EXPECT_EQ(5.0f, keyframes[3]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[3]->getTimingFunctionForTesting()->getType()); } TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimation) @@ -825,26 +833,26 @@ std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(4UL, keyframes.size()); - EXPECT_TRUE(keyframedFloatCurve->curveHasLinearTimingFunctionForTesting()); + EXPECT_EQ(keyframedFloatCurve->getTimingFunctionForTesting()->getType(), TimingFunction::Type::LINEAR); - EXPECT_EQ(0, keyframes[0].time); - EXPECT_EQ(2.0f, keyframes[0].value); - EXPECT_EQ(CubicBezierTimingFunction::EaseType::EASE_IN, keyframedFloatCurve->getKeyframeEaseTypeForTesting(0)); + EXPECT_EQ(0, keyframes[0]->time()); + EXPECT_EQ(2.0f, keyframes[0]->value()); + ExpectKeyframeTimingFunctionCubic(*keyframes[0], CubicBezierTimingFunction::EaseType::EASE_IN); - EXPECT_EQ(0.25, keyframes[1].time); - EXPECT_EQ(-1.0f, keyframes[1].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(1)); + EXPECT_EQ(0.25, keyframes[1]->time()); + EXPECT_EQ(-1.0f, keyframes[1]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[1]->getTimingFunctionForTesting()->getType()); - EXPECT_EQ(0.5, keyframes[2].time); - EXPECT_EQ(20.0f, keyframes[2].value); - EXPECT_EQ(CubicBezierTimingFunction::EaseType::CUSTOM, keyframedFloatCurve->getKeyframeEaseTypeForTesting(2)); + EXPECT_EQ(0.5, keyframes[2]->time()); + EXPECT_EQ(20.0f, keyframes[2]->value()); + ExpectKeyframeTimingFunctionCubic(*keyframes[2], CubicBezierTimingFunction::EaseType::CUSTOM); - EXPECT_EQ(1.0, keyframes[3].time); - EXPECT_EQ(5.0f, keyframes[3].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(3)); + EXPECT_EQ(1.0, keyframes[3]->time()); + EXPECT_EQ(5.0f, keyframes[3]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[3]->getTimingFunctionForTesting()->getType()); } TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimationNegativeStartDelay) @@ -870,7 +878,7 @@ std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(2UL, keyframes.size()); } @@ -895,7 +903,7 @@ std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(2UL, keyframes.size()); } @@ -943,18 +951,25 @@ std::unique_ptr<CompositorFloatAnimationCurve> keyframedFloatCurve = animation->floatCurveForTesting(); - Vector<CompositorFloatKeyframe> keyframes = keyframedFloatCurve->keyframesForTesting(); + auto curveTimingFunction = keyframedFloatCurve->getTimingFunctionForTesting(); + EXPECT_EQ(curveTimingFunction->getType(), TimingFunction::Type::CUBIC_BEZIER); + const auto& cubicTimingFunction = toCubicBezierTimingFunction(*curveTimingFunction); + EXPECT_EQ(cubicTimingFunction.getEaseType(), CubicBezierTimingFunction::EaseType::CUSTOM); + EXPECT_EQ(cubicTimingFunction.x1(), 1.0); + EXPECT_EQ(cubicTimingFunction.y1(), 2.0); + EXPECT_EQ(cubicTimingFunction.x2(), 3.0); + EXPECT_EQ(cubicTimingFunction.y2(), 4.0); + + CompositorFloatAnimationCurve::Keyframes keyframes = keyframedFloatCurve->keyframesForTesting(); ASSERT_EQ(2UL, keyframes.size()); - EXPECT_EQ(CubicBezierTimingFunction::EaseType::CUSTOM, keyframedFloatCurve->getCurveEaseTypeForTesting()); + EXPECT_EQ(0, keyframes[0]->time()); + EXPECT_EQ(2.0f, keyframes[0]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[0]->getTimingFunctionForTesting()->getType()); - EXPECT_EQ(0, keyframes[0].time); - EXPECT_EQ(2.0f, keyframes[0].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(0)); - - EXPECT_EQ(1.0, keyframes[1].time); - EXPECT_EQ(5.0f, keyframes[1].value); - EXPECT_TRUE(keyframedFloatCurve->keyframeHasLinearTimingFunctionForTesting(1)); + EXPECT_EQ(1.0, keyframes[1]->time()); + EXPECT_EQ(5.0f, keyframes[1]->value()); + EXPECT_EQ(TimingFunction::Type::LINEAR, keyframes[1]->getTimingFunctionForTesting()->getType()); } TEST_F(AnimationCompositorAnimationsTest, cancelIncompatibleCompositorAnimations)
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index cb40f8f..2441698 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -3267,6 +3267,8 @@ 'html/parser/HTMLParserIdioms.cpp', 'html/parser/HTMLParserOptions.cpp', 'html/parser/HTMLParserOptions.h', + 'html/parser/HTMLParserReentryPermit.cpp', + 'html/parser/HTMLParserReentryPermit.h', 'html/parser/HTMLParserScheduler.cpp', 'html/parser/HTMLParserScheduler.h', 'html/parser/HTMLParserThread.cpp',
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 8ba679e..1236dcaa 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -107,6 +107,7 @@ #include "core/dom/VisitedLinkState.h" #include "core/dom/XMLDocument.h" #include "core/dom/custom/CustomElement.h" +#include "core/dom/custom/CustomElementsRegistry.h" #include "core/dom/custom/V0CustomElementMicrotaskRunQueue.h" #include "core/dom/custom/V0CustomElementRegistrationContext.h" #include "core/dom/shadow/ElementShadow.h" @@ -460,6 +461,12 @@ m_fetcher = m_frame->loader().documentLoader()->fetcher(); FrameFetchContext::provideDocumentToContext(m_fetcher->context(), this); + + CustomElementsRegistry* registry = m_frame->localDOMWindow() + ? m_frame->localDOMWindow()->maybeCustomElements() + : nullptr; + if (registry && m_registrationContext) + registry->entangle(m_registrationContext); } else if (m_importsController) { m_fetcher = FrameFetchContext::createContextAndFetcher(nullptr, this); } else {
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp index 8807b83..8b7bd54 100644 --- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp +++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -529,9 +529,10 @@ } DCHECK(styleSheet); - styleSheet->setTitle(e->title()); - if (!e->isInShadowTree()) + if (!e->isInShadowTree()) { + styleSheet->setTitle(e->title()); setPreferredStylesheetSetNameIfNotSet(e->title()); + } return styleSheet; }
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.cpp index 1bd3aad..6ecc7a8e 100644 --- a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.cpp +++ b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.cpp
@@ -20,6 +20,7 @@ #include "core/dom/custom/CustomElementUpgradeReaction.h" #include "core/dom/custom/CustomElementUpgradeSorter.h" #include "core/dom/custom/V0CustomElementRegistrationContext.h" +#include "core/frame/LocalDOMWindow.h" #include "wtf/Allocator.h" namespace blink { @@ -63,16 +64,19 @@ }; CustomElementsRegistry* CustomElementsRegistry::create( - Document* document) + const LocalDOMWindow* owner) { - CustomElementsRegistry* registry = new CustomElementsRegistry(document); - if (V0CustomElementRegistrationContext* v0Context = registry->v0()) - v0Context->setV1(registry); + CustomElementsRegistry* registry = new CustomElementsRegistry(owner); + Document* document = owner->document(); + if (V0CustomElementRegistrationContext* v0 = + document ? document->registrationContext() : nullptr) + registry->entangle(v0); return registry; } -CustomElementsRegistry::CustomElementsRegistry(Document* document) - : m_document(document) +CustomElementsRegistry::CustomElementsRegistry(const LocalDOMWindow* owner) + : m_owner(owner) + , m_v0 (new V0RegistrySet()) , m_upgradeCandidates(new UpgradeCandidateMap()) { } @@ -80,7 +84,8 @@ DEFINE_TRACE(CustomElementsRegistry) { visitor->trace(m_definitions); - visitor->trace(m_document); + visitor->trace(m_owner); + visitor->trace(m_v0); visitor->trace(m_upgradeCandidates); visitor->trace(m_whenDefinedPromiseMap); } @@ -189,20 +194,35 @@ return definition->getConstructorForScript(); } +CustomElementDefinition* CustomElementsRegistry::definitionFor(const CustomElementDescriptor& desc) const +{ + CustomElementDefinition* definition = definitionForName(desc.name()); + if (!definition) + return nullptr; + // The definition for a customized built-in element, such as + // <button is="my-button"> should not be provided for an + // autonomous element, such as <my-button>, even though the + // name "my-button" matches. + return definition->descriptor() == desc ? definition : nullptr; +} + bool CustomElementsRegistry::nameIsDefined(const AtomicString& name) const { return m_definitions.contains(name); } -V0CustomElementRegistrationContext* CustomElementsRegistry::v0() +void CustomElementsRegistry::entangle(V0CustomElementRegistrationContext* v0) { - return m_document->registrationContext(); + m_v0->add(v0); + v0->setV1(this); } bool CustomElementsRegistry::v0NameIsDefined(const AtomicString& name) { - if (V0CustomElementRegistrationContext* v0Context = v0()) - return v0Context->nameIsDefined(name); + for (const auto& v0 : *m_v0) { + if (v0->nameIsDefined(name)) + return true; + } return false; } @@ -264,7 +284,12 @@ } m_upgradeCandidates->remove(it); - sorter.sorted(elements, m_document.get()); + + Document* document = m_owner->document(); + if (!document) + return; + + sorter.sorted(elements, document); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.h b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.h index e5b58b4a..ecb2074 100644 --- a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.h +++ b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.h
@@ -20,10 +20,10 @@ class CustomElementDefinition; class CustomElementDefinitionBuilder; class CustomElementDescriptor; -class Document; class Element; class ElementRegistrationOptions; class ExceptionState; +class LocalDOMWindow; class ScriptPromiseResolver; class ScriptState; class ScriptValue; @@ -35,7 +35,7 @@ DEFINE_WRAPPERTYPEINFO(); WTF_MAKE_NONCOPYABLE(CustomElementsRegistry); public: - static CustomElementsRegistry* create(Document*); + static CustomElementsRegistry* create(const LocalDOMWindow*); virtual ~CustomElementsRegistry() = default; @@ -56,6 +56,10 @@ bool nameIsDefined(const AtomicString& name) const; CustomElementDefinition* definitionForName(const AtomicString& name) const; + // TODO(dominicc): Switch most callers of definitionForName to + // definitionFor when implementing type extensions. + CustomElementDefinition* definitionFor(const CustomElementDescriptor&) const; + // TODO(dominicc): Consider broadening this API when type extensions are // implemented. void addCandidate(Element*); @@ -64,14 +68,15 @@ const AtomicString& name, ExceptionState&); + void entangle(V0CustomElementRegistrationContext*); + DECLARE_TRACE(); private: - friend class CustomElementsRegistryTestBase; + friend class CustomElementsRegistryTest; - CustomElementsRegistry(Document*); + CustomElementsRegistry(const LocalDOMWindow*); - V0CustomElementRegistrationContext* v0(); bool v0NameIsDefined(const AtomicString& name); void collectCandidates( @@ -85,7 +90,10 @@ HeapHashMap<AtomicString, Member<CustomElementDefinition>>; DefinitionMap m_definitions; - Member<Document> m_document; + Member<const LocalDOMWindow> m_owner; + + using V0RegistrySet = HeapHashSet<WeakMember<V0CustomElementRegistrationContext>>; + Member<V0RegistrySet> m_v0; using UpgradeCandidateSet = HeapHashSet<WeakMember<Element>>; using UpgradeCandidateMap = HeapHashMap<
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistryTest.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistryTest.cpp index 96321e1..9f8d84ae 100644 --- a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistryTest.cpp +++ b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistryTest.cpp
@@ -25,63 +25,21 @@ namespace blink { -class CustomElementsRegistryTestBase : public ::testing::Test { +class CustomElementsRegistryTest : public ::testing::Test { protected: - virtual Document& document() = 0; - virtual CustomElementsRegistry& registry() = 0; - - void collectCandidates( - const CustomElementDescriptor& desc, - HeapVector<Member<Element>>* elements) + void SetUp() { - registry().collectCandidates(desc, elements); - } -}; - -class CustomElementsRegistryTest : public CustomElementsRegistryTestBase { -protected: - void SetUp() override - { - CustomElementsRegistryTestBase::SetUp(); - - m_document = HTMLDocument::create(); - m_document->appendChild(CreateElement("html").inDocument(m_document)); - - m_registry = CustomElementsRegistry::create(m_document); - } - - void TearDown() override - { - m_document = nullptr; - m_registry = nullptr; - CustomElementsRegistryTestBase::TearDown(); - } - - Document& document() override { return *m_document; } - CustomElementsRegistry& registry() override { return *m_registry; } - -private: - Persistent<Document> m_document; - Persistent<CustomElementsRegistry> m_registry; -}; - -class CustomElementsRegistryFrameTest : public CustomElementsRegistryTestBase { -protected: - void SetUp() override - { - CustomElementsRegistryTestBase::SetUp(); m_page.reset(DummyPageHolder::create(IntSize(1, 1)).release()); } - void TearDown() override + void TearDown() { m_page = nullptr; - CustomElementsRegistryTestBase::TearDown(); } - Document& document() override { return m_page->document(); } + Document& document() { return m_page->document(); } - CustomElementsRegistry& registry() override + CustomElementsRegistry& registry() { return *m_page->frame().localDOMWindow()->customElements(); } @@ -91,6 +49,13 @@ return ScriptState::forMainWorld(&m_page->frame()); } + void collectCandidates( + const CustomElementDescriptor& desc, + HeapVector<Member<Element>>* elements) + { + registry().collectCandidates(desc, elements); + } + ShadowRoot* attachShadowTo(Element* element) { NonThrowableExceptionState noExceptions; @@ -361,7 +326,7 @@ } }; -TEST_F(CustomElementsRegistryFrameTest, define_upgradesInDocumentElements) +TEST_F(CustomElementsRegistryTest, define_upgradesInDocumentElements) { ScriptForbiddenScope doNotRelyOnScript; @@ -408,7 +373,7 @@ << "upgrade should not invoke other callbacks"; } -TEST_F(CustomElementsRegistryFrameTest, attributeChangedCallback) +TEST_F(CustomElementsRegistryTest, attributeChangedCallback) { ScriptForbiddenScope doNotRelyOnScript; @@ -445,7 +410,7 @@ << "upgrade should not invoke other callbacks"; } -TEST_F(CustomElementsRegistryFrameTest, disconnectedCallback) +TEST_F(CustomElementsRegistryTest, disconnectedCallback) { ScriptForbiddenScope doNotRelyOnScript;
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp index 7379a49a1..2bc7c78 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -1328,7 +1328,12 @@ CustomElementsRegistry* LocalDOMWindow::customElements() const { if (!m_customElements && m_document) - m_customElements = CustomElementsRegistry::create(document()); + m_customElements = CustomElementsRegistry::create(this); + return m_customElements; +} + +CustomElementsRegistry* LocalDOMWindow::maybeCustomElements() const +{ return m_customElements; }
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h index d1db19f..94351da 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -154,6 +154,7 @@ void cancelIdleCallback(int id) override; CustomElementsRegistry* customElements(ScriptState*) const override; CustomElementsRegistry* customElements() const; + CustomElementsRegistry* maybeCustomElements() const; void registerProperty(DOMWindowProperty*); void unregisterProperty(DOMWindowProperty*);
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp index b4b4d92..4c9e0d3 100644 --- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -473,7 +473,8 @@ clearSheet(); m_sheet = CSSStyleSheet::create(restoredSheet, m_owner); m_sheet->setMediaQueries(MediaQuerySet::create(m_owner->media())); - m_sheet->setTitle(m_owner->title()); + if (m_owner->isInDocumentTree()) + m_sheet->setTitle(m_owner->title()); setCrossOriginStylesheetStatus(m_sheet.get()); m_loading = false; @@ -494,7 +495,8 @@ m_sheet = CSSStyleSheet::create(styleSheet, m_owner); m_sheet->setMediaQueries(MediaQuerySet::create(m_owner->media())); - m_sheet->setTitle(m_owner->title()); + if (m_owner->isInDocumentTree()) + m_sheet->setTitle(m_owner->title()); setCrossOriginStylesheetStatus(m_sheet.get()); styleSheet->parseAuthorStyleSheet(cachedStyleSheet, m_owner->document().getSecurityOrigin()); @@ -710,7 +712,7 @@ void LinkStyle::setSheetTitle(const String& title) { - if (m_sheet) + if (m_sheet && m_owner->isInDocumentTree()) m_sheet->setTitle(title); }
diff --git a/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp b/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp index c8a3610..f989a92 100644 --- a/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
@@ -60,7 +60,7 @@ void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& value) { - if (name == titleAttr && m_sheet) { + if (name == titleAttr && m_sheet && isInDocumentTree()) { m_sheet->setTitle(value); } else if (name == mediaAttr && isConnected() && document().isActive() && m_sheet) { m_sheet->setMediaQueries(MediaQuerySet::create(value));
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp index 33ce143..cf1b568 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -26,6 +26,8 @@ #include "core/html/parser/HTMLConstructionSite.h" +#include "bindings/core/v8/Microtask.h" +#include "bindings/core/v8/V8PerIsolateData.h" #include "core/HTMLElementFactory.h" #include "core/HTMLNames.h" #include "core/dom/Comment.h" @@ -33,9 +35,15 @@ #include "core/dom/DocumentType.h" #include "core/dom/Element.h" #include "core/dom/ElementTraversal.h" +#include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" #include "core/dom/ScriptLoader.h" #include "core/dom/TemplateContentDocumentFragment.h" #include "core/dom/Text.h" +#include "core/dom/custom/CEReactionsScope.h" +#include "core/dom/custom/CustomElementDefinition.h" +#include "core/dom/custom/CustomElementDescriptor.h" +#include "core/dom/custom/CustomElementsRegistry.h" +#include "core/frame/LocalDOMWindow.h" #include "core/frame/LocalFrame.h" #include "core/html/HTMLFormElement.h" #include "core/html/HTMLHtmlElement.h" @@ -44,6 +52,7 @@ #include "core/html/HTMLTemplateElement.h" #include "core/html/parser/AtomicHTMLToken.h" #include "core/html/parser/HTMLParserIdioms.h" +#include "core/html/parser/HTMLParserReentryPermit.h" #include "core/html/parser/HTMLStackItem.h" #include "core/html/parser/HTMLToken.h" #include "core/loader/FrameLoader.h" @@ -314,8 +323,9 @@ // We might be detached now. } -HTMLConstructionSite::HTMLConstructionSite(Document& document, ParserContentPolicy parserContentPolicy) - : m_document(&document) +HTMLConstructionSite::HTMLConstructionSite(HTMLParserReentryPermit* reentryPermit, Document& document, ParserContentPolicy parserContentPolicy) + : m_reentryPermit(reentryPermit) + , m_document(&document) , m_attachmentRoot(document) , m_parserContentPolicy(parserContentPolicy) , m_isParsingFragment(false) @@ -747,17 +757,111 @@ return currentNode()->document(); } +// "look up a custom element definition" for a token +// https://html.spec.whatwg.org/#look-up-a-custom-element-definition +CustomElementDefinition* HTMLConstructionSite::lookUpCustomElementDefinition(Document& document, AtomicHTMLToken* token) +{ + // "2. If document does not have a browsing context, return null." + LocalDOMWindow* window = document.domWindow(); + if (!window) + return nullptr; + + // "3. Let registry be document's browsing context's Window's + // CustomElementsRegistry object." + CustomElementsRegistry* registry = window->maybeCustomElements(); + if (!registry) + return nullptr; + + const AtomicString& localName = token->name(); + const Attribute* isAttribute = token->getAttributeItem(HTMLNames::isAttr); + const AtomicString& name = isAttribute ? isAttribute->value() : localName; + CustomElementDescriptor descriptor(name, localName); + + // 4.-6. + return registry->definitionFor(descriptor); +} + +// "create an element for a token" +// https://html.spec.whatwg.org/#create-an-element-for-the-token +// TODO(dominicc): When form association is separate from creation, +// unify this with foreign element creation. Add a namespace parameter +// and check for HTML namespace to lookupCustomElementDefinition. HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token) { + // "1. Let document be intended parent's node document." Document& document = ownerDocumentForCurrentNode(); + // Only associate the element with the current form if we're creating the new element // in a document with a browsing context (rather than in <template> contents). + // TODO(dominicc): Change form to happen after element creation when + // implementing customized built-in elements. HTMLFormElement* form = document.frame() ? m_form.get() : nullptr; - // FIXME: This can't use HTMLConstructionSite::createElement because we - // have to pass the current form element. We should rework form association - // to occur after construction to allow better code sharing here. - HTMLElement* element = HTMLElementFactory::createHTMLElement(token->name(), document, form, getCreateElementFlags()); - setAttributes(element, token, m_parserContentPolicy); + + // "2. Let local name be the tag name of the token." + // "3. Let is be the value of the "is" attribute in the giev token ..." etc. + // "4. Let definition be the result of looking up a custom element ..." etc. + CustomElementDefinition* definition = m_isParsingFragment ? nullptr : lookUpCustomElementDefinition(document, token); + // "5. If definition is non-null and the parser was not originally created + // for the HTML fragment parsing algorithm, then let will execute script + // be true." + bool willExecuteScript = definition && !m_isParsingFragment; + + HTMLElement* element; + + if (willExecuteScript) { + // "6.1 Increment the parser's script nesting level." + HTMLParserReentryPermit::ScriptNestingLevelIncrementer incrementScriptNestingLevel = m_reentryPermit->incrementScriptNestingLevel(); + + // "6.2 Set the parser pause flag to true." + m_reentryPermit->pause(); + + // TODO(dominicc): Change this once resolved: + // https://github.com/whatwg/html/issues/1630 + IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWrites( + &document); + + // "6.3 If the JavaScript execution context stack is empty, + // then perform a microtask checkpoint." + + // TODO(dominicc): This is the way the Blink HTML parser + // performs checkpoints, but note the spec is different--it + // talks about the JavaScript stack, not the script nesting + // level. + if (1u == m_reentryPermit->scriptNestingLevel()) + Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); + + // "6.4 Push a new element queue onto the custom element + // reactions stack." + CEReactionsScope reactions; + + // 7. + QualifiedName elementQName(nullAtom, token->name(), HTMLNames::xhtmlNamespaceURI); + element = definition->createElementSync(document, elementQName); + + // "8. Append each attribute in the given token to element." + // We don't use setAttributes here because the custom element + // constructor may have manipulated attributes. + for (const auto& attribute : token->attributes()) + element->setAttribute(attribute.name(), attribute.value()); + + // "9. If will execute script is true, then ..." etc. The + // CEReactionsScope and ScriptNestingLevelIncrementer + // destructors implement steps 9.1-4. + } else { + // FIXME: This can't use + // HTMLConstructionSite::createElement because we have to + // pass the current form element. We should rework form + // association to occur after construction to allow better + // code sharing here. + element = HTMLElementFactory::createHTMLElement(token->name(), document, form, getCreateElementFlags()); + + // "8. Append each attribute in the given token to element." + setAttributes(element, token, m_parserContentPolicy); + } + + // TODO(dominicc): Implement steps 10-12 when customized built-in + // elements are implemented. + return element; }
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h index 3d661623..1d175f36 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h +++ b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
@@ -31,9 +31,8 @@ #include "core/dom/ParserContentPolicy.h" #include "core/html/parser/HTMLElementStack.h" #include "core/html/parser/HTMLFormattingElementList.h" +#include "platform/heap/Handle.h" #include "wtf/Noncopyable.h" -#include "wtf/PassRefPtr.h" -#include "wtf/RefPtr.h" #include "wtf/Vector.h" #include "wtf/text/StringBuilder.h" @@ -101,15 +100,17 @@ }; class AtomicHTMLToken; +class CustomElementDefinition; class Document; class Element; class HTMLFormElement; +class HTMLParserReentryPermit; class HTMLConstructionSite final { WTF_MAKE_NONCOPYABLE(HTMLConstructionSite); DISALLOW_NEW(); public: - HTMLConstructionSite(Document&, ParserContentPolicy); + HTMLConstructionSite(HTMLParserReentryPermit*, Document&, ParserContentPolicy); ~HTMLConstructionSite(); DECLARE_TRACE(); @@ -243,6 +244,9 @@ void executeTask(HTMLConstructionSiteTask&); void queueTask(const HTMLConstructionSiteTask&); + CustomElementDefinition* lookUpCustomElementDefinition(Document&, AtomicHTMLToken*); + + HTMLParserReentryPermit* m_reentryPermit; Member<Document> m_document; // This is the root ContainerNode to which the parser attaches all newly
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp index 20960c46..1a42b3b 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -92,7 +92,7 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, ParserSynchronizationPolicy syncPolicy) : HTMLDocumentParser(document, AllowScriptingContent, syncPolicy) { - m_scriptRunner = HTMLScriptRunner::create(&document, this); + m_scriptRunner = HTMLScriptRunner::create(reentryPermit(), &document, this); m_treeBuilder = HTMLTreeBuilder::create(this, document, AllowScriptingContent, m_options); } @@ -110,6 +110,7 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document, ParserContentPolicy contentPolicy, ParserSynchronizationPolicy syncPolicy) : ScriptableDocumentParser(document, contentPolicy) , m_options(&document) + , m_reentryPermit(HTMLParserReentryPermit::create()) , m_token(syncPolicy == ForceSynchronousParsing ? wrapUnique(new HTMLToken) : nullptr) , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create(m_options) : nullptr) , m_loadingTaskRunner(TaskRunnerHelper::getLoadingTaskRunner(&document)->clone()) @@ -955,7 +956,7 @@ // never be possible to end up with both objects holding a blocking script. ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); // If either object has a blocking script, the parser should be paused. - return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript; + return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript || m_reentryPermit->parserPauseFlag(); } void HTMLDocumentParser::resumeParsingAfterScriptExecution()
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h index e83f3bb..84a12b1 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
@@ -35,6 +35,7 @@ #include "core/html/parser/CompactHTMLToken.h" #include "core/html/parser/HTMLInputStream.h" #include "core/html/parser/HTMLParserOptions.h" +#include "core/html/parser/HTMLParserReentryPermit.h" #include "core/html/parser/HTMLPreloadScanner.h" #include "core/html/parser/HTMLScriptRunnerHost.h" #include "core/html/parser/HTMLSourceTracker.h" @@ -47,6 +48,7 @@ #include "core/html/parser/XSSAuditorDelegate.h" #include "platform/text/SegmentedString.h" #include "wtf/Deque.h" +#include "wtf/RefPtr.h" #include "wtf/WeakPtr.h" #include "wtf/text/TextPosition.h" #include <memory> @@ -95,6 +97,8 @@ void suspendScheduledTasks() final; void resumeScheduledTasks() final; + HTMLParserReentryPermit* reentryPermit() { return m_reentryPermit.get(); } + struct TokenizedChunk { USING_FAST_MALLOC(TokenizedChunk); public: @@ -204,6 +208,7 @@ HTMLParserOptions m_options; HTMLInputStream m_input; + RefPtr<HTMLParserReentryPermit> m_reentryPermit; std::unique_ptr<HTMLToken> m_token; std::unique_ptr<HTMLTokenizer> m_tokenizer;
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserReentryPermit.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserReentryPermit.cpp new file mode 100644 index 0000000..dc609100 --- /dev/null +++ b/third_party/WebKit/Source/core/html/parser/HTMLParserReentryPermit.cpp
@@ -0,0 +1,18 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/html/parser/HTMLParserReentryPermit.h" + +namespace blink { + +PassRefPtr<HTMLParserReentryPermit> HTMLParserReentryPermit::create() +{ + return adoptRef(new HTMLParserReentryPermit()); +} + +HTMLParserReentryPermit::HTMLParserReentryPermit() + : m_scriptNestingLevel(0) + , m_parserPauseFlag(false) {} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserReentryPermit.h b/third_party/WebKit/Source/core/html/parser/HTMLParserReentryPermit.h new file mode 100644 index 0000000..4538b4c --- /dev/null +++ b/third_party/WebKit/Source/core/html/parser/HTMLParserReentryPermit.h
@@ -0,0 +1,95 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef HTMLParserReentryPermit_h +#define HTMLParserReentryPermit_h + +#include "base/macros.h" +#include "wtf/PassRefPtr.h" +#include "wtf/RefCounted.h" + +namespace blink { + +// The HTML spec for parsing controls reentering the parser from +// script with the "parser pause flag" and "script nesting level." +// +// The parser pause flag puts a brake on whether the tokenizer will +// produce more tokens. When the parser is paused, nested invocations +// of the tokenizer unwind. +// +// The script nesting level is incremented and decremented any time +// the parser causes script to run. The script nesting level: +// +// - May prevent document.open from blowing away the document. +// +// - Governs whether a script element becomes the "pending +// parsing-blocking script." The pending parsing-blocking script in +// turn affects whether document.write reenters the parser. +// +// Clearing the parser pause flag is simple: Whenever the script +// nesting level hits zero, the parser pause flag is cleared. However +// setting the parser pause flag is subtle. +// +// Processing a typical script end tag, or running a chain of pending +// parser-blocking scripts after that, does not set the parser pause +// flag. However recursively parsing end script tags, or running +// custom element constructors, does set the parser pause flag. +class HTMLParserReentryPermit final : public RefCounted<HTMLParserReentryPermit> { +public: + static PassRefPtr<HTMLParserReentryPermit> create(); + ~HTMLParserReentryPermit() = default; + + unsigned scriptNestingLevel() const { return m_scriptNestingLevel; } + bool parserPauseFlag() const { return m_parserPauseFlag; } + void pause() + { + CHECK(m_scriptNestingLevel); + m_parserPauseFlag = true; + } + + class ScriptNestingLevelIncrementer final { + STACK_ALLOCATED(); + public: + explicit ScriptNestingLevelIncrementer(HTMLParserReentryPermit* permit) + : m_permit(permit) + { + m_permit->m_scriptNestingLevel++; + } + + ScriptNestingLevelIncrementer(ScriptNestingLevelIncrementer&&) + = default; + + ~ScriptNestingLevelIncrementer() + { + m_permit->m_scriptNestingLevel--; + if (!m_permit->m_scriptNestingLevel) + m_permit->m_parserPauseFlag = false; + } + + private: + HTMLParserReentryPermit* m_permit; + + DISALLOW_COPY_AND_ASSIGN(ScriptNestingLevelIncrementer); + }; + + ScriptNestingLevelIncrementer incrementScriptNestingLevel() + { + return ScriptNestingLevelIncrementer(this); + } + +private: + HTMLParserReentryPermit(); + + // https://html.spec.whatwg.org/#script-nesting-level + unsigned m_scriptNestingLevel; + + // https://html.spec.whatwg.org/#parser-pause-flag + bool m_parserPauseFlag; + + DISALLOW_COPY_AND_ASSIGN(HTMLParserReentryPermit); +}; + +} // namespace blink + +#endif // HTMLParserReentryPermit_h
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp index d386b0977..05c63f6 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
@@ -133,11 +133,11 @@ using namespace HTMLNames; -HTMLScriptRunner::HTMLScriptRunner(Document* document, HTMLScriptRunnerHost* host) - : m_document(document) +HTMLScriptRunner::HTMLScriptRunner(HTMLParserReentryPermit* reentryPermit, Document* document, HTMLScriptRunnerHost* host) + : m_reentryPermit(reentryPermit) + , m_document(document) , m_host(host) , m_parserBlockingScript(PendingScript::create(nullptr, nullptr)) - , m_scriptNestingLevel(0) , m_hasScriptsWaitingForResources(false) { ASSERT(m_host); @@ -164,6 +164,9 @@ pendingScript->releaseElementAndClear(); } m_document = nullptr; + // m_reentryPermit is not cleared here, because the script runner + // may continue to run pending scripts after the parser has + // detached. } bool HTMLScriptRunner::isPendingScriptReady(const PendingScript* script) @@ -208,7 +211,7 @@ // Clear the pending script before possible re-entrancy from executeScript() Element* element = pendingScript->releaseElementAndClear(); if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { - NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); + HTMLParserReentryPermit::ScriptNestingLevelIncrementer nestingLevelIncrementer = m_reentryPermit->incrementScriptNestingLevel(); IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_document); if (errorOccurred) { TRACE_EVENT_WITH_FLOW1("blink", "HTMLScriptRunner ExecuteScriptFailed", element, TRACE_EVENT_FLAG_FLOW_IN, @@ -419,7 +422,7 @@ Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); InsertionPointRecord insertionPointRecord(m_host->inputStream()); - NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); + HTMLParserReentryPermit::ScriptNestingLevelIncrementer nestingLevelIncrementer = m_reentryPermit->incrementScriptNestingLevel(); scriptLoader->prepareScript(scriptStartPosition); @@ -429,11 +432,11 @@ if (scriptLoader->willExecuteWhenDocumentFinishedParsing()) { requestDeferredScript(script); } else if (scriptLoader->readyToBeParserExecuted()) { - if (m_scriptNestingLevel == 1) { + if (m_reentryPermit->scriptNestingLevel() == 1u) { m_parserBlockingScript->setElement(script); m_parserBlockingScript->setStartingPosition(scriptStartPosition); } else { - ASSERT(m_scriptNestingLevel > 1); + DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u); m_parserBlockingScript->releaseElementAndClear(); ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition); doExecuteScript(script, sourceCode, scriptStartPosition);
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h b/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h index eeb2959..c69e4e06 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h +++ b/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h
@@ -29,9 +29,10 @@ #include "bindings/core/v8/ScriptStreamer.h" #include "core/dom/PendingScript.h" #include "core/fetch/ResourceClient.h" +#include "core/html/parser/HTMLParserReentryPermit.h" #include "platform/heap/Handle.h" #include "wtf/Deque.h" -#include "wtf/PassRefPtr.h" +#include "wtf/RefPtr.h" #include "wtf/text/TextPosition.h" namespace blink { @@ -46,9 +47,9 @@ USING_GARBAGE_COLLECTED_MIXIN(HTMLScriptRunner); USING_PRE_FINALIZER(HTMLScriptRunner, detach); public: - static HTMLScriptRunner* create(Document* document, HTMLScriptRunnerHost* host) + static HTMLScriptRunner* create(HTMLParserReentryPermit* reentryPermit, Document* document, HTMLScriptRunnerHost* host) { - return new HTMLScriptRunner(document, host); + return new HTMLScriptRunner(reentryPermit, document, host); } ~HTMLScriptRunner(); @@ -63,7 +64,7 @@ bool executeScriptsWaitingForParsing(); bool hasParserBlockingScript() const; - bool isExecutingScript() const { return !!m_scriptNestingLevel; } + bool isExecutingScript() const { return !!m_reentryPermit->scriptNestingLevel(); } // ResourceClient void notifyFinished(Resource*) override; @@ -72,7 +73,7 @@ DECLARE_TRACE(); private: - HTMLScriptRunner(Document*, HTMLScriptRunnerHost*); + HTMLScriptRunner(HTMLParserReentryPermit*, Document*, HTMLScriptRunnerHost*); void executeParsingBlockingScript(); void executePendingScriptAndDispatchEvent(PendingScript*, ScriptStreamer::Type); @@ -88,12 +89,12 @@ void stopWatchingResourceForLoad(Resource*); + RefPtr<HTMLParserReentryPermit> m_reentryPermit; Member<Document> m_document; Member<HTMLScriptRunnerHost> m_host; Member<PendingScript> m_parserBlockingScript; // http://www.whatwg.org/specs/web-apps/current-work/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing HeapDeque<Member<PendingScript>> m_scriptsToExecuteAfterParsing; - unsigned m_scriptNestingLevel; // We only want stylesheet loads to trigger script execution if script // execution is currently stopped due to stylesheet loads, otherwise we'd
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp index ff36b58..72ac560 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
@@ -267,7 +267,7 @@ #if ENABLE(ASSERT) , m_isAttached(true) #endif - , m_tree(document, parserContentPolicy) + , m_tree(parser->reentryPermit(), document, parserContentPolicy) , m_insertionMode(InitialMode) , m_originalInsertionMode(InitialMode) , m_shouldSkipLeadingNewline(false) @@ -326,8 +326,9 @@ void HTMLTreeBuilder::detach() { #if ENABLE(ASSERT) - // This call makes little sense in fragment mode, but for consistency - // DocumentParser expects detach() to always be called before it's destroyed. + // This call makes little sense in fragment mode, but for + // consistency DocumentParser expects detach() to always be called + // before it's destroyed. m_isAttached = false; #endif // HTMLConstructionSite might be on the callstack when detach() is called @@ -619,7 +620,12 @@ m_tree.openElements()->bodyElement()->remove(ASSERT_NO_EXCEPTION); m_tree.openElements()->popUntil(m_tree.openElements()->bodyElement()); m_tree.openElements()->popHTMLBodyElement(); - ASSERT(m_tree.openElements()->top() == m_tree.openElements()->htmlElement()); + + // Note: in the fragment case the root is a DocumentFragment instead of + // a proper html element which is a quirk in Blink's implementation. + DCHECK(!isParsingTemplateContents()); + DCHECK(!isParsingFragment() || toDocumentFragment(m_tree.openElements()->topNode())); + DCHECK(isParsingFragment() || m_tree.openElements()->top() == m_tree.openElements()->htmlElement()); m_tree.insertHTMLElement(token); setInsertionMode(InFramesetMode); return;
diff --git a/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp b/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp index e7a2086..8a9ad0bd 100644 --- a/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp
@@ -100,7 +100,7 @@ void SVGStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& value) { if (name == SVGNames::titleAttr) { - if (m_sheet) + if (m_sheet && isInDocumentTree()) m_sheet->setTitle(value); return;
diff --git a/third_party/WebKit/Source/platform/SharedBuffer.cpp b/third_party/WebKit/Source/platform/SharedBuffer.cpp index 02006e7..6ce6466 100644 --- a/third_party/WebKit/Source/platform/SharedBuffer.cpp +++ b/third_party/WebKit/Source/platform/SharedBuffer.cpp
@@ -240,25 +240,27 @@ return 0; } -bool SharedBuffer::getAsBytesInternal(void* dest, size_t byteLength) const +bool SharedBuffer::getAsBytesInternal(void* dest, size_t loadPosition, size_t byteLength) const { - if (!dest || byteLength != size()) + if (!dest) return false; - const char* segment = 0; - size_t position = 0; - while (size_t segmentSize = getSomeDataInternal(segment, position)) { - memcpy(static_cast<char*>(dest) + position, segment, segmentSize); - position += segmentSize; + const char* segment = nullptr; + size_t writePosition = 0; + while (byteLength > 0) { + size_t loadSize = getSomeDataInternal(segment, loadPosition); + if (loadSize == 0) + break; + + if (byteLength < loadSize) + loadSize = byteLength; + memcpy(static_cast<char*>(dest) + writePosition, segment, loadSize); + loadPosition += loadSize; + writePosition += loadSize; + byteLength -= loadSize; } - if (position != byteLength) { - ASSERT_NOT_REACHED(); - // Don't return the incomplete data. - return false; - } - - return true; + return byteLength == 0; } sk_sp<SkData> SharedBuffer::getAsSkData() const
diff --git a/third_party/WebKit/Source/platform/SharedBuffer.h b/third_party/WebKit/Source/platform/SharedBuffer.h index b03aa858..a8d96c0 100644 --- a/third_party/WebKit/Source/platform/SharedBuffer.h +++ b/third_party/WebKit/Source/platform/SharedBuffer.h
@@ -125,7 +125,20 @@ bool getAsBytes(void* dest, STRICTLY_TYPED_ARG(byteLength)) const { STRICT_ARG_TYPE(size_t); - return getAsBytesInternal(dest, byteLength); + if (byteLength != size()) + return false; + + return getAsBytesInternal(dest, 0, byteLength); + } + + // Copies "byteLength" bytes from "position"-th bytes (0 origin) of the content + // data into "dest" as a flat buffer, + // Returns true on success, otherwise the content of "dest" is not guaranteed. + HAS_STRICTLY_TYPED_ARG + bool getPartAsBytes(void* dest, STRICTLY_TYPED_ARG(position), STRICTLY_TYPED_ARG(byteLength)) const + { + STRICT_ARG_TYPE(size_t); + return getAsBytesInternal(dest, position, byteLength); } // Creates an SkData and copies this SharedBuffer's contents to that @@ -155,7 +168,7 @@ void mergeSegmentsIntoBuffer() const; void appendInternal(const char* data, size_t); - bool getAsBytesInternal(void* dest, size_t) const; + bool getAsBytesInternal(void* dest, size_t, size_t) const; size_t getSomeDataInternal(const char*& data, size_t position) const; size_t m_size;
diff --git a/third_party/WebKit/Source/platform/SharedBufferTest.cpp b/third_party/WebKit/Source/platform/SharedBufferTest.cpp index a93154e..904b274 100644 --- a/third_party/WebKit/Source/platform/SharedBufferTest.cpp +++ b/third_party/WebKit/Source/platform/SharedBufferTest.cpp
@@ -59,6 +59,32 @@ EXPECT_EQ(0, memcmp(expectedConcatenation, data.get(), strlen(expectedConcatenation))); } +TEST(SharedBufferTest, getPartAsBytes) +{ + char testData0[] = "Hello"; + char testData1[] = "World"; + char testData2[] = "Goodbye"; + + RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(testData0, strlen(testData0)); + sharedBuffer->append(testData1, strlen(testData1)); + sharedBuffer->append(testData2, strlen(testData2)); + + struct TestData { + size_t position; + size_t size; + const char* expected; + } testData[] = { + {0, 17, "HelloWorldGoodbye"}, + {0, 7, "HelloWo"}, + {4, 7, "oWorldG"}, + }; + for (TestData& test : testData) { + std::unique_ptr<char[]> data = wrapArrayUnique(new char[test.size]); + ASSERT_TRUE(sharedBuffer->getPartAsBytes(data.get(), test.position, test.size)); + EXPECT_EQ(0, memcmp(test.expected, data.get(), test.size)); + } +} + TEST(SharedBufferTest, getAsBytesLargeSegments) { Vector<char> vector0(0x4000);
diff --git a/third_party/WebKit/Source/platform/animation/CompositorAnimation.cpp b/third_party/WebKit/Source/platform/animation/CompositorAnimation.cpp index 63becca..e9aaf24 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorAnimation.cpp +++ b/third_party/WebKit/Source/platform/animation/CompositorAnimation.cpp
@@ -133,7 +133,7 @@ DCHECK_EQ(cc::AnimationCurve::FLOAT, curve->Type()); auto keyframedCurve = base::WrapUnique(static_cast<cc::KeyframedFloatAnimationCurve*>(curve->Clone().release())); - return CompositorFloatAnimationCurve::CreateForTesting(std::move(keyframedCurve)); + return CompositorFloatAnimationCurve::createForTesting(std::move(keyframedCurve)); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp index df10488..645e227 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp +++ b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp
@@ -20,12 +20,9 @@ { } -void CompositorFilterAnimationCurve::addKeyframe(const CompositorFilterKeyframe& keyframe, const TimingFunction& timingFunction) +void CompositorFilterAnimationCurve::addKeyframe(const CompositorFilterKeyframe& keyframe) { - const cc::FilterOperations& filterOperations = keyframe.value().asFilterOperations(); - m_curve->AddKeyframe(cc::FilterKeyframe::Create( - base::TimeDelta::FromSecondsD(keyframe.time()), filterOperations, - timingFunction.cloneToCC())); + m_curve->AddKeyframe(keyframe.cloneToCC()); } void CompositorFilterAnimationCurve::setTimingFunction(const TimingFunction& timingFunction)
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h index a2d95ee9..2a6ae5f 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h +++ b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h
@@ -33,7 +33,7 @@ } ~CompositorFilterAnimationCurve() override; - void addKeyframe(const CompositorFilterKeyframe&, const TimingFunction&); + void addKeyframe(const CompositorFilterKeyframe&); void setTimingFunction(const TimingFunction&); // blink::CompositorAnimationCurve implementation.
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFilterKeyframe.cpp b/third_party/WebKit/Source/platform/animation/CompositorFilterKeyframe.cpp index d67ba928..3cabf96 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorFilterKeyframe.cpp +++ b/third_party/WebKit/Source/platform/animation/CompositorFilterKeyframe.cpp
@@ -4,19 +4,33 @@ #include "platform/animation/CompositorFilterKeyframe.h" +#include "platform/animation/TimingFunction.h" #include <memory> namespace blink { -CompositorFilterKeyframe::CompositorFilterKeyframe(double time, std::unique_ptr<CompositorFilterOperations> value) - : m_time(time) - , m_value(std::move(value)) +CompositorFilterKeyframe::CompositorFilterKeyframe(double time, const CompositorFilterOperations& value, const TimingFunction& timingFunction) + : m_filterKeyframe(cc::FilterKeyframe::Create(base::TimeDelta::FromSecondsD(time), value.asFilterOperations(), timingFunction.cloneToCC())) { } CompositorFilterKeyframe::~CompositorFilterKeyframe() { - m_value.reset(); +} + +double CompositorFilterKeyframe::time() const +{ + return m_filterKeyframe->Time().InSecondsF(); +} + +const cc::TimingFunction* CompositorFilterKeyframe::ccTimingFunction() const +{ + return m_filterKeyframe->timing_function(); +} + +std::unique_ptr<cc::FilterKeyframe> CompositorFilterKeyframe::cloneToCC() const +{ + return m_filterKeyframe->Clone(); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFilterKeyframe.h b/third_party/WebKit/Source/platform/animation/CompositorFilterKeyframe.h index bbecf3fa..dab49b3 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorFilterKeyframe.h +++ b/third_party/WebKit/Source/platform/animation/CompositorFilterKeyframe.h
@@ -5,24 +5,30 @@ #ifndef CompositorFilterKeyframe_h #define CompositorFilterKeyframe_h +#include "cc/animation/keyframed_animation_curve.h" #include "platform/PlatformExport.h" +#include "platform/animation/CompositorKeyframe.h" #include "platform/graphics/CompositorFilterOperations.h" -#include <memory> +#include "wtf/Noncopyable.h" namespace blink { -class PLATFORM_EXPORT CompositorFilterKeyframe { +class TimingFunction; + +class PLATFORM_EXPORT CompositorFilterKeyframe : public CompositorKeyframe { + WTF_MAKE_NONCOPYABLE(CompositorFilterKeyframe); public: - CompositorFilterKeyframe(double time, std::unique_ptr<CompositorFilterOperations>); + CompositorFilterKeyframe(double time, const CompositorFilterOperations& value, const TimingFunction&); ~CompositorFilterKeyframe(); - double time() const { return m_time; } + std::unique_ptr<cc::FilterKeyframe> cloneToCC() const; - const CompositorFilterOperations& value() const { return *m_value.get(); } + // CompositorKeyframe implementation. + double time() const override; + const cc::TimingFunction* ccTimingFunction() const override; private: - double m_time; - std::unique_ptr<CompositorFilterOperations> m_value; + std::unique_ptr<cc::FilterKeyframe> m_filterKeyframe; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp index 88874c1..7640ac8 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp +++ b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp
@@ -26,56 +26,27 @@ { } -std::unique_ptr<CompositorFloatAnimationCurve> CompositorFloatAnimationCurve::CreateForTesting(std::unique_ptr<cc::KeyframedFloatAnimationCurve> curve) +std::unique_ptr<CompositorFloatAnimationCurve> CompositorFloatAnimationCurve::createForTesting(std::unique_ptr<cc::KeyframedFloatAnimationCurve> curve) { return wrapUnique(new CompositorFloatAnimationCurve(std::move(curve))); } -Vector<CompositorFloatKeyframe> CompositorFloatAnimationCurve::keyframesForTesting() const +CompositorFloatAnimationCurve::Keyframes CompositorFloatAnimationCurve::keyframesForTesting() const { - Vector<CompositorFloatKeyframe> keyframes; - for (const auto& ccKeyframe : m_curve->keyframes_for_testing()) { - CompositorFloatKeyframe keyframe(ccKeyframe->Time().InSecondsF(), ccKeyframe->Value()); - keyframes.append(keyframe); - } + Keyframes keyframes; + for (const auto& ccKeyframe : m_curve->keyframes_for_testing()) + keyframes.append(wrapUnique(new CompositorFloatKeyframe(ccKeyframe->Clone()))); return keyframes; } -CubicBezierTimingFunction::EaseType CompositorFloatAnimationCurve::getCurveEaseTypeForTesting() const +PassRefPtr<TimingFunction> CompositorFloatAnimationCurve::getTimingFunctionForTesting() const { - const cc::TimingFunction* timingFunction = m_curve->timing_function_for_testing(); - DCHECK(timingFunction); - DCHECK_EQ(timingFunction->GetType(), cc::TimingFunction::Type::CUBIC_BEZIER); - auto cubicTimingFunction = static_cast<const cc::CubicBezierTimingFunction*>(timingFunction); - return cubicTimingFunction->ease_type(); + return createCompositorTimingFunctionFromCC(m_curve->timing_function_for_testing()); } -bool CompositorFloatAnimationCurve::curveHasLinearTimingFunctionForTesting() const +void CompositorFloatAnimationCurve::addKeyframe(const CompositorFloatKeyframe& keyframe) { - return !m_curve->timing_function_for_testing(); -} - -CubicBezierTimingFunction::EaseType CompositorFloatAnimationCurve::getKeyframeEaseTypeForTesting(unsigned long index) const -{ - DCHECK_LT(index, m_curve->keyframes_for_testing().size()); - const cc::TimingFunction* timingFunction = m_curve->keyframes_for_testing()[index]->timing_function(); - DCHECK(timingFunction); - DCHECK_EQ(timingFunction->GetType(), cc::TimingFunction::Type::CUBIC_BEZIER); - auto cubicTimingFunction = static_cast<const cc::CubicBezierTimingFunction*>(timingFunction); - return cubicTimingFunction->ease_type(); -} - -bool CompositorFloatAnimationCurve::keyframeHasLinearTimingFunctionForTesting(unsigned long index) const -{ - DCHECK_LT(index, m_curve->keyframes_for_testing().size()); - return !m_curve->keyframes_for_testing()[index]->timing_function(); -} - -void CompositorFloatAnimationCurve::addKeyframe(const CompositorFloatKeyframe& keyframe, const TimingFunction& timingFunction) -{ - m_curve->AddKeyframe(cc::FloatKeyframe::Create( - base::TimeDelta::FromSecondsD(keyframe.time), keyframe.value, - timingFunction.cloneToCC())); + m_curve->AddKeyframe(keyframe.cloneToCC()); } void CompositorFloatAnimationCurve::setTimingFunction(const TimingFunction& timingFunction)
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h index 00b6312f..1b82b90 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h +++ b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h
@@ -10,6 +10,7 @@ #include "platform/animation/CompositorFloatKeyframe.h" #include "platform/animation/TimingFunction.h" #include "wtf/Noncopyable.h" +#include "wtf/PassRefPtr.h" #include "wtf/PtrUtil.h" #include "wtf/Vector.h" #include <memory> @@ -19,7 +20,7 @@ } namespace blink { -struct CompositorFloatKeyframe; +class CompositorFloatKeyframe; } namespace blink { @@ -35,23 +36,20 @@ ~CompositorFloatAnimationCurve() override; - static std::unique_ptr<CompositorFloatAnimationCurve> CreateForTesting(std::unique_ptr<cc::KeyframedFloatAnimationCurve>); - Vector<CompositorFloatKeyframe> keyframesForTesting() const; - - // TODO(loyso): Erase these methods once blink/cc timing functions unified. - CubicBezierTimingFunction::EaseType getCurveEaseTypeForTesting() const; - bool curveHasLinearTimingFunctionForTesting() const; - CubicBezierTimingFunction::EaseType getKeyframeEaseTypeForTesting(unsigned long index) const; - bool keyframeHasLinearTimingFunctionForTesting(unsigned long index) const; - - void addKeyframe(const CompositorFloatKeyframe&, const TimingFunction&); + void addKeyframe(const CompositorFloatKeyframe&); void setTimingFunction(const TimingFunction&); - float getValue(double time) const; // CompositorAnimationCurve implementation. std::unique_ptr<cc::AnimationCurve> cloneToAnimationCurve() const override; + static std::unique_ptr<CompositorFloatAnimationCurve> createForTesting(std::unique_ptr<cc::KeyframedFloatAnimationCurve>); + + using Keyframes = Vector<std::unique_ptr<CompositorFloatKeyframe>>; + Keyframes keyframesForTesting() const; + + PassRefPtr<TimingFunction> getTimingFunctionForTesting() const; + private: CompositorFloatAnimationCurve(); CompositorFloatAnimationCurve(std::unique_ptr<cc::KeyframedFloatAnimationCurve>);
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurveTest.cpp b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurveTest.cpp index 7cb88f5..88d2c50 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurveTest.cpp +++ b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurveTest.cpp
@@ -19,7 +19,7 @@ TEST(WebFloatAnimationCurveTest, OneFloatKeyframe) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 2), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 2, *LinearTimingFunction::shared())); EXPECT_FLOAT_EQ(2, curve->getValue(-1)); EXPECT_FLOAT_EQ(2, curve->getValue(0)); EXPECT_FLOAT_EQ(2, curve->getValue(0.5)); @@ -31,8 +31,8 @@ TEST(WebFloatAnimationCurveTest, TwoFloatKeyframe) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 2), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(1, 4), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 2, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(1, 4, *LinearTimingFunction::shared())); EXPECT_FLOAT_EQ(2, curve->getValue(-1)); EXPECT_FLOAT_EQ(2, curve->getValue(0)); EXPECT_FLOAT_EQ(3, curve->getValue(0.5)); @@ -44,9 +44,9 @@ TEST(WebFloatAnimationCurveTest, ThreeFloatKeyframe) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 2), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(1, 4), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(2, 8), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 2, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(1, 4, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(2, 8, *LinearTimingFunction::shared())); EXPECT_FLOAT_EQ(2, curve->getValue(-1)); EXPECT_FLOAT_EQ(2, curve->getValue(0)); EXPECT_FLOAT_EQ(3, curve->getValue(0.5)); @@ -60,10 +60,10 @@ TEST(WebFloatAnimationCurveTest, RepeatedFloatKeyTimes) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 4), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(1, 4), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(1, 6), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(2, 6), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 4, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(1, 4, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(1, 6, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(2, 6, *LinearTimingFunction::shared())); EXPECT_FLOAT_EQ(4, curve->getValue(-1)); EXPECT_FLOAT_EQ(4, curve->getValue(0)); @@ -82,9 +82,9 @@ TEST(WebFloatAnimationCurveTest, UnsortedKeyframes) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(2, 8), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(0, 2), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(1, 4), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(2, 8, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(0, 2, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(1, 4, *LinearTimingFunction::shared())); EXPECT_FLOAT_EQ(2, curve->getValue(-1)); EXPECT_FLOAT_EQ(2, curve->getValue(0)); @@ -100,8 +100,8 @@ { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); RefPtr<CubicBezierTimingFunction> cubic = CubicBezierTimingFunction::create(0.25, 0, 0.75, 1); - curve->addKeyframe(CompositorFloatKeyframe(0, 0), *cubic); - curve->addKeyframe(CompositorFloatKeyframe(1, 1), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 0, *cubic)); + curve->addKeyframe(CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); EXPECT_FLOAT_EQ(0, curve->getValue(0)); EXPECT_LT(0, curve->getValue(0.25)); @@ -116,8 +116,8 @@ TEST(WebFloatAnimationCurveTest, EaseTimingFunction) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 0), *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE)); - curve->addKeyframe(CompositorFloatKeyframe(1, 1), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 0, *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE))); + curve->addKeyframe(CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); std::unique_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::CreatePreset(CubicBezierTimingFunction::EaseType::EASE)); @@ -131,8 +131,8 @@ TEST(WebFloatAnimationCurveTest, LinearTimingFunction) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 0), *LinearTimingFunction::shared()); - curve->addKeyframe(CompositorFloatKeyframe(1, 1), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 0, *LinearTimingFunction::shared())); + curve->addKeyframe(CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); for (int i = 0; i <= 4; ++i) { const double time = i * 0.25; @@ -144,8 +144,8 @@ TEST(WebFloatAnimationCurveTest, EaseInTimingFunction) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 0), *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN)); - curve->addKeyframe(CompositorFloatKeyframe(1, 1), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 0, *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN))); + curve->addKeyframe(CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); std::unique_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::CreatePreset(CubicBezierTimingFunction::EaseType::EASE_IN)); @@ -159,8 +159,8 @@ TEST(WebFloatAnimationCurveTest, EaseOutTimingFunction) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 0), *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT)); - curve->addKeyframe(CompositorFloatKeyframe(1, 1), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 0, *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT))); + curve->addKeyframe(CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); std::unique_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::CreatePreset(CubicBezierTimingFunction::EaseType::EASE_OUT)); @@ -174,8 +174,8 @@ TEST(WebFloatAnimationCurveTest, EaseInOutTimingFunction) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 0), *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT)); - curve->addKeyframe(CompositorFloatKeyframe(1, 1), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 0, *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT))); + curve->addKeyframe(CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); std::unique_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::CreatePreset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT)); @@ -194,8 +194,8 @@ double x2 = 0.8; double y2 = 0.7; RefPtr<CubicBezierTimingFunction> cubic = CubicBezierTimingFunction::create(x1, y1, x2, y2); - curve->addKeyframe(CompositorFloatKeyframe(0, 0), *cubic); - curve->addKeyframe(CompositorFloatKeyframe(1, 1), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 0, *cubic)); + curve->addKeyframe(CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); std::unique_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)); @@ -209,8 +209,8 @@ TEST(WebFloatAnimationCurveTest, DefaultTimingFunction) { std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0, 0), *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE)); - curve->addKeyframe(CompositorFloatKeyframe(1, 1), *LinearTimingFunction::shared()); + curve->addKeyframe(CompositorFloatKeyframe(0, 0, *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE))); + curve->addKeyframe(CompositorFloatKeyframe(1, 1, *LinearTimingFunction::shared())); std::unique_ptr<cc::TimingFunction> timingFunction( cc::CubicBezierTimingFunction::CreatePreset(CubicBezierTimingFunction::EaseType::EASE));
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatKeyframe.cpp b/third_party/WebKit/Source/platform/animation/CompositorFloatKeyframe.cpp new file mode 100644 index 0000000..42eb200 --- /dev/null +++ b/third_party/WebKit/Source/platform/animation/CompositorFloatKeyframe.cpp
@@ -0,0 +1,40 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/animation/CompositorFloatKeyframe.h" + +#include "platform/animation/TimingFunction.h" + +namespace blink { + +CompositorFloatKeyframe::CompositorFloatKeyframe(double time, float value, const TimingFunction& timingFunction) + : m_floatKeyframe(cc::FloatKeyframe::Create(base::TimeDelta::FromSecondsD(time), value, timingFunction.cloneToCC())) +{ +} + +CompositorFloatKeyframe::CompositorFloatKeyframe(std::unique_ptr<cc::FloatKeyframe> floatKeyframe) + : m_floatKeyframe(std::move(floatKeyframe)) +{ +} + +CompositorFloatKeyframe::~CompositorFloatKeyframe() +{ +} + +double CompositorFloatKeyframe::time() const +{ + return m_floatKeyframe->Time().InSecondsF(); +} + +const cc::TimingFunction* CompositorFloatKeyframe::ccTimingFunction() const +{ + return m_floatKeyframe->timing_function(); +} + +std::unique_ptr<cc::FloatKeyframe> CompositorFloatKeyframe::cloneToCC() const +{ + return m_floatKeyframe->Clone(); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatKeyframe.h b/third_party/WebKit/Source/platform/animation/CompositorFloatKeyframe.h index 6d22d29..24ddf71 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorFloatKeyframe.h +++ b/third_party/WebKit/Source/platform/animation/CompositorFloatKeyframe.h
@@ -5,17 +5,31 @@ #ifndef CompositorFloatKeyframe_h #define CompositorFloatKeyframe_h +#include "cc/animation/keyframed_animation_curve.h" +#include "platform/PlatformExport.h" +#include "platform/animation/CompositorKeyframe.h" +#include "wtf/Noncopyable.h" + namespace blink { -struct CompositorFloatKeyframe { - CompositorFloatKeyframe(double time, float value) - : time(time) - , value(value) - { - } +class TimingFunction; - double time; - float value; +class PLATFORM_EXPORT CompositorFloatKeyframe : public CompositorKeyframe { + WTF_MAKE_NONCOPYABLE(CompositorFloatKeyframe); +public: + CompositorFloatKeyframe(double time, float value, const TimingFunction&); + CompositorFloatKeyframe(std::unique_ptr<cc::FloatKeyframe>); + ~CompositorFloatKeyframe() override; + + // CompositorKeyframe implementation. + double time() const override; + const cc::TimingFunction* ccTimingFunction() const override; + + float value() { return m_floatKeyframe->Value(); } + std::unique_ptr<cc::FloatKeyframe> cloneToCC() const; + +private: + std::unique_ptr<cc::FloatKeyframe> m_floatKeyframe; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorKeyframe.cpp b/third_party/WebKit/Source/platform/animation/CompositorKeyframe.cpp new file mode 100644 index 0000000..e22613e --- /dev/null +++ b/third_party/WebKit/Source/platform/animation/CompositorKeyframe.cpp
@@ -0,0 +1,16 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/animation/CompositorKeyframe.h" + +#include "platform/animation/TimingFunction.h" + +namespace blink { + +PassRefPtr<TimingFunction> CompositorKeyframe::getTimingFunctionForTesting() const +{ + return createCompositorTimingFunctionFromCC(ccTimingFunction()); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorKeyframe.h b/third_party/WebKit/Source/platform/animation/CompositorKeyframe.h new file mode 100644 index 0000000..fc8ed52 --- /dev/null +++ b/third_party/WebKit/Source/platform/animation/CompositorKeyframe.h
@@ -0,0 +1,33 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CompositorKeyframe_h +#define CompositorKeyframe_h + +#include "platform/PlatformExport.h" +#include "wtf/PassRefPtr.h" + +namespace cc { +class TimingFunction; +} + +namespace blink { + +class TimingFunction; + +class PLATFORM_EXPORT CompositorKeyframe { +public: + virtual ~CompositorKeyframe() {} + + virtual double time() const = 0; + + PassRefPtr<TimingFunction> getTimingFunctionForTesting() const; + +private: + virtual const cc::TimingFunction* ccTimingFunction() const = 0; +}; + +} // namespace blink + +#endif // CompositorKeyframe_h
diff --git a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp index 722f4be..de26f28 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp +++ b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp
@@ -20,12 +20,9 @@ { } -void CompositorTransformAnimationCurve::addKeyframe(const CompositorTransformKeyframe& keyframe, const TimingFunction& timingFunction) +void CompositorTransformAnimationCurve::addKeyframe(const CompositorTransformKeyframe& keyframe) { - const cc::TransformOperations& transformOperations = keyframe.value().asTransformOperations(); - m_curve->AddKeyframe(cc::TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(keyframe.time()), transformOperations, - timingFunction.cloneToCC())); + m_curve->AddKeyframe(keyframe.cloneToCC()); } void CompositorTransformAnimationCurve::setTimingFunction(const TimingFunction& timingFunction)
diff --git a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h index ac63cd0..528fd29 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h +++ b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h
@@ -34,7 +34,7 @@ ~CompositorTransformAnimationCurve() override; - void addKeyframe(const CompositorTransformKeyframe&, const TimingFunction&); + void addKeyframe(const CompositorTransformKeyframe&); void setTimingFunction(const TimingFunction&); // CompositorAnimationCurve implementation.
diff --git a/third_party/WebKit/Source/platform/animation/CompositorTransformKeyframe.cpp b/third_party/WebKit/Source/platform/animation/CompositorTransformKeyframe.cpp index 0bcc1d2..cc0656b 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorTransformKeyframe.cpp +++ b/third_party/WebKit/Source/platform/animation/CompositorTransformKeyframe.cpp
@@ -8,25 +8,28 @@ namespace blink { -CompositorTransformKeyframe::CompositorTransformKeyframe(double time, std::unique_ptr<CompositorTransformOperations> value) - : m_time(time) - , m_value(std::move(value)) +CompositorTransformKeyframe::CompositorTransformKeyframe(double time, const CompositorTransformOperations& value, const TimingFunction& timingFunction) + : m_transformKeyframe(cc::TransformKeyframe::Create(base::TimeDelta::FromSecondsD(time), value.asTransformOperations(), timingFunction.cloneToCC())) { } CompositorTransformKeyframe::~CompositorTransformKeyframe() { - m_value.reset(); } double CompositorTransformKeyframe::time() const { - return m_time; + return m_transformKeyframe->Time().InSecondsF(); } -const CompositorTransformOperations& CompositorTransformKeyframe::value() const +const cc::TimingFunction* CompositorTransformKeyframe::ccTimingFunction() const { - return *m_value.get(); + return m_transformKeyframe->timing_function(); +} + +std::unique_ptr<cc::TransformKeyframe> CompositorTransformKeyframe::cloneToCC() const +{ + return m_transformKeyframe->Clone(); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorTransformKeyframe.h b/third_party/WebKit/Source/platform/animation/CompositorTransformKeyframe.h index 1eeecd6..c8f339f 100644 --- a/third_party/WebKit/Source/platform/animation/CompositorTransformKeyframe.h +++ b/third_party/WebKit/Source/platform/animation/CompositorTransformKeyframe.h
@@ -5,25 +5,29 @@ #ifndef CompositorTransformKeyframe_h #define CompositorTransformKeyframe_h +#include "cc/animation/keyframed_animation_curve.h" #include "platform/PlatformExport.h" +#include "platform/animation/CompositorKeyframe.h" #include "platform/animation/CompositorTransformOperations.h" +#include "platform/animation/TimingFunction.h" #include "wtf/Noncopyable.h" -#include <memory> namespace blink { -class PLATFORM_EXPORT CompositorTransformKeyframe { +class PLATFORM_EXPORT CompositorTransformKeyframe : public CompositorKeyframe { WTF_MAKE_NONCOPYABLE(CompositorTransformKeyframe); public: - CompositorTransformKeyframe(double time, std::unique_ptr<CompositorTransformOperations> value); + CompositorTransformKeyframe(double time, const CompositorTransformOperations& value, const TimingFunction&); ~CompositorTransformKeyframe(); - double time() const; - const CompositorTransformOperations& value() const; + std::unique_ptr<cc::TransformKeyframe> cloneToCC() const; + + // CompositorKeyframe implementation. + double time() const override; + const cc::TimingFunction* ccTimingFunction() const override; private: - double m_time; - std::unique_ptr<CompositorTransformOperations> m_value; + std::unique_ptr<cc::TransformKeyframe> m_transformKeyframe; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunction.cpp b/third_party/WebKit/Source/platform/animation/TimingFunction.cpp index c13b4ed..aea7cda 100644 --- a/third_party/WebKit/Source/platform/animation/TimingFunction.cpp +++ b/third_party/WebKit/Source/platform/animation/TimingFunction.cpp
@@ -121,6 +121,33 @@ } +PassRefPtr<TimingFunction> createCompositorTimingFunctionFromCC(const cc::TimingFunction* timingFunction) +{ + if (!timingFunction) + return LinearTimingFunction::shared(); + + switch (timingFunction->GetType()) { + case cc::TimingFunction::Type::CUBIC_BEZIER: { + auto cubicTimingFunction = static_cast<const cc::CubicBezierTimingFunction*>(timingFunction); + if (cubicTimingFunction->ease_type() != cc::CubicBezierTimingFunction::EaseType::CUSTOM) + return CubicBezierTimingFunction::preset(cubicTimingFunction->ease_type()); + + const auto& bezier = cubicTimingFunction->bezier(); + return CubicBezierTimingFunction::create(bezier.GetX1(), bezier.GetY1(), bezier.GetX2(), bezier.GetY2()); + } + + case cc::TimingFunction::Type::STEPS: { + auto stepsTimingFunction = static_cast<const cc::StepsTimingFunction*>(timingFunction); + return StepsTimingFunction::create(stepsTimingFunction->steps(), stepsTimingFunction->step_position()); + } + + default: + NOTREACHED(); + return nullptr; + } +} + + // Equals operators bool operator==(const LinearTimingFunction& lhs, const TimingFunction& rhs) {
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunction.h b/third_party/WebKit/Source/platform/animation/TimingFunction.h index c792adb0..386abd59 100644 --- a/third_party/WebKit/Source/platform/animation/TimingFunction.h +++ b/third_party/WebKit/Source/platform/animation/TimingFunction.h
@@ -212,6 +212,8 @@ std::unique_ptr<cc::StepsTimingFunction> m_steps; }; +PLATFORM_EXPORT PassRefPtr<TimingFunction> createCompositorTimingFunctionFromCC(const cc::TimingFunction*); + PLATFORM_EXPORT bool operator==(const LinearTimingFunction&, const TimingFunction&); PLATFORM_EXPORT bool operator==(const CubicBezierTimingFunction&, const TimingFunction&); PLATFORM_EXPORT bool operator==(const StepsTimingFunction&, const TimingFunction&);
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi index 7f4084b..d619bfd 100644 --- a/third_party/WebKit/Source/platform/blink_platform.gypi +++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -165,7 +165,10 @@ 'animation/CompositorFilterKeyframe.h', 'animation/CompositorFloatAnimationCurve.cpp', 'animation/CompositorFloatAnimationCurve.h', + 'animation/CompositorFloatKeyframe.cpp', 'animation/CompositorFloatKeyframe.h', + 'animation/CompositorKeyframe.cpp', + 'animation/CompositorKeyframe.h', 'animation/CompositorScrollOffsetAnimationCurve.cpp', 'animation/CompositorScrollOffsetAnimationCurve.h', 'animation/CompositorTargetProperty.h',
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp index f17cef0..76e307f5 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -108,7 +108,7 @@ ASSERT_FALSE(m_platformLayer->hasActiveAnimationForTesting()); std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::create(); - curve->addKeyframe(CompositorFloatKeyframe(0.0, 0.0), *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE)); + curve->addKeyframe(CompositorFloatKeyframe(0.0, 0.0, *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE))); std::unique_ptr<CompositorAnimation> floatAnimation(CompositorAnimation::create(*curve, CompositorTargetProperty::OPACITY, 0, 0)); int animationId = floatAnimation->id();
diff --git a/third_party/WebKit/Source/web/LinkHighlightImpl.cpp b/third_party/WebKit/Source/web/LinkHighlightImpl.cpp index 041f80e..fa8f552d 100644 --- a/third_party/WebKit/Source/web/LinkHighlightImpl.cpp +++ b/third_party/WebKit/Source/web/LinkHighlightImpl.cpp
@@ -313,13 +313,13 @@ const auto& timingFunction = *CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE); - curve->addKeyframe(CompositorFloatKeyframe(0, startOpacity), timingFunction); + curve->addKeyframe(CompositorFloatKeyframe(0, startOpacity, timingFunction)); // Make sure we have displayed for at least minPreFadeDuration before starting to fade out. float extraDurationRequired = std::max(0.f, minPreFadeDuration - static_cast<float>(monotonicallyIncreasingTime() - m_startTime)); if (extraDurationRequired) - curve->addKeyframe(CompositorFloatKeyframe(extraDurationRequired, startOpacity), timingFunction); + curve->addKeyframe(CompositorFloatKeyframe(extraDurationRequired, startOpacity, timingFunction)); // For layout tests we don't fade out. - curve->addKeyframe(CompositorFloatKeyframe(fadeDuration + extraDurationRequired, layoutTestMode() ? startOpacity : 0), timingFunction); + curve->addKeyframe(CompositorFloatKeyframe(fadeDuration + extraDurationRequired, layoutTestMode() ? startOpacity : 0, timingFunction)); std::unique_ptr<CompositorAnimation> animation = CompositorAnimation::create(*curve, CompositorTargetProperty::OPACITY, 0, 0);
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py index 28d7b0bd..9cbf72f 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
@@ -300,7 +300,7 @@ def git_commit_detail(self, commit, log_format=None): args = ['log', '-1', commit] - if log_format: + if format: args.append('--format=' + log_format) return self._run_git(args)
diff --git a/tools/clang/translation_unit/TranslationUnitGenerator.cpp b/tools/clang/translation_unit/TranslationUnitGenerator.cpp index 3590b0c..4d7524d9 100644 --- a/tools/clang/translation_unit/TranslationUnitGenerator.cpp +++ b/tools/clang/translation_unit/TranslationUnitGenerator.cpp
@@ -31,6 +31,7 @@ #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Path.h" using clang::HeaderSearchOptions; using clang::tooling::CommonOptionsParser;
diff --git a/tools/metrics/histograms/find_unmapped_histograms.py b/tools/metrics/histograms/find_unmapped_histograms.py index e25f52ae..95f5d970 100644 --- a/tools/metrics/histograms/find_unmapped_histograms.py +++ b/tools/metrics/histograms/find_unmapped_histograms.py
@@ -24,6 +24,16 @@ import extract_histograms +C_FILENAME = re.compile(r""" + .* # Anything + \.(cc|cpp|h|mm) # Ending in these extensions + $ # End of string + """, re.VERBOSE) +TEST_FILENAME = re.compile(r""" + .* # Anything + test # The word test + \. # A literal '.' + """, re.VERBOSE) CPP_COMMENT = re.compile(r""" \s* # Optional whitespace (?: # Non-capturing group @@ -185,7 +195,9 @@ # 'path/to/foo.cc:420: UMA_HISTOGRAM_COUNTS_100("FooGroup.FooName",' # 'path/to/bar.cc:632: UMA_HISTOGRAM_ENUMERATION(' locations = RunGit(['gs', 'UMA_HISTOGRAM']).split('\n') - filenames = set([location.split(':')[0] for location in locations]) + all_filenames = set(location.split(':')[0] for location in locations); + filenames = [f for f in all_filenames + if C_FILENAME.match(f) and not TEST_FILENAME.match(f)] histograms = set() location_map = dict()
diff --git a/ui/app_list/presenter/app_list_presenter_impl.cc b/ui/app_list/presenter/app_list_presenter_impl.cc index cd181d1..572528b 100644 --- a/ui/app_list/presenter/app_list_presenter_impl.cc +++ b/ui/app_list/presenter/app_list_presenter_impl.cc
@@ -80,14 +80,12 @@ is_visible_ = false; - // The dismissal may have occurred in response to the app list losing - // activation. Otherwise, our widget is currently active. When the animation - // completes we'll hide the widget, changing activation. If a menu is shown - // before the animation completes then the activation change triggers the menu - // to close. By deactivating now we ensure there is no activation change when - // the animation completes and any menus stay open. - if (view_->GetWidget()->IsActive()) - view_->GetWidget()->Deactivate(); + // Our widget is currently active. When the animation completes we'll hide + // the widget, changing activation. If a menu is shown before the animation + // completes then the activation change triggers the menu to close. By + // deactivating now we ensure there is no activation change when the + // animation completes and any menus stay open. + view_->GetWidget()->Deactivate(); presenter_delegate_->OnDismissed(); ScheduleAnimation();
diff --git a/ui/file_manager/file_manager/background/js/test_util_base.js b/ui/file_manager/file_manager/background/js/test_util_base.js index 2bcb3af..c10a0f2d 100644 --- a/ui/file_manager/file_manager/background/js/test_util_base.js +++ b/ui/file_manager/file_manager/background/js/test_util_base.js
@@ -26,6 +26,7 @@ } var styles = {}; var styleNames = opt_styleNames || []; + assert(Array.isArray(styleNames)); var computedStyles = contentWindow.getComputedStyle(element); for (var i = 0; i < styleNames.length; i++) { styles[styleNames[i]] = computedStyles[styleNames[i]]; @@ -223,32 +224,79 @@ /** * Queries all elements. * - * @param {Window} contentWindow Window to be tested. + * @param {!Window} contentWindow Window to be tested. * @param {string} targetQuery Query to specify the element. * @param {?string} iframeQuery Iframe selector or null if no iframe. * @param {Array<string>=} opt_styleNames List of CSS property name to be * obtained. - * @return {Array<{attributes:Object<string>, text:string, + * @return {!Array<{attributes:Object<string>, text:string, * styles:Object<string>, hidden:boolean}>} Element * information that contains contentText, attribute names and * values, hidden attribute, and style names and values. */ test.util.sync.queryAllElements = function( contentWindow, targetQuery, iframeQuery, opt_styleNames) { + return test.util.sync.deepQueryAllElements( + contentWindow, [targetQuery], iframeQuery, opt_styleNames); +}; + +/** + * Queries elements inside shadow DOM. + * + * @param {!Window} contentWindow Window to be tested. + * @param {!Array<string>} targetQuery Query to specify the element. + * |targetQuery[0]| specifies the first element(s). |targetQuery[1]| specifies + * elements inside the shadow DOM of the first element, and so on. + * @param {?string} iframeQuery Iframe selector or null if no iframe. + * @param {Array<string>=} opt_styleNames List of CSS property name to be + * obtained. + * @return {!Array<{attributes:Object<string>, text:string, + * styles:Object<string>, hidden:boolean}>} Element + * information that contains contentText, attribute names and + * values, hidden attribute, and style names and values. + */ +test.util.sync.deepQueryAllElements = function( + contentWindow, targetQuery, iframeQuery, opt_styleNames) { var doc = test.util.sync.getDocument_( contentWindow, iframeQuery || undefined); if (!doc) return []; - // The return value of querySelectorAll is not an array. - return Array.prototype.map.call( - doc.querySelectorAll(targetQuery), - function(element) { - return extractElementInfo(element, contentWindow, opt_styleNames); - }); + + var elems = test.util.sync.deepQuerySelectorAll_(doc, targetQuery); + return elems.map(function(element) { + return extractElementInfo(element, contentWindow, opt_styleNames); + }); }; /** - * Get the information of the active element. + * Selects elements below |root|, possibly following shadow DOM subtree. + * + * @param {(!HTMLElement|!Document)} root Element to search from. + * @param {!Array<string>} targetQuery Query to specify the element. + * |targetQuery[0]| specifies the first element(s). |targetQuery[1]| specifies + * elements inside the shadow DOM of the first element, and so on. + * @return {!Array<!HTMLElement>} Matched elements. + * + * @private + */ +test.util.sync.deepQuerySelectorAll_ = function(root, targetQuery) { + var elems = Array.prototype.slice.call(root.querySelectorAll(targetQuery[0])); + var remaining = targetQuery.slice(1); + if (remaining.length === 0) + return elems; + + var res = []; + for (var i = 0; i < elems.length; i++) { + if (elems[i].shadowRoot) { + res = res.concat( + test.util.sync.deepQuerySelectorAll_(elems[i].shadowRoot, remaining)); + } + } + return res; +}; + +/** + * Gets the information of the active element. * * @param {Window} contentWindow Window to be tested. * @param {string} targetQuery Query to specify the element.
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js new file mode 100644 index 0000000..033d52d --- /dev/null +++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -0,0 +1,56 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +'use strict'; + +/** + * Tests opening the Quick View. + */ +testcase.openQuickView = function() { + var appId; + + StepsRunner.run([ + function() { + setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next); + }, + function(results) { + appId = results.windowId; + // Select an image file. + remoteCall.callRemoteTestUtil( + 'selectFile', appId, ['My Desktop Background.png'], this.next); + }, + function(results) { + chrome.test.assertTrue(results); + // Press Space key. + remoteCall.callRemoteTestUtil( + 'fakeKeyDown', appId, + ['#file-list', ' ', ' ', false, false, false], this.next); + }, + function(results) { + chrome.test.assertTrue(results); + + // Wait until Quick View is displayed. + repeatUntil(function() { + return remoteCall + .callRemoteTestUtil( + 'deepQueryAllElements', appId, + [['#quick-view', '#dialog'], null, ['display']]) + .then(function(results) { + chrome.test.assertEq(1, results.length); + if (results[0].styles.display === 'none') { + return pending('Quick View is not opened yet.'); + }; + return results; + }); + }).then(this.next); + }, + function(results) { + chrome.test.assertEq(1, results.length); + // Check Quick View dialog is displayed. + chrome.test.assertEq('block', results[0].styles.display); + + checkIfNoErrorsOccured(this.next); + }, + ]); +};
diff --git a/ui/file_manager/integration_tests/file_manager_test_manifest.json b/ui/file_manager/integration_tests/file_manager_test_manifest.json index 4e979295..eec95004 100644 --- a/ui/file_manager/integration_tests/file_manager_test_manifest.json +++ b/ui/file_manager/integration_tests/file_manager_test_manifest.json
@@ -28,6 +28,7 @@ "file_manager/open_image_files.js", "file_manager/open_video_files.js", "file_manager/providers.js", + "file_manager/quick_view.js", "file_manager/restore_geometry.js", "file_manager/restore_prefs.js", "file_manager/share_dialog.js",
diff --git a/ui/file_manager/integration_tests/remote_call.js b/ui/file_manager/integration_tests/remote_call.js index aa014c6..547e031 100644 --- a/ui/file_manager/integration_tests/remote_call.js +++ b/ui/file_manager/integration_tests/remote_call.js
@@ -26,7 +26,8 @@ }; /** - * Calls a remote test util in Files.app's extension. See: test_util.js. + * Calls a remote test util in Files.app's extension. See: + * registerRemoteTestUtils in test_util_base.js. * * @param {string} func Function name. * @param {?string} appId Target window's App ID or null for functions @@ -59,10 +60,11 @@ appId: appId, args: args }, + {}, function(var_args) { if (stepByStep) { console.info('Returned value:'); - console.info(arguments); + console.info(JSON.stringify(arguments)); } if (opt_callback) opt_callback.apply(null, arguments);